[SCM] blender/upstream: Imported Upstream version 2.63a

mfv-guest at users.alioth.debian.org mfv-guest at users.alioth.debian.org
Sat May 12 18:55:12 UTC 2012


The following commit has been merged in the upstream branch:
commit ec8d47e80d4aa9b3bf180cc17d1b2eaba540dab5
Author: Matteo F. Vescovi <mfv.debian at gmail.com>
Date:   Sat May 12 16:31:19 2012 +0200

    Imported Upstream version 2.63a

diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 9100a27..50b4765 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -41,6 +41,7 @@
 #include <cstdlib>
 #include <cstring>
 #include <cmath>
+#include <sstream>
 
 #include "AUD_NULLDevice.h"
 #include "AUD_I3DDevice.h"
@@ -1236,6 +1237,47 @@ const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int lengt
 	}
 }
 
+const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
+{
+	try
+	{
+		AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get());
+
+		f->setSpecs(specs.specs);
+
+		std::vector<AUD_Reference<AUD_IWriter> > writers;
+
+		int channels = specs.channels;
+		specs.channels = AUD_CHANNELS_MONO;
+
+		for(int i = 0; i < channels; i++)
+		{
+			std::stringstream stream;
+			std::string fn = filename;
+			size_t index = fn.find_last_of('.');
+			size_t index_slash = fn.find_last_of('/');
+			size_t index_backslash = fn.find_last_of('\\');
+			if((index == std::string::npos) ||
+					((index < index_slash) && (index_slash != std::string::npos)) ||
+					((index < index_backslash) && (index_backslash != std::string::npos)))
+				stream << filename << "_" << (i + 1);
+			else
+				stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
+			writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
+		}
+
+		AUD_Reference<AUD_IReader> reader = f->createQualityReader();
+		reader->seek(start);
+		AUD_FileWriter::writeReader(reader, writers, length, buffersize);
+
+		return NULL;
+	}
+	catch(AUD_Exception& e)
+	{
+		return e.str;
+	}
+}
+
 AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
 {
 	try
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 8388af2..a52a1fa 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -710,6 +710,21 @@ extern void* AUD_getSet(void* set);
 extern const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
 
 /**
+ * Mixes a sound down into multiple files.
+ * \param sound The sound scene to mix down.
+ * \param start The start frame.
+ * \param length The count of frames to write.
+ * \param buffersize How many samples should be written at once.
+ * \param filename The file to write to, the channel number and an underscore are added at the beginning.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return An error message or NULL in case of success.
+ */
+extern const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
+
+/**
  * Opens a read device and prepares it for mixdown of the sound scene.
  * \param specs Output audio specifications.
  * \param sequencer The sound scene to mix down.
diff --git a/intern/audaspace/intern/AUD_FileWriter.cpp b/intern/audaspace/intern/AUD_FileWriter.cpp
index df76b66..f74021a 100644
--- a/intern/audaspace/intern/AUD_FileWriter.cpp
+++ b/intern/audaspace/intern/AUD_FileWriter.cpp
@@ -93,3 +93,39 @@ void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, AUD_Referenc
 		writer->write(len, buf);
 	}
 }
+
+void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize)
+{
+	AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
+	AUD_Buffer buffer2(buffersize * sizeof(sample_t));
+	sample_t* buf = buffer.getBuffer();
+	sample_t* buf2 = buffer2.getBuffer();
+
+	int len;
+	bool eos = false;
+	int channels = reader->getSpecs().channels;
+
+	for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
+	{
+		len = buffersize;
+		if((len > length - pos) && (length > 0))
+			len = length - pos;
+		reader->read(len, eos, buf);
+
+		for(int channel = 0; channel < channels; channel++)
+		{
+			for(int i = 0; i < len; i++)
+			{
+				// clamping!
+				if(buf[i * channels + channel] > 1)
+					buf2[i] = 1;
+				else if(buf[i * channels + channel] < -1)
+					buf2[i] = -1;
+				else
+					buf2[i] = buf[i * channels + channel];
+			}
+
+			writers[channel]->write(len, buf2);
+		}
+	}
+}
diff --git a/intern/audaspace/intern/AUD_FileWriter.h b/intern/audaspace/intern/AUD_FileWriter.h
index c9ee2b1..385aba5 100644
--- a/intern/audaspace/intern/AUD_FileWriter.h
+++ b/intern/audaspace/intern/AUD_FileWriter.h
@@ -31,6 +31,7 @@
 #define __AUD_FILEWRITER_H__
 
 #include <string>
+#include <vector>
 
 #include "AUD_Reference.h"
 
@@ -68,6 +69,15 @@ public:
 	 * \param buffersize How many samples should be transfered at once.
 	 */
 	static void writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
+
+	/**
+	 * Writes a reader to several writers.
+	 * \param reader The reader to read from.
+	 * \param writers The writers to write to.
+	 * \param length How many samples should be transfered.
+	 * \param buffersize How many samples should be transfered at once.
+	 */
+	static void writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
 };
 
 #endif //__AUD_FILEWRITER_H__
diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h
index 2e07417..5a1aa94 100644
--- a/intern/audaspace/intern/AUD_Reference.h
+++ b/intern/audaspace/intern/AUD_Reference.h
@@ -31,6 +31,7 @@
 
 #include <map>
 #include <cstddef>
+#include <pthread.h>
 
 // #define MEM_DEBUG
 
@@ -49,8 +50,13 @@ private:
 	 * Saves the reference counts.
 	 */
 	static std::map<void*, unsigned int> m_references;
+	static pthread_mutex_t m_mutex;
+	static bool m_mutex_initialised;
 
 public:
+
+	static pthread_mutex_t* getMutex();
+
 	/**
 	 * Reference increment.
 	 * \param reference The reference.
@@ -108,6 +114,7 @@ public:
 	template <class U>
 	AUD_Reference(U* reference)
 	{
+		pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
 		m_original = reference;
 		m_reference = dynamic_cast<T*>(reference);
 		AUD_ReferenceHandler::incref(m_original);
@@ -115,6 +122,7 @@ public:
 		if(m_reference != NULL)
 			std::cerr << "+" << typeid(*m_reference).name() << std::endl;
 #endif
+		pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
 	}
 
 	AUD_Reference()
@@ -129,6 +137,7 @@ public:
 	 */
 	AUD_Reference(const AUD_Reference& ref)
 	{
+		pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
 		m_original = ref.m_original;
 		m_reference = ref.m_reference;
 		AUD_ReferenceHandler::incref(m_original);
@@ -136,11 +145,13 @@ public:
 		if(m_reference != NULL)
 			std::cerr << "+" << typeid(*m_reference).name() << std::endl;
 #endif
+		pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
 	}
 
 	template <class U>
 	explicit AUD_Reference(const AUD_Reference<U>& ref)
 	{
+		pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
 		m_original = ref.get();
 		m_reference = dynamic_cast<T*>(ref.get());
 		AUD_ReferenceHandler::incref(m_original);
@@ -148,6 +159,7 @@ public:
 		if(m_reference != NULL)
 			std::cerr << "+" << typeid(*m_reference).name() << std::endl;
 #endif
+		pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
 	}
 
 	/**
@@ -156,12 +168,20 @@ public:
 	 */
 	~AUD_Reference()
 	{
+		pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
 #ifdef MEM_DEBUG
 		if(m_reference != NULL)
 			std::cerr << "-" << typeid(*m_reference).name() << std::endl;
 #endif
 		if(AUD_ReferenceHandler::decref(m_original))
+		{
+			pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
 			delete m_reference;
+		}
+		else
+		{
+			pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
+		}
 	}
 
 	/**
@@ -173,12 +193,18 @@ public:
 		if(&ref == this)
 			return *this;
 
+		pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
+
 #ifdef MEM_DEBUG
 		if(m_reference != NULL)
 			std::cerr << "-" << typeid(*m_reference).name() << std::endl;
 #endif
 		if(AUD_ReferenceHandler::decref(m_original))
+		{
+			pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
 			delete m_reference;
+			pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
+		}
 
 		m_original = ref.m_original;
 		m_reference = ref.m_reference;
@@ -188,6 +214,8 @@ public:
 			std::cerr << "+" << typeid(*m_reference).name() << std::endl;
 #endif
 
+		pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
+
 		return *this;
 	}
 
diff --git a/intern/audaspace/intern/AUD_ReferenceHandler.cpp b/intern/audaspace/intern/AUD_ReferenceHandler.cpp
index 24f645d..3e9f670 100644
--- a/intern/audaspace/intern/AUD_ReferenceHandler.cpp
+++ b/intern/audaspace/intern/AUD_ReferenceHandler.cpp
@@ -29,3 +29,24 @@
 #include "AUD_Reference.h"
 
 std::map<void*, unsigned int> AUD_ReferenceHandler::m_references;
+pthread_mutex_t AUD_ReferenceHandler::m_mutex;
+bool AUD_ReferenceHandler::m_mutex_initialised = false;
+
+pthread_mutex_t *AUD_ReferenceHandler::getMutex()
+{
+	if(!m_mutex_initialised)
+	{
+		pthread_mutexattr_t attr;
+		pthread_mutexattr_init(&attr);
+		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+		pthread_mutex_init(&m_mutex, &attr);
+
+		pthread_mutexattr_destroy(&attr);
+
+		m_mutex_initialised = true;
+	}
+
+	return &m_mutex;
+}
+
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 96faee1..f1c0175 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -253,7 +253,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
 	BL::Scene::objects_iterator b_ob;
 
 	for(b_scene.objects.begin(b_ob); b_ob != b_scene.objects.end(); ++b_ob) {
-		bool hide = (b_v3d)? b_ob->hide(): b_ob->hide_render();
+		bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
 		uint ob_layer = get_layer(b_ob->layers());
 
 		if(!hide && (ob_layer & scene_layer)) {
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 5a28629..639308e 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -208,6 +208,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
 			render_layer.holdout_layer = 0;
 			render_layer.material_override = PointerRNA_NULL;
 			render_layer.use_background = true;
+			render_layer.use_viewport_visibility = true;
 			return;
 		}
 	}
@@ -226,6 +227,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
 			render_layer.layer |= render_layer.holdout_layer;
 			render_layer.material_override = b_rlay->material_override();
 			render_layer.use_background = b_rlay->use_sky();
+			render_layer.use_viewport_visibility = false;
 		}
 
 		first_layer = false;
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index d2550a1..68d7da3 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -108,7 +108,8 @@ private:
 		RenderLayerInfo()
 		: scene_layer(0), layer(0), holdout_layer(0),
 		  material_override(PointerRNA_NULL),
-		  use_background(true)
+		  use_background(true),
+		  use_viewport_visibility(false)
 		{}
 
 		string name;
@@ -117,6 +118,7 @@ private:
 		uint holdout_layer;
 		BL::Material material_override;
 		bool use_background;
+		bool use_viewport_visibility;
 	} render_layer;
 };
 
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 0c08baa..0a780e5 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -172,11 +172,18 @@ public:
 
 		CUresult result;
 
-		if(background)
+		if(background) {
 			result = cuCtxCreate(&cuContext, 0, cuDevice);
-		else
+		}
+		else {
 			result = cuGLCtxCreate(&cuContext, 0, cuDevice);
 
+			if(result != CUDA_SUCCESS) {
+				result = cuCtxCreate(&cuContext, 0, cuDevice);
+				background = true;
+			}
+		}
+
 		if(cuda_error(result))
 			return;
 
@@ -686,14 +693,25 @@ public:
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 			glBindTexture(GL_TEXTURE_2D, 0);
 			
-			cuda_assert(cuGraphicsGLRegisterBuffer(&pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE))
+			CUresult result = cuGraphicsGLRegisterBuffer(&pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
 
-			cuda_pop_context();
+			if(!cuda_error(result)) {
+				cuda_pop_context();
 
-			mem.device_pointer = pmem.cuTexId;
-			pixel_mem_map[mem.device_pointer] = pmem;
+				mem.device_pointer = pmem.cuTexId;
+				pixel_mem_map[mem.device_pointer] = pmem;
 
-			return;
+				return;
+			}
+			else {
+				/* failed to register buffer, fallback to no interop */
+				glDeleteBuffers(1, &pmem.cuPBO);
+				glDeleteTextures(1, &pmem.cuTexId);
+
+				cuda_pop_context();
+
+				background = true;
+			}
 		}
 
 		Device::pixels_alloc(mem);
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 019dede..bffed7d 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -487,6 +487,11 @@ __device_inline float len(const float3 a)
 	return sqrtf(dot(a, a));
 }
 
+__device_inline float len_squared(const float3 a)
+{
+	return dot(a, a);
+}
+
 #ifndef __KERNEL_OPENCL__
 
 __device_inline float3 normalize(const float3 a)
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index aeaef7b..a036277 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -233,12 +233,12 @@ __device_inline bool transform_uniform_scale(const Transform& tfm, float& scale)
 	Transform ttfm = transform_transpose(tfm);
 	float eps = 1e-7f; 
 	
-	float sx = len(float4_to_float3(tfm.x));
-	float sy = len(float4_to_float3(tfm.y));
-	float sz = len(float4_to_float3(tfm.z));
-	float stx = len(float4_to_float3(ttfm.x));
-	float sty = len(float4_to_float3(ttfm.y));
-	float stz = len(float4_to_float3(ttfm.z));
+	float sx = len_squared(float4_to_float3(tfm.x));
+	float sy = len_squared(float4_to_float3(tfm.y));
+	float sz = len_squared(float4_to_float3(tfm.z));
+	float stx = len_squared(float4_to_float3(ttfm.x));
+	float sty = len_squared(float4_to_float3(ttfm.y));
+	float stz = len_squared(float4_to_float3(ttfm.z));
 	
 	if(fabsf(sx - sy) < eps && fabsf(sx - sz) < eps &&
 	   fabsf(sx - stx) < eps && fabsf(sx - sty) < eps &&
diff --git a/intern/dualcon/intern/Projections.h b/intern/dualcon/intern/Projections.h
index 18533b2..1477dd9 100644
--- a/intern/dualcon/intern/Projections.h
+++ b/intern/dualcon/intern/Projections.h
@@ -788,17 +788,17 @@ public:
 		LONG proj0 = cubeProj[i][0] ;
 		LONG proj1 = cubeProj[i][0] + cubeProj[i][edgeInd + 1] ;
 		LONG proj2 = inherit->trigProj[i][1] ;
+		LONG d = proj1 - proj0;
+		double alpha;
 
-		// double alpha = (double)( ( proj2 - proj0 ) * cubeProj[edgeInd][edgeInd + 1] ) / (double)( proj1 - proj0 ) ;
-		double alpha = (double)( ( proj2 - proj0 ) ) / (double)( proj1 - proj0 ) ;
-		
-		if ( alpha < 0 )
-		{
-			alpha = 0.5 ;
+		if (d == 0) {
+			alpha = 0.5;
 		}
-		else if ( alpha > 1 )
-		{
-			alpha = 0.5 ;
+		else {
+			alpha = (double)((proj2 - proj0)) / (double)d;
+
+			if (alpha < 0 || alpha > 1)
+				alpha = 0.5;
 		}
 		
 
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
index 1e78caf..565324a 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
@@ -37,6 +37,8 @@ GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
 	setDeadZone(0.1f); /* how to calibrate on Linux? throw away slight motion! */
 
 	if (spnav_open() != -1) {
+		m_available = true;
+
 		/* determine exactly which device (if any) is plugged in */
 
 #define MAX_LINE_LENGTH 100
@@ -49,7 +51,6 @@ GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
 				unsigned short vendor_id = 0, product_id = 0;
 				if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
 					if (setDevice(vendor_id, product_id)) {
-						m_available = true;
 						break; /* stop looking once the first 3D mouse is found */
 					}
 			}
diff --git a/intern/guardedalloc/cpp/mallocn.cpp b/intern/guardedalloc/cpp/mallocn.cpp
index 97e68d0..130fcb6 100644
--- a/intern/guardedalloc/cpp/mallocn.cpp
+++ b/intern/guardedalloc/cpp/mallocn.cpp
@@ -41,5 +41,7 @@ void* operator new (size_t size, const char *str)
 
 void operator delete (void *p)
 {
-	MEM_freeN(p);
+	/* delete NULL is valid in c++ */
+	if(p)
+		MEM_freeN(p);
 }
diff --git a/intern/tools/credits_svn_gen.py b/intern/tools/credits_svn_gen.py
index f3aa2bf..76b3c90 100644
--- a/intern/tools/credits_svn_gen.py
+++ b/intern/tools/credits_svn_gen.py
@@ -255,7 +255,6 @@ author_name_mapping = {
     "xglasyliax": "Peter Larabell",
     "lockal": "Sv. Lockal",
     "kupoman": "Daniel Stokes",
-    "xercesblue": "Francisco De La Cruz",
     # TODO, find remaining names
     "nlin": "",
     }
@@ -499,7 +498,6 @@ def main():
                (fn, now.year, now.month, now.day))
 
     file.close()
-    print("written: credits.html")
 
 if __name__ == "__main__":
     main()
diff --git a/release/scripts/addons/add_mesh_extra_objects/__init__.py b/release/scripts/addons/add_mesh_extra_objects/__init__.py
index adead24..97ec361 100644
--- a/release/scripts/addons/add_mesh_extra_objects/__init__.py
+++ b/release/scripts/addons/add_mesh_extra_objects/__init__.py
@@ -43,6 +43,9 @@ if "bpy" in locals():
     imp.reload(add_mesh_polysphere)
     imp.reload(add_mesh_supertoroid)
     imp.reload(add_mesh_pyramid)
+    imp.reload(add_mesh_torusknot)
+    imp.reload(add_mesh_honeycomb)
+    imp.reload(add_mesh_teapot)
 else:
     from . import add_mesh_extra_objects
     from . import add_mesh_twisted_torus
@@ -52,6 +55,9 @@ else:
     from . import add_mesh_polysphere
     from . import add_mesh_supertoroid
     from . import add_mesh_pyramid
+    from . import add_mesh_torusknot
+    from . import add_mesh_honeycomb
+    from . import add_mesh_teapot
 import bpy
 
 
@@ -67,14 +73,8 @@ class INFO_MT_mesh_extras_add(bpy.types.Menu):
         layout.menu("INFO_MT_mesh_gears_add", text="Gears")
         layout.menu("INFO_MT_mesh_math_add", text="Math Function")
         layout.menu("INFO_MT_mesh_basic_add", text="Basic Objects")
-        layout.operator("mesh.primitive_twisted_torus_add",
-            text="Twisted Torus")
-        layout.operator("mesh.primitive_polysphere_add",
-            text="Polysphere")
-        layout.operator("mesh.primitive_supertoroid_add",
-            text="Supertoroid")
-        layout.operator("mesh.primitive_steppyramid_add",
-            text="Pyramid")
+        layout.menu("INFO_MT_mesh_torus_add", text="Torus Objects")
+        layout.menu("INFO_MT_mesh_misc_add", text="Misc Objects")
 
 class INFO_MT_mesh_gemstones_add(bpy.types.Menu):
     # Define the "Gemstones" menu
@@ -131,7 +131,38 @@ class INFO_MT_mesh_basic_add(bpy.types.Menu):
             text="Star")
         layout.operator("mesh.primitive_trapezohedron_add",
             text="Trapezohedron")
+        layout.operator("mesh.primitive_polysphere_add",
+            text="Polysphere")
+			
+class INFO_MT_mesh_torus_add(bpy.types.Menu):
+    # Define the "Simple Objects" menu
+    bl_idname = "INFO_MT_mesh_torus_add"
+    bl_label = "Torus Objects"
 
+    def draw(self, context):
+        layout = self.layout
+        layout.operator_context = 'INVOKE_REGION_WIN'
+        layout.operator("mesh.primitive_twisted_torus_add",
+            text="Twisted Torus")
+        layout.operator("mesh.primitive_supertoroid_add",
+            text="Supertoroid")
+        layout.operator("mesh.primitive_torusknot_add",
+            text="Torus Knot")
+
+class INFO_MT_mesh_misc_add(bpy.types.Menu):
+    # Define the "Simple Objects" menu
+    bl_idname = "INFO_MT_mesh_misc_add"
+    bl_label = "Misc Objects"
+
+    def draw(self, context):
+        layout = self.layout
+        layout.operator_context = 'INVOKE_REGION_WIN'
+        layout.operator("mesh.primitive_steppyramid_add",
+            text="Step Pyramid")
+        layout.operator("mesh.honeycomb_add",
+            text="Honeycomb")
+        layout.operator("mesh.primitive_teapot_add",
+            text="Teapot+")
 # Register all operators and panels
 
 # Define "Extras" menu
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py
new file mode 100644
index 0000000..f58cd55
--- /dev/null
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py
@@ -0,0 +1,284 @@
+'''# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+    "name": "HoneyComb",
+    "author": "Kayo Phoenix <kayo at illumium.org>",
+    "version": (0, 1),
+    "blender": (2, 5, 7),
+    "api": 35853,
+    "location": "View3D > Add > Mesh > HoneyComb",
+    "description": "Adds HoneyComb Mesh",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_Mesh/HoneyComb",
+    "category": "Add Mesh"
+    }
+'''
+from math import pi, sin, cos
+
+class honeycomb_geometry():
+    def __init__(self, rows, cols, D, E):
+        self.rows = rows
+        self.cols = cols
+        self.D = D
+        self.E = E
+        
+        self.hE = 0.5 * self.E
+        self.R = 0.5 * self.D
+    
+        self.a = sin(pi / 3)
+        
+        self.d = self.a * self.D
+        self.hd = 0.5 * self.d
+        self.e = self.hE / self.a
+        self.he = 0.5 * self.e
+        self.r = self.R - self.e
+        self.hr = 0.5 * self.r
+        
+        
+        self.H = self.R * (1.5 * self.rows + 0.5) + self.e
+        if self.rows > 1:
+            self.W = self.d * (self.cols + 0.5) + self.E
+        else:
+            self.W = self.d * self.cols + self.E
+        
+        self.hH = 0.5 * self.H
+        self.hW = 0.5 * self.W
+        
+        self.sy = -self.hH + self.he + self.R
+        self.sx = -self.hW + self.hE + self.hd
+        
+        self.gx = self.hd
+        
+        self.dy = 1.5 * self.R
+        self.dx = self.d
+    
+    def vert(self, row, col):
+        # full cell
+        if row >= 0 and row < self.rows and col >= 0 and col < self.cols: return [0, 1, 2, 3, 4, 5]
+        # right down corner
+        if row == -1 and col == self.cols - 1: return [1, 2]
+        if row == 0 and self.rows > 1 and col == self.cols: return [1, 2, 3]
+        # left down corner
+        if row == -1 and col == -1: return [0, 1]
+        if self.rows % 2:
+            # left up corner
+            if row == self.rows and col == -1: return [4, 5]
+            # right up corner
+            if row == self.rows and col == self.cols - 1: return [3, 4]
+            if row == self.rows - 1 and self.rows > 1 and col == self.cols: return [2, 3, 4]
+        else:
+            # left up corner
+            if row == self.rows and col == 0: return [4, 5]
+            if row == self.rows - 1 and self.rows > 1 and col == -1: return [0, 4, 5]
+            # right up corner
+            if row == self.rows and col == self.cols: return [3, 4]
+        # horizontal lines
+        if col >= 0 and col < self.cols:
+            if row == -1: return [0, 1, 2]
+            if row == self.rows: return [3, 4, 5]
+        # vertical lines
+        if row >= 0 and row < self.rows:
+            if col == -1:
+                if row % 2: return [0, 1, 4, 5]
+                else: return [0, 5]
+            if col == self.cols:
+                if row % 2 or self.rows == 1: return [2, 3]
+                else: return [1, 2, 3, 4]
+        return []
+    
+    def cell(self, row, col, idx):
+        cp = [self.sx + self.dx * col, self.sy + self.dy * row, 0] # central point
+        if row % 2: cp[0] += self.gx
+        co = [] # vertexes coords
+        vi = self.vert(row, col)
+        ap = {}
+        
+        for i in vi:
+            a = pi / 6 + i * pi / 3 # angle
+            ap[i] = idx + len(co)
+            co.append((cp[0] + cos(a) * self.r, cp[1] + sin(a) * self.r, cp[2]))
+        return co, ap
+    
+    def generate(self):
+        ar = 1
+        ac = 1
+
+        cells = []
+        verts = []
+        faces = []
+        
+        for row in range(-ar, self.rows + ar):
+            level = []
+            for col in range(-ac, self.cols + ac):
+                co, ap = self.cell(row, col, len(verts))
+                verts += co
+                level.append(ap)
+            cells.append(level)
+        
+        # bottom row
+        row = 0
+        for col in range(1, len(cells[row]) - 1):
+            s = cells[row][col]
+            l = cells[row][col - 1]
+            u = cells[row + 1][col]
+            
+            faces.append((s[1], u[5], u[4], s[2]))
+            faces.append((s[2], u[4], l[0]))
+
+        # top row
+        row = len(cells) - 1
+        cs = 0
+        if row % 2: cs += 1
+        for col in range(1 + cs, len(cells[row]) - 1):
+            s = cells[row][col]
+            l = cells[row][col - 1]
+            d = cells[row - 1][col - cs]
+            faces.append((s[3], l[5], d[1]))
+            faces.append([s[3], d[1], d[0], s[4]])
+            
+        # middle rows
+        for row in range(1, len(cells) - 1):
+            cs = 0
+            if row % 2: cs += 1
+            for col in range(1, len(cells[row]) - 1):
+                s = cells[row][col]
+                l = cells[row][col - 1]
+                u = cells[row + 1][col - cs]
+                d = cells[row - 1][col - cs]
+                
+                faces.append((s[1], u[5], u[4], s[2]))
+                faces.append((s[2], u[4], l[0]))
+                faces.append([s[2], l[0], l[5], s[3]])
+                faces.append((s[3], l[5], d[1]))
+                faces.append([s[3], d[1], d[0], s[4]])
+        
+        # right column
+        row = 0
+        col = len(cells[row]) - 1
+        for row in range(1, len(cells) - 1):
+            cs = 0
+            if row % 2: cs += 1
+            
+            s = cells[row][col]
+            l = cells[row][col - 1]
+            u = cells[row + 1][col - cs]
+            d = cells[row - 1][col - cs]
+            
+            if row % 2 and row < len(cells) - 2:
+                faces.append((s[1], u[5], u[4], s[2]))
+            faces.append((s[2], u[4], l[0]))
+            faces.append([s[2], l[0], l[5], s[3]])
+            faces.append((s[3], l[5], d[1]))
+            if row % 2 and row > 1:
+                faces.append([s[3], d[1], d[0], s[4]])
+                
+        # final fix
+        if not self.rows % 2:
+            row = len(cells) - 1
+            s = cells[row][col]
+            l = cells[row][col - 1]
+            d = cells[row - 1][col - 1]
+            faces.append((s[3], l[5], d[1]))
+            faces.append([s[3], d[1], d[0], s[4]])
+        
+        return verts, faces
+
+import bpy
+from bpy.props import *
+from bpy_extras import object_utils
+
+def edge_max(diam):
+    return diam * sin(pi / 3)
+
+class add_mesh_honeycomb(bpy.types.Operator):
+    '''Simple honeycomb mesh generator'''
+    bl_idname = 'mesh.honeycomb_add'
+    bl_label = 'Add HoneyComb'
+    bl_options = {'REGISTER', 'UNDO'}
+    
+    rows = IntProperty(
+        name = 'Num of rows', default = 2,
+        min = 1, max = 100,
+        description='Number of the rows')
+    
+    cols = IntProperty(
+        name = 'Num of cols', default = 2,
+        min = 1, max = 100,
+        description='Number of the columns')
+    
+    def fix_edge(self, context):
+        m = edge_max(self.diam)
+        if self.edge > m: self.edge = m
+    
+    diam = FloatProperty(
+        name = 'Cell Diameter', default = 1.0,
+        min = 0.0, update = fix_edge,
+        description='Diameter of the cell')
+    
+    edge = FloatProperty(
+        name = 'Edge Width', default = 0.1,
+        min = 0.0, update = fix_edge,
+        description='Width of the edge')
+    
+    # generic transform props
+    view_align = BoolProperty(
+        name="Align to View",
+        default=False)
+    location = FloatVectorProperty(
+        name="Location",
+        subtype='TRANSLATION')
+    rotation = FloatVectorProperty(
+        name="Rotation",
+        subtype='EULER')
+    
+    ##### POLL #####
+    @classmethod
+    def poll(cls, context):
+        return context.scene is not None
+    
+    ##### EXECUTE #####
+    def execute(self, context):
+        mesh = bpy.data.meshes.new(name='honeycomb')
+        
+        comb = honeycomb_geometry(self.rows, self.cols, self.diam, self.edge)
+        verts, faces = comb.generate()
+        
+        mesh.from_pydata(vertices = verts, edges = [], faces = faces)
+        mesh.update()
+        
+        object_utils.object_data_add(context, mesh, operator=self)
+        
+        return {'FINISHED'}
+'''
+def menu_func(self, context):
+    self.layout.operator(add_mesh_honeycomb.bl_idname, text = bl_info['name'], icon="PLUGIN")
+
+def register():
+    bpy.utils.register_module(__name__)
+    
+    bpy.types.INFO_MT_mesh_add.append(menu_func)
+
+def unregister():
+    bpy.utils.unregister_module(__name__)
+    
+    bpy.types.INFO_MT_mesh_add.remove(menu_func)
+    
+if __name__ == "__main__":
+    register()
+'''
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py
index 0b961b1..da14e99 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py
@@ -159,4 +159,4 @@ def unregister():
 
 if __name__ == "__main__":
     register()
-'''
\ No newline at end of file
+'''
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py
new file mode 100644
index 0000000..2eb9905
--- /dev/null
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py
@@ -0,0 +1,832 @@
+'''# +---------------------------------------------------------+
+# | Copyright (c) 2005-2010 Anthony D'Agostino              |
+# | http://home.comcast.net/~chronosphere                   |
+# | scorpius at netzero.com                                    |
+# | February 12, 2005                                       |
+# | Newell Teapot Generator                                 |
+# | Adds the famous missing primitive to Blender            |
+# +---------------------------------------------------------+
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+bl_info = {
+	"name": "Teapot+",
+	"author": "Anthony D'Agostino",
+	"version": (1, 0),
+	"blender": (2, 5, 7),
+	"location": "View3D > Add > Mesh ",
+	"url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_Teapot",
+	"category": "Add Mesh"}
+'''
+import bpy, mathutils, io, operator, functools
+
+class AddTeapot(bpy.types.Operator):
+	'''Add a teapot mesh.'''
+	bl_idname = "mesh.primitive_teapot_add"
+	bl_label = "Add Teapot"
+	bl_options = {"REGISTER", "UNDO"}
+
+	resolution = bpy.props.IntProperty(name="Resolution",
+		description="Resolution of the Teapot",
+		default=5, min=2, max=15)
+
+	objecttype = bpy.props.IntProperty(name="Object Type",
+		description="Type of Bezier Object",
+		default=1, min=1, max=2)
+
+	def execute(self, context):
+		verts, faces = make_teapot(self.objecttype,
+								   self.resolution)
+        # Actually create the mesh object from this geometry data.
+		obj = create_mesh_object(context, verts, [], faces, "Teapot")
+		return {"FINISHED"}
+
+def menu_func(self, context):
+	self.layout.operator(AddTeapot.bl_idname, text="Teapot+", icon="MESH_CUBE")
+
+def register():
+	bpy.utils.register_module(__name__)
+	bpy.types.INFO_MT_mesh_add.append(menu_func)
+
+def unregister():
+	bpy.utils.unregister_module(__name__)
+	bpy.types.INFO_MT_mesh_add.remove(menu_func)
+
+if __name__ == "__main__":
+	register()
+
+def create_mesh_object(context, verts, edges, faces, name):
+    # Create new mesh
+    mesh = bpy.data.meshes.new(name)
+    # Make a mesh from a list of verts/edges/faces.
+    mesh.from_pydata(verts, edges, faces)
+    # Update mesh geometry after adding stuff.
+    mesh.update()
+    from bpy_extras import object_utils
+    return object_utils.object_data_add(context, mesh, operator=None)
+
+# ==========================
+# === Bezier patch Block ===
+# ==========================
+def read_indexed_patch_file(filename):
+	file = io.StringIO(filename)
+	rawpatches = []
+	patches = []
+	numpatches = int(file.readline())
+	for i in range(numpatches):
+		line = file.readline()
+		a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p = map(int, line.split(","))
+		patches.append([[a,b,c,d], [e,f,g,h], [i,j,k,l], [m,n,o,p]])
+		rawpatches.append([[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]])
+	verts = []
+	numverts = int(file.readline())
+	for i in range(numverts):
+		line = file.readline()
+		v1,v2,v3 = map(float, line.split(","))
+		verts.append((v1,v2,v3))
+	for i in range(len(patches)):
+		for j in range(4):	#len(patches[i])):
+			for k in range(4):	#len(patches[i][j])):
+				index = patches[i][j][k] - 1
+				rawpatches[i][j][k] = verts[index]
+	return rawpatches
+
+def patches_to_raw(patches, resolution):
+	raw = []
+	for patch in patches:
+		verts = make_verts(patch, resolution)
+		faces = make_faces(resolution)
+		rawquads = indexed_to_rawquads(verts, faces)
+		raw.append(rawquads)
+	raw = functools.reduce(operator.add, raw)  # flatten the list
+	return raw
+
+def make_bezier(ctrlpnts, resolution):
+	b1 = lambda t: t*t*t
+	b2 = lambda t: 3*t * t * (1-t)
+	b3 = lambda t: 3*t * (1-t) * (1-t)
+	b4 = lambda t: (1-t) * (1-t) * (1-t)
+	makevec = lambda v: mathutils.Vector(v)
+	p1,p2,p3,p4 = map(makevec, ctrlpnts)
+	curveverts = []
+	for i in range(resolution+1):
+		t = i/resolution
+		x,y,z = b1(t)*p1 + b2(t)*p2 + b3(t)*p3 + b4(t)*p4
+		curveverts.append((x,y,z))
+	return curveverts
+
+def make_bezier(ctrlpnts, resolution):
+	b1 = lambda t: t*t*t
+	b2 = lambda t: 3*t * t * (1-t)
+	b3 = lambda t: 3*t * (1-t) * (1-t)
+	b4 = lambda t: (1-t) * (1-t) * (1-t)
+	p1,p2,p3,p4 = map(mathutils.Vector, ctrlpnts)
+	def makevert(t):
+		x,y,z = b1(t)*p1 + b2(t)*p2 + b3(t)*p3 + b4(t)*p4
+		return (x,y,z)
+	curveverts = [makevert(i/resolution) for i in range(resolution+1)]
+	return curveverts
+
+def make_verts(a, resolution):
+	s = []
+	for i in a:
+		c = make_bezier(i, resolution)
+		s.append(c)
+	b = transpose(s)
+	s = []
+	for i in b:
+		c = make_bezier(i, resolution)
+		s.append(c)
+	verts = s
+	verts = functools.reduce(operator.add, verts)  # flatten the list
+	return verts
+
+def make_faces(resolution):
+	n = resolution+1
+	faces = []
+	for i in range(n-1):
+		for j in range(n-1):
+			v1 = (i+1)*n+j
+			v2 = (i+1)*n+j+1
+			v3 = i*n+j+1
+			v4 = i*n+j
+			faces.append([v1,v2,v3,v4])
+	return faces
+
+def indexed_to_rawquads(verts, faces):
+	rows = len(faces)
+	cols = len(faces[0])	# or 4
+	rawquads = [[None]*cols for i in range(rows)]
+	for i in range(rows):
+		for j in range(cols):
+			index = faces[i][j]
+			rawquads[i][j] = verts[index]
+	return rawquads
+
+def raw_to_indexed(rawfaces): # Generate verts and faces lists, without dups
+	verts = []
+	coords = {}
+	index = 0
+	for i in range(len(rawfaces)):
+		for j in range(len(rawfaces[i])):
+			vertex = rawfaces[i][j]
+			if vertex not in coords:
+				coords[vertex] = index
+				index += 1
+				verts.append(vertex)
+			rawfaces[i][j] = coords[vertex]
+	return verts, rawfaces
+
+def transpose(rowsbycols):
+	rows = len(rowsbycols)
+	cols = len(rowsbycols[0])
+	colsbyrows = [[None]*rows for i in range(cols)]
+	for i in range(cols):
+		for j in range(rows):
+			colsbyrows[i][j] = rowsbycols[j][i]
+	return colsbyrows
+
+def make_teapot(filename, resolution):
+	filenames = [None, teapot, teaspoon]
+	filename = filenames[filename]
+	patches = read_indexed_patch_file(filename)
+	raw = patches_to_raw(patches, resolution)
+	verts, faces = raw_to_indexed(raw)
+	return (verts, faces)
+
+# =================================
+# === Indexed Bezier Data Block ===
+# =================================
+teapot="""32
+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+4,17,18,19,8,20,21,22,12,23,24,25,16,26,27,28
+19,29,30,31,22,32,33,34,25,35,36,37,28,38,39,40
+31,41,42,1,34,43,44,5,37,45,46,9,40,47,48,13
+13,14,15,16,49,50,51,52,53,54,55,56,57,58,59,60
+16,26,27,28,52,61,62,63,56,64,65,66,60,67,68,69
+28,38,39,40,63,70,71,72,66,73,74,75,69,76,77,78
+40,47,48,13,72,79,80,49,75,81,82,53,78,83,84,57
+57,58,59,60,85,86,87,88,89,90,91,92,93,94,95,96
+60,67,68,69,88,97,98,99,92,100,101,102,96,103,104,105
+69,76,77,78,99,106,107,108,102,109,110,111,105,112,113,114
+78,83,84,57,108,115,116,85,111,117,118,89,114,119,120,93
+121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136
+124,137,138,121,128,139,140,125,132,141,142,129,136,143,144,133
+133,134,135,136,145,146,147,148,149,150,151,152,69,153,154,155
+136,143,144,133,148,156,157,145,152,158,159,149,155,160,161,69
+162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177
+165,178,179,162,169,180,181,166,173,182,183,170,177,184,185,174
+174,175,176,177,186,187,188,189,190,191,192,193,194,195,196,197
+177,184,185,174,189,198,199,186,193,200,201,190,197,202,203,194
+204,204,204,204,207,208,209,210,211,211,211,211,212,213,214,215
+204,204,204,204,210,217,218,219,211,211,211,211,215,220,221,222
+204,204,204,204,219,224,225,226,211,211,211,211,222,227,228,229
+204,204,204,204,226,230,231,207,211,211,211,211,229,232,233,212
+212,213,214,215,234,235,236,237,238,239,240,241,242,243,244,245
+215,220,221,222,237,246,247,248,241,249,250,251,245,252,253,254
+222,227,228,229,248,255,256,257,251,258,259,260,254,261,262,263
+229,232,233,212,257,264,265,234,260,266,267,238,263,268,269,242
+270,270,270,270,279,280,281,282,275,276,277,278,271,272,273,274
+270,270,270,270,282,289,290,291,278,286,287,288,274,283,284,285
+270,270,270,270,291,298,299,300,288,295,296,297,285,292,293,294
+270,270,270,270,300,305,306,279,297,303,304,275,294,301,302,271
+306
+1.4,0.0,2.4
+1.4,-0.784,2.4
+0.784,-1.4,2.4
+0.0,-1.4,2.4
+1.3375,0.0,2.53125
+1.3375,-0.749,2.53125
+0.749,-1.3375,2.53125
+0.0,-1.3375,2.53125
+1.4375,0.0,2.53125
+1.4375,-0.805,2.53125
+0.805,-1.4375,2.53125
+0.0,-1.4375,2.53125
+1.5,0.0,2.4
+1.5,-0.84,2.4
+0.84,-1.5,2.4
+0.0,-1.5,2.4
+-0.784,-1.4,2.4
+-1.4,-0.784,2.4
+-1.4,0.0,2.4
+-0.749,-1.3375,2.53125
+-1.3375,-0.749,2.53125
+-1.3375,0.0,2.53125
+-0.805,-1.4375,2.53125
+-1.4375,-0.805,2.53125
+-1.4375,0.0,2.53125
+-0.84,-1.5,2.4
+-1.5,-0.84,2.4
+-1.5,0.0,2.4
+-1.4,0.784,2.4
+-0.784,1.4,2.4
+0.0,1.4,2.4
+-1.3375,0.749,2.53125
+-0.749,1.3375,2.53125
+0.0,1.3375,2.53125
+-1.4375,0.805,2.53125
+-0.805,1.4375,2.53125
+0.0,1.4375,2.53125
+-1.5,0.84,2.4
+-0.84,1.5,2.4
+0.0,1.5,2.4
+0.784,1.4,2.4
+1.4,0.784,2.4
+0.749,1.3375,2.53125
+1.3375,0.749,2.53125
+0.805,1.4375,2.53125
+1.4375,0.805,2.53125
+0.84,1.5,2.4
+1.5,0.84,2.4
+1.75,0.0,1.875
+1.75,-0.98,1.875
+0.98,-1.75,1.875
+0.0,-1.75,1.875
+2.0,0.0,1.35
+2.0,-1.12,1.35
+1.12,-2.0,1.35
+0.0,-2.0,1.35
+2.0,0.0,0.9
+2.0,-1.12,0.9
+1.12,-2.0,0.9
+0.0,-2.0,0.9
+-0.98,-1.75,1.875
+-1.75,-0.98,1.875
+-1.75,0.0,1.875
+-1.12,-2.0,1.35
+-2.0,-1.12,1.35
+-2.0,0.0,1.35
+-1.12,-2.0,0.9
+-2.0,-1.12,0.9
+-2.0,0.0,0.9
+-1.75,0.98,1.875
+-0.98,1.75,1.875
+0.0,1.75,1.875
+-2.0,1.12,1.35
+-1.12,2.0,1.35
+0.0,2.0,1.35
+-2.0,1.12,0.9
+-1.12,2.0,0.9
+0.0,2.0,0.9
+0.98,1.75,1.875
+1.75,0.98,1.875
+1.12,2.0,1.35
+2.0,1.12,1.35
+1.12,2.0,0.9
+2.0,1.12,0.9
+2.0,0.0,0.45
+2.0,-1.12,0.45
+1.12,-2.0,0.45
+0.0,-2.0,0.45
+1.5,0.0,0.225
+1.5,-0.84,0.225
+0.84,-1.5,0.225
+0.0,-1.5,0.225
+1.5,0.0,0.15
+1.5,-0.84,0.15
+0.84,-1.5,0.15
+0.0,-1.5,0.15
+-1.12,-2.0,0.45
+-2.0,-1.12,0.45
+-2.0,0.0,0.45
+-0.84,-1.5,0.225
+-1.5,-0.84,0.225
+-1.5,0.0,0.225
+-0.84,-1.5,0.15
+-1.5,-0.84,0.15
+-1.5,0.0,0.15
+-2.0,1.12,0.45
+-1.12,2.0,0.45
+0.0,2.0,0.45
+-1.5,0.84,0.225
+-0.84,1.5,0.225
+0.0,1.5,0.225
+-1.5,0.84,0.15
+-0.84,1.5,0.15
+0.0,1.5,0.15
+1.12,2.0,0.45
+2.0,1.12,0.45
+0.84,1.5,0.225
+1.5,0.84,0.225
+0.84,1.5,0.15
+1.5,0.84,0.15
+-1.6,0.0,2.025
+-1.6,-0.3,2.025
+-1.5,-0.3,2.25
+-1.5,0.0,2.25
+-2.3,0.0,2.025
+-2.3,-0.3,2.025
+-2.5,-0.3,2.25
+-2.5,0.0,2.25
+-2.7,0.0,2.025
+-2.7,-0.3,2.025
+-3.0,-0.3,2.25
+-3.0,0.0,2.25
+-2.7,0.0,1.8
+-2.7,-0.3,1.8
+-3.0,-0.3,1.8
+-3.0,0.0,1.8
+-1.5,0.3,2.25
+-1.6,0.3,2.025
+-2.5,0.3,2.25
+-2.3,0.3,2.025
+-3.0,0.3,2.25
+-2.7,0.3,2.025
+-3.0,0.3,1.8
+-2.7,0.3,1.8
+-2.7,0.0,1.575
+-2.7,-0.3,1.575
+-3.0,-0.3,1.35
+-3.0,0.0,1.35
+-2.5,0.0,1.125
+-2.5,-0.3,1.125
+-2.65,-0.3,0.9375
+-2.65,0.0,0.9375
+-2.0,-0.3,0.9
+-1.9,-0.3,0.6
+-1.9,0.0,0.6
+-3.0,0.3,1.35
+-2.7,0.3,1.575
+-2.65,0.3,0.9375
+-2.5,0.3,1.125
+-1.9,0.3,0.6
+-2.0,0.3,0.9
+1.7,0.0,1.425
+1.7,-0.66,1.425
+1.7,-0.66,0.6
+1.7,0.0,0.6
+2.6,0.0,1.425
+2.6,-0.66,1.425
+3.1,-0.66,0.825
+3.1,0.0,0.825
+2.3,0.0,2.1
+2.3,-0.25,2.1
+2.4,-0.25,2.025
+2.4,0.0,2.025
+2.7,0.0,2.4
+2.7,-0.25,2.4
+3.3,-0.25,2.4
+3.3,0.0,2.4
+1.7,0.66,0.6
+1.7,0.66,1.425
+3.1,0.66,0.825
+2.6,0.66,1.425
+2.4,0.25,2.025
+2.3,0.25,2.1
+3.3,0.25,2.4
+2.7,0.25,2.4
+2.8,0.0,2.475
+2.8,-0.25,2.475
+3.525,-0.25,2.49375
+3.525,0.0,2.49375
+2.9,0.0,2.475
+2.9,-0.15,2.475
+3.45,-0.15,2.5125
+3.45,0.0,2.5125
+2.8,0.0,2.4
+2.8,-0.15,2.4
+3.2,-0.15,2.4
+3.2,0.0,2.4
+3.525,0.25,2.49375
+2.8,0.25,2.475
+3.45,0.15,2.5125
+2.9,0.15,2.475
+3.2,0.15,2.4
+2.8,0.15,2.4
+0.0,0.0,3.15
+0.0,-0.002,3.15
+0.002,0.0,3.15
+0.8,0.0,3.15
+0.8,-0.45,3.15
+0.45,-0.8,3.15
+0.0,-0.8,3.15
+0.0,0.0,2.85
+0.2,0.0,2.7
+0.2,-0.112,2.7
+0.112,-0.2,2.7
+0.0,-0.2,2.7
+-0.002,0.0,3.15
+-0.45,-0.8,3.15
+-0.8,-0.45,3.15
+-0.8,0.0,3.15
+-0.112,-0.2,2.7
+-0.2,-0.112,2.7
+-0.2,0.0,2.7
+0.0,0.002,3.15
+-0.8,0.45,3.15
+-0.45,0.8,3.15
+0.0,0.8,3.15
+-0.2,0.112,2.7
+-0.112,0.2,2.7
+0.0,0.2,2.7
+0.45,0.8,3.15
+0.8,0.45,3.15
+0.112,0.2,2.7
+0.2,0.112,2.7
+0.4,0.0,2.55
+0.4,-0.224,2.55
+0.224,-0.4,2.55
+0.0,-0.4,2.55
+1.3,0.0,2.55
+1.3,-0.728,2.55
+0.728,-1.3,2.55
+0.0,-1.3,2.55
+1.3,0.0,2.4
+1.3,-0.728,2.4
+0.728,-1.3,2.4
+0.0,-1.3,2.4
+-0.224,-0.4,2.55
+-0.4,-0.224,2.55
+-0.4,0.0,2.55
+-0.728,-1.3,2.55
+-1.3,-0.728,2.55
+-1.3,0.0,2.55
+-0.728,-1.3,2.4
+-1.3,-0.728,2.4
+-1.3,0.0,2.4
+-0.4,0.224,2.55
+-0.224,0.4,2.55
+0.0,0.4,2.55
+-1.3,0.728,2.55
+-0.728,1.3,2.55
+0.0,1.3,2.55
+-1.3,0.728,2.4
+-0.728,1.3,2.4
+0.0,1.3,2.4
+0.224,0.4,2.55
+0.4,0.224,2.55
+0.728,1.3,2.55
+1.3,0.728,2.55
+0.728,1.3,2.4
+1.3,0.728,2.4
+0.0,0.0,0.0
+1.5,0.0,0.15
+1.5,0.84,0.15
+0.84,1.5,0.15
+0.0,1.5,0.15
+1.5,0.0,0.075
+1.5,0.84,0.075
+0.84,1.5,0.075
+0.0,1.5,0.075
+1.425,0.0,0.0
+1.425,0.798,0.0
+0.798,1.425,0.0
+0.0,1.425,0.0
+-0.84,1.5,0.15
+-1.5,0.84,0.15
+-1.5,0.0,0.15
+-0.84,1.5,0.075
+-1.5,0.84,0.075
+-1.5,0.0,0.075
+-0.798,1.425,0.0
+-1.425,0.798,0.0
+-1.425,0.0,0.0
+-1.5,-0.84,0.15
+-0.84,-1.5,0.15
+0.0,-1.5,0.15
+-1.5,-0.84,0.075
+-0.84,-1.5,0.075
+0.0,-1.5,0.075
+-1.425,-0.798,0.0
+-0.798,-1.425,0.0
+0.0,-1.425,0.0
+0.84,-1.5,0.15
+1.5,-0.84,0.15
+0.84,-1.5,0.075
+1.5,-0.84,0.075
+0.798,-1.425,0.0
+1.425,-0.798,0.0
+"""
+
+teaspoon="""16
+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
+33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48
+49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
+65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80
+81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96
+97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112
+113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128
+129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144
+145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160
+161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176
+177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192
+193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208
+209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224
+225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240
+241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256
+256
+-0.000107143,0.205357,0.0
+0.0,0.196429,-0.0178571
+0.0,0.196429,-0.0178571
+0.000107143,0.205357,0.0
+-0.0535714,0.205357,0.0
+-0.0222714,0.178571,-0.0534286
+0.0222714,0.178571,-0.0534286
+0.0535714,0.205357,0.0
+-0.107143,0.0952429,-0.0178571
+-0.0446429,0.0952429,-0.0892857
+0.0446429,0.0952429,-0.0892857
+0.107143,0.0952429,-0.0178571
+-0.107143,0.0,-0.0178571
+-0.0446429,0.0,-0.0892857
+0.0446429,0.0,-0.0892857
+0.107143,0.0,-0.0178571
+0.000107143,0.205357,0.0
+0.000135714,0.207589,0.00446429
+0.000157143,0.216518,0.00446429
+0.000125,0.214286,0.0
+0.0535714,0.205357,0.0
+0.0613964,0.212054,0.0133571
+0.0714286,0.220982,0.015625
+0.0625,0.214286,0.0
+0.107143,0.0952429,-0.0178571
+0.122768,0.0952429,0.0
+0.142857,0.0952429,0.00446429
+0.125,0.0952429,-0.0178571
+0.107143,0.0,-0.0178571
+0.122768,0.0,0.0
+0.142857,0.0,0.00446429
+0.125,0.0,-0.0178571
+0.000125,0.214286,0.0
+0.0,0.205357,-0.0178571
+0.0,0.205357,-0.0178571
+-0.000125,0.214286,0.0
+0.0625,0.214286,0.0
+0.0267857,0.1875,-0.0625
+-0.0267857,0.1875,-0.0625
+-0.0625,0.214286,0.0
+0.125,0.0952429,-0.0178571
+0.0535714,0.0952429,-0.107143
+-0.0535714,0.0952429,-0.107143
+-0.125,0.0952429,-0.0178571
+0.125,0.0,-0.0178571
+0.0535714,0.0,-0.107143
+-0.0535714,0.0,-0.107143
+-0.125,0.0,-0.0178571
+-0.000125,0.214286,0.0
+-0.000157143,0.216518,0.00446429
+-0.000135714,0.207589,0.00446429
+-0.000107143,0.205357,0.0
+-0.0625,0.214286,0.0
+-0.0714286,0.220982,0.015625
+-0.0613964,0.212054,0.0133571
+-0.0535714,0.205357,0.0
+-0.125,0.0952429,-0.0178571
+-0.142857,0.0952429,0.00446429
+-0.122768,0.0952429,0.0
+-0.107143,0.0952429,-0.0178571
+-0.125,0.0,-0.0178571
+-0.142857,0.0,0.00446429
+-0.122768,0.0,0.0
+-0.107143,0.0,-0.0178571
+-0.107143,0.0,-0.0178571
+-0.0446429,0.0,-0.0892857
+0.0446429,0.0,-0.0892857
+0.107143,0.0,-0.0178571
+-0.107143,-0.142857,-0.0178571
+-0.0446429,-0.142857,-0.0892857
+0.0446429,-0.142857,-0.0892857
+0.107143,-0.142857,-0.0178571
+-0.0133929,-0.160714,0.0386893
+-0.00557857,-0.160714,0.0386893
+0.00557857,-0.160714,0.0386893
+0.0133929,-0.160714,0.0386893
+-0.0133929,-0.25,0.0535714
+-0.00557857,-0.25,0.0535714
+0.00557857,-0.25,0.0535714
+0.0133929,-0.25,0.0535714
+0.107143,0.0,-0.0178571
+0.122768,0.0,0.0
+0.142857,0.0,0.00446429
+0.125,0.0,-0.0178571
+0.107143,-0.142857,-0.0178571
+0.122768,-0.142857,0.0
+0.142857,-0.142857,0.00446429
+0.125,-0.142857,-0.0178571
+0.0133929,-0.160714,0.0386893
+0.0153464,-0.160714,0.0386893
+0.0178571,-0.160714,0.0314357
+0.015625,-0.160714,0.0297607
+0.0133929,-0.25,0.0535714
+0.0153464,-0.25,0.0535714
+0.0178571,-0.25,0.0463179
+0.015625,-0.25,0.0446429
+0.125,0.0,-0.0178571
+0.0535714,0.0,-0.107143
+-0.0535714,0.0,-0.107143
+-0.125,0.0,-0.0178571
+0.125,-0.142857,-0.0178571
+0.0535714,-0.142857,-0.107143
+-0.0535714,-0.142857,-0.107143
+-0.125,-0.142857,-0.0178571
+0.015625,-0.160714,0.0297607
+0.00669643,-0.160714,0.0230643
+-0.00781071,-0.160714,0.0208321
+-0.015625,-0.160714,0.0297607
+0.015625,-0.25,0.0446429
+0.00669643,-0.25,0.0379464
+-0.00781071,-0.25,0.0357143
+-0.015625,-0.25,0.0446429
+-0.125,0.0,-0.0178571
+-0.142857,0.0,0.00446429
+-0.122768,0.0,0.0
+-0.107143,0.0,-0.0178571
+-0.125,-0.142857,-0.0178571
+-0.142857,-0.142857,0.00446429
+-0.122768,-0.142857,0.0
+-0.107143,-0.142857,-0.0178571
+-0.015625,-0.160714,0.0297607
+-0.0175786,-0.160714,0.0319929
+-0.0153464,-0.160714,0.0386893
+-0.0133929,-0.160714,0.0386893
+-0.015625,-0.25,0.0446429
+-0.0175786,-0.25,0.046875
+-0.0153464,-0.25,0.0535714
+-0.0133929,-0.25,0.0535714
+-0.0133929,-0.25,0.0535714
+-0.00557857,-0.25,0.0535714
+0.00557857,-0.25,0.0535714
+0.0133929,-0.25,0.0535714
+-0.0133929,-0.46425,0.0892857
+-0.00557857,-0.46425,0.0892857
+0.00557857,-0.46425,0.0892857
+0.0133929,-0.46425,0.0892857
+-0.0446429,-0.678571,0.0535714
+-0.00892857,-0.678571,0.0625
+0.00892857,-0.678571,0.0625
+0.0446429,-0.678571,0.0535714
+-0.0446429,-0.857143,0.0357143
+-0.00892857,-0.857143,0.0446429
+0.00892857,-0.857143,0.0446429
+0.0446429,-0.857143,0.0357143
+0.0133929,-0.25,0.0535714
+0.0153464,-0.25,0.0535714
+0.0178571,-0.25,0.0463179
+0.015625,-0.25,0.0446429
+0.0133929,-0.46425,0.0892857
+0.0153464,-0.464286,0.0892857
+0.0178571,-0.46425,0.0820321
+0.015625,-0.46425,0.0803571
+0.0446429,-0.678571,0.0535714
+0.0535714,-0.678571,0.0513393
+0.0535714,-0.678571,0.0334821
+0.0446429,-0.678571,0.0357143
+0.0446429,-0.857143,0.0357143
+0.0535714,-0.857143,0.0334821
+0.0535714,-0.857143,0.015625
+0.0446429,-0.857143,0.0178571
+0.015625,-0.25,0.0446429
+0.00669643,-0.25,0.0379464
+-0.00781071,-0.25,0.0357143
+-0.015625,-0.25,0.0446429
+0.015625,-0.46425,0.0803571
+0.00669643,-0.464286,0.0736607
+-0.00781071,-0.46425,0.0714286
+-0.015625,-0.46425,0.0803571
+0.0446429,-0.678571,0.0357143
+0.00892857,-0.678571,0.0446429
+-0.00892857,-0.678571,0.0446429
+-0.0446429,-0.678571,0.0357143
+0.0446429,-0.857143,0.0178571
+0.00892857,-0.857143,0.0267857
+-0.00892857,-0.857143,0.0267857
+-0.0446429,-0.857143,0.0178571
+-0.015625,-0.25,0.0446429
+-0.0175786,-0.25,0.046875
+-0.0153464,-0.25,0.0535714
+-0.0133929,-0.25,0.0535714
+-0.015625,-0.46425,0.0803571
+-0.0175786,-0.464286,0.0825893
+-0.0153464,-0.464286,0.0892857
+-0.0133929,-0.46425,0.0892857
+-0.0446429,-0.678571,0.0357143
+-0.0535714,-0.678571,0.0334821
+-0.0535714,-0.678571,0.0513393
+-0.0446429,-0.678571,0.0535714
+-0.0446429,-0.857143,0.0178571
+-0.0535714,-0.857143,0.015625
+-0.0535714,-0.857143,0.0334821
+-0.0446429,-0.857143,0.0357143
+-0.0446429,-0.857143,0.0357143
+-0.00892857,-0.857143,0.0446429
+0.00892857,-0.857143,0.0446429
+0.0446429,-0.857143,0.0357143
+-0.0446429,-0.928571,0.0285714
+-0.00892857,-0.928571,0.0375
+0.00892857,-0.928571,0.0375
+0.0446429,-0.928571,0.0285714
+-0.0539286,-0.999643,0.0178571
+0.000357143,-0.999643,0.0178571
+0.0,-0.999643,0.0178571
+0.0535714,-0.999643,0.0178571
+-0.000357143,-1,0.0178571
+0.000357143,-1,0.0178571
+0.0,-1,0.0178571
+0.0,-1,0.0178571
+0.0446429,-0.857143,0.0357143
+0.0535714,-0.857143,0.0334821
+0.0535714,-0.857143,0.015625
+0.0446429,-0.857143,0.0178571
+0.0446429,-0.928571,0.0285714
+0.0535714,-0.928571,0.0263393
+0.0535714,-0.928571,0.00848214
+0.0446429,-0.928571,0.0107143
+0.0535714,-0.999643,0.0178571
+0.0669643,-0.999643,0.0178571
+0.0673214,-0.999643,0.0
+0.0539286,-0.999643,0.0
+0.0,-1,0.0178571
+0.0,-1,0.0178571
+0.000357143,-1,0.0
+0.000357143,-1,0.0
+0.0446429,-0.857143,0.0178571
+0.00892857,-0.857143,0.0267857
+-0.00892857,-0.857143,0.0267857
+-0.0446429,-0.857143,0.0178571
+0.0446429,-0.928571,0.0107143
+0.00892857,-0.928571,0.0196429
+-0.00892857,-0.928571,0.0196429
+-0.0446429,-0.928571,0.0107143
+0.0539286,-0.999643,0.0
+0.000357143,-0.999643,0.0
+-0.000357143,-0.999643,0.0
+-0.0539286,-0.999643,0.0
+0.000357143,-1,0.0
+0.000357143,-1,0.0
+-0.000357143,-1,0.0
+-0.000357143,-1,0.0
+-0.0446429,-0.857143,0.0178571
+-0.0535714,-0.857143,0.015625
+-0.0535714,-0.857143,0.0334821
+-0.0446429,-0.857143,0.0357143
+-0.0446429,-0.928571,0.0107143
+-0.0535714,-0.928571,0.00848214
+-0.0535714,-0.928571,0.0263393
+-0.0446429,-0.928571,0.0285714
+-0.0539286,-0.999643,0.0
+-0.0673214,-0.999643,0.0
+-0.0675,-0.999643,0.0178571
+-0.0539286,-0.999643,0.0178571
+-0.000357143,-1,0.0
+-0.000357143,-1,0.0
+-0.000535714,-1,0.0178571
+-0.000357143,-1,0.0178571
+"""
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py
new file mode 100644
index 0000000..b3ae651
--- /dev/null
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py
@@ -0,0 +1,150 @@
+'''# +---------------------------------------------------------+
+# | Copyright (c) 2005-2010 Anthony D'Agostino              |
+# | http://home.comcast.net/~chronosphere                   |
+# | scorpius at netzero.com                                    |
+# | February 12, 2005                                       |
+# | Torus Knot Generator                                    |
+# | Adds the famous missing primitive to Blender            |
+# +---------------------------------------------------------+
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+bl_info = {
+	"name": "Torus Knot",
+	"author": "Anthony D'Agostino",
+	"version": (1, 0),
+	"blender": (2, 5, 7),
+	"location": "View3D > Add > Mesh ",
+	"url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_TorusKnot",
+	"category": "Add Mesh"}
+'''	
+import bpy, mathutils, math
+
+def create_mesh_object(context, verts, edges, faces, name):
+    # Create new mesh
+    mesh = bpy.data.meshes.new(name)
+    # Make a mesh from a list of verts/edges/faces.
+    mesh.from_pydata(verts, edges, faces)
+    # Update mesh geometry after adding stuff.
+    mesh.update()
+    from bpy_extras import object_utils
+    return object_utils.object_data_add(context, mesh, operator=None)
+
+# ========================
+# === Torus Knot Block ===
+# ========================
+def k1(t):
+	x = math.cos(t) - 2*math.cos(2*t)
+	y = math.sin(t) + 2*math.sin(2*t)
+	z = math.sin(3*t)
+	return mathutils.Vector([x,y,z])
+
+def k2(t):
+	x = 10 * (math.cos(t) + math.cos(3*t)) + math.cos(2*t) + math.cos(4*t)
+	y = 6 * math.sin(t) + 10 * math.sin(3*t)
+	z = 4 * math.sin(3*t) * math.sin(5*t/2) + 4*math.sin(4*t) - 2*math.sin(6*t)
+	return mathutils.Vector([x,y,z]) * 0.2
+
+def k3(t):
+	x = 2.5*math.cos(t+math.pi)/3 + 2*math.cos(3*t)
+	y = 2.5*math.sin(t)/3 + 2*math.sin(3*t)
+	z = 1.5*math.sin(4*t) + math.sin(2*t)/3
+	return mathutils.Vector([x,y,z])
+
+def make_verts(ures, vres, r2, knotfunc):
+	verts = []
+	for i in range(ures):
+		t1 = (i+0) * 2*math.pi/ures
+		t2 = (i+1) * 2*math.pi/ures
+		a = knotfunc(t1)		# curr point
+		b = knotfunc(t2)		# next point
+		a,b = map(mathutils.Vector, (a,b))
+		e = a-b
+		f = a+b
+		g = e.cross(f)
+		h = e.cross(g)
+		g.normalize()
+		h.normalize()
+		for j in range(vres):
+			k = j * 2*math.pi/vres
+			l = (math.cos(k),0.0,math.sin(k))
+			l = mathutils.Vector(l)
+			m = l * r2
+			x,y,z = m
+			n = h*x
+			o = g*z
+			p = n+o
+			q = a+p
+			verts.append(q)
+	return verts
+
+def make_faces(ures, vres):
+	faces = []
+	for u in range(0, ures):
+		for v in range(0, vres):
+			p1 = v + u*vres
+			p2 = v + ((u+1)%ures)*vres
+			p4 = (v+1)%vres + u*vres
+			p3 = (v+1)%vres + ((u+1)%ures)*vres
+			faces.append([p4, p3, p2, p1])
+	return faces
+
+def make_knot(knotidx, ures):
+	knots = [k1,k2,k3]
+	knotfunc = knots[knotidx-1]
+	vres = ures//10
+	r2 = 0.5
+	verts = make_verts(ures, vres, r2, knotfunc)
+	faces = make_faces(ures, vres)
+	return (verts, faces)
+
+class AddTorusKnot(bpy.types.Operator):
+	'''Add a torus-knot mesh.'''
+	bl_idname = "mesh.primitive_torusknot_add"
+	bl_label = "Add Torus Knot"
+	bl_options = {"REGISTER", "UNDO"}
+
+	resolution = bpy.props.IntProperty(name="Resolution",
+		description="Resolution of the Torus Knot",
+		default=80, min=30, max=256)
+
+	objecttype = bpy.props.IntProperty(name="Knot Type",
+		description="Type of Knot",
+		default=1, min=1, max=3)
+
+	def execute(self, context):
+		verts, faces = make_knot(self.objecttype,
+								 self.resolution)
+		obj = create_mesh_object(context, verts, [], faces, "Torus Knot")
+		return {"FINISHED"}
+'''
+def menu_func(self, context):
+	self.layout.operator(AddTorusKnot.bl_idname, text="Torus Knot", icon="MESH_CUBE")
+
+def register():
+    bpy.utils.register_module(__name__)
+    bpy.types.INFO_MT_mesh_add.append(menu_func)
+
+def unregister():
+    bpy.utils.unregister_module(__name__)
+    bpy.types.INFO_MT_mesh_add.remove(menu_func)
+
+if __name__ == "__main__":
+	register()
+'''
diff --git a/release/scripts/addons/animation_add_corrective_shape_key.py b/release/scripts/addons/animation_add_corrective_shape_key.py
index 567d8ff..dc24639 100644
--- a/release/scripts/addons/animation_add_corrective_shape_key.py
+++ b/release/scripts/addons/animation_add_corrective_shape_key.py
@@ -224,7 +224,7 @@ class object_duplicate_flatten_modifiers(bpy.types.Operator):
         scene = context.scene
         obj_act = context.active_object
 
-        new_object = func_object_duplicate_flatten_modifiers(obj_act, scene)
+        new_object = func_object_duplicate_flatten_modifiers(scene, obj_act)
 
         # setup the context
         bpy.ops.object.select_all(action='DESELECT')
diff --git a/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py b/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py
index 713d32e..901938d 100644
--- a/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py
+++ b/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py
@@ -19,8 +19,8 @@
 bl_info = {
     "name": "HiRISE DTM from PDS IMG",
     "author": "Tim Spriggs (tims at uahirise.org)",
-    "version": (0, 1, 3),
-    "blender": (2, 6, 2),
+    "version": (0, 1, 4),
+    "blender": (2, 6, 3),
     "location": "File > Import > HiRISE DTM from PDS IMG (.IMG)",
     "description": "Import a HiRISE DTM formatted as a PDS IMG file",
     "warning": "May consume a lot of memory",
@@ -41,6 +41,9 @@ bl_info = {
 # 0.1.3 - upstream blender updates
 #         performance enhancements by Chris Van Horne
 #         (TJS - 2012-03-14)
+# 0.1.4 - use bmesh from_pydata in blender 2.6.3
+#         fixed/optimized bin2 method
+#         (TJS - 2012-04-30)
 
 
 if "bpy" in locals():
diff --git a/release/scripts/addons/io_convert_image_to_mesh_img/import_img.py b/release/scripts/addons/io_convert_image_to_mesh_img/import_img.py
index 4eb88a7..0489206 100644
--- a/release/scripts/addons/io_convert_image_to_mesh_img/import_img.py
+++ b/release/scripts/addons/io_convert_image_to_mesh_img/import_img.py
@@ -194,6 +194,8 @@ class hirise_dtm_importer(object):
     def bin2(self, image_iter, bin2_method_type="SLOW"):
       ''' this is an iterator that: Given an image iterator will yield binned lines '''
 
+      ignore_value = self.__ignore_value
+
       img_props = next(image_iter)
       # dimensions shrink as we remove pixels
       processed_dims = img_props.processed_dims()
@@ -207,7 +209,7 @@ class hirise_dtm_importer(object):
 
       # Take two lists  [a1, a2, a3], [b1, b2, b3] and combine them into one
       # list of [a1 + b1, a2+b2,  ... ] as long as both values are not ignorable
-      combine_fun = lambda a, b: a != self.__ignore_value and b != self.__ignore_value and a + b or self.__ignore_value
+      combine_fun = lambda a, b: a != ignore_value and b != ignore_value and (a + b)/2 or ignore_value
 
       line_count = 0
       ret_list = []
@@ -220,7 +222,9 @@ class hirise_dtm_importer(object):
             del tmp_list[0:2]
           yield ret_list
           ret_list = []
-        line_count += 1
+        else:
+          last_line = line
+          line_count += 1
 
     def bin6(self, image_iter, bin6_method_type="SLOW"):
       ''' this is an iterator that: Given an image iterator will yield binned lines '''
@@ -276,9 +280,10 @@ class hirise_dtm_importer(object):
         if not ints:
           binned_data.append( IGNORE_VALUE )
         else:
-          binned_data.append( sum(ints) / len(ints) )
+          binned_data.append( sum(ints, 0.0) / len(ints) )
 
         base += 6
+
       return binned_data
 
     def bin6_real_fast(self, raw_data):
@@ -499,7 +504,7 @@ class hirise_dtm_importer(object):
       point_offset += len( last_line ) - last_line.count(None)
       for z in last_line:
         if z != None:
-          coords.extend([x*scale_x, 0.0, z])
+          coords.append( (x*scale_x, 0.0, z) )
           coord += 1
         x += 1
 
@@ -531,7 +536,7 @@ class hirise_dtm_importer(object):
         x = 0
         for z in dtm_line:
           if z != None:
-            coords.extend( [x*scale_x, y_val, z] )
+            coords.append( (x*scale_x, y_val, z) )
             coord += 1
           x += 1
 
@@ -549,12 +554,12 @@ class hirise_dtm_importer(object):
 
           # Common case: we can create a square face
           if none_val == 0:
-            faces.extend( [
+            faces.append( (
               previous_point_offset,
               previous_point_offset+1,
               point_offset+1,
               point_offset,
-              ] )
+              ) )
             face_count += 1
           elif none_val == 1:
             # special case: we can implement a triangular face
@@ -579,12 +584,27 @@ class hirise_dtm_importer(object):
         last_line = dtm_line
 
       me = bpy.data.meshes.new(img_props.name()) # create a new mesh
-
-      me.vertices.add(len(coords)/3)
-      me.vertices.foreach_set("co", coords)
-
-      me.faces.add(len(faces)/4)
-      me.faces.foreach_set("vertices_raw", faces)
+      #from_pydata(self, vertices, edges, faces)
+      #Make a mesh from a list of vertices/edges/faces
+      #Until we have a nicer way to make geometry, use this.
+      #:arg vertices:
+      #   float triplets each representing (X, Y, Z)
+      #   eg: [(0.0, 1.0, 0.5), ...].
+      #:type vertices: iterable object
+      #:arg edges:
+      #   int pairs, each pair contains two indices to the
+      #   *vertices* argument. eg: [(1, 2), ...]
+      #:type edges: iterable object
+      #:arg faces:
+      #   iterator of faces, each faces contains three or more indices to
+      #   the *vertices* argument. eg: [(5, 6, 8, 9), (1, 2, 3), ...]
+      #:type faces: iterable object
+      me.from_pydata(coords, [], faces)      
+
+      # me.vertices.add(len(coords)/3)
+      # me.vertices.foreach_set("co", coords)
+      # me.faces.add(len(faces)/4)
+      # me.faces.foreach_set("vertices_raw", faces)
 
       me.update()
 
diff --git a/release/scripts/addons/io_export_directx_x.py b/release/scripts/addons/io_export_directx_x.py
index 20949e6..9dbfba7 100644
--- a/release/scripts/addons/io_export_directx_x.py
+++ b/release/scripts/addons/io_export_directx_x.py
@@ -1296,4 +1296,4 @@ def unregister():
 
 
 if __name__ == "__main__":
-    register()
\ No newline at end of file
+    register()
diff --git a/release/scripts/addons/io_export_unreal_psk_psa.py b/release/scripts/addons/io_export_unreal_psk_psa.py
index efefd9c..16c2b9c 100644
--- a/release/scripts/addons/io_export_unreal_psk_psa.py
+++ b/release/scripts/addons/io_export_unreal_psk_psa.py
@@ -18,9 +18,9 @@
 
 bl_info = {
     "name": "Export Unreal Engine Format(.psk/.psa)",
-    "author": "Darknet/Optimus_P-Fat/Active_Trash/Sinsoft/VendorX",
-    "version": (2, 4),
-    "blender": (2, 6, 2),
+    "author": "Darknet/Optimus_P-Fat/Active_Trash/Sinsoft/VendorX/Spoof",
+    "version": (2, 5),
+    "blender": (2, 6, 3),
     "api": 36079,
     "location": "File > Export > Skeletal Mesh/Animation Data (.psk/.psa)",
     "description": "Export Skeleletal Mesh/Animation Data",
@@ -969,6 +969,56 @@ def triangulate_mesh( object ):
 	bpy.context.scene.update()
 	return me_ob
 
+#copy mesh data and then merge them into one object
+def meshmerge(selectedobjects):
+    bpy.ops.object.mode_set(mode='OBJECT')
+    cloneobjects = []
+    if len(selectedobjects) > 1:
+        print("selectedobjects:",len(selectedobjects))
+        count = 0 #reset count
+        for count in range(len( selectedobjects)):
+            #print("Index:",count)
+            if selectedobjects[count] != None:
+                me_da = selectedobjects[count].data.copy() #copy data
+                me_ob = selectedobjects[count].copy() #copy object
+                #note two copy two types else it will use the current data or mesh
+                me_ob.data = me_da
+                bpy.context.scene.objects.link(me_ob)#link the object to the scene #current object location
+                print("Index:",count,"clone object",me_ob.name)
+                cloneobjects.append(me_ob)
+        #bpy.ops.object.mode_set(mode='OBJECT')
+        for i in bpy.data.objects: i.select = False #deselect all objects
+        count = 0 #reset count
+        #bpy.ops.object.mode_set(mode='OBJECT')
+        for count in range(len( cloneobjects)):
+            if count == 0:
+                bpy.context.scene.objects.active = cloneobjects[count]
+                print("Set Active Object:",cloneobjects[count].name)
+            cloneobjects[count].select = True
+        bpy.ops.object.join()
+        if len(cloneobjects) > 1:
+            bpy.types.Scene.udk_copy_merge = True
+    return cloneobjects[0]
+	
+#sort the mesh center top list and not center at the last array. Base on order while select to merge mesh to make them center.
+def sortmesh(selectmesh):
+	print("MESH SORTING...")
+	centermesh = []
+	notcentermesh = []
+	for countm in range(len(selectmesh)):
+		if selectmesh[countm].location.x == 0 and selectmesh[countm].location.y == 0 and selectmesh[countm].location.z == 0:
+			centermesh.append(selectmesh[countm])
+		else:
+			notcentermesh.append(selectmesh[countm])
+	selectmesh = []
+	for countm in range(len(centermesh)):
+		selectmesh.append(centermesh[countm])
+	for countm in range(len(notcentermesh)):
+		selectmesh.append(notcentermesh[countm])
+	if len(selectmesh) == 1:
+		return selectmesh[0]
+	else:
+		return meshmerge(selectmesh)
 
 #===========================================================================
 # parse_mesh
@@ -981,7 +1031,10 @@ def parse_mesh( mesh, psk ):
 	scene = bpy.context.scene
 	for i in scene.objects: i.select = False # deselect all objects
 	scene.objects.active	= mesh
+	setmesh = mesh
 	mesh = triangulate_mesh(mesh)
+	if bpy.types.Scene.udk_copy_merge == True:
+		bpy.context.scene.objects.unlink(setmesh)
 	#print("FACES----:",len(mesh.data.tessfaces))
 	verbose("Working mesh object: {}".format(mesh.name))
 	
@@ -1547,7 +1600,7 @@ def find_armature_and_mesh():
 	
 	# TODO:
 	# this could be more intuitive
-
+	bpy.ops.object.mode_set(mode='OBJECT')
 	# try the active object
 	if active_object and active_object.type == 'ARMATURE':
 		armature = active_object
@@ -1567,10 +1620,15 @@ def find_armature_and_mesh():
 	
 	verbose("Found armature: {}".format(armature.name))
 	
-	
+	meshselected = []
+	parented_meshes = [obj for obj in armature.children if obj.type == 'MESH']
+	for obj in armature.children:
+		#print(dir(obj))
+		if obj.type == 'MESH' and obj.select == True:
+			meshselected.append(obj)
 	# try the active object
-	if active_object and active_object.type == 'MESH':
-		
+	if active_object and active_object.type == 'MESH' and len(meshselected) == 0:
+	
 		if active_object.parent == armature:
 			mesh = active_object
 		
@@ -1579,14 +1637,16 @@ def find_armature_and_mesh():
 	
 	# otherwise, expect a single mesh parented to the armature (other object types are ignored)
 	else:
-		parented_meshes = [obj for obj in armature.children if obj.type == 'MESH']
 		print("Number of meshes:",len(parented_meshes))
+		print("Number of meshes (selected):",len(meshselected))
 		if len(parented_meshes) == 1:
 			mesh = parented_meshes[0]
 			
 		elif len(parented_meshes) > 1:
-			raise Error("More than one mesh parented to armature")
-			
+			if len(meshselected) >= 1:
+				mesh = sortmesh(meshselected)
+			else:
+				raise Error("More than one mesh(s) parented to armature. Select object(s)!")
 		else:
 			raise Error("No mesh parented to armature")
 		
@@ -1613,14 +1673,13 @@ def collate_vertex_groups( mesh ):
 		verbose("  " + group.name)
 	
 	return groups
-
-
+		
 #===========================================================================
 # Main
 #===========================================================================
 def export(filepath):
 	print(header("Export", 'RIGHT'))
-	
+	bpy.types.Scene.udk_copy_merge = False #in case fail to export set this to default
 	t		= time.clock()
 	context	= bpy.context
 	
@@ -1792,6 +1851,11 @@ bpy.types.Scene.udk_option_clamp_uv = BoolProperty(
 		name		= "Clamp UV",
 		description	= "Clamp UV co-ordinates to [0-1]",
 		default		= False)
+		
+bpy.types.Scene.udk_copy_merge = BoolProperty(
+		name		= "merge mesh",
+		description	= "Deal with unlinking the mesh to be remove while exporting the object.",
+		default		= False)
 
 bpy.types.Scene.udk_option_export = EnumProperty(
 		name		= "Export",
@@ -1817,9 +1881,246 @@ bpy.types.Scene.udk_option_triangulate = BoolProperty(
 		default		= False)
 		
 
+import bmesh
 #===========================================================================
 # User interface
 #===========================================================================
+class OBJECT_OT_UTSelectedFaceSmooth(bpy.types.Operator):
+    bl_idname = "object.utselectfacesmooth"  # XXX, name???
+    bl_label = "Select Smooth faces"
+    __doc__ = """It will only select smooth faces that is select mesh"""
+    
+    def invoke(self, context, event):
+        print("----------------------------------------")
+        print("Init Select Face(s):")
+        bselected = False
+        for obj in bpy.data.objects:
+            if obj.type == 'MESH' and obj.select == True:
+                smoothcount = 0
+                flatcount = 0
+                bpy.ops.object.mode_set(mode='OBJECT')#it need to go into object mode to able to select the faces
+                for i in bpy.context.scene.objects: i.select = False #deselect all objects
+                obj.select = True #set current object select
+                bpy.context.scene.objects.active = obj #set active object
+                mesh = bmesh.new();
+                mesh.from_mesh(obj.data)
+                for face in mesh.faces:
+                    face.select = False
+                for face in mesh.faces:
+                    if face.smooth == True:
+                        face.select = True
+                        smoothcount += 1
+                    else:
+                        flatcount += 1
+                        face.select = False
+                mesh.to_mesh(obj.data)
+                bpy.context.scene.update()
+                bpy.ops.object.mode_set(mode='EDIT')
+                print("Select Smooth Count(s):",smoothcount," Flat Count(s):",flatcount)
+                bselected = True
+                break
+        if bselected:
+            print("Selected Face(s) Exectue!")
+            self.report({'INFO'}, "Selected Face(s) Exectue!")
+        else:
+            print("Didn't select Mesh Object!")
+            self.report({'INFO'}, "Didn't Select Mesh Object!")
+        print("----------------------------------------")        
+        return{'FINISHED'}
+		
+class OBJECT_OT_MeshClearWeights(bpy.types.Operator):
+    bl_idname = "object.meshclearweights"  # XXX, name???
+    bl_label = "Remove Mesh vertex weights"
+    __doc__ = """Remove all mesh vertex groups weights for the bones."""
+    
+    def invoke(self, context, event):
+        for obj in bpy.data.objects:
+            if obj.type == 'MESH' and obj.select == True:
+                for vg in obj.vertex_groups:
+                    obj.vertex_groups.remove(vg)
+                self.report({'INFO'}, "Mesh Vertex Groups Remove!")
+                break			
+        return{'FINISHED'}
+
+def unpack_list(list_of_tuples):
+    l = []
+    for t in list_of_tuples:
+        l.extend(t)
+    return l
+	
+class OBJECT_OT_UTRebuildMesh(bpy.types.Operator):
+    bl_idname = "object.utrebuildmesh"  # XXX, name???
+    bl_label = "Rebuild Mesh"
+    __doc__ = """It rebuild the mesh from scrape from the selected mesh object. Note the scale will be 1:1 for object mode. To keep from deforming"""
+    
+    def invoke(self, context, event):
+        print("----------------------------------------")
+        print("Init Mesh Bebuild...")
+        bselected = False
+        for obj in bpy.data.objects:
+            if obj.type == 'MESH' and obj.select == True:
+                for i in bpy.context.scene.objects: i.select = False #deselect all objects
+                obj.select = True
+                bpy.context.scene.objects.active = obj
+                bpy.ops.object.mode_set(mode='OBJECT')
+                me_ob = bpy.data.meshes.new(("Re_"+obj.name))
+                mesh = obj.data
+                faces = []
+                verts = []
+                smoothings = []
+                uvfaces = []
+                print("creating array build mesh...")
+                mmesh = obj.to_mesh(bpy.context.scene,True,'PREVIEW')
+                uv_layer = mmesh.tessface_uv_textures.active
+                for face in mmesh.tessfaces:
+                    smoothings.append(face.use_smooth)#smooth or flat in boolean
+                    if uv_layer != None:#check if there texture data exist
+                        faceUV = uv_layer.data[face.index]
+                        uvs = []
+                        for uv in faceUV.uv:
+                            uvs.append((uv[0],uv[1]))
+                        uvfaces.append(uvs)
+                    print((face.vertices[:]))
+                    if len(face.vertices) == 3:
+                        faces.extend([(face.vertices[0],face.vertices[1],face.vertices[2],0)])
+                    else:
+                        faces.extend([(face.vertices[0],face.vertices[1],face.vertices[2],face.vertices[3])])
+                #vertex positions
+                for vertex in mesh.vertices:
+                    verts.append(vertex.co.to_tuple())				
+                #vertices weight groups into array
+                vertGroups = {} #array in strings
+                for vgroup in obj.vertex_groups:
+                    vlist = []
+                    for v in mesh.vertices:
+                        for vg in v.groups:
+                            if vg.group == vgroup.index:
+                                vlist.append((v.index,vg.weight))
+                                #print((v.index,vg.weight))
+                    vertGroups[vgroup.name] = vlist
+                
+                print("creating mesh object...")
+                #me_ob.from_pydata(verts, [], faces)
+                me_ob.vertices.add(len(verts))
+                me_ob.tessfaces.add(len(faces))
+                me_ob.vertices.foreach_set("co", unpack_list(verts)) 
+                me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
+                me_ob.tessfaces.foreach_set("use_smooth", smoothings)#smooth array from face
+                
+                #check if there is uv faces
+                if len(uvfaces) > 0:
+                    uvtex = me_ob.tessface_uv_textures.new(name="retex")
+                    for i, face in enumerate(me_ob.tessfaces):
+                        blender_tface = uvtex.data[i] #face
+                        mfaceuv = uvfaces[i]
+                        if len(mfaceuv) == 3:
+                            blender_tface.uv1 = mfaceuv[0];
+                            blender_tface.uv2 = mfaceuv[1];
+                            blender_tface.uv3 = mfaceuv[2];
+                        if len(mfaceuv) == 4:
+                            blender_tface.uv1 = mfaceuv[0];
+                            blender_tface.uv2 = mfaceuv[1];
+                            blender_tface.uv3 = mfaceuv[2];
+                            blender_tface.uv4 = mfaceuv[3];
+                
+                me_ob.update()#need to update the information to able to see into the secne
+                obmesh = bpy.data.objects.new(("Re_"+obj.name),me_ob)
+                bpy.context.scene.update()
+                #Build tmp materials
+                materialname = "ReMaterial"
+                for matcount in mesh.materials:
+                    matdata = bpy.data.materials.new(materialname)
+                    me_ob.materials.append(matdata)
+                #assign face to material id
+                for face in mesh.tessfaces:
+                    me_ob.faces[face.index].material_index = face.material_index
+                #vertices weight groups
+                for vgroup in vertGroups:
+                    group = obmesh.vertex_groups.new(vgroup)
+                    for v in vertGroups[vgroup]:
+                        group.add([v[0]], v[1], 'ADD')# group.add(array[vertex id],weight,add)
+                bpy.context.scene.objects.link(obmesh)
+                print("Mesh Material Count:",len(me_ob.materials))
+                matcount = 0
+                print("MATERIAL ID OREDER:")
+                for mat in me_ob.materials:
+                    print("-Material:",mat.name,"INDEX:",matcount)
+                    matcount += 1
+                print("Object Name:",obmesh.name)
+                bpy.context.scene.update()
+                bselected = True
+                break
+        if bselected:
+            self.report({'INFO'}, "Rebuild Mesh Finish!")
+            print("Finish Mesh Build...")
+        else:
+            self.report({'INFO'}, "Didn't Select Mesh Object!")
+            print("Didn't Select Mesh Object!")
+        print("----------------------------------------")
+        return{'FINISHED'}
+		
+class OBJECT_OT_UTRebuildArmature(bpy.types.Operator):
+    bl_idname = "object.utrebuildarmature"  # XXX, name???
+    bl_label = "Rebuild Armature"
+    __doc__ = """If mesh is deform when importing to unreal engine try this. It rebuild the bones one at the time by select one armature object scrape to raw setup build. Note the scale will be 1:1 for object mode. To keep from deforming"""
+    
+    def invoke(self, context, event):
+        print("----------------------------------------")
+        print("Init Rebuild Armature...")
+        bselected = False
+        for obj in bpy.data.objects:
+            if obj.type == 'ARMATURE' and obj.select == True:
+                currentbone = [] #select armature for roll copy
+                print("Armature Name:",obj.name)
+                objectname = "ArmatureDataPSK"
+                meshname ="ArmatureObjectPSK"
+                armdata = bpy.data.armatures.new(objectname)
+                ob_new = bpy.data.objects.new(meshname, armdata)
+                bpy.context.scene.objects.link(ob_new)
+                bpy.ops.object.mode_set(mode='OBJECT')
+                for i in bpy.context.scene.objects: i.select = False #deselect all objects
+                ob_new.select = True
+                bpy.context.scene.objects.active = obj
+                
+                bpy.ops.object.mode_set(mode='EDIT')
+                for bone in obj.data.edit_bones:
+                    if bone.parent != None:
+                        currentbone.append([bone.name,bone.roll])
+                    else:
+                        currentbone.append([bone.name,bone.roll])
+                bpy.ops.object.mode_set(mode='OBJECT')
+                for i in bpy.context.scene.objects: i.select = False #deselect all objects
+                bpy.context.scene.objects.active = ob_new
+                bpy.ops.object.mode_set(mode='EDIT')
+                
+                for bone in obj.data.bones:
+                    bpy.ops.object.mode_set(mode='EDIT')
+                    newbone = ob_new.data.edit_bones.new(bone.name)
+                    newbone.head = bone.head_local
+                    newbone.tail = bone.tail_local
+                    for bonelist in currentbone:
+                        if bone.name == bonelist[0]:
+                            newbone.roll = bonelist[1]
+                            break
+                    if bone.parent != None:
+                        parentbone = ob_new.data.edit_bones[bone.parent.name]
+                        newbone.parent = parentbone
+                print("Bone Count:",len(obj.data.bones))
+                print("Hold Bone Count",len(currentbone))
+                print("New Bone Count",len(ob_new.data.edit_bones))
+                print("Rebuild Armture Finish:",ob_new.name)
+                bpy.context.scene.update()
+                bselected = True
+                break
+        if bselected:
+            self.report({'INFO'}, "Rebuild Armature Finish!")
+        else:
+            self.report({'INFO'}, "Didn't Select Armature Object!")
+        print("End of Rebuild Armature.")
+        print("----------------------------------------")
+        return{'FINISHED'}
+
+
 class Panel_UDKExport( bpy.types.Panel ):
 
 	bl_label		= "UDK Export"
@@ -1856,22 +2157,26 @@ class Panel_UDKExport( bpy.types.Panel ):
 		row = layout.row()
 		row.label(text="Active object: " + object_name)
 
-		layout.separator()
+		#layout.separator()
 
 		layout.prop(context.scene, "udk_option_filename_src")
 		row = layout.row()
 		row.label(text=path)
 
-		layout.separator()
+		#layout.separator()
 
 		layout.prop(context.scene, "udk_option_export")
 		layout.operator("object.udk_export")
 		
-		layout.separator()
+		#layout.separator()
 		
 		layout.operator("object.toggle_console")
+		layout.operator(OBJECT_OT_UTRebuildArmature.bl_idname)
+		layout.operator(OBJECT_OT_MeshClearWeights.bl_idname)
+		layout.operator(OBJECT_OT_UTSelectedFaceSmooth.bl_idname)
+		layout.operator(OBJECT_OT_UTRebuildMesh.bl_idname)
 
-		layout.separator()
+		#layout.separator()
 
 class ExportUDKAnimData(bpy.types.Operator):
     
@@ -1931,6 +2236,7 @@ class ExportUDKAnimData(bpy.types.Operator):
 def menu_func(self, context):
     default_path = os.path.splitext(bpy.data.filepath)[0] + ".psk"
     self.layout.operator(ExportUDKAnimData.bl_idname, text="Skeleton Mesh / Animation Data (.psk/.psa)").filepath = default_path
+
 #===========================================================================
 # Entry
 #===========================================================================
@@ -1951,4 +2257,4 @@ if __name__ == "__main__":
 	
 #loader
 #filename = "D:/Projects/BlenderScripts/io_export_udk_psa_psk_alpha.py"
-#exec(compile(open(filename).read(), filename, 'exec'))
\ No newline at end of file
+#exec(compile(open(filename).read(), filename, 'exec'))
diff --git a/release/scripts/addons/io_import_scene_mhx.py b/release/scripts/addons/io_import_scene_mhx.py
index 5c9b84d..0f9d867 100644
--- a/release/scripts/addons/io_import_scene_mhx.py
+++ b/release/scripts/addons/io_import_scene_mhx.py
@@ -194,10 +194,8 @@ Plural = {
 #
 
 def readMhxFile(filePath):
-    global todo, nErrors, theScale, defaultScale, One, toggle, warnedVersion, BMeshAware, theMessage
+    global todo, nErrors, theScale, defaultScale, One, toggle, warnedVersion, theMessage
 
-    print("Blender r%s" % bpy.app.build_revision)
-    BMeshAware = (int(bpy.app.build_revision) > 44136)    
     defaultScale = theScale
     One = 1.0/theScale
     warnedVersion = False
@@ -1191,7 +1189,7 @@ def unpackList(list_of_tuples):
 #
 
 def parseMesh (args, tokens):
-    global todo
+    global todo, BMeshAware
     if verbosity > 2:
         print( "Parsing mesh %s" % args )
 
@@ -1220,6 +1218,15 @@ def parseMesh (args, tokens):
         me.from_pydata(verts, edges, [])
     me.update()
     linkObject(ob, me)
+    
+    if faces:
+        try:
+            me.polygons
+            BMeshAware = True
+            print("Using BMesh")
+        except:
+            BMeshAware = False
+            print("Not using BMesh")
         
     mats = []
     nuvlayers = 0
diff --git a/release/scripts/addons/io_scene_fbx/export_fbx.py b/release/scripts/addons/io_scene_fbx/export_fbx.py
index 8090c44..a33cf78 100644
--- a/release/scripts/addons/io_scene_fbx/export_fbx.py
+++ b/release/scripts/addons/io_scene_fbx/export_fbx.py
@@ -1971,6 +1971,7 @@ def save_single(operator, scene, filepath="",
                         mats = me.materials
                     else:
                         me = ob.data
+                        me.update(calc_tessface=True)
                         mats = me.materials
 
 # 						# Support object colors
diff --git a/release/scripts/addons/io_scene_map/export_map.py b/release/scripts/addons/io_scene_map/export_map.py
index 77108b8..2d11aad 100644
--- a/release/scripts/addons/io_scene_map/export_map.py
+++ b/release/scripts/addons/io_scene_map/export_map.py
@@ -355,7 +355,7 @@ def export_map(context, filepath):
         #XXX25: BPyMesh.meshCalcNormals(dummy_mesh)
 
         # We need tessfaces
-        dummy_mesh.update(calc_tessface)
+        dummy_mesh.update(calc_tessface=True)
 
         # Split mesh into connected regions
         for face_group in mesh_utils.mesh_linked_tessfaces(dummy_mesh):
diff --git a/release/scripts/addons/render_renderfarmfi.py b/release/scripts/addons/render_renderfarmfi.py
index 704daad..a2b26a1 100644
--- a/release/scripts/addons/render_renderfarmfi.py
+++ b/release/scripts/addons/render_renderfarmfi.py
@@ -1094,7 +1094,7 @@ class ORE_LoginOp(bpy.types.Operator):
         ore = sce.ore_render
 
         ore.password = ore.password.strip()
-        ore.username = ore.username.strip().lower()
+        ore.username = ore.username.strip()
         
         if ore.hash=='':
             if ore.password != '' and ore.username != '':
diff --git a/release/scripts/addons/texture_paint_layer_manager.py b/release/scripts/addons/texture_paint_layer_manager.py
index 757f8a9..9f6d68b 100644
--- a/release/scripts/addons/texture_paint_layer_manager.py
+++ b/release/scripts/addons/texture_paint_layer_manager.py
@@ -633,4 +633,4 @@ def unregister():
     bpy.utils.unregister_module(__name__)
 
 if __name__ == "__main__":
-    register()
\ No newline at end of file
+    register()
diff --git a/release/scripts/addons_contrib/add_curve_objects/__init__.py b/release/scripts/addons_contrib/add_curve_objects/__init__.py
deleted file mode 100644
index 53f212e..0000000
--- a/release/scripts/addons_contrib/add_curve_objects/__init__.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-# Contributed to by
-# meta-androcto #
-
-bl_info = {
-    "name": "Curve Objects",
-    "author": "Multiple Authors",
-    "version": (0, 1),
-    "blender": (2, 6, 3),
-    "location": "View3D > Add > Curve > Curve Objects",
-    "description": "Add extra curve object types",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Add Curve"}
-
-
-if "bpy" in locals():
-    import imp
-    imp.reload(add_curve_rectangle_259)
-    imp.reload(add_curve_spirals)
-    imp.reload(cotejrp1_particle_tracer)
-    imp.reload(cotejrp1_string_it)
-    imp.reload(curve_simplify)
-	
-else:
-    from . import add_curve_rectangle_259
-    from . import add_curve_spirals
-    from . import cotejrp1_particle_tracer
-    from . import cotejrp1_string_it
-    from . import curve_simplify
-
-import bpy
-
-
-class INFO_MT_curve_extras_add(bpy.types.Menu):
-    # Define the "Extras" menu
-    bl_idname = "INFO_MT_curve_extra_objects_add"
-    bl_label = "Curve Objects"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        layout.operator("curve.rectangle",
-            text="Rectangle")
-        layout.operator("curve.spirals",
-            text="Spirals")
-        layout.operator("curve.particle_tracer",
-            text="Particle Tracer")
-        layout.operator("curve.string_it_operator",
-            text="String It")
-        layout.operator("curve.simplify",
-            text="Curve Simplify")
-
-# Register all operators and panels
-
-# Define "Extras" menu
-def menu_func(self, context):
-    self.layout.menu("INFO_MT_curve_extra_objects_add", icon="PLUGIN")
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    # Add "Extras" menu to the "Add Mesh" menu
-    bpy.types.INFO_MT_curve_add.append(menu_func)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    # Remove "Extras" menu from the "Add Mesh" menu.
-    bpy.types.INFO_MT_curve_add.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_curve_objects/add_curve_rectangle_259.py b/release/scripts/addons_contrib/add_curve_objects/add_curve_rectangle_259.py
deleted file mode 100644
index 89fe704..0000000
--- a/release/scripts/addons_contrib/add_curve_objects/add_curve_rectangle_259.py
+++ /dev/null
@@ -1,244 +0,0 @@
-'''# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-bl_info = {
-    "name": "Rectangle",
-    "author": "Carbonic Wolf",
-    "version": (1,1),
-    "blender": (2, 5, 9),
-    "api": 39933,
-    "location": "View3D > Add > Curve",
-    "description": "Add rectangle",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Add Curve"}
-    
- '''   
-##------------------------------------------------------------
-#### import modules
-import bpy
-from bpy.props import *
-from mathutils import *
-from math import *
-
-##------------------------------------------------------------
-# calculates the matrix for the new object
-# depending on user pref
-def align_matrix(context):
-    loc = Matrix.Translation(context.scene.cursor_location)
-    obj_align = context.user_preferences.edit.object_align
-    if (context.space_data.type == 'VIEW_3D'
-        and obj_align == 'VIEW'):
-        rot = context.space_data.region_3d.view_matrix.rotation_part().invert().resize4x4()
-    else:
-        rot = Matrix()
-    align_matrix = loc * rot
-    return align_matrix
-
-##------------------------------------------------------------
-#### Curve creation functions
-# sets bezierhandles to auto
-def setBezierHandles(obj, mode = 'AUTOMATIC'):
-    scene = bpy.context.scene
-    if obj.type != 'CURVE':
-        return
-    scene.objects.active = obj
-    bpy.ops.object.mode_set(mode='EDIT', toggle=True)
-    bpy.ops.curve.select_all(action='SELECT')
-    bpy.ops.curve.handle_type_set(type=mode)
-    bpy.ops.object.mode_set(mode='OBJECT', toggle=True)
-
-##------------------------------------------------------------
-#### Curve creation functions
-
-# get array of vertcoordinates acording to splinetype
-def vertsToPoints(Verts):
-    vertArray = []
-
-    for v in Verts:
-        vertArray += v
-
-    return vertArray
-
-# create new CurveObject from vertarray and splineType
-def createCurve(vertArray, props, align_matrix):
-    # options to vars
-    splineType = 'BEZIER'
-    name = 'rectangle'
-
-    # create curve
-    scene = bpy.context.scene
-    newCurve = bpy.data.curves.new(name, type = 'CURVE') # curvedatablock
-    newSpline = newCurve.splines.new(type = splineType)  # spline
-
-    # create spline from vertarray
-    newSpline.bezier_points.add(int(len(vertArray)*0.33))
-    newSpline.bezier_points.foreach_set('co', vertArray)
-
-    # Curve settings
-    newCurve.dimensions = '2D'
-    newSpline.use_cyclic_u = True
-    newSpline.use_endpoint_u = True
-    newSpline.order_u = 4
-
-    # create object with newCurve
-    new_obj = bpy.data.objects.new(name, newCurve)  # object
-    scene.objects.link(new_obj)                     # place in active scene
-    new_obj.select = True                           # set as selected
-    scene.objects.active = new_obj                  # set as active
-    new_obj.matrix_world = align_matrix             # apply matrix
-
-    setBezierHandles(new_obj, 'VECTOR')
-
-    return
-
-########################################################################
-#######################  Definitions ###################################
-########################################################################
-
-#### rectangle
-def rectangle_Curve(rectangle_w=2, rectangle_l=2, rectangle_r=1):
-    newPoints = []
-    x=rectangle_w/2
-    y=rectangle_l/2
-    r=rectangle_r/2
-    
-    if r>0:
-       newPoints.append([-x+r,y,0])
-       newPoints.append([x-r,y,0])
-       newPoints.append([x,y-r,0])
-       newPoints.append([x,-y+r,0])
-       newPoints.append([x-r,-y,0])
-       newPoints.append([-x+r,-y,0])
-       newPoints.append([-x,-y+r,0])
-       newPoints.append([-x,y-r,0])
-    else:
-       newPoints.append([-x,y,0])
-       newPoints.append([x,y,0])
-       newPoints.append([x,-y,0])
-       newPoints.append([-x,-y,0])
-
-    return newPoints
-
-##------------------------------------------------------------
-# Main Function
-def main(context, props, align_matrix):
-    # deselect all objects
-    bpy.ops.object.select_all(action='DESELECT')
-
-    # get verts
-    verts = rectangle_Curve(props.rectangle_w,
-                            props.rectangle_l,
-                            props.rectangle_r)
-
-    # turn verts into array
-    vertArray = vertsToPoints(verts)
-
-    # create object
-    createCurve(vertArray, props, align_matrix)
-
-    return
-
-class rectangle(bpy.types.Operator):
-    ''''''
-    bl_idname = "curve.rectangle"
-    bl_label = "Rectangle"
-    bl_options = {'REGISTER', 'UNDO'}
-    bl_description = "adds rectangle"
-
-    # align_matrix for the invoke
-    align_matrix = Matrix()
-
-    #### Parameters
-    rectangle_w = FloatProperty(name="Width",
-                default=2,
-                min=0, soft_min=0,
-                description="Width")
-    rectangle_l = FloatProperty(name="Length",
-                default=2,
-                min=0, soft_min=0,
-                description="Length")
-    rectangle_r = FloatProperty(name="Rounded",
-                default=1,
-                min=0, soft_min=0,
-                description="Rounded")
-
-    ##### DRAW #####
-    def draw(self, context):
-        props = self.properties
-        layout = self.layout
-
-        # general options        
-        col = layout.column()
-        #col.prop(props, 'rectangle')
-        col.label(text="Rectangle Parameters")
-
-        # Parameters 
-        box = layout.box()
-        box.prop(props, 'rectangle_w')
-        box.prop(props, 'rectangle_l')
-        box.prop(props, 'rectangle_r')
-
-    ##### POLL #####
-    @classmethod
-    def poll(cls, context):
-        return context.scene != None
-
-    ##### EXECUTE #####
-    def execute(self, context):
-        # turn off undo
-        undo = bpy.context.user_preferences.edit.use_global_undo
-        bpy.context.user_preferences.edit.use_global_undo = False
-
-        props = self.properties
-        
-        # main function
-        main(context, props, self.align_matrix)
-        
-        # restore pre operator undo state
-        bpy.context.user_preferences.edit.use_global_undo = undo
-
-        return {'FINISHED'}
-
-    ##### INVOKE #####
-    def invoke(self, context, event):
-        # store creation_matrix
-        self.align_matrix = align_matrix(context)
-        self.execute(context)
-
-        return {'FINISHED'}
-
-################################################################################
-##### REGISTER #####
-
-def rectangle_button(self, context):
-    self.layout.operator(rectangle.bl_idname, text="Rectangle", icon="PLUGIN")
-
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_curve_add.append(rectangle_button)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_curve_add.remove(rectangle_button)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_curve_objects/add_curve_spirals.py b/release/scripts/addons_contrib/add_curve_objects/add_curve_spirals.py
deleted file mode 100644
index 18f3d00..0000000
--- a/release/scripts/addons_contrib/add_curve_objects/add_curve_spirals.py
+++ /dev/null
@@ -1,261 +0,0 @@
-'''bl_info = {
-    "name": "Spirals",
-    "description": "Make spirals",
-    "author": "Alejandro Omar Chocano Vasquez",
-    "version": (1, 2),
-    "blender": (2, 62, 0),
-    "location": "View3D > Add > Curve",
-    "warning": "", # used for warning icon and text in addons panel
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.4/Py/Scripts/Object/Spirals",
-    "tracker_url": "http://alexvaqp.googlepages.com?"
-                   "func=detail&aid=<number>",
-    "category": "Add Curve"}
-'''
-import bpy, time
-from bpy.props import *
-from math import sin, cos, pi, exp
-from bpy_extras.object_utils import AddObjectHelper, object_data_add
-
-#make normal spiral
-#-----------------------------------------------------------------------------
-def make_spiral(props, context):                  #archemedian and logarithmic can be plottet in zylindrical coordinates
-    #if props.spiral_type != 1 and props.spiral_type != 2:
-    #    return None
-
-    #INPUT: turns->degree->max_phi, steps, direction
-    #Initialise Polar Coordinate Enviroment
-    #-------------------------------
-    props.degree = 360*props.turns                #If you want to make the slider for degree
-    steps = props.steps * props.turns             #props.steps[per turn] -> steps[for the whole spiral]
-    props.z_scale = props.dif_z * props.turns
-    
-    max_phi  = pi*props.degree/180                #max angle in radian
-    step_phi = max_phi/steps                      #angle in radians between two vertices
-    if props.spiral_direction == 1:
-        step_phi *= -1                            #flip direction
-        max_phi *= -1
-    step_z   = props.z_scale/(steps-1)            #z increase in one step
-    
-    verts = []
-    verts.extend([props.radius,0,0,1])
-    
-    cur_phi = 0
-    cur_z   = 0
-    #-------------------------------
-
-    #Archemedean: dif_radius, radius
-    cur_rad = props.radius
-    step_rad = props.dif_radius/(steps * 360/props.degree)        #radius increase per angle for archemedean spiral| (steps * 360/props.degree)...Steps needed for 360 deg
-    #Logarithmic: radius, B_force, ang_div, dif_z
-    
-    #print("max_phi:",max_phi,"step_phi:",step_phi,"step_rad:",step_rad,"step_z:",step_z)
-    while abs(cur_phi) <= abs(max_phi):
-        cur_phi += step_phi
-        cur_z   += step_z
-        
-        #-------------------------------
-        if props.spiral_type == 1:
-            cur_rad += step_rad
-        if props.spiral_type == 2:
-            #r = a*e^{|theta| * b}
-            cur_rad = props.radius * pow(props.B_force, abs(cur_phi)) 
-        #-------------------------------
-    
-        px = cur_rad * cos(cur_phi)
-        py = cur_rad * sin(cur_phi)
-        verts.extend( [px,py,cur_z,1] )
-
-    return verts
-
-
-#make Spheric spiral
-#-----------------------------------------------------------------------------
-def make_spiral_spheric(props, context):
-    #INPUT: turns, steps[per turn], radius
-    #use spherical Coordinates
-    step_phi = (2*pi) / props.steps               #Step of angle in radians for one turn
-    steps = props.steps * props.turns             #props.steps[per turn] -> steps[for the whole spiral]
-    
-    max_phi  = 2*pi*props.turns                   #max angle in radian
-    step_phi = max_phi/steps                      #angle in radians between two vertices
-    if props.spiral_direction == 1:               #flip direction
-        step_phi *= -1
-        max_phi *= -1
-    step_theta = pi / (steps-1)                   #theta increase in one step (pi == 180 deg)
-
-    verts = []
-    verts.extend([0,0,-props.radius,1])           #First vertex at south pole
-
-    #cur_rad = props.radius = CONST
-
-    cur_phi = 0
-    cur_theta = -pi/2                             #Beginning at south pole
-
-    while abs(cur_phi) <= abs(max_phi):
-        #Coordinate Transformation sphere->rect
-        px = props.radius * cos(cur_theta) * cos(cur_phi)
-        py = props.radius * cos(cur_theta) * sin(cur_phi)
-        pz = props.radius * sin(cur_theta)
-
-        verts.extend([px,py,pz,1])
-        cur_theta += step_theta
-        cur_phi += step_phi
-
-    return verts
-
-#make torus spiral
-#-----------------------------------------------------------------------------
-
-def make_spiral_torus(props, context):
-    #INPUT: turns, steps, inner_radius, curves_number, mul_height, dif_inner_radius, cycles
-    max_phi  = 2*pi*props.turns * props.cycles    #max angle in radian
-    step_phi = 2*pi/props.steps                   #Step of angle in radians between two vertices
-    if props.spiral_direction == 1:               #flip direction
-        step_phi *= -1
-        max_phi *= -1
-    step_theta = (2*pi / props.turns) / props.steps
-    step_rad = props.dif_radius / (props.steps * props.turns)
-    step_inner_rad = props.dif_inner_radius / props.steps
-    step_z = props.dif_z / (props.steps * props.turns)
-
-    verts = []
-    
-    cur_phi = 0                                   #Inner Ring Radius Angle
-    cur_theta = 0                                 #Ring Radius Angle
-    cur_rad = props.radius
-    cur_inner_rad = props.inner_radius
-    cur_z = 0
-    n_cycle = 0
-    
-    while abs(cur_phi) <= abs(max_phi):
-        #Torus Coordinates -> Rect
-        px = ( cur_rad + cur_inner_rad * cos(cur_phi) ) * cos(props.curves_number * cur_theta)
-        py = ( cur_rad + cur_inner_rad * cos(cur_phi) ) * sin(props.curves_number * cur_theta)
-        pz = cur_inner_rad * sin(cur_phi) + cur_z
-
-        verts.extend([px,py,pz,1])
-
-        if props.touch == True and cur_phi >= n_cycle * 2*pi:
-            step_z = ( (n_cycle+1) * props.dif_inner_radius + props.inner_radius ) * 2 / (props.steps * props.turns)
-            n_cycle += 1
-
-        cur_theta += step_theta
-        cur_phi += step_phi
-        cur_rad += step_rad
-        cur_inner_rad += step_inner_rad
-        cur_z += step_z
-
-    return verts
-#-----------------------------------------------------------------------------
-
-def draw_curve(props, context):
-    if props.spiral_type == 1:
-        verts = make_spiral(props, context)
-    if props.spiral_type == 2:
-        verts = make_spiral(props, context)
-    if props.spiral_type == 3:
-        verts = make_spiral_spheric(props, context)
-    if props.spiral_type == 4:
-        verts = make_spiral_torus(props, context)
-    
-    curve_data = bpy.data.curves.new(name='Spiral', type='CURVE')
-    curve_data.dimensions = '3D'
-    
-    if props.curve_type == 0:
-        spline = curve_data.splines.new(type='POLY')
-    elif props.curve_type == 1:
-        spline = curve_data.splines.new(type='NURBS')
-    
-    spline.points.add( len(verts)*0.25-1 )                          #Add only one quarter of points as elements in verts, because verts looks like: "x,y,z,?,x,y,z,?,x,..."
-    spline.points.foreach_set('co', verts)
-#    new_obj = object_data_add(bpy.context, curve_data)
-    new_obj = object_data_add(context, curve_data)   
-
-class spirals(bpy.types.Operator):
-    bl_idname = "curve.spirals"
-    bl_label = "Spirals"
-    bl_options = {'REGISTER','UNDO'}            #UNDO needed for operator redo and therefore also to let the addobjecthelp appear!!!
-    bl_description = "adds different types of spirals"
-
-    spiral_type = IntProperty(default=1, min=1, max=4, description="1:archemedian, 2:logarithmic, 3:spheric, 4:torus")
-    curve_type = IntProperty(default=0, min=0, max=1, description="0:Poly, 1:Nurb")
-    spiral_direction = IntProperty(default=0, min=0, max=1, description="0:counter-clockwise, 1:clockwise")
-    
-    turns = IntProperty(default=1, min=1, max=1000, description="Length of Spiral in 360 deg")
-    steps = IntProperty(default=24, min=2, max=1000, description="Number of Vertices per turn")
-
-    
-    radius = FloatProperty(default=1.00, min=0.00, max=100.00, description="radius for first turn")
-    dif_z = FloatProperty(default=0, min=-10.00, max=100.00, description="increase in z axis per turn")            #needed for 1 and 2 spiral_type
-    #ARCHMEDEAN variables
-    dif_radius = FloatProperty(default=0.00, min=-50.00, max=50.00, description="radius increment in each turn")        #step between turns(one turn equals 360 deg)
-    #LOG variables 
-    B_force = FloatProperty(default=1.00, min=0.00, max=30.00, description="factor of exponent")
-    #TORUS variables
-    inner_radius = FloatProperty(default=0.20, min=0.00, max=100, description="Inner Radius of Torus")
-    dif_inner_radius = FloatProperty(default=0, min=-10, max=100, description="Increase of inner Radius per Cycle")
-    dif_radius = FloatProperty(default=0, min=-10, max=100, description="Increase of Torus Radius per Cycle")
-    cycles = FloatProperty(default=1, min=0.00, max=1000, description="Number of Cycles")
-    curves_number = IntProperty(default=1, min=1, max=400, description="Number of curves of spiral")
-    touch = BoolProperty(default=False, description="No empty spaces between cycles")
-
-    def draw(self, context):                #Function used by Blender to draw the menu
-        layout = self.layout
-        layout.prop(self, 'spiral_type', text="Spiral Type")
-        layout.prop(self, 'curve_type', text="Curve Type")
-        layout.prop(self, 'spiral_direction', text="Spiral Direction")
-        
-        layout.label(text="Spiral Parameters:")
-        layout.prop(self, 'turns', text = "Turns")
-        layout.prop(self, 'steps', text = "Steps")
-
-        box = layout.box()
-        if self.spiral_type == 1:
-            box.prop(self, 'dif_radius', text = "Radius Growth")
-            box.prop(self, 'radius', text = "Radius")
-            box.prop(self, 'dif_z', text = "Height")
-        if self.spiral_type == 2:
-            box.prop(self, 'radius', text = "Radius")
-            box.prop(self, 'B_force', text = "Expansion Force")
-            box.prop(self, 'dif_z', text = "Height")
-        if self.spiral_type == 3:
-            box.prop(self, 'radius', text = "Radius")
-        if self.spiral_type == 4:
-            box.prop(self, 'cycles', text = "Number of Cycles")
-            if self.dif_inner_radius == 0 and self.dif_z == 0:
-                self.cycles = 1
-            box.prop(self, 'radius', text = "Radius")
-            if self.dif_z == 0:
-                box.prop(self, 'dif_z', text = "Height per Cycle")
-            else:
-                box2 = box.box()
-                box2.prop(self, 'dif_z', text = "Height per Cycle")
-                box2.prop(self, 'touch', text = "Make Snail")
-            box.prop(self, 'inner_radius', text = "Inner Radius")
-            box.prop(self, 'curves_number', text = "Curves Number")
-            box.prop(self, 'dif_radius', text = "Increase of Torus Radius")
-            box.prop(self, 'dif_inner_radius', text = "Increase of Inner Radius")
-
-    @classmethod
-    def poll(cls, context):                            #method called by blender to check if the operator can be run
-        return context.scene != None
-    def execute(self, context):
-        time_start = time.time()
-        draw_curve(self, context)
-        print("Drawing Spiral Finished: %.4f sec", time.time() - time_start)
-        return {'FINISHED'}
-#------------------------------------------------------------------------------------
-
-def spirals_button(self, context):
-    self.layout.operator(spirals.bl_idname, text="Spirals")
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_curve_add.append(spirals_button)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_curve_add.remove(spirals_button)
-
-if __name__=="__main__ ":
-   register()
diff --git a/release/scripts/addons_contrib/add_curve_objects/cotejrp1_particle_tracer.py b/release/scripts/addons_contrib/add_curve_objects/cotejrp1_particle_tracer.py
deleted file mode 100644
index 0be3768..0000000
--- a/release/scripts/addons_contrib/add_curve_objects/cotejrp1_particle_tracer.py
+++ /dev/null
@@ -1,154 +0,0 @@
-'''# tickertape.py (c) 2011 Phil Cote (cotejrp1)
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-"""
-How to use:
-1.  Set up a scene object with an emitter particle system.
-2.  Adjust for the unborn, alive, and dead particle lifecycle.
-3.  Advance the timeline til the particles are in the desired position.
-4.  MAKE SURE you select the emitter object AFTER you'vbe advanced the timeline.
-5.  In the tools menu in the 3D view, click "Make Curve" under the Particle Tracer Panel
-6.  Adjust for what kind of what life state of particles to include as well as the curve thickness bevel.
-"""
-
-# BUG? : You do have to make sure you select the emitter object AFTER you've
-# advanced the timeline.  If you don't, the current frame changes on you 
-# when you change the particle tracer options.
-'''
-bl_info = {
-    'name': 'Particle Tracer',
-    'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
-    'version': (0,1),
-    "blender": (2, 5, 8),
-    "api": 37702,
-    'location': '',
-    'description': 'Creates curves based on location of particles at a specific point in time.',
-    'warning': '', # used for warning icon and text in addons panel
-    'category': 'Add Curve'}
-
-import bpy
-
-def getParticleSys( ob ):
-    """
-    Grab the first particle system available or None if there aren't any.
-    """
-    if ob == None:
-        return None
-    
-    pSysList = [ mod for mod in ob.modifiers if mod.type == 'PARTICLE_SYSTEM']
-    if len( pSysList ) == 0:
-        return None
-    
-    pSys = pSysList[0].particle_system
-    return pSys
-
-
-def buildLocationList( psys, includeAlive, includeDead, includeUnborn ):
-    """
-    Build a flattened list of locations for each of the particles which the curve creation
-    code will act on.
-    Which particles get included it dictated by the user choice of any combo of unborn, alive, or dead.
-    """
-    locList = []
-    aliveList = []
-    deadList = []
-    unbornList = []
-    
-    def listByAliveState( psys, aliveArg ):
-    
-        newList = []
-        for p in psys.particles:
-            if p.alive_state == aliveArg:
-                newList.extend( list( p.location ) )
-                
-        return newList
-     
-    aliveList = listByAliveState( psys, "ALIVE" )
-    deadList = listByAliveState( psys, "DEAD" )
-    unbornList = listByAliveState( psys, "UNBORN" )
-        
-        
-    if includeAlive:
-        locList = locList + aliveList
-    if includeDead:
-        locList = locList + deadList
-    if includeUnborn:
-        locList = locList + unbornList
-           
-    return locList    
-    
-    
-class PTracerOp(bpy.types.Operator):
-    '''Tooltip'''
-    bl_idname = "curve.particle_tracer"
-    bl_label = "Particle Tracer Options"
-    bl_region_type = "VIEW_3D"
-    bl_context = "tools"
-    bl_options = { "REGISTER", "UNDO" }
-    
-    curveName = bpy.props.StringProperty( name = "Curve Name", default="ptracecurve" )
-    includeAlive = bpy.props.BoolProperty( name="Alive Particles", default=True )
-    includeDead = bpy.props.BoolProperty( name = "Dead Particles", default = True )
-    includeUnborn = bpy.props.BoolProperty( name="Unborn Particles", default = True )
-    thickness = bpy.props.FloatProperty( name = "Thickness", min=0, max=1 )
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        if getParticleSys( ob ) == None:
-            return False
-        return True
-    
-
-    def execute(self, context):
-        
-        ob = context.active_object
-        psys = getParticleSys( ob )
-        locList = buildLocationList( psys, self.includeAlive, self.includeDead, self.includeUnborn )
-        
-        crv = bpy.data.curves.new( self.curveName, type="CURVE" )
-        spline = crv.splines.new( type="BEZIER" )
-        crv.bevel_depth = self.thickness
-        
-        pointCount = len( locList ) / 3
-        if pointCount > 0:
-            spline.bezier_points.add( pointCount - 1 )
-            
-        spline.bezier_points.foreach_set( "co", locList )
-        
-        for point in spline.bezier_points:
-            point.handle_left_type = "AUTO"
-            point.handle_right_type = "AUTO"
-       
-        scn = context.scene
-        crvob = bpy.data.objects.new( self.curveName, crv )
-        scn.objects.link( crvob )
-        
-        return {'FINISHED'}
-    
-def register():
-    bpy.utils.register_class(PTracerOp)
-
-def unregister():
-    bpy.utils.unregister_class(PTracerOp)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_curve_objects/cotejrp1_string_it.py b/release/scripts/addons_contrib/add_curve_objects/cotejrp1_string_it.py
deleted file mode 100644
index 694a344..0000000
--- a/release/scripts/addons_contrib/add_curve_objects/cotejrp1_string_it.py
+++ /dev/null
@@ -1,104 +0,0 @@
-'''
-# string_it.py (c) 2011 Phil Cote (cotejrp1)
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    'name': 'String It',
-    'author': 'Phil Cote, cotejrp1, (http://www.blenderpythontutorials.com)',
-    'version': (0,1),
-    "blender": (2, 5, 8),
-    "api": 37702,
-    'location': '',
-    'description': 'Run a curve through each selected object in a scene.',
-    'warning': '', # used for warning icon and text in addons panel
-    'category': 'Add Curve'}
-'''
-import bpy
-
-def makeBezier( spline, vertList ):
-    numPoints = ( len( vertList ) / 3 ) - 1
-    spline.bezier_points.add( numPoints )
-    spline.bezier_points.foreach_set( "co", vertList )
-    for point in spline.bezier_points:
-        point.handle_left_type = "AUTO"
-        point.handle_right_type = "AUTO"
-    
-def makePoly( spline, vertList ):
-    numPoints = ( len( vertList ) / 4 ) - 1
-    spline.points.add( numPoints )
-    spline.points.foreach_set( "co", vertList )
-    
-
-class StringItOperator(bpy.types.Operator):
-    '''Creates a curve that runs through the centers of each selected object.'''
-    bl_idname = "curve.string_it_operator"
-    bl_label = "String It Options"
-    bl_options = { "REGISTER", "UNDO" }
-    
-    splineOptionList = [  ( 'poly', 'poly', 'poly' ), ( 'bezier', 'bezier', 'bezier' ), ]
-    splineChoice = bpy.props.EnumProperty( name="Spline Type", items=splineOptionList )
-    closeSpline = bpy.props.BoolProperty( name="Close Spline?", default=False )
-        
-    @classmethod   
-    def poll( self, context ):
-        totalSelected = len( [ob for ob in context.selectable_objects if ob.select] )
-        return totalSelected > 1
-    
-    def execute(self, context):
-        
-        splineType = self.splineChoice.upper()
-        scn = context.scene
-        obList = [ ob for ob in scn.objects if ob.select ]
-
-        # build the vert data set to use to make the curve
-        vertList = []
-        for sceneOb in obList:
-            vertList.append( sceneOb.location.x )
-            vertList.append( sceneOb.location.y )
-            vertList.append( sceneOb.location.z )
-            if splineType == 'POLY':
-                vertList.append( 0 )
-
-        # build the curve itself.
-        crv = bpy.data.curves.new( "curve", type = "CURVE" )
-        crv.splines.new( type = splineType )
-        spline = crv.splines[0]
-        if splineType == 'BEZIER':
-            makeBezier( spline, vertList )
-                
-        else: #polyline case.
-            makePoly( spline, vertList )
-        
-        spline.use_cyclic_u = self.closeSpline
-        
-        # add the curve to the scene.
-        crvOb = bpy.data.objects.new( "curveOb", crv )
-        scn.objects.link( crvOb )            
-        return {'FINISHED'}
-
-def register():
-    bpy.utils.register_class(StringItOperator)
-
-def unregister():
-    bpy.utils.unregister_class(StringItOperator)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_curve_objects/curve_simplify.py b/release/scripts/addons_contrib/add_curve_objects/curve_simplify.py
deleted file mode 100644
index 7003ef2..0000000
--- a/release/scripts/addons_contrib/add_curve_objects/curve_simplify.py
+++ /dev/null
@@ -1,593 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Simplify curves",
-    "author": "testscreenings",
-    "version": (1,),
-    "blender": (2, 5, 9),
-    "location": "Search > Simplify Curves",
-    "description": "Simplifies 3D curves and fcurves",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Curve/Curve_Simplify",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=22327",
-    "category": "Add Curve"}
-
-"""
-This script simplifies Curves.
-"""
-
-####################################################
-import bpy
-from bpy.props import *
-import mathutils
-import math
-
-##############################
-#### simplipoly algorithm ####
-##############################
-# get SplineVertIndices to keep
-def simplypoly(splineVerts, options):
-    # main vars
-    newVerts = [] # list of vertindices to keep
-    points = splineVerts # list of 3dVectors
-    pointCurva = [] # table with curvatures
-    curvatures = [] # averaged curvatures per vert
-    for p in points:
-        pointCurva.append([])
-    order = options[3] # order of sliding beziercurves
-    k_thresh = options[2] # curvature threshold
-    dis_error = options[6] # additional distance error
-
-    # get curvatures per vert
-    for i, point in enumerate(points[:-(order-1)]):
-        BVerts = points[i:i+order]
-        for b, BVert in enumerate(BVerts[1:-1]):
-            deriv1 = getDerivative(BVerts, 1/(order-1), order-1)
-            deriv2 = getDerivative(BVerts, 1/(order-1), order-2)
-            curva = getCurvature(deriv1, deriv2)
-            pointCurva[i+b+1].append(curva)
-
-    # average the curvatures
-    for i in range(len(points)):
-        avgCurva = sum(pointCurva[i]) / (order-1)
-        curvatures.append(avgCurva)
-
-    # get distancevalues per vert - same as Ramer-Douglas-Peucker
-    # but for every vert
-    distances = [0.0] #first vert is always kept
-    for i, point in enumerate(points[1:-1]):
-        dist = altitude(points[i], points[i+2], points[i+1])
-        distances.append(dist)
-    distances.append(0.0) # last vert is always kept
-
-    # generate list of vertindices to keep
-    # tested against averaged curvatures and distances of neighbour verts
-    newVerts.append(0) # first vert is always kept
-    for i, curv in enumerate(curvatures):
-        if (curv >= k_thresh*0.01
-        or distances[i] >= dis_error*0.1):
-            newVerts.append(i)
-    newVerts.append(len(curvatures)-1) # last vert is always kept
-
-    return newVerts
-
-# get binomial coefficient
-def binom(n, m):
-    b = [0] * (n+1)
-    b[0] = 1
-    for i in range(1, n+1):
-        b[i] = 1
-        j = i-1
-        while j > 0:
-            b[j] += b[j-1]
-            j-= 1
-    return b[m]
-
-# get nth derivative of order(len(verts)) bezier curve
-def getDerivative(verts, t, nth):
-    order = len(verts) - 1 - nth
-    QVerts = []
-
-    if nth:
-        for i in range(nth):
-            if QVerts:
-                verts = QVerts
-            derivVerts = []
-            for i in range(len(verts)-1):
-                derivVerts.append(verts[i+1] - verts[i])
-            QVerts = derivVerts
-    else:
-        QVerts = verts
-
-    if len(verts[0]) == 3:
-        point = mathutils.Vector((0, 0, 0))
-    if len(verts[0]) == 2:
-        point = mathutils.Vector((0, 0))
-
-    for i, vert in enumerate(QVerts):
-        point += binom(order, i) * math.pow(t, i) * math.pow(1-t, order-i) * vert
-    deriv = point
-
-    return deriv
-
-# get curvature from first, second derivative
-def getCurvature(deriv1, deriv2):
-    if deriv1.length == 0: # in case of points in straight line
-        curvature = 0
-        return curvature
-    curvature = (deriv1.cross(deriv2)).length / math.pow(deriv1.length, 3)
-    return curvature
-
-#########################################
-#### Ramer-Douglas-Peucker algorithm ####
-#########################################
-# get altitude of vert
-def altitude(point1, point2, pointn):
-    edge1 = point2 - point1
-    edge2 = pointn - point1
-    if edge2.length == 0:
-        altitude = 0
-        return altitude
-    if edge1.length == 0:
-        altitude = edge2.length
-        return altitude
-    alpha = edge1.angle(edge2)
-    altitude = math.sin(alpha) * edge2.length
-    return altitude
-
-# iterate through verts
-def iterate(points, newVerts, error):
-    new = []
-    for newIndex in range(len(newVerts)-1):
-        bigVert = 0
-        alti_store = 0
-        for i, point in enumerate(points[newVerts[newIndex]+1:newVerts[newIndex+1]]):
-            alti = altitude(points[newVerts[newIndex]], points[newVerts[newIndex+1]], point)
-            if alti > alti_store:
-                alti_store = alti
-                if alti_store >= error:
-                    bigVert = i+1+newVerts[newIndex]
-        if bigVert:
-            new.append(bigVert)
-    if new == []:
-        return False
-    return new
-
-#### get SplineVertIndices to keep
-def simplify_RDP(splineVerts, options):
-    #main vars
-    error = options[4]
-
-    # set first and last vert
-    newVerts = [0, len(splineVerts)-1]
-
-    # iterate through the points
-    new = 1
-    while new != False:
-        new = iterate(splineVerts, newVerts, error)
-        if new:
-            newVerts += new
-            newVerts.sort()
-    return newVerts
-
-##########################
-#### CURVE GENERATION ####
-##########################
-# set bezierhandles to auto
-def setBezierHandles(newCurve):
-    bpy.ops.object.mode_set(mode='EDIT', toggle=True)
-    bpy.ops.curve.select_all(action='SELECT')
-    bpy.ops.curve.handle_type_set(type='AUTOMATIC')
-    bpy.ops.object.mode_set(mode='OBJECT', toggle=True)
-
-# get array of new coords for new spline from vertindices
-def vertsToPoints(newVerts, splineVerts, splineType):
-    # main vars
-    newPoints = []
-
-    # array for BEZIER spline output
-    if splineType == 'BEZIER':
-        for v in newVerts:
-            newPoints += splineVerts[v].to_tuple()
-
-    # array for nonBEZIER output
-    else:
-        for v in newVerts:
-            newPoints += (splineVerts[v].to_tuple())
-            if splineType == 'NURBS':
-                newPoints.append(1) #for nurbs w=1
-            else: #for poly w=0
-                newPoints.append(0)
-    return newPoints
-
-#########################
-#### MAIN OPERATIONS ####
-#########################
-
-def main(context, obj, options):
-    #print("\n_______START_______")
-    # main vars
-    mode = options[0]
-    output = options[1]
-    degreeOut = options[5]
-    keepShort = options[7]
-    bpy.ops.object.select_all(action='DESELECT')
-    scene = context.scene
-    splines = obj.data.splines.values()
-
-    # create curvedatablock
-    curve = bpy.data.curves.new("simple_"+obj.name, type = 'CURVE')
-
-    # go through splines
-    for spline_i, spline in enumerate(splines):
-        # test if spline is a long enough
-        if len(spline.points) >= 7 or keepShort:
-            #check what type of spline to create
-            if output == 'INPUT':
-                splineType = spline.type
-            else:
-                splineType = output
-            
-            # get vec3 list to simplify
-            if spline.type == 'BEZIER': # get bezierverts
-                splineVerts = [splineVert.co.copy()
-                                for splineVert in spline.bezier_points.values()]
-
-            else: # verts from all other types of curves
-                splineVerts = [splineVert.co.to_3d()
-                                for splineVert in spline.points.values()]
-
-            # simplify spline according to mode
-            if mode == 'distance':
-                newVerts = simplify_RDP(splineVerts, options)
-
-            if mode == 'curvature':
-                newVerts = simplypoly(splineVerts, options)
-
-            # convert indices into vectors3D
-            newPoints = vertsToPoints(newVerts, splineVerts, splineType)
-
-            # create new spline            
-            newSpline = curve.splines.new(type = splineType)
-
-            # put newPoints into spline according to type
-            if splineType == 'BEZIER':
-                newSpline.bezier_points.add(int(len(newPoints)*0.33))
-                newSpline.bezier_points.foreach_set('co', newPoints)
-            else:
-                newSpline.points.add(int(len(newPoints)*0.25 - 1))
-                newSpline.points.foreach_set('co', newPoints)
-
-            # set degree of outputNurbsCurve
-            if output == 'NURBS':
-                newSpline.order_u = degreeOut
-
-            # splineoptions
-            newSpline.use_endpoint_u = spline.use_endpoint_u
-
-    # create ne object and put into scene
-    newCurve = bpy.data.objects.new("simple_"+obj.name, curve)
-    scene.objects.link(newCurve)
-    newCurve.select = True
-    scene.objects.active = newCurve
-    newCurve.matrix_world = obj.matrix_world
-
-    # set bezierhandles to auto
-    setBezierHandles(newCurve)
-
-    #print("________END________\n")
-    return
-
-##################
-## get preoperator fcurves
-def getFcurveData(obj):
-    fcurves = []
-    for fc in obj.animation_data.action.fcurves:
-        if fc.select:
-            fcVerts = [vcVert.co.to_3d()
-                        for vcVert in fc.keyframe_points.values()]
-            fcurves.append(fcVerts)
-    return fcurves
-
-def selectedfcurves(obj):
-    fcurves_sel = []
-    for i, fc in enumerate(obj.animation_data.action.fcurves):
-        if fc.select:
-            fcurves_sel.append(fc)
-    return fcurves_sel
-
-###########################################################
-## fCurves Main
-def fcurves_simplify(context, obj, options, fcurves):
-    # main vars
-    mode = options[0]
-
-    #get indices of selected fcurves
-    fcurve_sel = selectedfcurves(obj)
-    
-    # go through fcurves
-    for fcurve_i, fcurve in enumerate(fcurves):
-        # test if fcurve is long enough
-        if len(fcurve) >= 7:
-
-            # simplify spline according to mode
-            if mode == 'distance':
-                newVerts = simplify_RDP(fcurve, options)
-
-            if mode == 'curvature':
-                newVerts = simplypoly(fcurve, options)
-
-            # convert indices into vectors3D
-            newPoints = []
-        
-            #this is different from the main() function for normal curves, different api...
-            for v in newVerts:
-                newPoints.append(fcurve[v])
-            
-            #remove all points from curve first
-            for i in range(len(fcurve)-1,0,-1):
-                fcurve_sel[fcurve_i].keyframe_points.remove(fcurve_sel[fcurve_i].keyframe_points[i])
-            # put newPoints into fcurve
-            for v in newPoints:
-                fcurve_sel[fcurve_i].keyframe_points.insert(frame=v[0],value=v[1])
-            #fcurve.points.foreach_set('co', newPoints)
-    return
-
-#################################################
-#### ANIMATION CURVES OPERATOR ##################
-#################################################
-class GRAPH_OT_simplify(bpy.types.Operator):
-    ''''''
-    bl_idname = "graph.simplify"
-    bl_label = "simplifiy f-curves"
-    bl_description = "simplify selected f-curves"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    ## Properties
-    opModes = [
-            ('distance', 'distance', 'distance'),
-            ('curvature', 'curvature', 'curvature')]
-    mode = EnumProperty(name="Mode",
-                            description="choose algorithm to use",
-                            items=opModes)
-    k_thresh = FloatProperty(name="k",
-                            min=0, soft_min=0,
-                            default=0, precision=3,
-                            description="threshold")
-    pointsNr = IntProperty(name="n",
-                            min=5, soft_min=5,
-                            max=16, soft_max=9,
-                            default=5,
-                            description="degree of curve to get averaged curvatures")
-    error = FloatProperty(name="error",
-                            description="maximum error to allow - distance",
-                            min=0.0, soft_min=0.0,
-                            default=0, precision=3)
-    degreeOut = IntProperty(name="degree",
-                            min=3, soft_min=3,
-                            max=7, soft_max=7,
-                            default=5,
-                            description="degree of new curve")
-    dis_error = FloatProperty(name="distance error",
-                            description="maximum error in Blenderunits to allow - distance",
-                            min=0, soft_min=0,
-                            default=0.0, precision=3)
-    fcurves = []
-
-    '''  Remove curvature mode as long as it isnn't significantly improved
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        col.label('Mode:')
-        col.prop(self, 'mode', expand=True)
-        if self.mode == 'distance':
-            box = layout.box()
-            box.label(self.mode, icon='ARROW_LEFTRIGHT')
-            box.prop(self, 'error', expand=True)
-        if self.mode == 'curvature':
-            box = layout.box()
-            box.label('degree', icon='SMOOTHCURVE')
-            box.prop(self, 'pointsNr', expand=True)
-            box.label('threshold', icon='PARTICLE_PATH')
-            box.prop(self, 'k_thresh', expand=True)
-            box.label('distance', icon='ARROW_LEFTRIGHT')
-            box.prop(self, 'dis_error', expand=True)
-        col = layout.column()
-    '''
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        col.prop(self, 'error', expand=True)
-        
-    ## Check for animdata
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        fcurves = False
-        if obj:
-            animdata = obj.animation_data
-            if animdata:
-                act = animdata.action
-                if act:
-                    fcurves = act.fcurves
-        return (obj and fcurves)
-
-    ## execute
-    def execute(self, context):
-        #print("------START------")
-
-        options = [
-                self.mode,       #0
-                self.mode,       #1
-                self.k_thresh,   #2
-                self.pointsNr,   #3
-                self.error,      #4
-                self.degreeOut,  #6
-                self.dis_error]  #7
-
-        obj = context.active_object
-
-        if not self.fcurves:
-            self.fcurves = getFcurveData(obj)
-        
-        fcurves_simplify(context, obj, options, self.fcurves)
-
-        #print("-------END-------")
-        return {'FINISHED'}
-
-###########################
-##### Curves OPERATOR #####
-###########################
-class CURVE_OT_simplify(bpy.types.Operator):
-    ''''''
-    bl_idname = "curve.simplify"
-    bl_label = "simplifiy curves"
-    bl_description = "simplify curves"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    ## Properties
-    opModes = [
-            ('distance', 'distance', 'distance'),
-            ('curvature', 'curvature', 'curvature')]
-    mode = EnumProperty(name="Mode",
-                            description="choose algorithm to use",
-                            items=opModes)
-    SplineTypes = [
-                ('INPUT', 'Input', 'same type as input spline'),
-                ('NURBS', 'Nurbs', 'NURBS'),
-                ('BEZIER', 'Bezier', 'BEZIER'),
-                ('POLY', 'Poly', 'POLY')]
-    output = EnumProperty(name="Output splines",
-                            description="Type of splines to output",
-                            items=SplineTypes)
-    k_thresh = FloatProperty(name="k",
-                            min=0, soft_min=0,
-                            default=0, precision=3,
-                            description="threshold")
-    pointsNr = IntProperty(name="n",
-                            min=5, soft_min=5,
-                            max=9, soft_max=9,
-                            default=5,
-                            description="degree of curve to get averaged curvatures")
-    error = FloatProperty(name="error in Bu",
-                            description="maximum error in Blenderunits to allow - distance",
-                            min=0, soft_min=0,
-                            default=0.0, precision=3)
-    degreeOut = IntProperty(name="degree",
-                            min=3, soft_min=3,
-                            max=7, soft_max=7,
-                            default=5,
-                            description="degree of new curve")
-    dis_error = FloatProperty(name="distance error",
-                            description="maximum error in Blenderunits to allow - distance",
-                            min=0, soft_min=0,
-                            default=0.0)
-    keepShort = BoolProperty(name="keep short Splines",
-                            description="keep short splines (less then 7 points)",
-                            default=True)
-
-    '''  Remove curvature mode as long as it isnn't significantly improved
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        col.label('Mode:')
-        col.prop(self, 'mode', expand=True)
-        if self.mode == 'distance':
-            box = layout.box()
-            box.label(self.mode, icon='ARROW_LEFTRIGHT')
-            box.prop(self, 'error', expand=True)
-        if self.mode == 'curvature':
-            box = layout.box()
-            box.label('degree', icon='SMOOTHCURVE')
-            box.prop(self, 'pointsNr', expand=True)
-            box.label('threshold', icon='PARTICLE_PATH')
-            box.prop(self, 'k_thresh', expand=True)
-            box.label('distance', icon='ARROW_LEFTRIGHT')
-            box.prop(self, 'dis_error', expand=True)
-        col = layout.column()
-        col.separator()
-        col.prop(self, 'output', text='Output', icon='OUTLINER_OB_CURVE')
-        if self.output == 'NURBS':
-            col.prop(self, 'degreeOut', expand=True)
-        col.prop(self, 'keepShort', expand=True)
-    '''
-        
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        col.prop(self, 'error', expand=True)
-        col.prop(self, 'output', text='Output', icon='OUTLINER_OB_CURVE')
-        if self.output == 'NURBS':
-            col.prop(self, 'degreeOut', expand=True)
-        col.prop(self, 'keepShort', expand=True)
-        
-        
-    ## Check for curve
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'CURVE')
-
-    ## execute
-    def execute(self, context):
-        #print("------START------")
-
-        options = [
-                self.mode,       #0
-                self.output,     #1
-                self.k_thresh,   #2
-                self.pointsNr,   #3
-                self.error,      #4
-                self.degreeOut,  #5
-                self.dis_error,  #6
-                self.keepShort]  #7
-
-
-        bpy.context.user_preferences.edit.use_global_undo = False
-
-        bpy.ops.object.mode_set(mode='OBJECT', toggle=True)
-        obj = context.active_object
-
-        main(context, obj, options)
-
-        bpy.context.user_preferences.edit.use_global_undo = True
-
-        #print("-------END-------")
-        return {'FINISHED'}
-
-#################################################
-#### REGISTER ###################################
-#################################################
-def register():
-    bpy.utils.register_module(__name__)
-
-    pass
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    pass
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_mesh_beam_builder.py b/release/scripts/addons_contrib/add_mesh_beam_builder.py
deleted file mode 100644
index a5a0114..0000000
--- a/release/scripts/addons_contrib/add_mesh_beam_builder.py
+++ /dev/null
@@ -1,1477 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Beam Builder",
-    "description": "Creates various types of beams.",
-    "author": "revolt_randy",
-    "version": (0, 1, 3),
-    "blender": (2, 6, 0),
-    "location": "View3D > Add > Mesh",
-    "warning": "Currently under development.", 
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Add_Mesh/BeamBuilder",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=26911",
-    "category": "Add Mesh"}
-
-#
-# Creates a rectangluar, 'C', 'L', 'T', or 'I' - type beam.
-#
-       
-# Version History
-#
-# v0.1 - Script only generates a multi-sided mesh object,
-#           initial release for testing. 3/12/11
-#
-# v0.1.1 - Added 'C'-type beam, updated to work with 
-#           api r35499. 3/13/11
-#
-# v0.1.2 - Totally changed the way beams are created, size
-#           is now calculated based off width, length, & height
-#           (x,y,z). Added ability to taper beams as well.
-#           Add 'L' - type beam
-#           Add 'T' - type beam
-#           Add 'I' - type beam 
-#
-# v0.1.3 - Updated to work with api r41226, including using object_utils.py -
-#           part of blender's bpy_extras scripts. This is what handles
-#           the 'align to view', 'location', & 'rotation' options in the
-#           toolshelf when creating mesh. Added wiki & tracker url. Fixed
-#           a few bugs & fixed some debug prints that were still printing
-#           to console.  
-#     
-
-import bpy
-
-from bpy_extras import object_utils
-
-
-def create_mesh (self, context, name, verts, faces, debug):
-    # Creates mesh and object
-    # name - name of object to create
-    # verts - a list of vertex tuples
-    # faces - a list of face tuples
-    # debug - debug flag - if true prints data to console
-           
-    # Actually create mesh and object
-    mesh = bpy.data.meshes.new(name)
-
-    # add verts & faces to object
-    mesh.from_pydata(verts, [], faces)
-    mesh.update(calc_edges=True)
-    
-    if debug:
-        print("create_mesh function called and finished")    
-      
-    return object_utils.object_data_add(context, mesh, operator=self)
-
-
-def recalc_normals(debug):
-    # Recalculate normals
-    # parts of this script creates faces that are backwards or
-    # have thier normals facing the wrong way, so recalculate them
-    # debug - debug flag - if true prints data to console
-    
-    
-    if bpy.context.mode != 'EDIT_MESH':
-        bpy.ops.object.editmode_toggle()
-        # Recalcuate normals
-        bpy.ops.mesh.normals_make_consistent()
-        bpy.ops.object.editmode_toggle()
-        if debug:
-            print("\nObjectMode")
-    else:
-        bpy.ops.mesh.normals_make_consistent()
-        if debug:
-            print("\nEditMode")
-            
-    return
-
-
-def create_end_faces(verts_list, thick, debug):
-    # Create End Faces
-    # verts_list - list of vertices
-    # thick - if true object is hollow, so construct loop of end faces
-    #           instead of a solid end face
-    # debug - if true prints values from this function to console
-    
-    # returns:
-    # faces - a list of tuples defining the end faces
-    
-    faces = []
-    
-    num_of_verts = len(verts_list)
-    faces_temp = []
-
-    sides = 4 # sides - number of sides to mesh *added because of code re-write
-    
-    if thick:
-        # has thickness, so build end faces            
-        num_of_verts = int(num_of_verts / 2)
-        
-        # Create a list of the front faces
-        for index in range(num_of_verts):
-            if index == (num_of_verts - 1):
-                faces_temp.append(verts_list[index])
-                faces_temp.append(verts_list[index-index])
-                faces_temp.append(verts_list[index+1])
-                faces_temp.append(verts_list[index*2+1])
-            else:
-                faces_temp.append(verts_list[index])
-                faces_temp.append(verts_list[index+1])
-                faces_temp.append(verts_list[index+num_of_verts+1])
-                faces_temp.append(verts_list[index+num_of_verts])
-                        
-            faces.append(tuple(faces_temp))
-            faces_temp = []                
-    else:
-        #this code may not be needed, depends upon rewrite...
-        if sides > 4:
-            # more than 4 sides, so replace last list item (center vert) with first list item 
-            # for looping and building faces
-            center_vert = verts_list[num_of_verts - 1]
-            verts_list[num_of_verts - 1] = verts_list[0]
-
-            for index in range(int(num_of_verts - 1)):
-                faces_temp.append(verts_list[index])
-                faces_temp.append(verts_list[index + 1])
-                faces_temp.append(center_vert)
-                faces.append(tuple(faces_temp))
-                faces_temp = []
-        
-        else:
-            # create 1 end face
-            for index in range(num_of_verts):
-                faces_temp.append(verts_list[index])
-            faces.append(tuple(faces_temp))               
-    
-    # print debug info to console
-    if debug:
-        print("\ncreate_end_faces Function Starts")
-        print("\n End Face Verts list :", verts_list)
-        print("\n End Faces: ", faces)
-        print("\ncreate_end_faces Function Ends\n\n")
-            
-    return faces
-
-
-def create_side_faces(front_verts, back_verts, debug):
-    # Create side faces - simple bridging of front_verts & back_verts vertices,
-    #                     both front_verts & back_verts must be ordered in same direction
-    #                     with respect to y-axis
-    # front_verts - a list of front face vertices
-    # back_verts - a list of back face vertices
-    # debug - if true prints values from this function to console
-    
-    # returns:
-    # new_faces - a list of tuples defining the faces bridged between front_verts & back_verts
-    
-    # Number of faces to create
-    num_of_faces = (len(front_verts))
-    new_faces = []
-    
-    # add first value to end of lists for looping
-    front_verts.append(front_verts[0])
-    back_verts.append(back_verts[0])
-    
-    # Build the new_faces list with tuples defining each face    
-    for index in range(num_of_faces):
-        facestemp = (front_verts[index], front_verts[index+1], back_verts[index+1], back_verts[index])
-        new_faces.append(facestemp)
-    
-    # print debug info to console
-    if debug:
-        print("\ncreate_side_faces Function Starts") 
-        print("\n Number of faces to create: ", num_of_faces)
-        print("\n New faces :", new_faces)
-        print("\ncreate_side_faces Function Ends\n\n")
-
-    return new_faces
-
-
-def calc_end_verts(size, y_off, thick, debug):
-    # Calculates vertex location for end of mesh
-    
-    # size - tuple of x,y,z dimensions of mesh to create
-    # y_off - y offset, lets function know where to create verts on y-axis
-    # thick - thickness, if not zero this is the thickness of a hollow mesh
-    #         with the inner faces inset from size dimensions
-    # debug - if true prints values from this function to console
-    
-    # returns:
-    # verts - a list of tuples of the x,y,z location of each vertex
-    
-    verts = []
-    
-    if debug:
-        print ("\ncalc_end_verts Function Starts\n")
-        print("\nsize = ",size)
-        print("y_off = ",y_off)
-        
-    # Create vertices by calculation 
-    x_pos = 0 + size[0]/2
-    z_pos = 0 + size[2]/2
-    verts.append((x_pos, y_off, z_pos))
-
-    x_pos = 0 - size[0]/2
-    z_pos = 0 + size[2]/2
-    verts.append((x_pos, y_off, z_pos))
-    
-    x_pos = 0 - size[0]/2
-    z_pos = 0 - size[2]/2
-    verts.append((x_pos, y_off, z_pos)) 
-    
-    x_pos = 0 + size[0]/2
-    z_pos = 0 - size[2]/2
-    verts.append((x_pos, y_off, z_pos))   
-         
-    if thick:
-        # has thickness, so calculate inside vertices
-        #### not too sure about this, but it does work the way the 
-        #### solidify modifier works, so leaving as is for now
-        x_pos = size[0] - (thick * 2)
-        z_pos = size[2] - (thick * 2)
-        size = (x_pos, y_off, z_pos)
-        
-        # Create vertices by calculation 
-        x_pos = 0 + size[0]/2
-        z_pos = 0 + size[2]/2
-        verts.append((x_pos, y_off, z_pos))
-
-        x_pos = 0 - size[0]/2
-        z_pos = 0 + size[2]/2
-        verts.append((x_pos, y_off, z_pos))
-    
-        x_pos = 0 - size[0]/2
-        z_pos = 0 - size[2]/2
-        verts.append((x_pos, y_off, z_pos)) 
-    
-        x_pos = 0 + size[0]/2
-        z_pos = 0 - size[2]/2
-        verts.append((x_pos, y_off, z_pos))          
-            
-    if debug:
-        print ("verts :", verts)
-        print ("\ncalc_end_verts Function Ends.\n\n")
-    
-    return verts
-
-
-def adjust_c_beam_verts(verts, taper, debug):
-    # Adjusts verts produced to correct c beam shape
-    # verts - a list of tuples of vertex locations for one end of beam
-    # taper - % to taper outside verts by
-    # debug - if true values are printed to console for debugging
-    
-    # returns:
-    # verts - the corrected list of tuples of the adjustec vertex locations
-    
-    # This function corrects vertex locations to properly shape the
-    # beam, because creating a c beam uses the same code as the 
-    # create_rectangular_beam function does. Therefore the 5th & 6th
-    # vertice's z location needs to be changed to match the 1st & 2nd
-    # vertice's z location.
-
-    vert_orig = verts[0]
-    
-    # get 3rd value, the z location
-    vert_z = vert_orig[2] 
-    # get 1st value, the x location, for vert taper calcs    
-    vert_x = vert_orig[0]
-  
-    # vert_z has the z value to be used in the 5th & 6th verts
-    # get value of 5th vert 
-    vert_temp = verts[4]
-    
-
-    
-    # calculate the amount of taper, updating vert_x
-    # with the new value calculated.
-    vert_x = calc_taper(vert_orig[0], vert_temp[0], taper)
-    
-    vert_new = (vert_x,vert_temp[1],vert_z)
-    
-    if debug:
-        print ("\nadjust_c_beam_verts function starting")
-        print ("vert_orig = ",vert_orig[0])
-        print ("vert_x = ",vert_x)
-        print("vert_temp =",vert_temp)
-        print("vert_new =",vert_new)
-
-    # update 5th vert with new value
-    verts[4] = vert_new
-    
-    vert_orig = verts[1]
-    
-    # get 3rd value, the z location
-    vert_z = vert_orig[2] 
-    # get 1st value, the x location, for vert taper calcs    
-    vert_x = vert_orig[0]
-    # vert_z has the z value to be used in the 5th & 6th verts
-    # get value of 5th vert 
-    vert_temp = verts[5]
-    
-
-    
-    # calculate the amount of taper, updating vert_x
-    # with the new value calculated.
-    vert_x = calc_taper(vert_orig[0], vert_temp[0], taper)
-    
-    vert_new = (vert_x,vert_temp[1],vert_z)
-    
-    if debug:
-        print ("vert_orig = ",vert_orig[0])
-        print ("vert_x = ",vert_x)
-        print("vert_temp =",vert_temp)
-        print("vert_new =",vert_new)
-    
-    # update 6th vert with new value
-    verts[5] = vert_new    
-    
-    if debug:
-        print("\n adjust_c_beam_verts function ending")
-        print("verts =", verts)
-        
-    return verts        
-
-
-def calc_taper(outer_vert, inner_vert, taper):
-    # Calculate tapered edges of beam - inner vert is moved towards
-    #    outer vert based upon percentage value in taper
-    # outer_vert - the outside vertex
-    # inner_vert - the inside vertex to be moved
-    # taper - percentage to move vert
-    
-    # returns:
-    # adjusted_vert - the calculated vertex
-
-    #print("outer_vert =",outer_vert,"inner_vert",inner_vert)
-    
-    # taper values range from 0 to 100 for UI, but for calculations
-    # this value needs to be flipped, ranging from 100 to 0
-    taper = 100 - taper
-    
-    # calcuate taper & adjust vertex
-    vert_delta = inner_vert - outer_vert
-    adjusted_vert = outer_vert + ((vert_delta/100) * taper)    
-    
-    #print("adjusted_vert =", adjusted_vert)    
-    return adjusted_vert
-
-    
-def create_rectangular_beam(size, thick, debug):
-    # Creates a rectangular beam mesh object
-    # size - tuple of x,y,z dimensions of box
-    # thick - thickness, if not zero this is the thickness of a hollow 
-    #         box with inner faces inset from size dimensions
-    # debug - if true prints values from this function to console
-    
-    # returns: 
-    # verts_final - a list of tuples of the x, y, z, location of each vertice
-    # faces_final - a list of tuples of the vertices that make up each face  
-    
-    # Create temporarylists to hold vertices locations
-    verts_front_temp=[]
-    verts_back_temp=[]
-    
-    #calculate y offset from center for front vertices
-    y_off = size[1]/2 
-      
-        
-    # Create front vertices by calculation
-    verts_front_temp = calc_end_verts(size, y_off, thick, debug)
-    
-    # re-calculate y offset from center for back vertices
-    y_off = 0 - y_off
-    
-    # Create back vertices by calculation
-    verts_back_temp = calc_end_verts(size, y_off, thick, debug)
-    
-    # Combine all vertices into a final list of tuples
-    verts_final = verts_front_temp + verts_back_temp   
-           
-    # Print debug info to console
-    if debug:
-        print("\ncreate_multi_side_box Function Start")
-        print("\n Front vertices :", verts_front_temp)
-        print("\n Back vertices:", verts_back_temp)
-        print("\n All vertices:", verts_final)
-                      
-    # Create front face
-    faces_front_temp = []
-    verts_front_list = []
-    numofverts = len(verts_front_temp)
-    
-    # Build vertex list
-    for index in range(numofverts):
-        verts_front_list.append(index)
-       
-    faces_front_temp = create_end_faces(verts_front_list, thick, debug) 
-    
-    # Create back face
-    faces_back_temp = []
-    verts_back_list = []
-    numofverts = len(verts_back_temp)
-    
-    # Build vertex list
-    for index in range(numofverts):
-        verts_back_list.append(index + len(verts_back_temp))
-        
-    faces_back_temp = create_end_faces(verts_back_list, thick, debug)
-
-    # Create side faces
-    faces_side_temp = []
-    
-    # better code needed here???
-    if thick:
-        # Object has thickness, create list of outside vertices
-        numofverts = len(verts_front_list)
-        verts_front_temp = verts_front_list[0:int(numofverts/2)]
-        verts_back_temp = verts_back_list[0:int(numofverts/2)]
-        
-        faces_side_temp = create_side_faces(verts_front_temp, verts_back_temp, debug)
-        
-        # Create list of inside vertices
-        verts_front_temp = verts_front_list[int(numofverts/2):numofverts]
-        verts_back_temp = verts_back_list[int(numofverts/2):numofverts]
-        
-        faces_side_temp += create_side_faces(verts_front_temp, verts_back_temp, debug)            
-    else:
-        # Create list of only outside faces
-        faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
-    
-    # Combine all faces 
-    faces_final = faces_front_temp + faces_back_temp + faces_side_temp
-    
-    # print debug info to console   
-    if debug:
-        print("\ncreate_multi_side_box Function")
-        print("\nAll faces :",faces_final)
-        print("\ncreate_multi_side_box Function Ends\n\n")
-    
-    return verts_final, faces_final
-
-
-def create_C_beam(size, thick, taper, debug):
-    # Creates a C or U shaped mesh beam object 
-    # size - tuple of x,y,z dimensions of beam
-    # thick - thickness, the amount the inner faces will be
-    #           inset from size dimensions
-    # taper - % to taper outside edges by
-    # debug - if true prints values from this function to console
-    
-    # returns: 
-    # verts_final - a list of tuples of the x, y, z, location of each vertice
-    # faces_final - a list of tuples of the vertices that make up each face
-    
-    # print debug info to console
-    if debug:
-        print ("\ncreate_C_beam - function called")
-
-    # Get y offset of vertices from center
-    y_off = size[1] / 2
-    
-    # Create temporarylists to hold vertices locations
-    verts_front_temp=[]
-    verts_back_temp=[]
-    
-    # Create front vertices by calculation
-    verts_front_temp = calc_end_verts(size, y_off, thick, debug)
-    # Additional adjustment to the verts needed - 5th & 6th verts
-    # needed because the calc_end_verts creates a rectangluar beam
-    # the insides are inset, for a U channel we need the inside
-    # verts on the open end to match the z-loc of the outside verts 
-    verts_front_temp = adjust_c_beam_verts(verts_front_temp, taper, debug)       
-    
-    # recalculate y_off for other end vertices
-    y_off = 0 - y_off
-    
-    # Create back vertices by calculation
-    verts_back_temp = calc_end_verts(size, y_off, thick, debug)
-    # Additional adjustment to the verts needed - the z location
-    verts_back_temp = adjust_c_beam_verts(verts_back_temp, taper, debug)  
-    
-    # Combine all vertices into a final list of tuples
-    verts_final = verts_front_temp + verts_back_temp   
-  
-    # Print debug info to console
-    if debug:
-        print("\ncreate_C_beam function start")
-        print("\n Front vertices :", verts_front_temp)
-        print("\n Back vertices:", verts_back_temp)
-        print("\n All vertices:", verts_final)
-    
-    # Create front face
-    faces_front_temp = []
-    verts_front_list = []
-    numofverts = len(verts_front_temp)
-    
-    # Build vertex list
-    for index in range(numofverts):
-        verts_front_list.append(index)
-    # problem area   
-    faces_front_temp = create_end_faces(verts_front_list, thick, debug) 
-    # Remove 1st face - only 3 end faces needed
-    faces_front_temp = faces_front_temp[1:4]
-        
-    # Create back face
-    faces_back_temp = []
-    verts_back_list = []
-    numofverts = len(verts_back_temp)
-    
-    # Build vertex list
-    for index in range(numofverts):
-        verts_back_list.append(index + len(verts_back_temp))
-      
-    faces_back_temp = create_end_faces(verts_back_list, thick, debug)
-    # Remove 1st face - only 3 end faces needed
-    faces_back_temp = faces_back_temp[1:4]
-
-    # Create list of outside vertices for the 3 outside faces
-    numofverts = (len(verts_front_list))
-    verts_front_temp = verts_front_list[0:int(numofverts/2)]
-    verts_back_temp = verts_back_list[0:int(numofverts/2)]
-        
-    faces_side_temp = create_side_faces(verts_front_temp, verts_back_temp, debug)
-    # create_side_faces creates 4 outside faces, we only want 3
-    # so remove the 1st face
-    faces_side_temp  = faces_side_temp[1:]
-    
-    # Create list of inside vertices for the 3 inside faces
-    verts_front_temp = verts_front_list[int(numofverts/2):numofverts]
-    verts_back_temp = verts_back_list[int(numofverts/2):numofverts]
-        
-    faces_side_temp += create_side_faces(verts_front_temp, verts_back_temp, debug)
-    # create_side_faces creates 4 outside faces, we only want 3
-    # so remove the 1st face
-    faces_side_temp  = faces_side_temp[0:3] + faces_side_temp[4:]
-    
-    # fill in top two faces
-    faces_side_temp.append((0, 4, 12, 8))
-    faces_side_temp.append((5, 1, 9, 13))    
-    
-    # Combine all faces 
-    faces_final = faces_front_temp + faces_back_temp + faces_side_temp
-
-    # Print debug info to console
-    if debug:
-        print("\ncreate_C_beam function") 
-        print("\nAll faces =", faces_final)
-        print("\ncreate_C_beam function ending")
-         
-    return verts_final, faces_final
-
-
-def create_L_beam(size, thick, taper, debug):
-    # Creates a L shaped mesh beam object
-    # size - tuple of x,y,z dimensions of beam
-    # thick - thickness, the amount the inner faces will be
-    #           inset from size dimensions
-    # taper - % to taper outside edges by
-    # debug - if true prints values from this function to console
-    
-    # returns:
-    # verts_final - a list of tuples of the x, y, z, location of each vertice
-    # faces_final - a list of tuples of the vertices that make up each face
-    
-    if debug:
-        print("\ncreate_L_beam function starting")
-
-    # Get offset of vertices from center
-    x_off = size[0] / 2
-    y_off = size[1] / 2
-    z_off = size[2] / 2
-    
-    # Create temporarylists to hold vertices locations
-    verts_front_temp=[]
-    verts_back_temp=[]
-    
-    # Create front vertices by calculation
-    verts_front_temp = [(0 - x_off, 0 - y_off, z_off), \
-        (0 - (x_off - thick), 0 - y_off, z_off), \
-        (0 - (x_off - thick), 0 - y_off, 0 - (z_off - thick)), \
-        (x_off, 0 - y_off, 0 - (z_off - thick)), \
-        (x_off, 0 - y_off, 0 - z_off), \
-        (0 - x_off, 0 - y_off, 0 - z_off)]
-    
-    # Adjust taper
-    vert_outside = verts_front_temp[0]
-    vert_inside = verts_front_temp[1]
-    verts_front_temp[1] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1],vert_inside[2]]
-   
-    vert_outside = verts_front_temp[4]
-    vert_inside = verts_front_temp[3]
-    verts_front_temp[3] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    # Create back vertices by calculation
-    verts_back_temp = [(0 - x_off, y_off, z_off), \
-        (0 - (x_off - thick), y_off, z_off), \
-        (0 - (x_off - thick), y_off, 0 - (z_off - thick)), \
-        (x_off, y_off, 0 - (z_off - thick)), \
-        (x_off, y_off, 0 - z_off), \
-        (0 - x_off, y_off, 0 - z_off)]
-
-    # Adjust taper
-    vert_outside = verts_back_temp[0]
-    vert_inside = verts_back_temp[1]
-    verts_back_temp[1] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1],vert_inside[2]]   
-    
-    vert_outside = verts_back_temp[4]
-    vert_inside = verts_back_temp[3]
-    verts_back_temp[3] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))] 
-    
-    verts_final = verts_front_temp + verts_back_temp
-    
-    if debug:
-        print("\n verts_front_temp =", verts_front_temp)
-        print("\n verts_back_temp =", verts_back_temp)
-        print("\n verts_final =", verts_final)
-    
-    # define end faces, only 4 so just coded
-    faces_front_temp = []
-    faces_back_temp = []
-    faces_side_temp = []
-    
-    faces_front_temp = [(0, 1, 2, 5), (2, 3, 4, 5)]
-    faces_back_temp = [(6, 7, 8, 11), (8, 9, 10, 11)]
-    
-    verts_front_list = []
-    verts_back_list = []
-    num_of_verts = len(verts_front_temp)
-    
-    # build lists of back and front verts for create_side_faces function
-    for index in range(num_of_verts):
-        verts_front_list.append(index)
-    for index in range(num_of_verts):
-        verts_back_list.append(index  + 6)
-    
-    faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
-        
-    faces_final = faces_front_temp + faces_back_temp + faces_side_temp
-    
-    if debug:
-        print("\n faces_front_temp =", faces_front_temp)
-        print("\n faces_back_temp =", faces_back_temp)
-        print("\n faces_side_temp =", faces_side_temp)
-        print("\n faces_final =", faces_final)
-        print("\ncreate_L_beam function ending")
-        
-    return verts_final, faces_final
-
-
-
-def create_T_beam(size, thick, taper, debug):
-    # Creates a T shaped mesh beam object
-    # size - tuple of x,y,z dimensions of beam
-    # thick - thickness, the amount the inner faces will be
-    #           inset from size dimensions
-    # taper - % to taper outside edges by
-    # debug - if true prints values from this function to console
-    
-    # returns:
-    # verts_final - a list of tuples of the x, y, z, location of each vertice
-    # faces_final - a list of tuples of the vertices that make up each face
-    debug = 0
-    
-    if debug:
-        print("\ncreate_T_beam function starting")
-
-    # Get offset of vertices from center
-    x_off = size[0] / 2
-    y_off = size[1] / 2
-    z_off = size[2] / 2
-    thick_off = thick / 2
-
-    # Create temporarylists to hold vertices locations
-    verts_front_temp=[]
-    verts_back_temp=[]
-    
-    # Create front vertices by calculation
-    verts_front_temp = [(0 - x_off, 0 - y_off, z_off), \
-        (0 - thick_off, 0 - y_off, z_off), \
-        (thick_off, 0 - y_off, z_off), \
-        (x_off, 0 - y_off, z_off), \
-        (x_off, 0 - y_off, z_off - thick), \
-        (thick_off, 0 - y_off, z_off - thick), \
-        (thick_off, 0 - y_off, 0 - z_off), \
-        (0 - thick_off, 0 - y_off, 0 - z_off), \
-        (0 - thick_off, 0 - y_off, z_off - thick), \
-        (0 - x_off, 0 - y_off, z_off - thick)]
-
-    # Adjust taper
-    vert_outside = verts_front_temp[0]
-    vert_inside = verts_front_temp[9]
-    verts_front_temp[9] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-
-    vert_outside = verts_front_temp[3]
-    vert_inside = verts_front_temp[4]
-    verts_front_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]  
-
-    # Adjust taper of bottom of beam, so 0 the center
-    # now becomes vert_outside, and vert_inside is calculated
-    # 1/2 way towards center
-    vert_outside = (0, 0 - y_off, 0 - z_off)
-    vert_inside = verts_front_temp[6]
-    verts_front_temp[6] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]  
-
-    vert_outside = (0, 0 - y_off, 0 - z_off)
-    vert_inside = verts_front_temp[7]
-    verts_front_temp[7] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]
-
-    # Create fack vertices by calculation
-    verts_back_temp = [(0 - x_off, y_off, z_off), \
-        (0 - thick_off, y_off, z_off), \
-        (thick_off, y_off, z_off), \
-        (x_off, y_off, z_off), \
-        (x_off, y_off, z_off - thick), \
-        (thick_off, y_off, z_off - thick), \
-        (thick_off, y_off, 0 - z_off), \
-        (0 - thick_off, y_off, 0 - z_off), \
-        (0 - thick_off, y_off, z_off - thick), \
-        (0 - x_off, y_off, z_off - thick)]
-
-    # Adjust taper
-    vert_outside = verts_back_temp[0]
-    vert_inside = verts_back_temp[9]
-    verts_back_temp[9] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-
-    vert_outside = verts_back_temp[3]
-    vert_inside = verts_back_temp[4]
-    verts_back_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    # Adjust taper of bottom of beam, so 0 the center
-    # now becomes vert_outside, and vert_inside is calculated
-    # 1/2 way towards center
-    vert_outside = (0, 0 - y_off, 0 - z_off)
-    vert_inside = verts_back_temp[6]
-    verts_back_temp[6] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]  
-
-    vert_outside = (0, 0 - y_off, 0 - z_off)
-    vert_inside = verts_back_temp[7]
-    verts_back_temp[7] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]
-        
-    verts_final = verts_front_temp + verts_back_temp
-    
-    
-    # define end faces, only 8 so just coded
-    faces_front_temp = []
-    faces_back_temp = []
-    faces_side_temp = []
-    
-    faces_front_temp = [(0, 1, 8, 9), (1, 2, 5, 8), \
-        (2, 3, 4, 5), (5, 6, 7, 8)]
-        
-    faces_back_temp = [(10, 11, 18, 19), (11, 12, 15, 18), \
-        (12, 13, 14, 15), (15, 16, 17,  18)]
-
-    verts_front_list = []
-    verts_back_list = []
-    num_of_verts = len(verts_front_temp)
-    
-    # build lists of back and front verts for create_side_faces function
-    for index in range(num_of_verts):
-        verts_front_list.append(index)
-    for index in range(num_of_verts):
-        verts_back_list.append(index  + 10)
-    
-    faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
-    
-    faces_final = faces_front_temp + faces_back_temp + faces_side_temp
-
-    if debug:
-        print("\ncreate_T_beam function ending")    
-        
-    return verts_final, faces_final
-
-
-def create_I_beam(size, thick, taper, debug):
-    # Creates a T shaped mesh beam object
-    # size - tuple of x,y,z dimensions of beam
-    # thick - thickness, the amount the inner faces will be
-    #           inset from size dimensions
-    # taper - % to taper outside edges by
-    # debug - if true prints values from this function to console
-    
-    # returns:
-    # verts_final - a list of tuples of the x, y, z, location of each vertice
-    # faces_final - a list of tuples of the vertices that make up each face
-    debug = 0
-    
-    if debug:
-        print("\ncreate_I_beam function starting")
-
-    # Get offset of vertices from center
-    x_off = size[0] / 2
-    y_off = size[1] / 2
-    z_off = size[2] / 2
-    thick_off = thick / 2
-
-    # Create temporarylists to hold vertices locations
-    verts_front_temp=[]
-    verts_back_temp=[]
-    
-    # Create front vertices by calculation
-    verts_front_temp = [(0 - x_off, 0 - y_off, z_off), \
-        (0 - thick_off, 0 - y_off, z_off), \
-        (thick_off, 0 - y_off, z_off), \
-        (x_off, 0 - y_off, z_off), \
-        (x_off, 0 - y_off, z_off - thick), \
-        (thick_off, 0 - y_off, z_off - thick), \
-        (thick_off, 0 - y_off, 0 - z_off + thick), \
-        (x_off, 0 - y_off, 0 - z_off + thick), \
-        (x_off, 0 - y_off, 0 - z_off), \
-        (thick_off, 0 - y_off, 0 - z_off), \
-        (0 - thick_off, 0 - y_off, 0 - z_off), \
-        (0 - x_off, 0 - y_off, 0 - z_off), \
-        (0 - x_off, 0 - y_off, 0 -z_off  + thick), \
-        (0 - thick_off, 0 - y_off, 0 - z_off + thick), \
-        (0 - thick_off, 0 - y_off, z_off - thick), \
-        (0 - x_off, 0 - y_off, z_off - thick)]
-    
-    # Adjust taper
-    vert_outside = verts_front_temp[0]
-    vert_inside = verts_front_temp[15]
-    verts_front_temp[15] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    vert_outside = verts_front_temp[3]
-    vert_inside = verts_front_temp[4]
-    verts_front_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    vert_outside = verts_front_temp[8]
-    vert_inside = verts_front_temp[7]
-    verts_front_temp[7] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    vert_outside = verts_front_temp[11]
-    vert_inside = verts_front_temp[12]
-    verts_front_temp[12] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-
-    # Create back vertices by calculation
-    verts_back_temp = [(0 - x_off, y_off, z_off), \
-        (0 - thick_off, y_off, z_off), \
-        (thick_off, y_off, z_off), \
-        (x_off, y_off, z_off), \
-        (x_off, y_off, z_off - thick), \
-        (thick_off, y_off, z_off - thick), \
-        (thick_off, y_off, 0 - z_off + thick), \
-        (x_off, y_off, 0 - z_off + thick), \
-        (x_off, y_off, 0 - z_off), \
-        (thick_off, y_off, 0 - z_off), \
-        (0 - thick_off, y_off, 0 - z_off), \
-        (0 - x_off, y_off, 0 - z_off), \
-        (0 - x_off, y_off, 0 -z_off  + thick), \
-        (0 - thick_off, y_off, 0 - z_off + thick), \
-        (0 - thick_off, y_off, z_off - thick), \
-        (0 - x_off, y_off, z_off - thick)]
-
-    # Adjust taper
-    vert_outside = verts_back_temp[0]
-    vert_inside = verts_back_temp[15]
-    verts_back_temp[15] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    vert_outside = verts_back_temp[3]
-    vert_inside = verts_back_temp[4]
-    verts_back_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    vert_outside = verts_back_temp[8]
-    vert_inside = verts_back_temp[7]
-    verts_back_temp[7] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
-    
-    vert_outside = verts_back_temp[11]
-    vert_inside = verts_back_temp[12]
-    verts_back_temp[12] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]       
- 
-    verts_final = verts_front_temp + verts_back_temp
-
-
-# define end faces, only 7 per end, so just coded
-    faces_front_temp = []
-    faces_back_temp = []
-    faces_side_temp = []
-    
-    faces_front_temp = [(0, 1, 14, 15), (1, 2, 5, 14), \
-        (2, 3, 4, 5), (6, 7, 8, 9), \
-        (6, 9, 10, 13), (12, 13, 10, 11), \
-        (5, 6, 13, 14)]
-        
-    faces_back_temp = [(16, 17, 30, 31), (17, 18, 21, 30), \
-        (18, 19, 20, 21), (22, 23, 24, 25), \
-        (22, 25, 26, 29), (28, 29, 26, 27), \
-        (21, 22, 29, 30)]
-        
-    verts_front_list = []
-    verts_back_list = []
-    num_of_verts = len(verts_front_temp)
-    
-    # build lists of back and front verts for create_side_faces function
-    for index in range(num_of_verts):
-        verts_front_list.append(index)
-    for index in range(num_of_verts):
-        verts_back_list.append(index  + 16)
-    
-    faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
-    
-    faces_final = faces_front_temp + faces_back_temp + faces_side_temp   
-    
-    if debug:
-        print("\ncreate_I_beam function ending")
-    
-    return verts_final, faces_final
-
-        
-
-# Define "Add_Rectangular_Beam" operator
-########### Needs Work ###############        
-class Add_Rectangular_Beam(bpy.types.Operator):
-    
-    bl_idname = "mesh.primitive_rectangle_add"
-    bl_label = "Add Rectangluar Beam"
-    bl_description = "Create a Rectangular Beam mesh"
-    bl_options = {'REGISTER', 'UNDO'}
-        
-    mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
-        description = "Height (along the z-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 1)
-        
-    mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
-        description = "Width (along the x-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = .5)
-        
-    mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
-        description = "Length (along y-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 2)
-            
-    thick_bool = bpy.props.BoolProperty(name = "Hollow",
-        description = "Create a hollow mesh with a defined thickness",
-        default = True)
-
-    thick = bpy.props.FloatProperty(name = "Thickness",
-        description = "Thickness of hollow mesh",
-        min = 0.01,
-        max = 1,
-        default = 0.1)
-        
-    # generic transform props
-    # required by object_utils.py - part of blender's
-    # code and is what handles alignment amongst other
-    # things.
-    view_align = bpy.props.BoolProperty(
-            name="Align to View",
-            default=False
-            )
-    location = bpy.props.FloatVectorProperty(
-            name="Location",
-            subtype='TRANSLATION',
-            )
-    rotation = bpy.props.FloatVectorProperty(
-            name="Rotation",
-            subtype='EULER',
-            )
-            
-    # Define tool parameter layout
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, 'mesh_z_size')
-        layout.prop(self, 'mesh_x_size')
-        layout.prop(self, 'mesh_y_size')
-        layout.prop(self, 'thick_bool')
-        if self.thick_bool:
-            layout.prop(self, 'thick')
-        layout.prop(self, 'view_align')
-        col = layout.column()
-        col.prop(self, 'location')
-        col.prop(self, 'rotation')
-                
-    def execute(self, context):
-        # debug flag - True prints debug info to console
-        debug = 0
-        
-        size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
-        if self.thick_bool is True:
-            thick = self.thick
-        else:
-            thick = 0
-                        
-        verts, faces = create_rectangular_beam(size, thick, debug)
-            
-        if debug:
-            print("\nCreated Verts:", verts)
-            print("\nCreated Faces:", faces)
-                
-        create_mesh(self, context, "Rectangular Beam", verts, faces, debug)
-        
-        recalc_normals(debug)        
-        
-        return {'FINISHED'}
-
-'''
-    def invoke(self, context, event):
-        #self.align_matrix = align_matrix(context)
-        self.execute(context)
-        return {'FINISHED'}    
-'''
-
-
-# Define "Add_C_Beam" operator        
-class Add_C_Beam(bpy.types.Operator):
-    
-    bl_idname = "mesh.primitive_c_beam_add"
-    bl_label = "Add C or U Channel"
-    bl_description = "Create a C or U channel mesh"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-        
-    mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
-        description = "Height (along the z-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 1)
-        
-    mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
-        description = "Width (along the x-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = .5)
-        
-    mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
-        description = "Length (along y-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 2)
-
-    thick = bpy.props.FloatProperty(name = "Thickness",
-        description = "Thickness of mesh",
-        min = 0.01,
-        max = 1,
-        default = 0.1)
-
-    taper = bpy.props.IntProperty(name = "Taper",
-        description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
-        min = 0,
-        max = 100,
-        default = 0)        
-
-    type = bpy.props.BoolProperty(name = "U-shaped",
-        description = "Create the beam in a U orientation rather than the defualt C orientation", 
-        default = True)
-                
-    # generic transform props
-    # required by object_utils.py - part of blender's
-    # code and is what handles alignment amongst other
-    # things.
-    view_align = bpy.props.BoolProperty(
-            name="Align to View",
-            default=False
-            )
-    location = bpy.props.FloatVectorProperty(
-            name="Location",
-            subtype='TRANSLATION',
-            )
-    rotation = bpy.props.FloatVectorProperty(
-            name="Rotation",
-            subtype='EULER',
-            )
-
-    # Define tool parameter layout
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, 'mesh_z_size')
-        layout.prop(self, 'mesh_x_size')
-        layout.prop(self, 'mesh_y_size')
-        layout.prop(self, 'thick')
-        layout.prop(self, 'taper')
-        layout.prop(self, 'type')
-        layout.prop(self, 'view_align')
-        col = layout.column()
-        col.prop(self, 'location')
-        col.prop(self, 'rotation')
-        
-                
-    def execute(self, context):
-        # debug flag - True prints debug info to console
-        debug = 0
-        
-        # if type == true beam is U chanel, otherwise it's a C
-        if self.type:
-            size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
-            mesh_name = "U Beam"
-        else:
-            size = (self.mesh_z_size, self.mesh_y_size, self.mesh_x_size)
-            mesh_name = "C Beam"
-                        
-        verts, faces = create_C_beam(size, self.thick, self.taper, debug)      
-
-        if debug:
-            print("\nCreated Verts:", verts)
-            print("\nCreated Faces:", faces)
-                
-        create_mesh(self, context, mesh_name, verts, faces, debug)
-        
-        recalc_normals(debug)
-           
-        if not self.type:
-        # C-type beam is actually created as a u-type beam
-        # so rotate 90 degrees on y-axis to make a c-type
-        # and apply rotation to reset those values
-        # if self.type is true, do nothing as beam is alreay u-type.
-        # rotation value is in radians
-            bpy.ops.transform.rotate(value=[1.570796], constraint_axis=[False, True, False])
-            bpy.ops.object.transform_apply(location=False, rotation =True, scale=False)
-        
-        return {'FINISHED'}
-
-'''
-    def invoke(self, context, event):
-        #self.align_matrix = align_matrix(context)
-        self.execute(context)
-        return {'FINISHED'}
-'''
-    
-
-# Define "Add_L_Beam" operator    
-class Add_L_Beam(bpy.types.Operator):
-    
-    bl_idname = "mesh.primitive_l_beam_add"
-    bl_label = "Add L Beam"
-    bl_description = "Create a L shaped mesh"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
-        description = "Height (along the z-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 1)
-        
-    mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
-        description = "Width (along the x-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = .5)
-        
-    mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
-        description = "Length (along y-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 2)
-
-    thick = bpy.props.FloatProperty(name = "Thickness",
-        description = "Thickness of mesh",
-        min = 0.01,
-        max = 1,
-        default = 0.1)
-
-    taper = bpy.props.IntProperty(name = "Taper",
-        description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
-        min = 0,
-        max = 100,
-        default = 0)
-
-    # generic transform props
-    # required by object_utils.py - part of blender's
-    # code and is what handles alignment amongst other
-    # things.
-    view_align = bpy.props.BoolProperty(
-            name="Align to View",
-            default=False
-            )
-    location = bpy.props.FloatVectorProperty(
-            name="Location",
-            subtype='TRANSLATION',
-            )
-    rotation = bpy.props.FloatVectorProperty(
-            name="Rotation",
-            subtype='EULER',
-            )
-
-    # Define tool parameter layout
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, 'mesh_z_size')
-        layout.prop(self, 'mesh_x_size')
-        layout.prop(self, 'mesh_y_size')
-        layout.prop(self, 'thick')
-        layout.prop(self, 'taper')
-        layout.prop(self, 'view_align')
-        col = layout.column()
-        col.prop(self, 'location')
-        col.prop(self, 'rotation')
-        
-
-    def execute(self, context):
-        # debug flag - True prints debug info to console
-        debug = 0 
-        
-        size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
-                           
-        verts, faces = create_L_beam(size, self.thick, self.taper, debug)
-        
-        if debug:
-            print("\nCreated Verts:", verts)
-            print("\nCreated Faces:", faces)
-                
-        create_mesh(self, context, "L Beam", verts, faces, debug)
-        
-        recalc_normals(debug) 
-        
-        return {'FINISHED'}
-
-'''
-    def invoke(self, context, event):
-        self.align_matrix = align_matrix(context)
-        self.execute(context)
-        return {'FINISHED'}
-'''
-    
-    
-# Define "Add_T_Beam" operator    
-class Add_T_Beam(bpy.types.Operator):
-    
-    bl_idname = "mesh.primitive_t_beam_add"
-    bl_label = "Add T Beam"
-    bl_description = "Create a T shaped mesh"
-    bl_options = {'REGISTER', 'UNDO'}    
-
-    mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
-        description = "Height (along the z-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 1)
-        
-    mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
-        description = "Width (along the x-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = .5)
-        
-    mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
-        description = "Length (along y-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 2)
-
-    thick = bpy.props.FloatProperty(name = "Thickness",
-        description = "Thickness of mesh",
-        min = 0.01,
-        max = 1,
-        default = 0.1)
-
-    taper = bpy.props.IntProperty(name = "Taper",
-        description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
-        min = 0,
-        max = 100,
-        default = 0)
-
-    # generic transform props
-    # required by object_utils.py - part of blender's
-    # code and is what handles alignment amongst other
-    # things.
-    view_align = bpy.props.BoolProperty(
-            name="Align to View",
-            default=False
-            )
-    location = bpy.props.FloatVectorProperty(
-            name="Location",
-            subtype='TRANSLATION',
-            )
-    rotation = bpy.props.FloatVectorProperty(
-            name="Rotation",
-            subtype='EULER',
-            )
-
-    # Define tool parameter layout
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, 'mesh_z_size')
-        layout.prop(self, 'mesh_x_size')
-        layout.prop(self, 'mesh_y_size')
-        layout.prop(self, 'thick')
-        layout.prop(self, 'taper')
-        layout.prop(self, 'view_align')
-        col = layout.column()
-        col.prop(self, 'location')
-        col.prop(self, 'rotation')
-
-
-    def execute(self, context):
-        # debug flag - True prints debug info to console
-        debug = 0
-        
-        size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
-                           
-        verts, faces = create_T_beam(size, self.thick, self.taper, debug)
-        
-        if debug:
-            print("\nCreated Verts:", verts)
-            print("\nCreated Faces:", faces)
-                
-        create_mesh(self, context, "T Beam", verts, faces, debug)
-        
-        recalc_normals(debug) 
-        
-        return {'FINISHED'}
-
-'''
-    def invoke(self, context, event):
-        self.align_matrix = align_matrix(context)
-        self.execute(context)
-        return {'FINISHED'}
-'''
-    
-    
-# Define "Add_I_Beam" operator    
-class Add_I_Beam(bpy.types.Operator):
-    
-    bl_idname = "mesh.primitive_i_beam_add"
-    bl_label = "Add I Beam"
-    bl_description = "Create a I shaped mesh"
-    bl_options = {'REGISTER', 'UNDO'}    
-
-    mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
-        description = "Height (along the z-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 1)
-        
-    mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
-        description = "Width (along the x-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = .5)
-        
-    mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
-        description = "Length (along y-axis) of mesh",
-        min = 0.01,
-        max = 100,
-        default = 2)
-
-    thick = bpy.props.FloatProperty(name = "Thickness",
-        description = "Thickness of mesh",
-        min = 0.01,
-        max = 1,
-        default = 0.1)
-
-    taper = bpy.props.IntProperty(name = "Taper",
-        description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
-        min = 0,
-        max = 100,
-        default = 0)
-
-    # generic transform props
-    # required by object_utils.py - part of blender's
-    # code and is what handles alignment amongst other
-    # things.
-    view_align = bpy.props.BoolProperty(
-            name="Align to View",
-            default=False
-            )
-    location = bpy.props.FloatVectorProperty(
-            name="Location",
-            subtype='TRANSLATION',
-            )
-    rotation = bpy.props.FloatVectorProperty(
-            name="Rotation",
-            subtype='EULER',
-            )
-    
-    # Define tool parameter layout
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, 'mesh_z_size')
-        layout.prop(self, 'mesh_x_size')
-        layout.prop(self, 'mesh_y_size')
-        layout.prop(self, 'thick')
-        layout.prop(self, 'taper')
-        layout.prop(self, 'view_align')
-        col = layout.column()
-        col.prop(self, 'location')
-        col.prop(self, 'rotation')
-        
-
-    def execute(self, context):
-        # debug flag - True prints debug info to console
-        debug = 0
-        
-        size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
-                           
-        verts, faces = create_I_beam(size, self.thick, self.taper, debug)
-        
-        if debug:
-            print("\nCreated Verts:", verts)
-            print("\nCreated Faces:", faces)
-                
-        create_mesh(self, context, "I Beam", verts, faces, debug)
-        
-        recalc_normals(debug) 
-        
-        return {'FINISHED'}
-
-
-'''
-    def invoke(self, context, event):
-        self.align_matrix = align_matrix(context)
-        self.execute(context)
-        return {'FINISHED'}    
-'''
-
-
-# Register all operators and define menus
-
-class INFO_MT_mesh_beambuilder_add(bpy.types.Menu):
-    # Define the "Beam Builder" menu
-    bl_idname = "INFO_MT_mesh_beambuilder_add"
-    bl_label = "Beam Builder"
-    
-    def draw(self, context):
-        layout = self.layout  
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        layout.operator("mesh.primitive_rectangle_add", text = "Rectangluar Beam")  
-        layout.operator("mesh.primitive_c_beam_add", text = "C or U Channel")
-        layout.operator("mesh.primitive_l_beam_add", text = "L Shaped Beam")
-        layout.operator("mesh.primitive_t_beam_add", text = "T Shaped Beam")
-        layout.operator("mesh.primitive_i_beam_add", text = "I Shaped Beam")
-        
-        
-    
-# Define menu    
-def menu_func(self, context):
-    self.layout.menu("INFO_MT_mesh_beambuilder_add", icon='PLUGIN')
-
-
-# Add     
-def register():
-    bpy.utils.register_module(__name__)
-    
-    # Add BeamBuilder menu to the 'Add Mesh' menu
-    bpy.types.INFO_MT_mesh_add.append(menu_func)
-
- 
-# Remove 
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    
-    # Remove BeamBuilder menu from 'Add Mesh' menu
-    bpy.types.INFO_MT_mesh_add.remove(menu_func)
-
- 
-if __name__ == "__main__":
-    register() 
-     
diff --git a/release/scripts/addons_contrib/add_mesh_chain_rope/__init__.py b/release/scripts/addons_contrib/add_mesh_chain_rope/__init__.py
deleted file mode 100644
index c4b5a29..0000000
--- a/release/scripts/addons_contrib/add_mesh_chain_rope/__init__.py
+++ /dev/null
@@ -1,37 +0,0 @@
-bl_info = {
-    "name": "Oscurart Chain and Rope Maker",
-    "author": "Oscurart",
-    "version": (1,1),
-    "blender": (2, 6, 2),
-    "api": 3800,
-    "location": "Add > Mesh",
-    "description": "Create chains and ropes",
-    "warning": "",
-    "wiki_url": "oscurart.blogspot.com",
-    "tracker_url": "",
-    "category": "Object"}
-
-
-import bpy
-from .oscurart_rope_maker import * 
-from .oscurart_chain_maker import *
-
-def register():
-    bpy.utils.register_class(OBJECT_OT_add_object)
-    bpy.types.INFO_MT_curve_add.append(oscRopeButton)
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_mesh_add.append(menu_oscChain)
-
-def unregister():
-    bpy.utils.unregister_class(OBJECT_OT_add_object)
-    bpy.types.INFO_MT_curve_add.remove(oscRopeButton)
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_mesh_add.remove(menu_oscChain)    
-
-if __name__ == "__main__":
-    register()
-
-
-
-
-
diff --git a/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_chain_maker.py b/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_chain_maker.py
deleted file mode 100644
index 893a565..0000000
--- a/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_chain_maker.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Oscurart Chain Maker",
-    "author": "Oscurart",
-    "version": (1,1),
-    "blender": (2, 5, 6),
-    "api": 3800,
-    "location": "Add > Mesh > Oscurart Chain",
-    "description": "Create chain links from armatures.",
-    "warning": "",
-    "wiki_url": "oscurart.blogspot.com",
-    "tracker_url": "",
-    "category": "Object"}
-
-
-
-
-
-import bpy
-
-
-def makeChain (context, mult, curverig): 
-    
-        # SI EL CONTEXTO ES OBJECT CORRE LA FUNCION
-        if bpy.context.mode == 'OBJECT':        
-            VAR_SWITCH=abs(1)
-            ARMATURE=bpy.context.active_object
-            
-            def creahuesocero(hueso):
-                ## CREO DATA PARA ESLABON
-                mesh=bpy.data.meshes.new("objectData"+str(hueso.name))
-                object=bpy.data.objects.new("EslabonCero"+str(hueso.name),mesh)
-                mesh.from_pydata(
-                [(-0.04986128956079483,-0.6918092370033264,-0.17846597731113434),(-0.04986128956079483,-0.6918091773986816,0.17846640944480896),(-0.049861326813697815,-0.154555082321167,0.17846627533435822),(-0.049861326813697815,-0.15455523133277893,-0.17846614122390747),(-0.04986133798956871,-0.03475356101989746,0.25805795192718506),(-0.04986133798956871,-0.03475397825241089,-0.25805795192718506),(-0.049861278384923935,-0.8116106986999512,-0.2580576539039612),(-0.049861278384923935,-0.8116104602813721,0.25805822014808655),(-0.04986128211021423,-0.7692053318023682,2.6668965347198537e-07),(-0.04986127093434334,-0.923523485660553,2.7834033744511544e-07),(-0.04986133426427841,-0.0771591067314148,3.5627678585115063e-08),(-0.04986134544014931,0.0771591067314148,-3.5627678585115063e-08),(0.04986133798956871,-0.03475397825241089,-0.25805795192718506),(0.04986133053898811,0.0771591067314148,-3.5627678585115063e-08),(0.04986133798956871,-0.03475356101989746,0.25805795192718506),(0.04986134544014931,-0.15455523133277893,-0.17846614122390747),(0.04986134544014931,-0.0771591067314148,3.5627678585115063e-08),(0.04986134544014931,-0.154555082321167,0.17846627533435822),(0.049861397594213486,-0.8116106986999512,-0.2580576539039612),(0.04986140504479408,-0.923523485660553,2.7834033744511544e-07),(0.049861397594213486,-0.8116104602813721,0.25805822014808655),(0.04986139014363289,-0.6918091773986816,0.17846640944480896),(0.04986139014363289,-0.7692053318023682,2.6668965347198537e-07),(0.04986139014363289,-0.6918092370033264,-0.17846597731113434)],
-            [(1,2),(0,3),(3,5),(2,4),(0,6),(5,6),(1,7),(4,7),(0,8),(1,8),(7,9),(6,9),(8,9),(2,10),(3,10),(4,11),(5,11),(10,11),(5,12),(12,13),(11,13),(13,14),(4,14),(10,16),(15,16),(3,15),(2,17),(16,17),(9,19),(18,19),(6,18),(7,20),(19,20),(8,22),(21,22),(1,21),(0,23),(22,23),(14,20),(12,18),(15,23),(17,21),(12,15),(13,16),(14,17),(20,21),(19,22),(18,23)],
-            [(6,0,3,5),(1,7,4,2),(0,6,9,8),(8,9,7,1),(2,4,11,10),(10,11,5,3),(11,13,12,5),(4,14,13,11),(3,15,16,10),(10,16,17,2),(6,18,19,9),(9,19,20,7),(1,21,22,8),(23,0,8,22),(7,20,14,4),(5,12,18,6),(0,23,15,3),(2,17,21,1),(16,15,12,13),(17,16,13,14),(22,21,20,19),(23,22,19,18),(21,17,14,20),(15,23,18,12)]
-                )
-                bpy.context.scene.objects.link(object)
-                ## ESCALO EL HUESO
-                bpy.data.objects['EslabonCero'+str(hueso.name)].scale= (hueso.length*mult,hueso.length*mult,hueso.length*mult)
-                
-                ## EMPARENTO
-                bpy.data.objects['EslabonCero'+str(hueso.name)].parent=ARMATURE
-                bpy.data.objects['EslabonCero'+str(hueso.name)].parent_type = 'BONE'
-                bpy.data.objects['EslabonCero'+str(hueso.name)].parent_bone=hueso.name   
-            
-            
-            def creahuesonoventa(hueso):
-                ## CREO DATA PARA ESLABON
-                mesh=bpy.data.meshes.new("objectData"+str(hueso.name))
-                object=bpy.data.objects.new("EslabonNov"+str(hueso.name),mesh)
-                mesh.from_pydata(
-                [(0.1784660965204239,-0.6918091773986816,-0.049861203879117966),(-0.1784662902355194,-0.6918091773986816,-0.04986126348376274),(-0.17846627533435822,-0.1545550525188446,-0.04986134544014931),(0.17846617102622986,-0.15455520153045654,-0.04986128583550453),(-0.25805795192718506,-0.03475359082221985,-0.049861375242471695),(0.25805795192718506,-0.034753888845443726,-0.04986129328608513),(0.2580578327178955,-0.8116105794906616,-0.04986117407679558),(-0.2580580413341522,-0.8116105198860168,-0.049861256033182144),(-9.672299938756623e-08,-0.7692052721977234,-0.04986122250556946),(-8.99775329799013e-08,-0.923523485660553,-0.04986120015382767),(-7.764004550381287e-09,-0.07715904712677002,-0.049861326813697815),(4.509517737005808e-08,0.0771591067314148,-0.049861349165439606),(0.25805795192718506,-0.034753888845443726,0.049861375242471695),(-2.2038317837314025e-08,0.0771591067314148,0.049861326813697815),(-0.25805795192718506,-0.03475359082221985,0.04986129328608513),(0.17846617102622986,-0.15455520153045654,0.04986138269305229),(-1.529285498236277e-08,-0.07715907692909241,0.049861352890729904),(-0.17846627533435822,-0.1545550525188446,0.049861323088407516),(0.2580578029155731,-0.8116105794906616,0.049861494451761246),(-1.5711103173998708e-07,-0.923523485660553,0.04986147582530975),(-0.2580580711364746,-0.8116105198860168,0.04986141249537468),(-0.1784663051366806,-0.6918091773986816,0.049861419945955276),(-1.340541757599567e-07,-0.7692052721977234,0.049861449748277664),(0.1784660816192627,-0.6918091773986816,0.04986146464943886)],
-                [(1,2),(0,3),(3,5),(2,4),(0,6),(5,6),(1,7),(4,7),(0,8),(1,8),(7,9),(6,9),(8,9),(2,10),(3,10),(4,11),(5,11),(10,11),(5,12),(12,13),(11,13),(13,14),(4,14),(10,16),(15,16),(3,15),(2,17),(16,17),(9,19),(18,19),(6,18),(7,20),(19,20),(8,22),(21,22),(1,21),(0,23),(22,23),(14,20),(12,18),(15,23),(17,21),(12,15),(13,16),(14,17),(20,21),(19,22),(18,23)],
-                [(6,0,3,5),(1,7,4,2),(0,6,9,8),(8,9,7,1),(2,4,11,10),(10,11,5,3),(11,13,12,5),(4,14,13,11),(3,15,16,10),(10,16,17,2),(6,18,19,9),(9,19,20,7),(1,21,22,8),(23,0,8,22),(7,20,14,4),(5,12,18,6),(0,23,15,3),(2,17,21,1),(16,15,12,13),(17,16,13,14),(22,21,20,19),(23,22,19,18),(21,17,14,20),(15,23,18,12)]
-                )
-                bpy.context.scene.objects.link(object)
-                
-                ## ESCALO EL HUESO
-                bpy.data.objects['EslabonNov'+str(hueso.name)].scale= (hueso.length*mult,hueso.length*mult,hueso.length*mult)
-            
-                ## EMPARENTO
-                bpy.data.objects['EslabonNov'+str(hueso.name)].parent=ARMATURE
-                bpy.data.objects['EslabonNov'+str(hueso.name)].parent_type = 'BONE'
-                bpy.data.objects['EslabonNov'+str(hueso.name)].parent_bone=hueso.name   
-            
-            
-            
-            for hueso in bpy.context.active_object.pose.bones:
-                if VAR_SWITCH == 1:
-                    creahuesocero(hueso)
-                else:
-                    creahuesonoventa(hueso)    
-                if VAR_SWITCH == 1:
-                    VAR_SWITCH = 0
-                    print(VAR_SWITCH)
-                else :
-                    VAR_SWITCH = 1
-                    print(VAR_SWITCH)
-                    
-                    
-        # SI NO TILDAMOS CURVERIG
-        if curverig == True:   
-                        
-                        
-            # VARIABLES
-            LISTA_POINTC=[]
-            ACTARM=bpy.context.active_object
-            
-            # CREO DATA , OBJETO Y LO CONECTO A LA ESCENA
-            crv= bpy.data.curves.new("CurvaCable", "CURVE")
-            obCable=bpy.data.objects.new("Cable",crv)
-            bpy.context.scene.objects.link(obCable)
-            
-            # SETEO ATRIBUTOS
-            crv.dimensions = "3D"
-            crv.resolution_u = 10
-            crv.resolution_v = 10
-            crv.twist_mode = "MINIMUM"
-            
-            
-            # CREO LISTA DE COORDENADAS DE TAIL Y HEAD
-            
-            LISTA_POINTC.append((
-                ACTARM.data.bones[0].head_local[0],
-                ACTARM.data.bones[0].head_local[1],
-                ACTARM.data.bones[0].head_local[2],
-                1
-            ))
-            
-            print("huesos: "+ str(len(ACTARM.data.bones)))
-            for hueso in ACTARM.data.bones:
-                LISTA_POINTC.append((hueso.tail_local[0],hueso.tail_local[1],hueso.tail_local[2],1))
-                
-            print(LISTA_POINTC)
-            
-            
-            # CREO EL SPLINE
-            spline=crv.splines.new("NURBS")
-            lencoord= len(LISTA_POINTC)
-            print("lencoord--> :"+str(lencoord))
-            rango=range(lencoord)
-            spline.points.add(lencoord-1)
-            for punto in rango:
-                spline.points[punto].co = LISTA_POINTC[punto]
-                print(LISTA_POINTC[punto])
-            
-            # SETEO ENDPOINT
-            bpy.data.objects['Cable'].data.splines[0].use_endpoint_u= True
-            
-            # SELECCIONO LA CURVA
-            bpy.ops.object.select_all(action='DESELECT')
-            bpy.data.objects['Cable'].select=1
-            bpy.context.scene.objects.active=bpy.data.objects['Cable']
-            
-            # PASO A EDIT
-            bpy.ops.object.mode_set(mode='EDIT')
-            
-            
-            # CREO HOOKS
-            POINTSTEP=0
-            for POINT in bpy.data.objects['Cable'].data.splines[0].points:
-                bpy.ops.curve.select_all(action="DESELECT")
-                bpy.data.objects['Cable'].data.splines[0].points[POINTSTEP].select=1
-                bpy.ops.object.hook_add_newob()
-                POINTSTEP+=1
-            
-            
-                print(POINT)
-            
-            # PASO A SELECCIONAR LOS OBJETOS
-            bpy.ops.object.mode_set(mode='OBJECT')
-            bpy.ops.object.select_all(action='DESELECT')
-            ACTARM.select=1
-            bpy.context.scene.objects.active=bpy.data.objects['Armature']
-            bpy.ops.object.mode_set(mode='POSE')
-            bpy.ops.pose.select_all(action='DESELECT')
-            ACTARM.data.bones[-1].select=1
-            ACTARM.data.bones.active=ACTARM.data.bones[-1]
-            # SETEO IK SPLINE
-            bpy.ops.pose.constraint_add_with_targets(type='SPLINE_IK')
-            ACTARM.pose.bones[-1].constraints['Spline IK'].target = bpy.data.objects['Cable']
-            ACTARM.pose.bones[-1].constraints['Spline IK'].chain_count=100
-            bpy.context.active_object.pose.bones[-1].constraints['Spline IK'].use_y_stretch= False     
-            # VUELVO A OBJECT MODE
-            bpy.ops.object.mode_set(mode='OBJECT')		
-                         
-            
-#---------------        
-from bpy.props import *
-
-class MESH_OT_chain_maker(bpy.types.Operator):
-    bl_idname="mesh.primitive_oscurart_chain_add"
-    bl_label="Oscurart Chain"
-    bl_options={'REGISTER','UNDO'}
-    
-    curverig= BoolProperty(name="Curve Rig", default=False)
-    multiplier= FloatProperty (name="Scale", default=1 , min=0.01, max=100.0)
-
-    @classmethod
-    def poll(cls, context):
-        return(bpy.context.active_object.type == "ARMATURE" and bpy.context.active_object.mode == "OBJECT") 
-    
-    def execute(self, context):
-        makeChain(context, 
-            self.multiplier,self.curverig)
-        return {'FINISHED'}
-    
-def menu_oscChain(self, context):
-    self.layout.operator("mesh.primitive_oscurart_chain_add", 
-        text="Oscurart Chain", 
-        icon='LINKED')
-
-def register():
-   bpy.utils.register_module(__name__)
-   bpy.types.INFO_MT_mesh_add.append(menu_oscChain)
- 
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_mesh_add.remove(menu_oscChain)
-    
- 
-if __name__ == "__main__":
-    register()    
diff --git a/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_rope_maker.py b/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_rope_maker.py
deleted file mode 100644
index 5faad59..0000000
--- a/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_rope_maker.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Oscurart Rope Maker",
-    "author": "Oscurart",
-    "version": (1,1),
-    "blender": (2, 5, 6),
-    "api": 3800,
-    "location": "Add > Curve > Oscurart Rope",
-    "description": "Create ropes",
-    "warning": "",
-    "wiki_url": "oscurart.blogspot.com",
-    "tracker_url": "",
-    "category": "Object"}
-
-
-
-import bpy, math
-
-
-
-
-
-def makeRope (context, DISTPOS, curvaResU, radius, FE, CUERDAS, stResU,DIAMETRO):    
-    
-    # CREO DATA , OBJETO Y LO CONECTO A LA ESCENA
-    crv= bpy.data.curves.new("CurvaCable", "CURVE")
-    obCable=bpy.data.objects.new("Cable",crv)
-    bpy.context.scene.objects.link(obCable)
-    
-    # SETEO ATRIBUTOS
-    crv.dimensions = "3D"
-    crv.resolution_u = 10
-    crv.resolution_v = 10
-    crv.twist_mode = "MINIMUM"
-    
-    # LISTA DE COMPONENTES
-    coordenadas= [
-        (0,radius,0,radius),
-        (radius,0,0,radius),
-        (0,-radius,0,radius),
-        (-radius,0,0,radius)
-    ]
-    
-    
-    
-    # CREO EL SPLINE
-    spline=crv.splines.new("NURBS")
-    lencoord= len(coordenadas)
-    #print("lencoord--> :"+str(lencoord))
-    rango=range(lencoord)
-    spline.points.add(lencoord-1)
-    for punto in rango:
-        spline.points[punto].co = coordenadas[punto]
-        #print(punto)
-        
-        
-    # MODIFICACIONES DE DATA
-    spline.use_cyclic_u = True
-    spline.resolution_u = curvaResU
-    spline.order_u = 3    
-    spline.use_endpoint_u = True
-    
-    
-    ## ==CREO CADENAS==
-    
-    ## DIVIDO EL RADIO POR LA CANTIDAD DE LINEAS Y SETEO UNA LISTA
-    
-    GRADOS=[]
-    VALORPORPARTE=[]
-    DIVISION=360/CUERDAS
-    TAJADA=0
-    
-    for parte in range(0,CUERDAS):
-        GRADOS.append(TAJADA)
-        TAJADA+=DIVISION
-        
-
-    
-    for GRAD in GRADOS:
-
-
-        # VARIABLES
-        FC=0
-        VARLISTVER=[]
-       
-        VARANGLEY=0
-        VARANGLEZ=90
-        VARPOSX=0
-        EDGEINDEX=0
-        # DEFINO EL PESO PARA LAS COORDENADAS
-        WEIGHT = 1
-        
-        while FC < FE:           
-            ## CREA 3 CADENAS EN 0 90 Y 180 GRADOS 
-            VARLISTVER.append((VARPOSX, math.sin(math.radians(GRAD))/(1/DIAMETRO) , math.sin(math.radians(GRAD+90))/(1/DIAMETRO),WEIGHT))
-    
-            GRAD += 30
-            FC += 1
-            VARPOSX += DISTPOS
-     
-        
-        
-        # CREO DATA , OBJETO Y LO CONECTO A LA ESCENA
-        crv= bpy.data.curves.new("curvaData", "CURVE")
-        ob=bpy.data.objects.new("Curva",crv)
-        bpy.context.scene.objects.link(ob)
-        
-        # SETEO ATRIBUTOS
-        crv.dimensions = "3D"
-        crv.resolution_u = 10
-        crv.resolution_v = 10
-        crv.twist_mode = "MINIMUM"
-        
-        # LISTA DE COMPONENTES
-        coordenadas= VARLISTVER
-        
-        
-        
-        # CREO EL SPLINE
-        spline=crv.splines.new("NURBS")
-        lencoord= len(coordenadas)
-        #print("lencoord--> :"+str(lencoord))
-        rango=range(lencoord)
-        spline.points.add(lencoord-1)
-        for punto in rango:
-            spline.points[punto].co = coordenadas[punto]
-            #print(punto)
-            
-            
-        # MODIFICACIONES DE DATA
-        spline.use_cyclic_u = False
-        spline.resolution_u = stResU
-        spline.order_u = 3    
-        spline.use_endpoint_u = True
-        
-        ob.data.bevel_object= bpy.data.objects["Cable"]
-        
-        #print(VARLISTVER)
-        
-#---------------        
-from bpy.props import *
-
-class OBJECT_OT_add_object(bpy.types.Operator):
-    bl_idname="curve.primitive_osc_rope_add"
-    bl_label="Oscurart Rope"
-    bl_options={'REGISTER','UNDO'}
-    
-    strands = IntProperty (name="Strands", default=5 , min=1, max=1000, step=1)
-    diameter = FloatProperty (name="Diameter", default=1 , min=0, max=1000)
-    distPos= FloatProperty (name="Stretch", default=1 , min=0.01, max=100.0)
-    vertices= IntProperty (name="Lenght", default=10 , min=0, max=1000, step=1)
-    distResU= IntProperty (name="Resolution V", default=5 , min=1, max=1000, step=1)
-    stResU= IntProperty (name="Resolution U", default=5 , min=1, max=1000, step=1)
-    radio= FloatProperty (name="Radius", default=1 , min=0, max=1000)
-
-    def execute(self, context):
-        makeRope(context, 
-            self.distPos,self.distResU,self.radio,self.vertices,self.strands, self.stResU,self.diameter)
-        return {'FINISHED'}
-    
-# Registration
-
-def oscRopeButton(self, context):
-    self.layout.operator(
-        OBJECT_OT_add_object.bl_idname,
-        text="Oscurart Rope",
-        icon="PLUGIN")
-
-
-def register():
-    bpy.utils.register_class(OBJECT_OT_add_object)
-    bpy.types.INFO_MT_curve_add.append(oscRopeButton)
-
-
-def unregister():
-    bpy.utils.unregister_class(OBJECT_OT_add_object)
-    bpy.types.INFO_MT_curve_add.remove(oscRopeButton)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/add_mesh_column.py b/release/scripts/addons_contrib/add_mesh_column.py
deleted file mode 100644
index c6dd00c..0000000
--- a/release/scripts/addons_contrib/add_mesh_column.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you may 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.
-#	51 Franklin Street, Fifth Floor
-#	Boston, MA 02110-1301, USA
-#
-# or go online at: http://www.gnu.org/licenses/ to view license options.
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-
-bl_info = {
-    "name": "Columns",
-    "author": "Jim Bates, jambay",
-    "version": (0, 11),
-    "blender": (2, 5, 7),
-    "location": "View3D > Add > Mesh > Columns",
-    "description": "Add architectural column(s).",
-    "warning": "WIP - Initial implementation; updates pending and API not final for Blender",
-    "wiki_url": "http://www.uthynq.com/JBDoc/index.php?title=Column",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=27655",
-    "category": "Add Mesh"
-}
-
-
-'''
-
-Create a column for use as an architectural element in a scene. Basically a glorified cylinder/cube.
-
-A column consists of three elements; base, shaft, and capital. They can be square or round, straight or tapered.
- The base and capital are optional.
-
-The shaft may be fluted and twisted.
-
-Only one column is created, at the current 3D cursor, expecting the user to duplicate and place as needed.
-
-This script is based on features from add_mesh_gears, add_curve_aceous_galore.py, and add_mesh_BoltFactory/createMesh.py.
-
-'''
-
-#
-# List of "enhancements"/"fixes" needed to finalize this script.
-#
-# @todo: Round top and bottom of flutes.
-# @todo: Add "plinth" (square platform) to base and "finale" for capital - different proportions for base and capital but same objective.
-# @todo: Create Ionic and Corinthian style capitals. External "mesh", quadrant, mirror-x, select all/join, then mirror-y.
-#    will need to "scale" to match column radius (size to column).
-# @todo: Allow control of negative radius for base and column functions.
-#    Interesting effect (inverts), but want to use separate from column setting.
-#
-
-
-# Version History
-# v0.11 2011/06/14	Added width parameter for base and capital.
-# v0.10 2011/06/13	Consolidated base and capital "add" functions. More styles. Fixed taper with negative radius.
-# v0.09 2011/06/06	Column fluting - 90%. Added "sides" parameter for flutes, not sure I want to fix "odd" behavior.
-# v0.08 2011/05/24	Common function to generate base and capitals, more types added.
-# v0.07 2011/05/21	Added Capitals, more base types, general cleanup.
-# v0.06 2011/05/20	Changed radius usage, separated base from column and use spin to generate base.
-# v0.05 2011/05/19	Added closing faces (top and bottom) to base and column.
-# v0.04 2011/05/17	Major "cleanup"; Flutes now not square, but not rounded either.
-# v0.03 2011/05/16	Made "flutes" a value; added taper and base options to UI; added wiki and tracker links.
-# v0.02 2011/05/14	UI mods and param checks added.
-# v0.01 2011/05/13	Initial implementation.
-
-
-import bpy
-import mathutils
-from math import *
-from bpy.props import *
-
-# A very simple "bridge" tool.
-# Connects two equally long vertex rows with faces.
-# Returns a list of the new faces (list of  lists)
-#
-# vertIdx1 ... First vertex list (list of vertex indices).
-# vertIdx2 ... Second vertex list (list of vertex indices).
-# closed ... Creates a loop (first & last are closed).
-# flipped ... Invert the normal of the face(s).
-#
-# Note: You can set vertIdx1 to a single vertex index to create
-#       a fan/star of faces.
-# Note: If both vertex idx list are the same length they have
-#       to have at least 2 vertices.
-def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
-    faces = []
-
-    if not vertIdx1 or not vertIdx2:
-        return None
-
-    if len(vertIdx1) < 2 and len(vertIdx2) < 2:
-        return None
-
-    fan = False
-    if (len(vertIdx1) != len(vertIdx2)):
-        if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
-            fan = True
-        else:
-            return None
-
-    total = len(vertIdx2)
-
-    if closed:
-        # Bridge the start with the end.
-        if flipped:
-            face = [
-                vertIdx1[0],
-                vertIdx2[0],
-                vertIdx2[total - 1]]
-            if not fan:
-                face.append(vertIdx1[total - 1])
-            faces.append(face)
-
-        else:
-            face = [vertIdx2[0], vertIdx1[0]]
-            if not fan:
-                face.append(vertIdx1[total - 1])
-            face.append(vertIdx2[total - 1])
-            faces.append(face)
-
-    # Bridge the rest of the faces.
-    for num in range(total - 1):
-        if flipped:
-            if fan:
-                face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
-            else:
-                face = [vertIdx2[num], vertIdx1[num],
-                    vertIdx1[num + 1], vertIdx2[num + 1]]
-            faces.append(face)
-        else:
-            if fan:
-                face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
-            else:
-                face = [vertIdx1[num], vertIdx2[num],
-                    vertIdx2[num + 1], vertIdx1[num + 1]]
-            faces.append(face)
-
-    return faces
-
-
-#####
-#
-# @todo: fine-tune curvature for flutes.
-# @todo: handle odd number of sides (flat in middle).
-#
-def add_col_flute(angle, target, zpos, radius, Ad, sides=6):
-    '''
- Create "flute" for column at passed location.
-
-    Parameters:
-        angle - starting point for column faces.
-            (type=float)
-        target - angle offset to end point for column faces.
-            (type=float)
-        zpos - vertical position for vertices.
-            (type=float)
-        radius - column face radius from current 3D cursor position.
-            (type=float)
-        Ad - Flute "depth" offset from radius
-            (type=float)
-        sides - number of faces for flute
-            (type=int)
-
-    Returns:
-        newpoints - a list of coordinates for flute points (list of tuples), [[x,y,z],[x,y,z],...n]
-            (type=list)
-    '''
-    newpoints = []
-
-    if sides < 2: sides = 2 # min number of sides.
-
-    halfSides = sides/2 # common value efficiency variable.
-
-    stepD = Ad/halfSides # in and out depth variation per side.
-
-    divSides = 0
-    curStep = 1
-
-    while curStep <= halfSides:
-        divSides += curStep*curStep
-        curStep+=1
-
-    stepCurve = target/(divSides*2) # logorithmic delta along radius for sides.
-
-    curStep = 0
-
-    t = angle
-
-    # curvature in
-    while curStep < halfSides:
-        t = t + (curStep*curStep*stepCurve)
-        x1 = (radius - (stepD * (curStep+1))) * cos(t)
-        y1 = (radius - (stepD * (curStep+1))) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        curStep+=1
-
-    # curvature out - includes mid-point, and end-point...
-    while curStep:
-        t = t + (curStep*curStep*stepCurve)
-        x1 = (radius - (stepD * curStep)) * cos(t)
-        y1 = (radius - (stepD * curStep)) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        curStep-=1
-
-    return newpoints
-
-
-# save a copy of add_col_flute, v 0.8, in case it gets "fixed"...
-# makes flower petal/notch effect...
-def add_notch(angle, target, zpos, radius, Ad, sides=6):
-
-    newpoints = []
-
-    if sides < 2: sides = 2 # min number of sides.
-
-    stepD = Ad/(sides/2) # in and out depth variation per side.
-    stepCurve = target/sides # points along radius for sides.
-
-    curStep = 0
-
-    # curvature in
-    while curStep < sides/2:
-        t = angle + (curStep*stepCurve)
-        x1 = (radius - (stepD * curStep)) * cos(t)
-        y1 = (radius - (stepD * curStep)) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        curStep+=1
-
-    # curvature out
-    while curStep:
-        t = angle + ((sides-curStep)*stepCurve)
-        x1 = (radius - (stepD * curStep)) * cos(t)
-        y1 = (radius - (stepD * curStep)) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        curStep-=1
-
-    # add the end point
-    x1 = radius * cos(angle+target)
-    y1 = radius * sin(angle+target)
-    newpoints.append([x1, y1, zpos])
-
-    return newpoints
-
-
-# save a copy of add_col_flute, v 0.4, in case it gets "fixed"...
-# this makes some interesting "fans" when addendum is more than radius
-def add_sawtooth(angle, target, zpos, radius, Ad, sides=6):
-    newpoints = []
-
-    step = target/sides
-    stepD = Ad/sides
-
-    i = 0
-    while i < sides:
-        t = angle + (i*step)
-        x1 = (radius - (stepD*i)) * cos(t)
-        y1 = (radius - (stepD*i)) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        i+=1
-
-    return newpoints
-
-
-# save a copy of add_col_flute, v 0.5, in case it gets "fixed"...
-# this makes some interesting "fans" when addendum is more than radius
-def add_sawtooth2(angle, target, zpos, radius, Ad, sides=6):
-    newpoints = []
-
-    step = target/sides
-    stepD = Ad/(sides/2)
-
-    # First point
-    x1 = radius * cos(angle)
-    y1 = radius * sin(angle)
-    newpoints.append([x1, y1, zpos])
-
-    # curve in...
-    i = 0
-    while i < sides/2:
-        t = angle + (i*step)
-        x1 = (radius - (stepD * i)) * cos(t)
-        y1 = (radius - (stepD * i)) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        i+=1
-
-    # curve out...
-    while i:
-        t = angle + ((sides - i)*step)
-        x1 = (radius - (stepD * i)) * cos(t)
-        y1 = (radius - (stepD * i)) * sin(t)
-# Interesting... not "regular" if this is only change.
-#        y1 = (radius + (stepD * (sides - i))) * sin(t)
-        newpoints.append([x1, y1, zpos])
-        i-=1
-
-# Also cool -
-    # curve out... jagged.
-#    while i:
-#        t = angle + ((sides - i)*step)
-#        x1 = (radius + (stepD * i)) * cos(t)
-#        y1 = (radius + (stepD * i)) * sin(t)
-#        newpoints.append([x1, y1, zpos])
-#        i-=1
-
-    # end point
-    x1 = radius * cos(angle+step*(sides-1))
-    y1 = radius * sin(angle+step*(sides-1))
-    newpoints.append([x1, y1, zpos])
-
-    return newpoints
-
-
-#####
-def add_col_face(angle, target, zpos, radius):
-    '''
-Calculate the vertex coordinates for column face.
-
-    Parameters:
-        angle - starting point for column faces.
-            (type=float)
-        target - end point for column faces.
-            (type=float)
-        zpos - vertical position for vertices.
-            (type=float)
-        radius - column face radius from current 3D cursor position.
-            (type=float)
-
-    Returns:
-        a list of coordinates for column face points (list of four tuples), [[x,y,z],[x,y,z],...4]
-            (type=list)
-    '''
-    targStep = target/4
-
-    verts_outer_face = [(radius * cos(angle+(targStep*I)), radius * sin(angle+(targStep*I)), zpos)
-        for I in range(4)]
-
-    return (verts_outer_face)
-
-
-#####
-#
-# Returns a list of faces that makes up a fill pattern for a circle.
-# copied from add_mesh_BoltFactory/createMesh.py - works like fill.
-#
-# @todo: replace this with call to mesh.fill() - must have mesh, and select vertices.
-#
-def Fill_Ring_Face(OFFSET, NUM, FACE_DOWN = 0):
-    Ret =[]
-    Face = [1,2,0]
-    TempFace = [0,0,0]
-    A = 0
-    B = 1
-    C = 2
-    if NUM < 3:
-        return None
-    for i in range(NUM-2):
-        if (i%2):
-            TempFace[0] = Face[C];
-            TempFace[1] = Face[C] + 1;
-            TempFace[2] = Face[B];
-            if FACE_DOWN:
-                Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]])
-            else:
-                Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]])
-        else:
-            TempFace[0] =Face[C];
-            if Face[C] == 0:
-                TempFace[1] = NUM-1; 
-            else:
-                TempFace[1] = Face[C] - 1;
-            TempFace[2] = Face[B];
-            if FACE_DOWN:
-                Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]])
-            else:
-                Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]])
-        
-        Face[0] = TempFace[0]
-        Face[1] = TempFace[1]
-        Face[2] = TempFace[2]
-    return Ret
-
-
-#####
-#
-# Common/shared function to create base or capital.
-#
-#    May need to separate in future but handy for now for "simple" styles. Simply use "menu select" to set type for
-#    base or capital if they shouldn't be same.
-#
-def add_extent(radius, height, width, zPos, type=1):
-    '''
-Create geometry for base/capital (shared function).
-
-    Params:
-	radius    area of the column (inner vertice for base/capital).
-	height    height of base/capital.
-	width     width (radius) of base/capital.
-        zPos      vertical origin (base height+column height for capital, zero for base).
-        type      type of base/capital to generate.
-
-    Returns:
-	list of vertices and edges
-
-    '''
-    verts = []
-    edges = []
-
-    if type == 2: # Angled
-        verts, edges = makeProfile(radius, zPos, 0, height, width, 2, 1, 1, False, False)
-        return verts, edges
-
-    if type == 3: #  straight half-Beveled half
-        verts, edges = makeProfile(radius, zPos, 0, height, width, 1, 1, 1, False, False)
-        return verts, edges
-
-    if type == 4: # Rounded
-        verts, edges = makeProfile(radius, zPos, 0, height, width, 6, 1.2, 0.05, True, False)
-        return verts, edges
-
-    if type == 5: # Curved
-        verts, edges = makeProfile(radius, zPos, 0, height, width, 6, 1.2, 0.05)
-        return verts, edges
-
-    if type == 6: # Bird-bath overshot
-        verts, edges = makeProfile(radius, zPos, 0, height, width, 6, 1.0, 0.15, False)
-        return verts, edges
-
-    if type == 7: # Complex type....
-        verts1, edges1 = makeProfile(radius, zPos, radius, height/2, width/2, 6, 1.2, 0.05)
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, zPos+height/2, 0, height/2, width/2, 0, 0, 0, False, False, len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        return verts, edges
-
-    if type == 8: # Complex type.... 2
-        verts1, edges1 = makeProfile(radius, zPos, radius, height/4, width/4, 6, 1.2, 0.05)
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, zPos+height/4, radius, height/4, width/4, 0, 0, 0, False, False, len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, zPos+height/2, 0, height/2, width/2, 2, 1, 1, False, False, len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        return verts, edges
-
-    if type == 9: # Complex type.... 3
-# @todo: figure out "inner" connectors without using makeProfile...
-        workZ = zPos # track "base" for each segment.
-
-        verts1, edges1 = makeProfile(radius, workZ, radius, height/8, width/4, 0, 0, 0, False, False)
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += height/8
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, workZ, radius, height/4, width/4, 6, 1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += height/4
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, radius-width/4, height/8, width/4, 0, 0, 0, False, False, len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += height/8
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, radius-width/4, height/8, width/4, 6, 1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-# should be height/8 but usiing height/4 to fill out height. Makes inner "straight edge" connector without makeProfile.
-        workZ += height/4
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, 0, height/4, width/2, 2, 1, 1, False, False, len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        return verts, edges
-
-    if type == 10: # Complex type.... Doric, Sans square topping.
-        workZ = zPos # track "base" for each segment.
-
-        verts1, edges1 = makeProfile(radius, workZ, radius, height/8, width/8, 0, 0, 0, False, False)
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += height/8
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, workZ, radius, height/8, width/4, 6, 1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-# should be height/8 but usiing height/4 to fill out height. Makes inner "straight edge" connector without makeProfile.
-        workZ += height/4
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, radius-width/4, height/8, width/2, 0, 0, 0, False, False, len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += height/4
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, radius-width/4, height/8, width/4, 6, 1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-# using different height accumulation value (more or less) makes inner "edge connector" without makeProfile.
-# should be height/8 but usiing height/4 to fill out height. Makes inner "straight edge" connector without makeProfile.
-        workZ += height/8
-
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, workZ, 0, height/4, width, 6, 1.3, 0.05, True, False, len(edges))
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        return verts, edges
-
-    if type == 11: # Complex type.... Doric, attempt square topping 2.
-        workZ = zPos # track "base" for each segment.
-
-        # square step - 1/8th.
-        workHeight = height/8
-        verts1, edges1 = makeProfile(radius, workZ, radius, workHeight, width/10, 0, 0, 0, False, False)
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += workHeight # accumulate offset...
-
-        # Rounded step - 1/8th; offset from radius reduction...
-#        workHeight = height/8
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, radius-width/4, workHeight, width/2, 6, 1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-# using different height accumulation value (more or less) makes inner "edge connector" without makeProfile.
-#        workZ += height/8
-        workZ += workHeight # accumulate offset...
-
-        # inverted round - half-height
-        workHeight = height/2
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, workZ, radius, workHeight, width/8, 6, -1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += workHeight # accumulate offset...
-# using different height accumulation value (more or less) makes inner "edge connector" without makeProfile.
-#        workZ += height/4 # Added to workZ after previous line - "normal accumulation"; caused "criss-cross" connection...
-# and overstepped height - which is fine, except for criss-cross thing.
-
-        # Rounded step - 1/8th; offset from radius reduction...
-        workHeight = height/8
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius-width/4, workZ, radius-width/4, workHeight, width, 6, 1.2, 0.05, startRow=len(edges) )
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        workZ += workHeight # accumulate offset...
-
-        # Curved step - 1/8th.
-#        workHeight = height/8
-        edges.append([len(edges), len(edges)+1]) # add connector edge...
-        verts1, edges1 = makeProfile(radius, workZ, 0, workHeight, width, 6, 1.3, 0.05, True, False, len(edges))
-        verts.extend(verts1)
-        edges.extend(edges1)
-
-        return verts, edges
-
-# default, type 1 - straight side, full height.
-    verts, edges = makeProfile(radius, zPos, 0, height, width, 0, 0, 0)
-    return verts, edges
-
-
-#####
-#
-# x is always zero. This is just a series of vertexes... on a plane (zero X) for spin dupli-replication.
-#
-# Expect that results are pairs, 0,1 (edgeSets) - two minimum (0,1).
-#
-# @todo: Fix for starts, or factors not valid; return default (square) values on error.
-#
-def makeProfile(startY, startZ, endY, height, width, facets, factor1, factor2, doubler=True, twoPart=True, startRow=0):
-    '''
-Create list of vertexes and edges that outline defined shape (as per parameters).
-
-    Params:
-	startY    Radius origin for vertexes.
-	startZ    Vertical origin.
-        endY      Radius end-point for vertexes.
-        height    Vertical offset from startZ for shape.
-        width     Horizontal dimension of shape.
-        facets    Number of edges (rows), use 0 for straight.
-        factor1   Horizontal multiplier.
-        factor2   Vertical multiplier, used with doubler.
-        doubler   Square factor2 for each facet if true.
-        twoPart   Repeat inverse of shape if true.
-        startRow  Edge list offset for concatenated shapes.
-
-    Returns:
-	list of vertices and edges
-
-    '''
-
-    # start here...
-    shapeVerts = []
-    shapeEdges = [] # invalid at this point.
-
-    halfHeight = height/2 # common calculated value, effeciency.
-    halfWidth = width/2 # common calculated value, effeciency.
-
-    capRadius = startY+halfWidth # "working radius" for base/capital.
-
-    if not facets:
-        rowVariance = 0
-        twoPart = False # override default for square.
-    else:
-        rowVariance = halfWidth/facets # width / 2 / number of angles to curve edge
-
-    workFactor = 0
-
-    shapeVerts.append([0, startY, startZ]) # starting point
-    numRows = startRow
-
-    for Ivec in range(facets): # skipped if no facets
-
-        if not doubler:
-            workFactor = Ivec * factor2
-
-        shapeVerts.append([0, capRadius+rowVariance*(Ivec*factor1), startZ+halfHeight*workFactor])
-        shapeEdges.append([numRows, numRows+1])
-        numRows += 1
-
-        if doubler:
-            if Ivec:
-                workFactor *= 2
-            else:
-                workFactor = factor2
-
-    # middle row... outer edge; bottom if no facets.
-
-    if not facets: # square?
-        workY = capRadius+halfWidth
-        workZ = startZ
-    else: # shaped
-        workY = capRadius+rowVariance*((facets-1)*factor1)
-        workZ = startZ+halfHeight
-
-    shapeVerts.append([0, workY, workZ])
-
-    shapeEdges.append([numRows, numRows+1])
-    numRows += 1
-
-    # do the middle up part...
-
-    if twoPart:
-        for Rvec in range(1,facets): # inverse...
-
-            if not doubler:
-                workFactor = Rvec * factor2
-            else:
-                workFactor /= 2
-
-            shapeVerts.append([0, capRadius+rowVariance*((facets-Rvec)*factor1), startZ+height-halfHeight*workFactor])
-            shapeEdges.append([numRows, numRows+1]) 
-            numRows += 1
-
-    # end here...
-
-    workZ = startZ+height
-
-    if twoPart: # match top to bottom for rounded styles
-        shapeVerts.append([0, capRadius, workZ])
-    else:
-        shapeVerts.append([0, startY+width, workZ])
-
-    shapeEdges.append([numRows, numRows+1]) # outer edge top
-    numRows += 1
-
-    shapeVerts.append([0, endY, workZ])
-    shapeEdges.append([numRows, numRows+1]) # last edge....
-
-#    print(shapeVerts)
-
-    return shapeVerts, shapeEdges
-
-
-#####
-#
-# @todo: fix closing faces on top/bottom for flutes.
-#
-def add_column(colBase, radius, taper, c_faces, rows, height, flutes, Ad, fsides, skew, colCap=False):
-    '''
-Create column geometry.
-
-    Params:
-	colBase   starting zPos for column (put on top of base).
-	radius    area of the column, negative for flute extrusions.
-	taper     radius reduction per row to taper column.
-	c_faces   surfaces (faces) on column per quadrant, 1 = square, increase to smooth, max 360, 180 is plenty.
-	rows      number of rows/vertical blocks for column. Use +1 to complete row (2 is working min).
-	flutes    make curfs, gouges, gear like indents.
-	Ad        Addendum, extent of flute from radius.
-        fsides    number of "sides" (faces) for flute.
-	height    height of column row.
-	skew      twist for column, use negative value for left twist.
-        colCap    true if adding cap to eliminate top fill.
-
-    Returns:
-	list of vertices
-	list of faces
-
-    '''
-    if flutes: # set working faces and modulo/flag for doing flutes...
-        c_faces -= c_faces % flutes
-        fluteFaces = c_faces / flutes
-    else:
-        fluteFaces = 0
-
-    isFluted = False
-
-    t = 2 * pi / c_faces # c_faces == 1 makes a square
-
-    verts = []
-    faces = []
-
-    edgeloop_prev = []
-    for Row in range(rows):
-        edgeloop = []
-
-        if Row: # apply taper to rows after base verts added.
-            if radius > 0: 
-                radius -= taper # decrease radius
-            else:
-                radius += taper # will decrease neg radius
-
-        for faceCnt in range(c_faces):
-            a = faceCnt * t
-
-            rSkew = Row * skew
-            zPos = colBase + Row * height
-
-            if fluteFaces and not faceCnt % fluteFaces: # making "flutes", and due a flute?
-                isFluted = True
-                verts1 = add_col_flute(a + rSkew, t, zPos, radius, Ad, fsides)
-
-            else: # column surface for section...
-                isFluted = False
-                verts1 = add_col_face(a + rSkew, t, zPos, radius)
-
-            verts_current = list(range(len(verts), len(verts) + len(verts1)))
-            verts.extend(verts1)
-
-            edgeloop.extend(verts_current)
-
-        # Create faces between rings/rows.
-        if edgeloop_prev:
-            faces.extend(createFaces(edgeloop, edgeloop_prev, closed=True))
-        else: # close column bottom if unfluted and no base.
-            if not fluteFaces and not colBase:
-                faces.extend(Fill_Ring_Face(0, c_faces*4))
-
-        # Remember last ring/row of vertices for next ring/row iteration.
-        edgeloop_prev = edgeloop
-
-    # close column top
-    if not fluteFaces and not colCap:
-        faces.extend(Fill_Ring_Face(len(edgeloop)*(rows-1), c_faces*4))
-
-    return verts, faces
-
-
-#####
-#
-class AddColumn(bpy.types.Operator):
-    '''
-Add a column mesh.
-
-    UI functions and object creation.
-
-    '''
-    bl_idname = "mesh.primitive_column"
-    bl_label = "Add Column"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    radius = FloatProperty(name="Radius",
-        description="Radius of the column; use negative to extrude flutes.",
-        min=-100.0,
-        max=100.0,
-        default=1.0)
-    taper = FloatProperty(name="Taper",
-        description="Radius reduction for taper - cannot exceed radius.",
-        min=0.00,
-        max=10.0,
-        default=0.0)
-    col_faces = IntProperty(name="Faces",
-        description="Number of faces per quadrant, 1 = square.",
-        min=1,
-        max=360,
-        default=10)
-    col_blocks = IntProperty(name="Rows",
-        description="Number of blocks in the column",
-        min=1,
-        max=100,
-        default=1)
-    row_height = FloatProperty(name="Row Height",
-        description="Height of each block row",
-        min=0.05,
-        max=100.0,
-        default=2)
-    skew = FloatProperty(name="Skew",
-        description="Twist the column (degrees) - neg for left twist.",
-        min=-180,
-        max=180,
-        default=0.00)
-
-    col_flutes = IntProperty(name="Flutes",
-        description="Channels on column",
-        min=0,
-        max=100,
-        default=0)
-    addendum = FloatProperty(name="Addendum",
-        description="flute (depth) offset from radius.",
-        min=0.01,
-        max=100.0,
-        default=0.1)
-    flute_sides = IntProperty(name="Sides",
-        description="facets for flute",
-        min=2,
-        max=100,
-        default=12)
-
-    col_base = BoolProperty(name="Base",
-         description="Column base",
-         default = False)
-    base_type = IntProperty(name="Type",
-        description="Type of base to generate, until menu selection added.",
-        min=1,
-        max=20,
-        default=1)
-    base_faces = IntProperty(name="Faces",
-        description="Number of faces per quadrant, 1 = square.",
-        min=1,
-        max=360,
-        default=1)
-    base_height = FloatProperty(name="Height",
-        description="Height of base",
-        min=0.05,
-        max=10.0,
-        default=0.5)
-    base_width = FloatProperty(name="Width",
-        description="Width of base (radius)",
-        min=0.05,
-        max=10.0,
-        default=0.5)
-
-    col_cap = BoolProperty(name="Capital",
-         description="Column capital",
-         default = False)
-    cap_type = IntProperty(name="Type",
-        description="Type of capital to generate, until menu selection added.",
-        min=1,
-        max=20,
-        default=1)
-    cap_faces = IntProperty(name="Faces",
-        description="Number of faces per quadrant, 1 = square.",
-        min=1,
-        max=360,
-        default=1)
-    cap_height = FloatProperty(name="Height",
-        description="Height of capital",
-        min=0.05,
-        max=10.0,
-        default=0.5)
-    cap_width = FloatProperty(name="Width",
-        description="Width of capital (radius)",
-        min=0.05,
-        max=10.0,
-        default=0.5)
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        box.label(text='Column Sizing')
-        box.prop(self, 'radius')
-        box.prop(self, 'taper')
-        box.prop(self, 'col_faces')
-        box.prop(self, 'col_blocks')
-        box.prop(self, 'row_height')
-        box.prop(self, 'skew')
-
-        box = layout.box()
-        box.prop(self, 'col_flutes')
-        if self.properties.col_flutes:
-            box.prop(self, 'addendum')
-            box.prop(self, 'flute_sides')
-
-        box = layout.box()
-        box.prop(self, 'col_base')
-        if self.properties.col_base:
-            box.prop(self, 'base_type')
-            box.prop(self, 'base_faces')
-            box.prop(self, 'base_height')
-            box.prop(self, 'base_width')
-
-        box = layout.box()
-        box.prop(self, 'col_cap')
-        if self.properties.col_cap:
-            box.prop(self, 'cap_type')
-            box.prop(self, 'cap_faces')
-            box.prop(self, 'cap_height')
-            box.prop(self, 'cap_width')
-
-    def execute(self, context):
-
-        # Taper can't exceed radius
-        if self.properties.radius < 0:
-            checkRadius = -self.properties.radius
-        else:
-            checkRadius = self.properties.radius
-
-        if self.properties.taper > checkRadius:
-            self.properties.taper = checkRadius # Reset UI if input out of bounds...
-
-        # Flutes can't exceed faces
-        if self.properties.col_flutes > self.properties.col_faces:
-            self.properties.col_flutes = self.properties.col_faces # Reset UI if input out of bounds...
-
-        baseH = 0.00
-        vertsBase = []
-        edgesBase = []
-
-        if self.col_base: # makig a base?
-            baseH = self.base_height
-
-            vertsBase, edgesBase = add_extent(
-                self.radius,
-                baseH,
-                self.base_width,
-                0,
-                self.base_type
-                )
-
-        vertsCap = []
-        edgesCap = []
-
-        if self.col_cap: # making a capital?
-            vertsCap, edgesCap = add_extent(
-                self.radius - self.properties.taper, # fit to top of column
-                self.cap_height,
-                self.cap_width,
-                baseH + (self.row_height * self.col_blocks),
-                self.cap_type
-                )
-
-        verts, faces = add_column(
-            baseH,
-            self.radius, # use neg to get extrusions.
-            self.taper/self.col_blocks, # taper column per number of rows.
-            self.col_faces, # "faces" on column, per quadrant, 1 = square.
-            self.col_blocks + 1, # need extra to complete row :)
-            self.row_height,
-            self.col_flutes,
-            self.addendum,
-            self.flute_sides,
-            radians(self.skew),
-            self.col_cap)
-
-        scene = context.scene
-
-        # Deselect all objects.
-        bpy.ops.object.select_all(action='DESELECT')
-
-        # Create new mesh
-
-        # Make a mesh from a list of verts/edges/faces.
-
-        if self.col_base:
-            meshBase = bpy.data.meshes.new("Base")
-            meshBase.from_pydata(vertsBase, edgesBase, [])
-            meshBase.update()
-
-            ob_new = bpy.data.objects.new("Base", meshBase)
-            scene.objects.link(ob_new)
-            scene.objects.active = ob_new
-            ob_new.select = True
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.mesh.spin(steps=(self.base_faces*4), dupli=False, degrees=360, center=(0,0,0), axis=(0,0,1))
-            bpy.ops.mesh.select_all(action='SELECT')
-            bpy.ops.object.editmode_toggle()
-
-            # since base and cap use same logic to generate, rotate and reposition base for use with column...
-            bpy.ops.transform.rotate(value=(3.14159,), axis=(1,0,0), constraint_axis=(True,False,False), constraint_orientation='GLOBAL',
-                mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False,
-                snap_target='CLOSEST', snap_point=(0,0,0), snap_align=False, snap_normal=(0,0,0), release_confirm=False)
-
-            bpy.ops.transform.translate(value=(0,0,baseH), constraint_axis=(False,False,True), constraint_orientation='GLOBAL',
-                mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False,
-                snap_target='CLOSEST', snap_point=(0,0,0), snap_align=False, snap_normal=(0,0,0), texture_space=False, release_confirm=False)
-
-        if self.col_cap:
-            meshCap = bpy.data.meshes.new("Capital")
-            meshCap.from_pydata(vertsCap, edgesCap, [])
-            meshCap.update()
-
-            ob_new = bpy.data.objects.new("Capital", meshCap)
-            scene.objects.link(ob_new)
-            scene.objects.active = ob_new
-            ob_new.select = True
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.mesh.spin(steps=(self.cap_faces*4), dupli=False, degrees=360, center=(0,0,0), axis=(0,0,1))
-            bpy.ops.object.editmode_toggle()
-        
-        mesh = bpy.data.meshes.new("Column")
-        mesh.from_pydata(verts, [], faces)
-
-        mesh.update()
-
-        ob_new = bpy.data.objects.new("Column", mesh)
-        scene.objects.link(ob_new)
-        scene.objects.active = ob_new
-        ob_new.select = True
-
-        if self.col_base or self.col_cap:
-            bpy.ops.object.join()
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.mesh.select_all(action='SELECT')
-            bpy.ops.mesh.remove_doubles(mergedist=0.0001)
-            bpy.ops.object.editmode_toggle()
-
-        ob_new.location = tuple(context.scene.cursor_location)
-#        ob_new.rotation_quaternion = [1.0,0.0,0.0,0.0]
-#        ob_new.rotation_quaternion = [0.0,0.0,0.0,0.0]
-
-        return {'FINISHED'}
-
-
-class INFO_MT_mesh_columns_add(bpy.types.Menu):
-    # Create the "Columns" menu
-    bl_idname = "INFO_MT_mesh_columns_add"
-    bl_label = "Columns"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        layout.operator("mesh.primitive_column", text="Column")
-
-
-def menu_func(self, context): # Define "Columns" menu
-    self.layout.menu("INFO_MT_mesh_columns_add", icon="PLUGIN")
-
-
-def register(): # Add entry to the "Add Mesh" menu.
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_mesh_add.append(menu_func)
-
-
-def unregister(): # Remove entry from the "Add Mesh" menu.
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_mesh_add.remove(menu_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/__init__.py b/release/scripts/addons_contrib/add_mesh_rocks/__init__.py
deleted file mode 100644
index cb4d37b..0000000
--- a/release/scripts/addons_contrib/add_mesh_rocks/__init__.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Paul "BrikBot" Marshall
-# Created: July 1, 2011
-# Last Modified: November 17, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas
-#   and testing.
-#
-# Coded in IDLE, tested in Blender 2.59.  NumPy Recommended.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  The Blender Rock Creation tool is for rapid generation of
-#  mesh rocks in Blender.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-    "name": "Rock Generator",
-    "author": "Paul Marshall (brikbot)",
-    "version": (1, 3),
-    "blender": (2, 6, 1),
-    "location": "View3D > Add > Rock Generator",
-    "description": "Adds a mesh rock to the Add Mesh menu",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5"\
-        "/Py/Scripts/Add_Mesh/Rock_Generator",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=27314",
-    "category": "Add Mesh"}
-
-if "bpy" in locals():
-    import imp
-    imp.reload(rockgen)
-else:
-    from add_mesh_rocks import rockgen
-
-import bpy
-
-
-# Register:
-def menu_func_rocks(self, context):
-    self.layout.operator(rockgen.rocks.bl_idname,
-                         text="Rock Generator",
-                         icon="PLUGIN")
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_mesh_add.append(menu_func_rocks)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_mesh_add.remove(menu_func_rocks)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml b/release/scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml
deleted file mode 100644
index 0202486..0000000
--- a/release/scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE settings [
-<!ELEMENT settings (default,preset*)>
-<!ELEMENT default (title,size,shape,material,random)>
-<!ELEMENT preset (title,size,shape,material,random)>
-<!ELEMENT title (#PCDATA)>
-<!ELEMENT size (scale+,skew+,use_scale_dis,scale_fac)>
-<!ELEMENT scale (axis,lower,upper)>
-<!ELEMENT axis (#PCDATA)>
-<!ELEMENT lower (#PCDATA)>
-<!ELEMENT upper (#PCDATA)>
-<!ELEMENT skew (axis,value)>
-<!ELEMENT value (#PCDATA)>
-<!ELEMENT use_scale_dis (#PCDATA)>
-<!ELEMENT scale_fac (#PCDATA)>
-<!ELEMENT shape (deform,rough,detail,display_detail,smooth_fac,smooth_it)>
-<!ELEMENT deform (#PCDATA)>
-<!ELEMENT rough (#PCDATA)>
-<!ELEMENT detail (#PCDATA)>
-<!ELEMENT display_detail (#PCDATA)>
-<!ELEMENT smooth_fac (#PCDATA)>
-<!ELEMENT smooth_it (#PCDATA)>
-<!ELEMENT material (mat_enable,mat_color,mat_bright,mat_rough,mat_spec,mat_hard,mat_use_trans,mat_alpha,mat_cloudy,mat_IOR,mat_mossy)>
-<!ELEMENT mat_enable (#PCDATA)>
-<!ELEMENT mat_color (#PCDATA)>
-<!ELEMENT mat_bright (#PCDATA)>
-<!ELEMENT mat_rough (#PCDATA)>
-<!ELEMENT mat_spec (#PCDATA)>
-<!ELEMENT mat_hard (#PCDATA)>
-<!ELEMENT mat_use_trans (#PCDATA)>
-<!ELEMENT mat_alpha (#PCDATA)>
-<!ELEMENT mat_cloudy (#PCDATA)>
-<!ELEMENT mat_IOR (#PCDATA)>
-<!ELEMENT mat_mossy (#PCDATA)>
-<!ELEMENT random (use_random_seed,user_seed)>
-<!ELEMENT use_generate (#PCDATA)>
-<!ELEMENT use_random_seed (#PCDATA)>
-<!ELEMENT user_seed (#PCDATA)>
-
-<!ATTLIST preset id ID #REQUIRED>
-]>
-<settings>
-	<default>
-		<title>Default</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>5.0</deform>
-			<rough>2.5</rough>
-			<detail>3</detail>
-			<display_detail>2</display_detail>
-			<smooth_fac>0.0</smooth_fac>
-			<smooth_it>0</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>False</mat_enable>
-			<mat_color>[0.5, 0.5, 0.5]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>1.0</mat_rough>
-			<mat_spec>0.2</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</default>
-	<preset id="1">
-		<title>River Rock</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>0.5</lower>
-				<upper>1.25</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>0.5</lower>
-				<upper>1.25</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>0.5</lower>
-				<upper>1.25</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>-0.5</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>-0.5</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>-0.5</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>3.0</deform>
-			<rough>2.0</rough>
-			<detail>2</detail>
-			<display_detail>2</display_detail>
-			<smooth_fac>2.0</smooth_fac>
-			<smooth_it>2</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.5, 0.5, 0.5]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>0.125</mat_rough>
-			<mat_spec>0.5</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="2">
-		<title>Astroid</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>1.0</lower>
-				<upper>5.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>1.0</lower>
-				<upper>5.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>1.0</lower>
-				<upper>5.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>7.5</deform>
-			<rough>3.0</rough>
-			<detail>4</detail>
-			<display_detail>3</display_detail>
-			<smooth_fac>0.0</smooth_fac>
-			<smooth_it>0</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.3, 0.25, 0.2]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>1.5</mat_rough>
-			<mat_spec>0.25</mat_spec>
-			<mat_hard>30</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="3">
-		<title>Sandstone</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>True</use_scale_dis>
-			<scale_fac>[5.0, 5.0, 0.1]</scale_fac>
-		</size>
-		<shape>
-			<deform>0.5</deform>
-			<rough>1.0</rough>
-			<detail>3</detail>
-			<display_detail>3</display_detail>
-			<smooth_fac>2.0</smooth_fac>
-			<smooth_it>2</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.5, 0.4, 0.35]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>0.1</mat_rough>
-			<mat_spec>0.2</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="4">
-		<title>Ice</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>0.0</lower>
-				<upper>2.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>0.0</lower>
-				<upper>2.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>0.0</lower>
-				<upper>2.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>5.0</deform>
-			<rough>1.0</rough>
-			<detail>3</detail>
-			<display_detail>2</display_detail>
-			<smooth_fac>2.0</smooth_fac>
-			<smooth_it>1</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.9, 0.95, 1.0]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>0.25</mat_rough>
-			<mat_spec>0.2</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>True</mat_use_trans>
-			<mat_alpha>0.9</mat_alpha>
-			<mat_cloudy>0.1</mat_cloudy>
-			<mat_IOR>1.31</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="5">
-		<title>Fake Ocean</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>10.0</lower>
-				<upper>10.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>10.0</lower>
-				<upper>10.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>0.0</lower>
-				<upper>0.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>7.5</deform>
-			<rough>3.0</rough>
-			<detail>4</detail>
-			<display_detail>3</display_detail>
-			<smooth_fac>0.0</smooth_fac>
-			<smooth_it>0</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.1, 0.12, 0.125]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>1.5</mat_rough>
-			<mat_spec>0.25</mat_spec>
-			<mat_hard>30</mat_hard>
-			<mat_use_trans>True</mat_use_trans>
-			<mat_alpha>0.5</mat_alpha>
-			<mat_cloudy>0.5</mat_cloudy>
-			<mat_IOR>1.333</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-</settings>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/factory.xml b/release/scripts/addons_contrib/add_mesh_rocks/factory.xml
deleted file mode 100644
index 0202486..0000000
--- a/release/scripts/addons_contrib/add_mesh_rocks/factory.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE settings [
-<!ELEMENT settings (default,preset*)>
-<!ELEMENT default (title,size,shape,material,random)>
-<!ELEMENT preset (title,size,shape,material,random)>
-<!ELEMENT title (#PCDATA)>
-<!ELEMENT size (scale+,skew+,use_scale_dis,scale_fac)>
-<!ELEMENT scale (axis,lower,upper)>
-<!ELEMENT axis (#PCDATA)>
-<!ELEMENT lower (#PCDATA)>
-<!ELEMENT upper (#PCDATA)>
-<!ELEMENT skew (axis,value)>
-<!ELEMENT value (#PCDATA)>
-<!ELEMENT use_scale_dis (#PCDATA)>
-<!ELEMENT scale_fac (#PCDATA)>
-<!ELEMENT shape (deform,rough,detail,display_detail,smooth_fac,smooth_it)>
-<!ELEMENT deform (#PCDATA)>
-<!ELEMENT rough (#PCDATA)>
-<!ELEMENT detail (#PCDATA)>
-<!ELEMENT display_detail (#PCDATA)>
-<!ELEMENT smooth_fac (#PCDATA)>
-<!ELEMENT smooth_it (#PCDATA)>
-<!ELEMENT material (mat_enable,mat_color,mat_bright,mat_rough,mat_spec,mat_hard,mat_use_trans,mat_alpha,mat_cloudy,mat_IOR,mat_mossy)>
-<!ELEMENT mat_enable (#PCDATA)>
-<!ELEMENT mat_color (#PCDATA)>
-<!ELEMENT mat_bright (#PCDATA)>
-<!ELEMENT mat_rough (#PCDATA)>
-<!ELEMENT mat_spec (#PCDATA)>
-<!ELEMENT mat_hard (#PCDATA)>
-<!ELEMENT mat_use_trans (#PCDATA)>
-<!ELEMENT mat_alpha (#PCDATA)>
-<!ELEMENT mat_cloudy (#PCDATA)>
-<!ELEMENT mat_IOR (#PCDATA)>
-<!ELEMENT mat_mossy (#PCDATA)>
-<!ELEMENT random (use_random_seed,user_seed)>
-<!ELEMENT use_generate (#PCDATA)>
-<!ELEMENT use_random_seed (#PCDATA)>
-<!ELEMENT user_seed (#PCDATA)>
-
-<!ATTLIST preset id ID #REQUIRED>
-]>
-<settings>
-	<default>
-		<title>Default</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>5.0</deform>
-			<rough>2.5</rough>
-			<detail>3</detail>
-			<display_detail>2</display_detail>
-			<smooth_fac>0.0</smooth_fac>
-			<smooth_it>0</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>False</mat_enable>
-			<mat_color>[0.5, 0.5, 0.5]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>1.0</mat_rough>
-			<mat_spec>0.2</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</default>
-	<preset id="1">
-		<title>River Rock</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>0.5</lower>
-				<upper>1.25</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>0.5</lower>
-				<upper>1.25</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>0.5</lower>
-				<upper>1.25</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>-0.5</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>-0.5</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>-0.5</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>3.0</deform>
-			<rough>2.0</rough>
-			<detail>2</detail>
-			<display_detail>2</display_detail>
-			<smooth_fac>2.0</smooth_fac>
-			<smooth_it>2</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.5, 0.5, 0.5]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>0.125</mat_rough>
-			<mat_spec>0.5</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="2">
-		<title>Astroid</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>1.0</lower>
-				<upper>5.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>1.0</lower>
-				<upper>5.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>1.0</lower>
-				<upper>5.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>7.5</deform>
-			<rough>3.0</rough>
-			<detail>4</detail>
-			<display_detail>3</display_detail>
-			<smooth_fac>0.0</smooth_fac>
-			<smooth_it>0</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.3, 0.25, 0.2]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>1.5</mat_rough>
-			<mat_spec>0.25</mat_spec>
-			<mat_hard>30</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="3">
-		<title>Sandstone</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>1.0</lower>
-				<upper>1.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>True</use_scale_dis>
-			<scale_fac>[5.0, 5.0, 0.1]</scale_fac>
-		</size>
-		<shape>
-			<deform>0.5</deform>
-			<rough>1.0</rough>
-			<detail>3</detail>
-			<display_detail>3</display_detail>
-			<smooth_fac>2.0</smooth_fac>
-			<smooth_it>2</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.5, 0.4, 0.35]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>0.1</mat_rough>
-			<mat_spec>0.2</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>False</mat_use_trans>
-			<mat_alpha>0.0</mat_alpha>
-			<mat_cloudy>0.0</mat_cloudy>
-			<mat_IOR>1.0</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="4">
-		<title>Ice</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>0.0</lower>
-				<upper>2.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>0.0</lower>
-				<upper>2.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>0.0</lower>
-				<upper>2.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>5.0</deform>
-			<rough>1.0</rough>
-			<detail>3</detail>
-			<display_detail>2</display_detail>
-			<smooth_fac>2.0</smooth_fac>
-			<smooth_it>1</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.9, 0.95, 1.0]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>0.25</mat_rough>
-			<mat_spec>0.2</mat_spec>
-			<mat_hard>50</mat_hard>
-			<mat_use_trans>True</mat_use_trans>
-			<mat_alpha>0.9</mat_alpha>
-			<mat_cloudy>0.1</mat_cloudy>
-			<mat_IOR>1.31</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-	<preset id="5">
-		<title>Fake Ocean</title>
-		<size>
-			<scale>
-				<axis>X</axis>
-				<lower>10.0</lower>
-				<upper>10.0</upper>
-			</scale>
-			<scale>
-				<axis>Y</axis>
-				<lower>10.0</lower>
-				<upper>10.0</upper>
-			</scale>
-			<scale>
-				<axis>Z</axis>
-				<lower>0.0</lower>
-				<upper>0.0</upper>
-			</scale>
-			<skew>
-				<axis>X</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Y</axis>
-				<value>0.0</value>
-			</skew>
-			<skew>
-				<axis>Z</axis>
-				<value>0.0</value>
-			</skew>
-			<use_scale_dis>False</use_scale_dis>
-			<scale_fac>[1.0, 1.0, 1.0]</scale_fac>
-		</size>
-		<shape>
-			<deform>7.5</deform>
-			<rough>3.0</rough>
-			<detail>4</detail>
-			<display_detail>3</display_detail>
-			<smooth_fac>0.0</smooth_fac>
-			<smooth_it>0</smooth_it>
-		</shape>
-		<material>
-			<mat_enable>True</mat_enable>
-			<mat_color>[0.1, 0.12, 0.125]</mat_color>
-			<mat_bright>0.85</mat_bright>
-			<mat_rough>1.5</mat_rough>
-			<mat_spec>0.25</mat_spec>
-			<mat_hard>30</mat_hard>
-			<mat_use_trans>True</mat_use_trans>
-			<mat_alpha>0.5</mat_alpha>
-			<mat_cloudy>0.5</mat_cloudy>
-			<mat_IOR>1.333</mat_IOR>
-			<mat_mossy>0.0</mat_mossy>
-		</material>
-		<random>
-			<use_generate>True</use_generate>
-			<use_random_seed>True</use_random_seed>
-			<user_seed>1</user_seed>
-		</random>
-	</preset>
-</settings>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/rockgen.py b/release/scripts/addons_contrib/add_mesh_rocks/rockgen.py
deleted file mode 100644
index b1efa62..0000000
--- a/release/scripts/addons_contrib/add_mesh_rocks/rockgen.py
+++ /dev/null
@@ -1,1602 +0,0 @@
-# Blender rock creation tool
-#
-# Based on BlenderGuru's asteroid tutorial and personal experimentation.
-#   Tutorial: http://www.blenderguru.com/how-to-make-a-realistic-asteroid/
-# Update with another tutorial shared by "rusted" of BlenderArtists:
-#   Tutorial: http://saschahenrichs.blogspot.com/2010/03/3dsmax-environment-modeling-1.html
-#
-# Uses the NumPy Gaussian random number generator to generate a
-# a rock within a given range and give some randomness to the displacement
-# texture values.  NumPy's gaussian generator was chosen as, based on
-# profiling I performed, it runs in about half the time as the built in
-# Python gaussian equivalent.  I would like to shift the script to use the
-# NumPy beta distribution as it ran in about half the time as the NumPy
-# gaussian once the skew calculations are added.
-#
-# Set lower and upper bounds to the same for no randomness.
-#
-# Tasks:
-#   Generate meshes with random scaling between given values.
-#       - Allow for a skewed distribution
-#           *** Completed on 4/17/2011 ***
-#       - Create a set of meshes that can be used
-#   Give the user the ability to set the subsurf level (detail level)
-#       *** Completed on 4/29/2011 ***
-#       - Set subsurf modifiers to default at view:3, render:3.
-#           *** Completed on 4/17/2011 ***
-#       - Set crease values to allow for hard edges on first subsurf.
-#           *** Completed on 4/29/2011 ***
-#   Be able to generate and add a texture to the displacement modifiers.
-#       *** Completed 5/17/2011 ***
-#       - Generate three displacement modifiers.
-#           - The first only uses a Musgrave for initial intentations.
-#           *** Now generating four displacement modifiers ***
-#           *** Completed on 5/17/2011 ***
-#       - Set a randomness for the type and values of the displacement texture.
-#           *** Completed 5/9/2011 ***
-#       - Allow the user to set a value for the range of displacement.
-#           -> Modification: have user set "roughness" and "roughness range".
-#           *** Compleded on 4/23/2011 ***
-#   Set material settings and assign material textures
-#       *** Completed 6/9/2011 ***
-#       - Mossiness of the rocks.
-#           *** Completed 6/9/2011 ***
-#       - Color of the rocks.
-#           *** Completed 5/16/2011 ***
-#       - Wetness/shinyness of the rock.
-#           *** Completed 5/6/2011 ***
-#       - For all the user provides a mean value for a skewed distribution.
-#           *** Removed to lessen usage complexity ***
-#   Add some presets (mesh) to make it easier to use
-#       - Examples: river rock, asteroid, quaried rock, etc
-#           *** Completed 7/12/2011 ***
-#
-# Code Optimization:
-#   Remove all "bpy.ops" operations with "bpy.data" base operations.
-#   Remove material/texture cataloging with building a list of
-#       returned values from bpy.data.*.new() operations.
-#       *** Completed on 9/6/2011 ***
-#   Search for places where list comprehensions can be used.
-#   Look for alternate methods
-#       - Possible alternate and more efficient data structures
-#       - Possible alternate algorithms may realize greater performance
-#       - Look again at multi-processing.  Without bpy.ops is might
-#           be viable.
-#
-# Future tasks:
-#   Multi-thread the script
-#       *** Will not be implemented.  Multi-processing is adding to much
-#           overhead to realize a performance increase ***
-#       - Learn basic multi-threading in Python (multiprocessing)
-#       - Break material generation into separate threads (processes)
-#       - Break mesh generation into separate threads (processes)
-#       - Move name generation, texture ID generation, etc to process first
-#       - Roll version to 2.0 on completion
-#
-# Paul "BrikBot" Marshall
-# Created: April 17, 2011
-# Last Modified: November 17, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas
-#   and testing.
-#
-# Coded in IDLE, tested in Blender 2.59.  NumPy Recommended.
-# Search for "@todo" to quickly find sections that need work.
-#
-# Remeber -
-#   Functional code comes before fast code.  Once it works, then worry about
-#   making it faster/more efficient.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  The Blender Rock Creation tool is for rapid generation of mesh rocks.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-import bpy
-import math
-import time
-from add_mesh_rocks import (settings,
-                            utils)
-from bpy_extras import object_utils
-from mathutils import (Color,
-                       Vector)
-from bpy.props import (BoolProperty,
-                       IntProperty,
-                       FloatProperty,
-                       FloatVectorProperty,
-                       EnumProperty)
-
-# This try block allows for the script to psudo-intelligently select the
-# appropriate random to use.  If Numpy's random is present it will use that.
-# If Numpy's random is not present, it will through a "module not found"
-# exception and instead use the slower built-in random that Python has.
-try:
-    from numpy.random import random_integers as randint
-    from numpy.random import normal as gauss
-    from numpy.random import (beta,
-                              uniform,
-                              seed,
-                              weibull)
-    print("Rock Generator: Numpy found.")
-    numpy = True
-except:
-    from random import (randint,
-                        gauss,
-                        uniform,
-                        seed)
-    from random import betavariate as beta
-    from random import weibullvariate as weibull
-    print("Rock Generator: Numpy not found.  Using Python's random.")
-    numpy = False
-
-# Global variables:
-lastRock = 0
-
-
-# Creates a new mesh:
-#
-# param: verts - Vector of vertices for the mesh.
-#        edges - Edges for the mesh.  Can be "[]".
-#        faces - Face tuples corresponding to vertices.
-#        name  - Name of the mesh.
-def createMeshObject(context, verts, edges, faces, name):
-    # Create new mesh
-    mesh = bpy.data.meshes.new(name)
-
-    # Make a mesh from a list of verts/edges/faces.
-    mesh.from_pydata(verts, edges, faces)
-
-    # Set mesh to use auto smoothing:
-    mesh.use_auto_smooth = True
-
-    # Update mesh geometry after adding stuff.
-    mesh.update()
-
-    return object_utils.object_data_add(context, mesh, operator=None)
-
-
-# Set the values for a texture from parameters.
-#
-# param: texture - bpy.data.texture to modify.
-#        level   - designated tweaked settings to use
-#                   -> Below 10 is a displacment texture
-#                   -> Between 10 and 20 is a base material texture
-def randomizeTexture(texture, level=1):
-    noises = ['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN', 'IMPROVED_PERLIN',
-              'VORONOI_F1', 'VORONOI_F2', 'VORONOI_F3', 'VORONOI_F4',
-              'VORONOI_F2_F1', 'VORONOI_CRACKLE']
-    if texture.type == 'CLOUDS':
-        if randint(0, 1) == 0:
-            texture.noise_type = 'SOFT_NOISE'
-        else:
-            texture.noise_type = 'HARD_NOISE'
-        if level != 11:
-            tempInt = randint(0, 6)
-        else:
-            tempInt = randint(0, 8)
-        texture.noise_basis = noises[tempInt]
-        texture.noise_depth = 8
-
-        if level == 0:
-            texture.noise_scale = gauss(0.625, 1 / 24)
-        elif level == 2:
-            texture.noise_scale = 0.15
-        elif level == 11:
-            texture.noise_scale = gauss(0.5, 1 / 24)
-
-            if texture.noise_basis in ['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN',
-                                       'IMPROVED_PERLIN', 'VORONOI_F1']:
-                texture.intensity = gauss(1, 1 / 6)
-                texture.contrast = gauss(4, 1 / 3)
-            elif texture.noise_basis in ['VORONOI_F2', 'VORONOI_F3', 'VORONOI_F4']:
-                texture.intensity = gauss(0.25, 1 / 12)
-                texture.contrast = gauss(2, 1 / 6)
-            elif texture.noise_basis == 'VORONOI_F2_F1':
-                texture.intensity = gauss(0.5, 1 / 6)
-                texture.contrast = gauss(2, 1 / 6)
-            elif texture.noise_basis == 'VORONOI_CRACKLE':
-                texture.intensity = gauss(0.5, 1 / 6)
-                texture.contrast = gauss(2, 1 / 6)
-    elif texture.type == 'MUSGRAVE':
-        musgraveType = ['MULTIFRACTAL', 'RIDGED_MULTIFRACTAL',
-                        'HYBRID_MULTIFRACTAL', 'FBM', 'HETERO_TERRAIN']
-        texture.musgrave_type = 'MULTIFRACTAL'
-        texture.dimension_max = abs(gauss(0, 0.6)) + 0.2
-        texture.lacunarity = beta(3, 8) * 8.2 + 1.8
-
-        if level == 0:
-            texture.noise_scale = gauss(0.625, 1 / 24)
-            texture.noise_intensity = 0.2
-            texture.octaves = 1.0
-        elif level == 2:
-            texture.intensity = gauss(1, 1 / 6)
-            texture.contrast = 0.2
-            texture.noise_scale = 0.15
-            texture.octaves = 8.0
-        elif level == 10:
-            texture.intensity = gauss(0.25, 1 / 12)
-            texture.contrast = gauss(1.5, 1 / 6)
-            texture.noise_scale = 0.5
-            texture.octaves = 8.0
-        elif level == 12:
-            texture.octaves = uniform(1, 3)
-        elif level > 12:
-            texture.octaves = uniform(2, 8)
-        else:
-            texture.intensity = gauss(1, 1 / 6)
-            texture.contrast = 0.2
-            texture.octaves = 8.0
-    elif texture.type == 'DISTORTED_NOISE':
-        tempInt = randint(0, 8)
-        texture.noise_distortion = noises[tempInt]
-        tempInt = randint(0, 8)
-        texture.noise_basis = noises[tempInt]
-        texture.distortion = skewedGauss(2.0, 2.6666, (0.0, 10.0), False)
-
-        if level == 0:
-            texture.noise_scale = gauss(0.625, 1 / 24)
-        elif level == 2:
-            texture.noise_scale = 0.15
-        elif level >= 12:
-            texture.noise_scale = gauss(0.2, 1 / 48)
-    elif texture.type == 'STUCCI':
-        stucciTypes = ['PLASTIC', 'WALL_IN', 'WALL_OUT']
-        if randint(0, 1) == 0:
-            texture.noise_type = 'SOFT_NOISE'
-        else:
-            texture.noise_type = 'HARD_NOISE'
-        tempInt = randint(0, 2)
-        texture.stucci_type = stucciTypes[tempInt]
-
-        if level == 0:
-            tempInt = randint(0, 6)
-            texture.noise_basis = noises[tempInt]
-            texture.noise_scale = gauss(0.625, 1 / 24)
-        elif level == 2:
-            tempInt = randint(0, 6)
-            texture.noise_basis = noises[tempInt]
-            texture.noise_scale = 0.15
-        elif level >= 12:
-            tempInt = randint(0, 6)
-            texture.noise_basis = noises[tempInt]
-            texture.noise_scale = gauss(0.2, 1 / 30)
-        else:
-            tempInt = randint(0, 6)
-            texture.noise_basis = noises[tempInt]
-    elif texture.type == 'VORONOI':
-        metrics = ['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', 'CHEBYCHEV',
-                   'MINKOVSKY_HALF', 'MINKOVSKY_FOUR', 'MINKOVSKY']
-        # Settings for first dispalcement level:
-        if level == 0:
-            tempInt = randint(0, 1)
-            texture.distance_metric = metrics[tempInt]
-            texture.noise_scale = gauss(0.625, 1 / 24)
-            texture.contrast = 0.5
-            texture.intensity = 0.7
-        elif level == 2:
-            texture.noise_scale = 0.15
-            tempInt = randint(0, 6)
-            texture.distance_metric = metrics[tempInt]
-        elif level >= 12:
-            tempInt = randint(0, 1)
-            texture.distance_metric = metrics[tempInt]
-            texture.noise_scale = gauss(0.125, 1 / 48)
-            texture.contrast = 0.5
-            texture.intensity = 0.7
-        else:
-            tempInt = randint(0, 6)
-            texture.distance_metric = metrics[tempInt]
-
-    return
-
-
-# Randomizes the given material given base values.
-#
-# param: Material to randomize
-def randomizeMaterial(material, color, dif_int, rough, spec_int, spec_hard,
-                      use_trans, alpha, cloudy, mat_IOR, mossiness, spec_IOR):
-    skew = False
-    stddev = 0.0
-    lastUsedTex = 1
-    numTex = 6
-    baseColor = []
-
-    # Diffuse settings:
-    material.diffuse_shader = 'OREN_NAYAR'
-    if 0.5 > dif_int:
-        stddev = dif_int / 3
-        skew = False
-    else:
-        stddev = (1 - dif_int) / 3
-        skew = True
-    material.diffuse_intensity = skewedGauss(dif_int, stddev, (0.0, 1.0), skew)
-    if 1.57 > rough:
-        stddev = rough / 3
-        skew = False
-    else:
-        stddev = (3.14 - rough) / 3
-        skew = True
-    material.roughness = skewedGauss(rough, stddev, (0.0, 3.14), skew)
-
-    for i in range(3):
-        if color[i] > 0.9 or color[i] < 0.1:
-            baseColor.append(skewedGauss(color[i], color[i] / 30,
-                                         (0, 1), color[i] > 0.9))
-        else:
-            baseColor.append(gauss(color[i], color[i] / 30))
-    material.diffuse_color = baseColor
-
-    # Specular settings:
-    material.specular_shader = 'BLINN'
-    if 0.5 > spec_int:
-        variance = spec_int / 3
-        skew = False
-    else:
-        variance = (1 - spec_int) / 3
-        skew = True
-    material.specular_intensity = skewedGauss(spec_int, stddev,
-                                              (0.0, 1.0), skew)
-    if 256 > spec_hard:
-        variance = (spec_hard - 1) / 3
-        skew = False
-    else:
-        variance = (511 - spec_hard) / 3
-        skew = True
-    material.specular_hardness = int(round(skewedGauss(spec_hard, stddev,
-                                                       (1.0, 511.0), skew)))
-    if 5.0 > spec_IOR:
-        variance = spec_IOR / 3
-        skew = False
-    else:
-        variance = (10.0 - spec_IOR) / 3
-        skew = True
-    material.specular_ior = skewedGauss(spec_IOR, stddev, (0.0, 10.0), skew)
-
-    # Raytrans settings:
-    #   *** Added on 11/17/2011 ***
-    material.use_transparency = use_trans
-    if use_trans:
-        trans = material.raytrace_transparency
-        # Fixed values:
-        material.transparency_method = 'RAYTRACE'
-        trans.depth = 24
-        trans.gloss_samples = 32
-        trans.falloff = 1.0
-        # Needs randomization:
-        material.alpha = -gauss(alpha, 0.05) + 1;
-        trans.gloss_factor = -gauss(cloudy, 0.05) + 1
-        trans.filter = gauss(cloudy, 0.1)
-        trans.ior = skewedGauss(mat_IOR, 0.01, [0.25, 4.0], mat_IOR > 2.125)
-
-    #Misc. settings:
-    material.use_transparent_shadows = True
-
-    # Rock textures:
-    # Now using slot.texture for texture access instead of
-    #   bpy.data.textures[newTex[<index>]]
-    #   *** Completed on 9/6/2011 ***
-    # Create the four new textures:
-    textureTypes = ['MUSGRAVE', 'CLOUDS', 'DISTORTED_NOISE',
-                    'STUCCI', 'VORONOI']
-
-    for i in range(numTex):
-        texColor = []
-
-        # Set the active material slot:
-        material.active_texture_index = i
-        # Assign a texture to the active material slot:
-        material.active_texture = bpy.data.textures.new(name = 'stone_tex',
-                                                        type = 'NONE')
-        # Store the slot to easy coding access:
-        slot = material.texture_slots[i]
-
-        # If the texture is not a moss texture:
-        if i > 1:
-            slot.texture.type = textureTypes[randint(0, 3)]
-
-            # Set the texture's color (RGB):
-            for j in range(3):
-                if color[j] > 0.9 or color[j] < 0.1:
-                    texColor.append(skewedGauss(color[j], color[j] / 30,
-                                                (0, 1), color[j] > 0.9))
-                else:
-                    texColor.append(gauss(color[j], color[j] / 30))
-            slot.color = texColor
-            # Randomize the value (HSV):
-            v = material.diffuse_color.v
-            if v == 0.5:
-                slot.color.v = gauss(v, v / 3)
-            elif v > 0.5:
-                slot.color.v = skewedGauss(v, v / 3, (0, 1), True)
-            else:
-                slot.color.v = skewedGauss(v, (1 - v) / 3, (0, 1), False)
-
-            # Adjust scale and normal based on texture type:
-            if slot.texture.type == 'VORONOI':
-                slot.scale = (gauss(5, 1), gauss(5, 1), gauss(5, 1))
-                slot.normal_factor = gauss(rough / 10, rough / 30)
-            elif slot.texture.type == 'STUCCI':
-                slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
-                              gauss(1.5, 0.25))
-                slot.normal_factor = gauss(rough / 10, rough / 30)
-            elif slot.texture.type == 'DISTORTED_NOISE':
-                slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
-                              gauss(1.5, 0.25))
-                slot.normal_factor = gauss(rough / 10, rough / 30)
-            elif slot.texture.type == 'MUSGRAVE':
-                slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
-                              gauss(1.5, 0.25))
-                slot.normal_factor = gauss(rough, rough / 3)
-            elif slot.texture.type == 'CLOUDS':
-                slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
-                              gauss(1.5, 0.25))
-                slot.normal_factor = gauss(rough, rough / 3)
-
-            # Set the color influence to 0.5.
-            # This allows for the moss textures to show:
-            slot.diffuse_color_factor = 0.5
-            # Set additional influence booleans:
-            slot.use_stencil = True
-            slot.use_map_specular = True
-            slot.use_map_color_spec = True
-            slot.use_map_hardness = True
-            slot.use_map_normal = True
-        # The following is for setting up the moss textures:
-        else:
-            slot.texture.type = textureTypes[i]
-
-            # Set the mosses color (RGB):
-            texColor.append(gauss(0.5, 1 / 6))
-            texColor.append(1)
-            texColor.append(0)
-            slot.color = texColor
-            # Randomize the value (HSV):
-            slot.color.v = gauss(0.275, 1 / 24)
-
-            # Scale the texture size:
-            slot.scale = (gauss(1.5, 0.25),
-                          gauss(1.5, 0.25),
-                          gauss(1.5, 0.25))
-
-            # Set the strength of the moss color:
-            slot.diffuse_color_factor = mossiness
-            # Have it influence spec and hardness:
-            slot.use_map_specular = True
-            slot.use_map_color_spec = True
-            slot.use_map_hardness = True
-
-            # If the texutre is a voronoi crackle clouds, use "Negative":
-            if slot.texture.type == 'CLOUDS':
-                if slot.texture.noise_basis == 'VORONOI_CRACKLE':
-                    slot.invert = True
-
-            if mossiness == 0:
-                slot.use = False
-
-        randomizeTexture(slot.texture, 10 + i)
-
-    return
-
-
-# Generates an object based on one of several different mesh types.
-# All meshes have exactly eight vertices, and may be built from either
-# tri's or quads.
-#
-# param: muX        - mean X offset value
-#        sigmaX     - X offset standard deviation
-#        scaleX     - X upper and lower bounds
-#        upperSkewX - Is the distribution upperskewed?
-#        muY        - mean Y offset value
-#        sigmaY     - Y offset standard deviation
-#        scaleY     - Y upper and lower bounds
-#        upperSkewY - Is the distribution upperskewed?
-#        muZ        - mean Z offset value
-#        sigmaZ     - Z offset standard deviation
-#        scaleZ     - Z upper and lower bounds
-#        upperSkewY - Is the distribution upperskewed?
-#        base       - base number on the end of the object name
-#        shift      - Addition to the base number for multiple runs.
-#        scaleDisplace - Scale the displacement maps
-#
-# return: name      - the built name of the object
-def generateObject(context, muX, sigmaX, scaleX, upperSkewX, muY, sigmaY,
-                   scaleY, upperSkewY, muZ, sigmaZ, scaleZ, upperSkewZ, base,
-                   shift, scaleDisplace, scale_fac):
-    x = []
-    y = []
-    z = []
-    shape = randint(0, 11)
-
-    # Cube
-    # Use parameters to re-scale cube:
-    # Reversed if/for nesting.  Should be a little faster.
-    if shape == 0:
-        for j in range(8):
-            if sigmaX == 0:
-                x.append(scaleX[0] / 2)
-            else:
-                x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-            if sigmaY == 0:
-                y.append(scaleY[0] / 2)
-            else:
-                y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-            if sigmaZ == 0:
-                z.append(scaleZ[0] / 2)
-            else:
-                z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 1:
-        for j in range(8):
-            if j in [0, 1, 3, 4]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j in [2, 5]:
-                if sigmaX == 0:
-                    x.append(0)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j in [6, 7]:
-                if sigmaX == 0:
-                    x.append(0)
-                else:
-                    x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 4)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 2:
-        for j in range(8):
-            if j in [0, 2, 5, 7]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 4)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 4)
-            elif j in [1, 3, 4, 6]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 3:
-        for j in range(8):
-            if j > 0:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            else:
-                if sigmaX == 0:
-                    x.append(0)
-                else:
-                    x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 8)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 8)
-                if sigmaZ == 0:
-                    z.append(0)
-                else:
-                    z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 8)
-    elif shape == 4:
-        for j in range(10):
-            if j in [0, 9]:
-                if sigmaX == 0:
-                    x.append(0)
-                else:
-                    x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j in [1, 2, 3, 4]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j in [5, 7]:
-                if sigmaX == 0:
-                    x.append(0)
-                else:
-                    x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 3)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 3)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 3)
-                if sigmaZ == 0:
-                    z.append(0)
-                else:
-                    z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 6)
-            elif j in [6, 8]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 3)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 3)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 3)
-                if sigmaZ == 0:
-                    z.append(0)
-                else:
-                    z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 6)
-    elif shape == 5:
-        for j in range(10):
-            if j == 0:
-                if sigmaX == 0:
-                    x.append(0)
-                else:
-                    x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 8)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 8)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j in [1, 2]:
-                if sigmaX == 0:
-                    x.append(scaleZ[0] * .125)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.125)
-                if sigmaY == 0:
-                    y.append(scaleZ[0] * 0.2165)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.2165)
-                if sigmaZ == 0:
-                    z.append(0)
-                else:
-                    z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 4)
-            elif j == 3:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 4)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
-                if sigmaZ == 0:
-                    z.append(0)
-                else:
-                    z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 4)
-            elif j in [4, 6]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] * 0.25)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.25)
-                if sigmaY == 0:
-                    y.append(scaleY[0] * 0.433)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.433)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j == 5:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 4)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j in [7, 9]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] * 0.10825)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.10825)
-                if sigmaY == 0:
-                    y.append(scaleY[0] * 0.2165)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.2165)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            elif j == 8:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 6:
-        for j in range(7):
-            if j > 0:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            else:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 7:
-        for j in range(10):
-            if j in [1, 3, 4, 5, 8, 9]:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(scaleY[0] / 2)
-                else:
-                    y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-            else:
-                if sigmaX == 0:
-                    x.append(scaleX[0] / 2)
-                else:
-                    x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-                if sigmaY == 0:
-                    y.append(0)
-                else:
-                    y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
-                if sigmaZ == 0:
-                    z.append(scaleZ[0] / 2)
-                else:
-                    z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 8:
-        for j in range(7):
-            if sigmaX == 0:
-                x.append(scaleX[0] / 2)
-            else:
-                x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-            if sigmaY == 0:
-                y.append(scaleY[0] / 2)
-            else:
-                y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-            if sigmaZ == 0:
-                z.append(scaleZ[0] / 2)
-            else:
-                z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 9:
-        for j in range(8):
-            if sigmaX == 0:
-                x.append(scaleX[0] / 2)
-            else:
-                x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-            if sigmaY == 0:
-                y.append(scaleY[0] / 2)
-            else:
-                y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-            if sigmaZ == 0:
-                z.append(scaleZ[0] / 2)
-            else:
-                z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 10:
-        for j in range(7):
-            if sigmaX == 0:
-                x.append(scaleX[0] / 2)
-            else:
-                x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-            if sigmaY == 0:
-                y.append(scaleY[0] / 2)
-            else:
-                y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-            if sigmaZ == 0:
-                z.append(scaleZ[0] / 2)
-            else:
-                z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-    elif shape == 11:
-        for j in range(7):
-            if sigmaX == 0:
-                x.append(scaleX[0] / 2)
-            else:
-                x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
-            if sigmaY == 0:
-                y.append(scaleY[0] / 2)
-            else:
-                y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
-            if sigmaZ == 0:
-                z.append(scaleZ[0] / 2)
-            else:
-                z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
-
-    # This is for scaling the displacement textures.
-    # Scale the vertices so that their average is equal to 1 * scale factor.
-    if scaleDisplace:
-        averageX = (sum(x) / len(x)) * scale_fac[0]
-        for i in range(len(x)):
-            x[i] /= averageX
-        averageY = (sum(y) / len(y)) * scale_fac[1]
-        for i in range(len(y)):
-            y[i] /= averageY
-        averageZ = (sum(z) / len(z)) * scale_fac[2]
-        for i in range(len(z)):
-            z[i] /= averageZ
-
-    # Build vertex and face arrays:
-    if shape == 1:
-        verts = [(-x[0],-y[0],-z[0]),(x[1],-y[1],-z[1]),(x[2],-y[2],z[2]),
-             (-x[3],y[3],-z[3]),(x[4],y[4],-z[4]),(x[5],y[5],z[5]),
-             (x[6],y[6],z[6]),(x[7],y[7],-z[7])]
-        faces = [[0,1,2],[0,1,7],[3,0,7],[3,4,7],[1,4,7],[3,4,5],[1,2,6],
-                 [1,4,6],[4,5,6],[0,2,6],[0,3,6],[3,5,6]]
-    elif shape == 2:
-        verts = [(-x[0],y[0],-z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
-             (-x[3],y[3],-z[3]),(-x[4],-y[4],z[4]),(x[5],y[5],z[5]),
-             (x[6],y[6],z[6]),(-x[7],y[7],z[7])]
-        faces = [[0,1,2],[0,2,3],[0,3,7],[0,7,4],[1,4,5],[0,1,4],[5,1,2],
-                 [5,2,6],[3,2,6],[3,6,7],[5,4,7],[5,6,7]]
-    elif shape == 3:
-        verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
-             (-x[3],y[3],-z[3]),(x[4],-y[4],z[4]),(x[5],y[5],z[5]),
-             (-x[6],y[6],z[6]),(-x[7],-y[7],z[7])]
-        faces = [[0,1,2],[0,2,3],[0,3,6],[0,6,7],[0,7,4],[0,4,1],[5,4,1,2],
-                 [5,6,3,2],[5,4,7,6]]
-    elif shape == 4:
-        verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
-             (-x[3],y[3],-z[3]),(-x[4],-y[4],-z[4]),(x[5],-y[5],-z[5]),
-             (x[6],y[6],-z[6]),(x[7],y[7],-z[7]),(-x[8],y[8],-z[8]),
-             (x[9],y[9],-z[9])]
-        faces = [[0,1,6],[0,6,2],[0,2,7],[0,7,3],[0,3,8],[0,8,4],[0,4,5],
-                 [0,5,1],[1,9,2],[2,9,3],[3,9,4],[4,9,1],[1,6,2],[2,7,3],
-                 [3,8,4],[4,5,1]]
-    elif shape == 5:
-        verts = [(x[0],y[0],z[0]),(x[1],-y[1],z[1]),(x[2],y[2],z[2]),
-             (-x[3],y[3],z[3]),(x[4],-y[4],-z[4]),(x[5],y[5],-z[5]),
-             (x[6],y[6],-z[6]),(-x[7],y[7],-z[7]),(-x[8],y[8],-z[8]),
-             (-x[9],-y[9],-z[9])]
-        faces = [[0,1,2],[0,2,3],[0,3,1],[1,4,5],[1,5,2],[2,5,6],[2,6,7],
-                 [2,7,3],[3,7,8],[3,8,9],[3,9,1],[1,9,4],[4,5,9],[5,6,7],
-                 [7,8,9],[9,5,7]]
-    elif shape == 6:
-        verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
-             (-x[3],y[3],-z[3]),(-x[4],y[4],z[4]),(-x[5],-y[5],z[5]),
-             (-x[6],-y[6],-z[6])]
-        faces = [[0,1,2],[0,2,3,4],[0,1,6,5],[0,4,5],[1,2,3,6],[3,4,5,6]]
-    elif shape == 7:
-        verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
-             (x[3],y[3],-z[3]),(-x[4],y[4],-z[4]),(-x[5],y[5],z[5]),
-             (-x[6],y[6],z[6]),(-x[7],y[7],-z[7]),(-x[8],-y[8],-z[8]),
-             (-x[9],-y[9],z[9])]
-        faces = [[0,1,2],[0,2,3],[0,5,6],[0,6,9],[0,1,8,9],[0,3,4,5],
-                 [1,2,7,8],[2,3,4,7],[4,5,6,7],[6,7,8,9]]
-    elif shape == 8:
-        verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
-             (-x[3],y[3],-z[3]),(-x[4],-y[4],-z[4]),(-x[5],-y[5],z[5]),
-             (-x[6],y[6],z[6])]
-        faces = [[0,2,1],[0,1,4],[0,4,5],[0,5,6],[0,6,3,2],[2,1,4,3],
-                 [3,6,5,4]]
-    elif shape == 9:
-        verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],y[2],z[2]),
-             (-x[3],-y[3],z[3]),(x[4],-y[4],-z[4]),(x[5],y[5],-z[5]),
-             (x[6],y[6],z[6]),(x[7],-y[7],z[7])]
-        faces = [[0,1,6,2],[1,5,7,6],[5,4,3,7],[4,0,2,3],[0,1,5,4],[3,2,6,7]]
-    elif shape == 10:
-        verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],y[2],z[2]),
-             (x[3],-y[3],z[3]),(x[4],y[4],z[4]),(x[5],y[5],-z[5]),
-             (x[6],-y[6],-z[6])]
-        faces = [[0,2,3],[0,3,6],[0,1,5,6],[2,3,4],[0,1,2],[1,2,4,5],[3,4,5,6]]
-    elif shape == 11:
-        verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],y[2],z[2]),
-             (x[3],-y[3],z[3]),(x[4],y[4],z[4]),(x[5],y[5],-z[5]),
-             (x[6],-y[6],-z[6])]
-        faces = [[0,2,3],[0,3,6],[0,1,5,6],[2,3,4],[5,6,3],[1,5,3,4],[0,1,4,2]]
-    else:
-        verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],-y[2],z[2]),
-             (-x[3],y[3],z[3]),(x[4],-y[4],-z[4]),(x[5],y[5],-z[5]),
-             (x[6],-y[6],z[6]),(x[7],y[7],z[7])]
-        faces = [[0,1,3,2],[0,1,5,4],[0,4,6,2],[7,5,4,6],[7,3,2,6],[7,5,1,3]]
-
-    name = "Rock." + str(base + shift).zfill(3)
-
-    # Make object:
-    obj = createMeshObject(context, verts, [], faces, name)
-
-    if scaleDisplace:
-        bpy.data.objects[name].scale = Vector((averageX, averageY, averageZ))
-
-    # For a slight speed bump / Readability:
-    mesh = bpy.data.meshes[name]
-
-    # Apply creasing:
-    if shape == 0:
-        for i in range(12):
-            # todo: "0.375 / 3"?  WTF?  That = 0.125. . . .
-            #   *** Completed 7/15/2011: Changed second one ***
-            mesh.edges[i].crease = gauss(0.125, 0.125)
-    elif shape == 1:
-        for i in [0, 2]:
-            mesh.edges[i].crease = gauss(0.5, 0.125)
-        for i in [6, 9, 11, 12]:
-            mesh.edges[i].crease = gauss(0.25, 0.05)
-        for i in [5, 7, 15, 16]:
-            mesh.edges[i].crease = gauss(0.125, 0.025)
-    elif shape == 2:
-        for i in range(18):
-            mesh.edges[i].crease = gauss(0.125, 0.025)
-    elif shape == 3:
-        for i in [0, 1, 6, 10, 13]:
-            mesh.edges[i].crease = gauss(0.25, 0.05)
-        mesh.edges[8].crease = gauss(0.5, 0.125)
-    elif shape == 4:
-        for i in [5, 6, 7, 10, 14, 16, 19, 21]:
-            mesh.edges[i].crease = gauss(0.5, 0.125)
-    elif shape == 7:
-        for i in range(18):
-            if i in [0, 1, 2, 3, 6, 7, 8, 9, 13, 16]:
-                mesh.edges[i].crease = gauss(0.5, 0.125)
-            elif i in [11,17]:
-                mesh.edges[i].crease = gauss(0.25, 0.05)
-            else:
-                mesh.edges[i].crease = gauss(0.125, 0.025)
-    elif shape == 8:
-        for i in range(12):
-            if i in [0, 3, 8, 9, 10]:
-                mesh.edges[i].crease = gauss(0.5, 0.125)
-            elif i == 11:
-                mesh.edges[i].crease = gauss(0.25, 0.05)
-            else:
-                mesh.edges[i].crease = gauss(0.125, 0.025)
-    elif shape == 9:
-        for i in range(12):
-            if i in [0, 3, 4, 11]:
-                mesh.edges[i].crease = gauss(0.5, 0.125)
-            else:
-                mesh.edges[i].crease = gauss(0.25, 0.05)
-    elif shape == 10:
-        for i in range(12):
-            if i in [0, 2, 3, 4, 8, 11]:
-                mesh.edges[i].crease = gauss(0.5, 0.125)
-            elif i in [1, 5, 7]:
-                mesh.edges[i].crease = gauss(0.25, 0.05)
-            else:
-                mesh.edges[i].crease = gauss(0.125, 0.025)
-    elif shape == 11:
-        for i in range(11):
-            if i in [1, 2, 3, 4, 8, 11]:
-                mesh.edges[i].crease = gauss(0.25, 0.05)
-            else:
-                mesh.edges[i].crease = gauss(0.125, 0.025)
-
-    return name
-
-
-# Artifically skews a normal (gaussian) distribution.  This will not create
-# a continuous distribution curve but instead acts as a piecewise finction.
-# This linearly scales the output on one side to fit the bounds.
-#
-# Example output historgrams:
-#
-# Upper skewed:                 Lower skewed:
-#  |                 â–„           |      _
-#  |                 â–ˆ           |      â–ˆ
-#  |                 â–ˆ_          |      â–ˆ
-#  |                 ██          |     _█
-#  |                _██          |     ██
-#  |              _▄███_         |     ██ _
-#  |             ▄██████         |    ▄██▄█▄_
-#  |          _█▄███████         |    ███████
-#  |         _██████████_        |   ████████▄▄█_ _
-#  |      _▄▄████████████        |   ████████████▄█_
-#  | _▄_ ▄███████████████▄_      | _▄███████████████▄▄_
-#   -------------------------     -----------------------
-#                    |mu               |mu
-#   Historgrams were generated in R (http://www.r-project.org/) based on the
-#   calculations below and manually duplicated here.
-#
-# param:  mu          - mu is the mean of the distribution.
-#         sigma       - sigma is the standard deviation of the distribution.
-#         bounds      - bounds[0] is the lower bound and bounds[1]
-#                       is the upper bound.
-#         upperSkewed - if the distribution is upper skewed.
-# return: out         - Rondomly generated value from the skewed distribution.
-#
-# @todo: Because NumPy's random value generators are faster when called
-#   a bunch of times at once, maybe allow this to generate and return
-#   multiple values at once?
-def skewedGauss(mu, sigma, bounds, upperSkewed=True):
-    raw = gauss(mu, sigma)
-
-    # Quicker to check an extra condition than do unnecessary math. . . .
-    if raw < mu and not upperSkewed:
-        out = ((mu - bounds[0]) / (3 * sigma)) * raw + ((mu * (bounds[0] - (mu - 3 * sigma))) / (3 * sigma))
-    elif raw > mu and upperSkewed:
-        out = ((mu - bounds[1]) / (3 * -sigma)) * raw + ((mu * (bounds[1] - (mu + 3 * sigma))) / (3 * -sigma))
-    else:
-        out = raw
-
-    return out
-
-
-# @todo create a def for generating an alpha and beta for a beta distribution
-#   given a mu, sigma, and an upper and lower bound.  This proved faster in
-#   profiling in addition to providing a much better distribution curve
-#   provided multiple iterations happen within this function; otherwise it was
-#   slower.
-#   This might be a scratch because of the bounds placed on mu and sigma:
-#
-#   For alpha > 1 and beta > 1:
-#   mu^2 - mu^3           mu^3 - mu^2 + mu
-#   ----------- < sigma < ----------------
-#      1 + mu                  2 - mu
-#
-##def generateBeta(mu, sigma, scale, repitions=1):
-##    results = []
-##
-##    return results
-
-# Creates rock objects:
-def generateRocks(context, scaleX, skewX, scaleY, skewY, scaleZ, skewZ,
-                  scale_fac, detail, display_detail, deform, rough,
-                  smooth_fac, smooth_it, mat_enable, color, mat_bright,
-                  mat_rough, mat_spec, mat_hard, mat_use_trans, mat_alpha,
-                  mat_cloudy, mat_IOR, mat_mossy, numOfRocks=1, userSeed=1.0,
-                  scaleDisplace=False, randomSeed=True):
-    global lastRock
-    newMat = []
-    sigmaX = 0
-    sigmaY = 0
-    sigmaZ = 0
-    upperSkewX = False
-    upperSkewY = False
-    upperSkewZ = False
-    shift = 0
-    lastUsedTex = 1
-    vertexScaling = []
-
-    # Seed the random Gaussian value generator:
-    if randomSeed:
-        seed(int(time.time()))
-    else:
-        seed(userSeed)
-
-    if mat_enable:
-        # Calculate the number of materials to use.
-        #   If less than 10 rocks are being generated, generate one material
-        #       per rock.
-        #   If more than 10 rocks are being generated, generate
-        #       ceil[(1/9)n + (80/9)] materials.
-        #       -> 100 rocks will result in 20 materials
-        #       -> 1000 rocks will result in 120 materials.
-        if numOfRocks < 10:
-            numOfMats = numOfRocks
-        else:
-            numOfMats = math.ceil((1/9) * numOfRocks + (80/9))
-
-        # newMat = generateMaterialsList(numOfMats)
-        #   *** No longer needed on 9/6/2011 ***
-
-        # todo Set general material settings:
-        #   *** todo completed 5/25/2011 ***
-        # Material roughness actual max = 3.14.  Needs scaling.
-        mat_rough *= 0.628
-        spec_IOR = 1.875 * (mat_spec ** 2) + 7.125 * mat_spec + 1
-
-        # Changed as material mapping is no longer needed.
-        #   *** Complete 9/6/2011 ***
-        for i in range(numOfMats):
-            newMat.append(bpy.data.materials.new(name = 'stone'))
-            randomizeMaterial(newMat[i], color, mat_bright,
-                              mat_rough, mat_spec, mat_hard, mat_use_trans,
-                              mat_alpha, mat_cloudy, mat_IOR, mat_mossy,
-                              spec_IOR)
-
-    # These values need to be really small to look good.
-    # So the user does not have to use such ridiculously small values:
-    deform /= 10
-    rough /= 100
-
-    # Verify that the min really is the min:
-    if scaleX[1] < scaleX[0]:
-        scaleX[0], scaleX[1] = scaleX[1], scaleX[0]
-    if scaleY[1] < scaleY[0]:
-        scaleY[0], scaleY[1] = scaleY[1], scaleY[0]
-    if scaleZ[1] < scaleZ[0]:
-        scaleZ[0], scaleZ[1] = scaleZ[1], scaleZ[0]
-
-    # todo: edit below to allow for skewing the distribution
-    #   *** todo completed 4/22/2011 ***
-    #   *** Code now generating "int not scriptable error" in Blender ***
-    #
-    # Calculate mu and sigma for a Gaussian distributed random number
-    #   generation:
-    # If the lower and upper bounds are the same, skip the math.
-    #
-    # sigma is the standard deviation of the values.  The 95% interval is three
-    # standard deviations, which is what we want most generated values to fall
-    # in.  Since it might be skewed we are going to use half the difference
-    # betwee the mean and the furthest bound and scale the other side down
-    # post-number generation.
-    if scaleX[0] != scaleX[1]:
-        skewX = (skewX + 1) / 2
-        muX = scaleX[0] + ((scaleX[1] - scaleX[0]) * skewX)
-        if skewX < 0.5:
-            sigmaX = (scaleX[1] - muX) / 3
-        else:
-            sigmaX = (muX - scaleX[0]) / 3
-            upperSkewX = True
-    else:
-        muX = scaleX[0]
-    if scaleY[0] != scaleY[1]:
-        skewY = (skewY + 1) / 2
-        muY = scaleY[0] + ((scaleY[1] - scaleY[0]) * skewY)
-        if skewY < 0.5:
-            sigmaY = (scaleY[1] - muY) / 3
-        else:
-            sigmaY = (muY - scaleY[0]) / 3
-            upperSkewY = True
-    else:
-        muY = scaleY[0]
-    if scaleZ[0] != scaleZ[1]:
-        skewZ = (skewZ + 1) / 2
-        muZ = scaleZ[0] + ((scaleZ[1] - scaleZ[0]) * skewZ)
-        if skewZ < 0.5:
-            sigmaZ = (scaleZ[1] - muZ) / 3
-        else:
-            sigmaZ = (muZ - scaleZ[0]) / 3
-            upperSkewZ = True
-    else:
-        muZ = scaleZ
-
-    for i in range(numOfRocks):
-        # todo: enable different random values for each (x,y,z) corrdinate for
-        # each vertex.  This will add additional randomness to the shape of the
-        # generated rocks.
-        #   *** todo completed 4/19/2011 ***
-        #   *** Code is notably slower at high rock counts ***
-
-        name = generateObject(context, muX, sigmaX, scaleX, upperSkewX, muY,
-                               sigmaY, scaleY, upperSkewY, muZ, sigmaZ, scaleZ,
-                               upperSkewZ, i, lastRock, scaleDisplace, scale_fac)
-
-        rock = bpy.data.objects[name]
-
-        # todo Map what the two new textures will be:
-        # This is not working.  It works on paper so . . . ???
-        #   *** todo completed on 4/23/2011 ***
-        #   *** todo re-added as the first rock is getting
-        #       'Texture.001' twice. ***
-        #   *** todo completed on 4/25/2011 ***
-        #   *** Script no longer needs to map new texture names 9/6/2011 ***
-
-        # Create the four new textures:
-        # todo Set displacement texture parameters:
-        #   *** todo completed on 5/31/2011 ***
-        # Voronoi has been removed from being an option for the fine detail
-        #   texture.
-        texTypes = ['CLOUDS', 'MUSGRAVE', 'DISTORTED_NOISE', 'STUCCI', 'VORONOI']
-        newTex = []
-        # The first texture is to give a more ranodm base shape appearance:
-        newTex.append(bpy.data.textures.new(name = 'rock_displacement',
-                                            type = texTypes[1]))
-        randomizeTexture(newTex[0], 0)
-        newTex.append(bpy.data.textures.new(name = 'rock_displacement',
-                                            type = texTypes[4]))
-        randomizeTexture(newTex[1], 0)
-        if numpy:
-            newTex.append(bpy.data.textures.new(name = 'rock_displacement',
-                                                type = texTypes[int(round(weibull(1, 1)[0] / 2.125))]))
-            randomizeTexture(newTex[2], 1)
-            newTex.append(bpy.data.textures.new(name = 'rock_displacement',
-                                                type = texTypes[int(round(weibull(1, 1)[0] / 2.125))]))
-            randomizeTexture(newTex[3], 2)
-        else:
-            newTex.append(bpy.data.textures.new(name = 'rock_displacement',
-                                                type = texTypes[int(round(weibull(1, 1) / 2.125))]))
-            randomizeTexture(newTex[2], 1)
-            newTex.append(bpy.data.textures.new(name = 'rock_displacement',
-                                                type = texTypes[int(round(weibull(1, 1) / 2.125))]))
-            randomizeTexture(newTex[3], 2)
-
-        # Add modifiers:
-        rock.modifiers.new(name = "Subsurf", type = 'SUBSURF')
-        rock.modifiers.new(name = "Subsurf", type = 'SUBSURF')
-        rock.modifiers.new(name = "Displace", type = 'DISPLACE')
-        rock.modifiers.new(name = "Displace", type = 'DISPLACE')
-        rock.modifiers.new(name = "Displace", type = 'DISPLACE')
-        rock.modifiers.new(name = "Displace", type = 'DISPLACE')
-
-        # If smoothing is enabled, allow a little randomness into the
-        #   smoothing factor. Then add the smoothing modifier.
-        if smooth_fac > 0.0 and smooth_it > 0:
-            rock.modifiers.new(name = "Smooth", type='SMOOTH')
-            rock.modifiers[6].factor = gauss(smooth_fac, (smooth_fac ** 0.5) / 12)
-            rock.modifiers[6].iterations = smooth_it
-        # Make a call to random to keep things consistant:
-        else:
-            gauss(0, 1)
-
-        # Set subsurf modifier parameters:
-        rock.modifiers[0].levels = display_detail
-        rock.modifiers[0].render_levels = detail
-        rock.modifiers[1].levels = display_detail
-        rock.modifiers[1].render_levels = detail
-
-        # todo Set displacement modifier parameters:
-        #   *** todo completed on 4/23/2011 ***
-        #   *** toned down the variance on 4/26/2011 ***
-        #   *** added third modifier on 4/28/2011 ***
-        #   *** texture access changed on 9/6/2011 ***
-        rock.modifiers[2].texture = newTex[0]
-        rock.modifiers[2].strength = gauss(deform / 100, (1 / 300) * deform)
-        rock.modifiers[2].mid_level = 0
-        rock.modifiers[3].texture = newTex[1]
-        rock.modifiers[3].strength = gauss(deform, (1 / 3) * deform)
-        rock.modifiers[3].mid_level = 0
-        rock.modifiers[4].texture = newTex[2]
-        rock.modifiers[4].strength = gauss(rough * 2, (1 / 3) * rough)
-        rock.modifiers[5].texture = newTex[3]
-        rock.modifiers[5].strength = gauss(rough, (1 / 3) * rough)
-
-        # Set mesh to be smooth and fix the normals:
-        utils.smooth(bpy.data.meshes[name])
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.mesh.normals_make_consistent()
-        bpy.ops.object.editmode_toggle()
-
-        if mat_enable:
-            bpy.ops.object.material_slot_add()
-            rock.material_slots[0].material = newMat[randint(0, numOfMats - 1)]
-
-        # Store the last value of i:
-        shift = i
-
-    # Add the shift to lastRock:
-    lastRock += shift + 1
-
-    return
-
-
-# Much of the code below is more-or-less imitation of other addons and as such
-# I have left it undocumented.
-
-class rocks(bpy.types.Operator):
-    '''Add rock objects'''
-    bl_idname = "mesh.rocks"
-    bl_label = "Add Rocks"
-    bl_options = {'REGISTER', 'UNDO'}
-    bl_description = "Add rocks"
-
-    # Get the preset values from the XML file.
-    #   -> The script was morphed into a Python module
-    #       to support this.
-    # Tell settings.py to parse the XML file with the settings.
-    # Then get the default values resulting from the parsing.
-    # Make a list containing the default values and append to that
-    # the presets specified in the same XML file.  This list will
-    # be used to load preset values.
-    settings.parse()
-    defaults = settings.getDefault()
-    presetsList = [defaults]
-    presetsList += settings.getPresetLists()
-    presets = []
-    lastPreset = 0
-
-    # Build the presets list for the enum property.
-    # This needs to be a for loop as the user might add presets to
-    # the XML file and those should show here:
-    for i in range(len(presetsList)):
-        value = str(i)
-        name = presetsList[i][0]
-        description = name + " preset values."
-        presets.append((value, name, description))
-
-    preset_values = EnumProperty(items = presets,
-                                 name = "Presets",
-                                 description = "Preset values for some rock types")
-
-    num_of_rocks = IntProperty(name = "Number of rocks",
-                               description = "Number of rocks to generate. WARNING: Slow at high values!",
-                               min = 1, max = 1048576,
-                               soft_max = 20,
-                               default = 1)
-
-    scale_X = FloatVectorProperty(name = "X scale",
-                                  description = "X axis scaling range.",
-                                  min = 0.0, max = 256.0, step = 1,
-                                  default = defaults[1], size = 2)
-    skew_X = FloatProperty(name = "X skew",
-                           description = "X Skew ratio. 0.5 is no skew.",
-                           min = -1.0, max = 1.0, default = defaults[4])
-    scale_Y = FloatVectorProperty(name = "Y scale",
-                                  description = "Y axis scaling range.",
-                                  min = 0.0, max = 256.0, step = 1,
-                                  default = defaults[2], size = 2)
-    skew_Y = FloatProperty(name = "Y skew",
-                           description = "Y Skew ratio. 0.5 is no skew.",
-                           min = -1.0, max = 1.0, default = defaults[5])
-    scale_Z = FloatVectorProperty(name = "Z scale",
-                                  description = "Z axis scaling range.",
-                                  min = 0.0, max = 256.0, step = 1,
-                                  default = defaults[3], size = 2)
-    skew_Z = FloatProperty(name = "Z skew",
-                           description = "Z Skew ratio. 0.5 is no skew.",
-                           min = -1.0, max = 1.0, default = defaults[6])
-    use_scale_dis = BoolProperty(name = "Scale displace textures",
-                                description = "Scale displacement textures with dimensions.  May cause streched textures.",
-                                default = defaults[7])
-    scale_fac = FloatVectorProperty(name = "Scaling Factor",
-                                    description = "XYZ scaling factor.  1 = no scaling.",
-                                    min = 0.0001, max = 256.0, step = 0.1,
-                                    default = defaults[8], size = 3)
-
-    # @todo Possible to title this section "Physical Properties:"?
-    deform = FloatProperty(name = "Deformation",
-                           description = "Rock deformation",
-                           min = 0.0, max = 1024.0, default = defaults[9])
-    rough = FloatProperty(name = "Roughness",
-                          description = "Rock roughness",
-                          min = 0.0, max = 1024.0, default = defaults[10])
-    detail = IntProperty(name = "Detail level",
-                         description = "Detail level.  WARNING: Slow at high values!",
-                         min = 1, max = 1024, default = defaults[11])
-    display_detail = IntProperty(name = "Display Detail",
-                                 description = "Display detail.  Use a lower value for high numbers of rocks.",
-                                 min = 1, max = 128, default = defaults[12])
-    smooth_fac = FloatProperty(name = "Smooth Factor",
-                               description = "Smoothing factor.  A value of 0 disables.",
-                               min = 0.0, max = 128.0, default = defaults[13])
-    smooth_it = IntProperty(name = "Smooth Iterations",
-                            description = "Smoothing iterations.  A value of 0 disables.",
-                            min = 0, max = 128, default = defaults[14])
-
-    # @todo Add material properties
-    mat_enable = BoolProperty(name = "Generate materials",
-                              description = "Generate materials and textures for the rocks",
-                              default = defaults[15])
-    mat_color = FloatVectorProperty(name = "Color",
-                                    description = "Base color settings (RGB)",
-                                    min = 0.0, max = 1.0, default = defaults[16], size = 3, subtype = 'COLOR')
-    mat_bright = FloatProperty(name = "Brightness",
-                               description = "Material brightness",
-                               min = 0.0, max = 1.0, default = defaults[17])
-    mat_rough = FloatProperty(name = "Roughness",
-                              description = "Material roughness",
-                              min = 0.0, max = 5.0, default = defaults[18])
-    mat_spec = FloatProperty(name = "Shine",
-                             description = "Material specularity strength",
-                             min = 0.0, max = 1.0, default = defaults[19])
-    mat_hard = IntProperty(name = "Hardness",
-                           description = "Material hardness",
-                           min = 0, max = 511, default = defaults[20])
-    mat_use_trans = BoolProperty(name = "Use Transparency",
-                                 description = "Enables transparency in rocks (WARNING: SLOW RENDER TIMES)",
-                                 default = defaults[21])
-    mat_alpha = FloatProperty(name = "Alpha",
-                              description = "Transparency of the rocks",
-                              min = 0.0, max = 1.0, default = defaults[22])
-    mat_cloudy = FloatProperty(name = "Cloudy",
-                               description = "How cloudy the transparent rocks look",
-                               min = 0.0, max = 1.0, default = defaults[23])
-    mat_IOR = FloatProperty(name = "IoR",
-                            description = "Index of Refraction",
-                            min = 0.25, max = 4.0, soft_max = 2.5,
-                            default = defaults[24])
-    mat_mossy = FloatProperty(name = "Mossiness",
-                              description = "Amount of mossiness on the rocks",
-                              min = 0.0, max = 1.0, default = defaults[25])
-
-    use_generate = BoolProperty(name = "Generate Rocks",
-                                description = "Enable actual generation.",
-                                default = defaults[26])
-    use_random_seed = BoolProperty(name = "Use a random seed",
-                                  description = "Create a seed based on time. Causes user seed to be ignored.",
-                                  default = defaults[27])
-    user_seed = IntProperty(name = "User seed",
-                            description = "Use a specific seed for the generator.",
-                            min = 0, max = 1048576, default = defaults[28])
-
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        box.prop(self, 'num_of_rocks')
-        box = layout.box()
-        box.prop(self, 'scale_X')
-        box.prop(self, 'skew_X')
-        box.prop(self, 'scale_Y')
-        box.prop(self, 'skew_Y')
-        box.prop(self, 'scale_Z')
-        box.prop(self, 'skew_Z')
-        box.prop(self, 'use_scale_dis')
-        if self.use_scale_dis:
-            box.prop(self, 'scale_fac')
-        else:
-            self.scale_fac = utils.toFloats(self.defaults[8])
-        box = layout.box()
-        box.prop(self, 'deform')
-        box.prop(self, 'rough')
-        box.prop(self, 'detail')
-        box.prop(self, 'display_detail')
-        box.prop(self, 'smooth_fac')
-        box.prop(self, 'smooth_it')
-        box = layout.box()
-        box.prop(self, 'mat_enable')
-        if self.mat_enable:
-            box.prop(self, 'mat_color')
-            box.prop(self, 'mat_bright')
-            box.prop(self, 'mat_rough')
-            box.prop(self, 'mat_spec')
-            box.prop(self, 'mat_hard')
-            box.prop(self, 'mat_use_trans')
-            if self.mat_use_trans:
-                box.prop(self, 'mat_alpha')
-                box.prop(self, 'mat_cloudy')
-                box.prop(self, 'mat_IOR')
-            box.prop(self, 'mat_mossy')
-        box = layout.box()
-        box.prop(self, 'use_generate')
-        box.prop(self, 'use_random_seed')
-        if not self.use_random_seed:
-            box.prop(self, 'user_seed')
-        box.prop(self, 'preset_values')
-
-
-    def execute(self, context):
-        # The following "if" block loads preset values:
-        if self.lastPreset != int(self.preset_values):
-            self.scale_X = utils.toFloats(self.presetsList[int(self.preset_values)][1])
-            self.scale_Y = utils.toFloats(self.presetsList[int(self.preset_values)][2])
-            self.scale_Z = utils.toFloats(self.presetsList[int(self.preset_values)][3])
-            self.skew_X = float(self.presetsList[int(self.preset_values)][4])
-            self.skew_Y = float(self.presetsList[int(self.preset_values)][5])
-            self.skew_Z = float(self.presetsList[int(self.preset_values)][6])
-            self.use_scale_dis = bool(self.presetsList[int(self.preset_values)][7])
-            self.scale_fac = utils.toFloats(self.presetsList[int(self.preset_values)][8])
-            self.deform = float(self.presetsList[int(self.preset_values)][9])
-            self.rough = float(self.presetsList[int(self.preset_values)][10])
-            self.detail = int(self.presetsList[int(self.preset_values)][11])
-            self.display_detail = int(self.presetsList[int(self.preset_values)][12])
-            self.smooth_fac = float(self.presetsList[int(self.preset_values)][13])
-            self.smooth_it = int(self.presetsList[int(self.preset_values)][14])
-            self.mat_enable = bool(self.presetsList[int(self.preset_values)][15])
-            self.mat_color = utils.toFloats(self.presetsList[int(self.preset_values)][16])
-            self.mat_bright = float(self.presetsList[int(self.preset_values)][17])
-            self.mat_rough = float(self.presetsList[int(self.preset_values)][18])
-            self.mat_spec = float(self.presetsList[int(self.preset_values)][19])
-            self.mat_hard = int(self.presetsList[int(self.preset_values)][20])
-            self.mat_use_trans = bool(self.presetsList[int(self.preset_values)][21])
-            self.mat_alpha = float(self.presetsList[int(self.preset_values)][22])
-            self.mat_cloudy = float(self.presetsList[int(self.preset_values)][23])
-            self.mat_IOR = float(self.presetsList[int(self.preset_values)][24])
-            self.mat_mossy = float(self.presetsList[int(self.preset_values)][25])
-            self.use_generate = bool(self.presetsList[int(self.preset_values)][26])
-            self.use_random_seed = bool(self.presetsList[int(self.preset_values)][27])
-            self.user_seed = int(self.presetsList[int(self.preset_values)][28])
-            self.lastPreset = int(self.preset_values)
-
-        # todo Add deform, deform_Var, rough, and rough_Var:
-        #   *** todo completed 4/23/2011 ***
-        #   *** Eliminated "deform_Var" and "rough_Var" so the script is not
-        #       as complex to use.  May add in again as advanced features. ***
-        if self.use_generate:
-            generateRocks(context,
-                          self.scale_X,
-                          self.skew_X,
-                          self.scale_Y,
-                          self.skew_Y,
-                          self.scale_Z,
-                          self.skew_Z,
-                          self.scale_fac,
-                          self.detail,
-                          self.display_detail,
-                          self.deform,
-                          self.rough,
-                          self.smooth_fac,
-                          self.smooth_it,
-                          self.mat_enable,
-                          self.mat_color,
-                          self.mat_bright,
-                          self.mat_rough,
-                          self.mat_spec,
-                          self.mat_hard,
-                          self.mat_use_trans,
-                          self.mat_alpha,
-                          self.mat_cloudy,
-                          self.mat_IOR,
-                          self.mat_mossy,
-                          self.num_of_rocks,
-                          self.user_seed,
-                          self.use_scale_dis,
-                          self.use_random_seed)
-
-        return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/settings.py b/release/scripts/addons_contrib/add_mesh_rocks/settings.py
deleted file mode 100644
index 647a62d..0000000
--- a/release/scripts/addons_contrib/add_mesh_rocks/settings.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# Paul "BrikBot" Marshall
-# Created: July 1, 2011
-# Last Modified: November 17, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas
-#   and testing.
-#
-# Coded in IDLE, tested in Blender 2.59.  NumPy Recommended.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  The Blender Rock Creation tool is for rapid generation of
-#  mesh rocks in Blender.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-import inspect
-import shutil
-from add_mesh_rocks import utils
-from xml.dom import minidom
-
-basePath = inspect.getfile(inspect.currentframe())[0:-len("settings.py")]
-path = basePath + "add_mesh_rocks.xml"
-
-try:
-    source = minidom.parse(path)
-    print("Rock generator settings file found:\n" + path)
-except:
-    print("Rock generator settings file not found.  Creating settings file.")
-    shutil.copy(basePath + "factory.xml", path)
-    source = minidom.parse(path)
-
-xmlDefault = source.getElementsByTagName('default')[0]
-xmlPresets = source.getElementsByTagName('preset')
-default = []
-presets = []
-
-#----- Gets and Sets -----#
-
-
-def getDefault():
-    global default
-    return default
-
-
-def getPresetLists():
-    global presets
-    return presets
-
-
-def getPreset(ID=0):
-    global presets
-    return presets[ID]
-
-#---------- Core ----------#
-
-
-def parse():
-    global xmlDefault
-    global xmlPresets
-    global default
-    global presets
-
-    # Parse default values
-    default = parseNode(xmlDefault)
-
-    # Parse preset values
-    for setting in xmlPresets:
-        presets.append(parseNode(setting))
-
-    return '{FINISHED}'
-
-
-# Takes a node and parses it for data.  Relies on that setting.xml has
-#   a valid format as specified by the DTD.
-# For some reason minidom places an empty child node for every other node.
-def parseNode(setting, title=True):
-    loc = 1
-
-    if title:
-        # Preset name (xmlPreset.childNodes[1]):
-        title = setting.childNodes[loc].childNodes[0].data
-        loc += 2
-
-    # Preset size values (xmlPreset.childNodes[3]):
-    scaleX = [float(setting.childNodes[loc].childNodes[1].childNodes[3].childNodes[0].data),
-              float(setting.childNodes[loc].childNodes[1].childNodes[5].childNodes[0].data)]
-    scaleY = [float(setting.childNodes[loc].childNodes[3].childNodes[3].childNodes[0].data),
-              float(setting.childNodes[loc].childNodes[3].childNodes[5].childNodes[0].data)]
-    scaleZ = [float(setting.childNodes[loc].childNodes[5].childNodes[3].childNodes[0].data),
-              float(setting.childNodes[loc].childNodes[5].childNodes[5].childNodes[0].data)]
-    skewX = float(setting.childNodes[loc].childNodes[7].childNodes[3].childNodes[0].data)
-    skewY = float(setting.childNodes[loc].childNodes[9].childNodes[3].childNodes[0].data)
-    skewZ = float(setting.childNodes[loc].childNodes[11].childNodes[3].childNodes[0].data)
-    if setting.childNodes[loc].childNodes[13].childNodes[0].data == 'False':
-        use_scale_dis = False
-    else:
-        use_scale_dis = True
-    scale_fac = utils.toList(setting.childNodes[loc].childNodes[15].childNodes[0].data)
-    loc += 2
-
-    # Presst shape values (xmlPreset.childNodes[5]):
-    deform = float(setting.childNodes[loc].childNodes[1].childNodes[0].data)
-    rough = float(setting.childNodes[loc].childNodes[3].childNodes[0].data)
-    detail = int(setting.childNodes[loc].childNodes[5].childNodes[0].data)
-    display_detail = int(setting.childNodes[loc].childNodes[7].childNodes[0].data)
-    smooth_fac = float(setting.childNodes[loc].childNodes[9].childNodes[0].data)
-    smooth_it = int(setting.childNodes[loc].childNodes[11].childNodes[0].data)
-    loc += 2
-
-    # Preset material values (xmlPreset.childNodes[7]):
-    if setting.childNodes[loc].childNodes[1].childNodes[0].data == 'False':
-        mat_enable = False
-    else:
-        mat_enable = True
-    mat_color = utils.toList(setting.childNodes[loc].childNodes[3].childNodes[0].data)
-    mat_bright = float(setting.childNodes[loc].childNodes[5].childNodes[0].data)
-    mat_rough = float(setting.childNodes[loc].childNodes[7].childNodes[0].data)
-    mat_spec = float(setting.childNodes[loc].childNodes[9].childNodes[0].data)
-    mat_hard = int(setting.childNodes[loc].childNodes[11].childNodes[0].data)
-    mat_use_trans = bool(setting.childNodes[loc].childNodes[13].childNodes[0].data)
-    mat_alpha = float(setting.childNodes[loc].childNodes[15].childNodes[0].data)
-    mat_cloudy = float(setting.childNodes[loc].childNodes[17].childNodes[0].data)
-    mat_IOR = float(setting.childNodes[loc].childNodes[19].childNodes[0].data)
-    #mat_use_mirror = float(setting.childNodes[loc].childNodes[21].childNodes[0].data)
-    #mat_mossy = float(setting.childNodes[loc].childNodes[23].childNodes[0].data)
-    #mat_mossy = float(setting.childNodes[loc].childNodes[25].childNodes[0].data)
-    mat_mossy = float(setting.childNodes[loc].childNodes[21].childNodes[0].data)
-    loc += 2
-
-    # Preset random values (xmlPreset.childNodes[9]):
-    if setting.childNodes[loc].childNodes[1].childNodes[0].data == 'True':
-        use_generate = True
-    else:
-        use_generate = False
-    if setting.childNodes[loc].childNodes[3].childNodes[0].data == 'False':
-        use_random_seed = False
-    else:
-        use_random_seed = True
-    user_seed = int(setting.childNodes[loc].childNodes[5].childNodes[0].data)
-
-    if title:
-        parsed = [title, scaleX, scaleY, scaleZ, skewX, skewY, skewZ,
-                  use_scale_dis, scale_fac, deform, rough, detail,
-                  display_detail, smooth_fac, smooth_it, mat_enable, mat_color,
-                  mat_bright, mat_rough, mat_spec, mat_hard, mat_use_trans,
-                  mat_alpha, mat_cloudy, mat_IOR, mat_mossy, use_generate,
-                  use_random_seed, user_seed]
-    else:
-        parsed = [scaleX, scaleY, scaleZ, skewX, skewY, skewZ, use_scale_dis,
-                  scale_fac, deform, rough, detail, display_detail, smooth_fac,
-                  smooth_it, mat_enable, mat_color, mat_bright, mat_rough,
-                  mat_spec, mat_hard, mat_use_trans, mat_alpha, mat_cloudy,
-                  mat_IOR, mat_mossy, use_generate, use_random_seed, user_seed]
-
-    return parsed
-
-
-def save():
-    return '{FINISHED}'
-
-
-def _print():
-    for i in presets:
-        print(i)
-    return '{FINISHED}'
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/utils.py b/release/scripts/addons_contrib/add_mesh_rocks/utils.py
deleted file mode 100644
index 94acaf7..0000000
--- a/release/scripts/addons_contrib/add_mesh_rocks/utils.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  The Blender Rock Creation tool is for rapid generation of mesh rocks.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-
-# Converts a formated string to a float tuple:
-#   IN - '(0.5, 0.2)' -> CONVERT -> OUT - (0.5, 0.2)
-def toTuple(stringIn):
-    sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ')
-    fTemp = []
-    for i in sTemp:
-        fTemp.append(float(i))
-    return tuple(fTemp)
-
-
-# Converts a formated string to a float tuple:
-#   IN - '[0.5, 0.2]' -> CONVERT -> OUT - [0.5, 0.2]
-def toList(stringIn):
-    sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ')
-    fTemp = []
-    for i in sTemp:
-        fTemp.append(float(i))
-    return fTemp
-
-
-# Converts each item of a list into a float:
-def toFloats(inList):
-    outList = []
-    for i in inList:
-        outList.append(float(i))
-    return outList
-
-
-# Converts each item of a list into an integer:
-def toInts(inList):
-    outList = []
-    for i in inList:
-        outList.append(int(i))
-    return outList
-
-
-# Sets all faces smooth.  Done this way since I can't
-# find a simple way without using bpy.ops:
-def smooth(mesh):
-    import bmesh
-    bm = bmesh.new()
-    bm.from_mesh(mesh)
-    for f in bm.faces:
-        f.smooth = True
-    bm.to_mesh(mesh)
-    return mesh
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/__init__.py b/release/scripts/addons_contrib/add_mesh_stairs/__init__.py
deleted file mode 100644
index 0f29567..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/__init__.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Paul "BrikBot" Marshall
-# Created: July 24, 2011
-# Last Modified: November 20, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.59.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  The Blender Rock Creation tool is for rapid generation of mesh rocks in Blender.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "StairBuilder",
-    "author": "Nick van Adium",
-    "version": (1,1),
-    "blender": (2, 6, 1),
-    "location": "View3D > Add > Stairs",
-    "description": "Creates a straight-run staircase with railings and stringer",
-    "warning": "Add-on is very feature incomplete beyond basic functionality.",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Add Mesh"}
-
-if "bpy" in locals():
-    import imp
-    imp.reload(stairbuilder)
-else:
-    from add_mesh_stairs import stairbuilder
-
-import bpy
-
-# Register:
-
-def menu_func_stairs(self, context):
-    self.layout.operator(stairbuilder.stairs.bl_idname, text="StairBuilder", icon = "PLUGIN")
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_mesh_add.append(menu_func_stairs)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_mesh_add.remove(menu_func_stairs)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/general.py b/release/scripts/addons_contrib/add_mesh_stairs/general.py
deleted file mode 100644
index 4012735..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/general.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Stairbuilder - General
-#
-# General is an object for creating meshes given the verts and faces.
-#   Stair Type (typ):
-#       - id1 = Freestanding staircase
-#       - id2 = Housed-open staircase
-#       - id3 = Box staircase
-#       - id4 = Circular staircase
-# 
-# Paul "BrikBot" Marshall
-# Created: September 19, 2011
-# Last Modified: January 29, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.61.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-import bpy
-from bpy_extras import object_utils
-from math import atan
-from mathutils import Vector
-
-class General:
-    def __init__(self,rise,run,N):
-        self.stop=float(N)*Vector([run,0,rise])
-        self.slope=rise/run
-        self.angle=atan(self.slope)
-        #identical quads for all objects except stringer
-        self.faces=[[0,1,3,2],[0,1,5,4],[0,2,6,4],[4,5,7,6],[2,3,7,6],[1,3,7,5]]
-
-    def Make_mesh(self, verts, faces, name):        
-        # Create new mesh
-        mesh = bpy.data.meshes.new(name)
-
-        # Make a mesh from a list of verts/edges/faces.
-        mesh.from_pydata(verts, [], faces)
-
-        # Set mesh to use auto smoothing:
-        mesh.use_auto_smooth = True
-
-        # Update mesh geometry after adding stuff.
-        mesh.update()
-
-        return object_utils.object_data_add(bpy.context, mesh, operator=None)
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/post.py b/release/scripts/addons_contrib/add_mesh_stairs/post.py
deleted file mode 100644
index 62f56a8..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/post.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Stairbuilder - Post generation
-#
-# Generates posts for stair generation.
-#   Stair Type (typ):
-#       - id1 = Freestanding staircase
-#       - id2 = Housed-open staircase
-#       - id3 = Box staircase
-#       - id4 = Circular staircase
-# 
-# Paul "BrikBot" Marshall
-# Created: September 19, 2011
-# Last Modified: January 29, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.61.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-from mathutils import Vector
-
-class Posts:
-    def __init__(self,G,rise,run,d,w,wT,nP,hR,tR, rEnable, lEnable):
-        self.G = G #General
-        self.rise = rise #Stair rise
-        self.run = run #Stair run
-        self.x1=Vector([0,0,hR-tR]) #rail start
-        self.x2=G.stop+Vector([0,0,hR-tR]) #rail stop
-        self.d=d #post depth
-        self.w=w #post width
-        self.wT=wT #tread width
-        self.nP=nP #number of posts 
-        self.sp=Vector([(self.x2[0]-self.x1[0])/float(nP+1),0,0]) #spacing between posts
-        self.rEnable = rEnable
-        self.lEnable = lEnable
-        self.Create()
-
-    def Intersect(self,i,d):
-        '''find intersection point, x, for rail and post'''
-        x3=self.x1+i*self.sp+Vector([d,d,d])
-        x4=x3+Vector([0,0,self.x2[-1]])
-        a=self.x2-self.x1
-        b=x4-x3
-        c=x3-self.x1
-        cr_ab=a.cross(b)
-        mag_cr_ab=(cr_ab * cr_ab)
-        return self.x1+a*((c.cross(b).dot(cr_ab))/mag_cr_ab)
-
-    def Create(self):
-        for i in range(0,self.nP+2,1):
-            coords = []
-            #intersections with rail
-            coords.append(self.Intersect(i,0.0))
-            coords.append(self.Intersect(i,self.d))
-            #intersections with tread
-            coords.append(Vector([self.x1[0]+i*self.sp[0],0,
-                                  int(coords[0][0]/self.run)*self.rise]))
-            coords.append(coords[2]+Vector([self.d,0,0]))
-            #inner face
-            for j in range(4):
-                coords.append(coords[j]+Vector([0,self.w,0]))
-            if self.rEnable:
-                self.G.Make_mesh(coords, self.G.faces, 'posts')
-            if self.lEnable:
-                #make post on other side of steps as well
-                for j in coords:
-                    j += Vector([0,self.wT-self.w,0])
-                self.G.Make_mesh(coords, self.G.faces, 'posts')
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/rail.py b/release/scripts/addons_contrib/add_mesh_stairs/rail.py
deleted file mode 100644
index 85c31dd..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/rail.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Stairbuilder - Retainer generation
-#
-# Generates retainers for stair generation.
-#   Stair Type (typ):
-#       - id1 = Freestanding staircase
-#       - id2 = Housed-open staircase
-#       - id3 = Box staircase
-#       - id4 = Circular staircase
-# 
-# Paul "BrikBot" Marshall
-# Created: September 19, 2011
-# Last Modified: January 29, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.61.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-from math import tan
-from mathutils import Vector
-
-class Rails:
-    def __init__(self,G,w,t,h,tT,wP,dP,wT, rEnable, lEnable):
-        self.G = G #General
-        self.w=w #rail width
-        self.t=t #rail thickness
-        self.h=h #rail height
-        self.start=Vector([0,0,self.h-self.t]) #rail start
-        self.stop=G.stop+Vector([0,0,self.h-self.t]) #rail stop
-        self.tT=tT #tread toe
-        self.wP=wP #post width
-        self.dP=dP #post depth
-        self.wT=wT #tread width
-        self.rEnable = rEnable
-        self.lEnable = lEnable
-        self.Create()
-
-    def Create(self):
-        #determine offset to include railing toe
-        offset=Vector([self.tT,0,self.tT*tan(self.G.angle)])
-        coords = []
-        coords.append(self.start-offset)
-        coords.append(self.stop+offset+Vector([self.dP,0,
-                                               self.dP*tan(self.G.angle)]))
-        coords.append(self.start-offset+Vector([0,self.w,0]))
-        coords.append(self.stop+offset+Vector([self.dP,self.w,
-                                               self.dP*tan(self.G.angle)]))
-        for j in range(4):
-            coords.append(coords[j]+Vector([0,0,self.t]))
-        #centre over posts
-        for j in coords:
-            j += Vector([0,0.5*(-self.w+self.wP),0])
-        if self.rEnable:
-            self.G.Make_mesh(coords, self.G.faces, 'rails')
-        if self.lEnable:
-            #make rail on other side
-            for j in coords:
-                j += Vector([0,self.wT-self.wP,0])
-            self.G.Make_mesh(coords, self.G.faces, 'rails')
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/retainer.py b/release/scripts/addons_contrib/add_mesh_stairs/retainer.py
deleted file mode 100644
index 8c8a22c..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/retainer.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Stairbuilder - Retainer generation
-#
-# Generates retainers for stair generation.
-#   Stair Type (typ):
-#       - id1 = Freestanding staircase
-#       - id2 = Housed-open staircase
-#       - id3 = Box staircase
-#       - id4 = Circular staircase
-# 
-# Paul "BrikBot" Marshall
-# Created: September 19, 2011
-# Last Modified: January 29, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.61.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-from mathutils import Vector
-
-class Retainers:
-    def __init__(self,G,w,h,wP,wT,hR,n, rEnable, lEnable):
-        self.G = G #General
-        self.w=w #retainer width
-        self.h=h #retainer height
-        self.wP=wP #post width
-        self.wT=wT #tread width
-        self.nR=n #number of retainers
-        self.sp=hR/float(n+1) #retainer spacing
-        self.rEnable = rEnable
-        self.lEnable = lEnable
-        self.Create()
-
-    def Create(self):
-        for i in range(self.nR):
-            coords = []
-            offset=(i+1)*Vector([0,0,self.sp])
-            coords.append(offset)
-            coords.append(self.G.stop + offset)
-            coords.append(offset + Vector([0,self.w,0]))
-            coords.append(self.G.stop + offset + Vector([0,self.w,0]))
-            for j in range(4):
-                coords.append(coords[j] + Vector([0,0,self.h]))
-            #centre in posts
-            for j in coords:
-                j += Vector([0,0.5*(self.wP-self.w),0])
-            if self.rEnable:
-                self.G.Make_mesh(coords, self.G.faces, 'retainers')
-            if self.lEnable:
-                #make retainer on other side
-                for j in coords:
-                    j += Vector([0,self.wT-self.wP,0])
-                self.G.Make_mesh(coords,self.G.faces, 'retainers')
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py b/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py
deleted file mode 100644
index 0ab252c..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/stairbuilder.py
+++ /dev/null
@@ -1,561 +0,0 @@
-# Stairs and railing creator script for blender 2.49
-# Author: Nick van Adium
-# Date: 2010 08 09
-# 
-# Creates a straight-run staircase with railings and stringer
-# All components are optional and can be turned on and off by setting e.g. makeTreads=True or makeTreads=False
-# No GUI for the script, all parameters must be defined below
-# Current values assume 1 blender unit = 1 metre
-# 
-# Stringer will rest on lower landing and hang from upper landing
-# Railings start on the lowest step and end on the upper landing
-# 
-# NOTE: You must have numpy installed for this script to work!
-#       numpy is used to easily perform the necessary algebra
-#       numpy can be found at http://www.scipy.org/Download
-# 
-# Note: I'm not sure how to use recalcNormals so not all normals points ouwards.
-#       Perhaps someone else can contribute this.
-#
-#-----------------------------------------------------------
-#
-# Converted to Blender 2.5:
-#   - Still uses NumPy.
-#   - Classes are basically copy-paste from the original code
-#   - New Make_mesh copied from BrikBot's rock generator
-#   - Implemented standard add mesh GUI.
-#   @todo:
-#   - global vs. local needs cleaned up.
-#   - Join separate stringer objects and then clean up the mesh.
-#   - Put all objects into a group.
-#   - Generate left/right posts/railings/retainers separatly with
-#       option to disable just the left/right.
-#   - Add wall railing type as an option for left/right
-#   - Add different rail styles (profiles).  Select with enum.
-#   - Should have a non-NumPy code path for cross-compatability.
-#       - Could be another file with equivalent classes/functions?
-#           Then we would just import from there instead of from
-#           NumPy without having to change the actual code.  It
-#           would instead be a "try-except" block that trys to use
-#           NumPy.
-#   - Would like to add additional staircase types.
-#       - Spiral staircase
-#       - "L" staircase
-#       - "T" staircase
-#
-# Last Modified By: Paul "brikbot" Marshall
-# Last Modification: January 29, 2011
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-#-----------------------------------------------------------
-# BEGIN NEW B2.5/Py3.2 CODE
-import bpy
-from add_mesh_stairs.general import General
-from add_mesh_stairs.post import Posts
-from add_mesh_stairs.rail import Rails
-from add_mesh_stairs.retainer import Retainers
-from add_mesh_stairs.stringer import Stringer
-from add_mesh_stairs.tread import Treads
-from bpy.props import (BoolProperty,
-                       EnumProperty,
-                       IntProperty,
-                       FloatProperty)
-from mathutils import Vector
-
-global G
-global typ
-global typ_s
-global typ_t
-global rise
-global run               
-            
-class stairs(bpy.types.Operator):
-    '''Add stair objects'''
-    bl_idname = "mesh.stairs"
-    bl_label = "Add Stairs"
-    bl_options = {'REGISTER', 'UNDO'}
-    bl_description = "Add stairs"
-
-    # Stair types for enum:
-    id1 = ("id1", "Freestanding", "Generate a freestanding staircase.")
-    id2 = ("id2", "Housed-Open", "Generate a housed-open staircase.")
-    id3 = ("id3", "Box", "Generate a box staircase.")
-    id4 = ("id4", "Circular", "Generate a circular or spiral staircase.")
-
-    # Tread types for enum:
-    tId1 = ("tId1", "Classic", "Generate wooden style treads")
-    tId2 = ("tId2", "Basic Steel", "Generate common steel style treads")
-    tId3 = ("tId3", "Bar 1", "Generate bar/slat steel treads")
-    tId4 = ("tId4", "Bar 2", "Generate bar-grating steel treads")
-    tId5 = ("tId5", "Bar 3", "Generate bar-support steel treads")
-
-    # Stringer types for enum:
-    sId1 = ("sId1", "Classic", "Generate a classic style stringer")
-    sId2 = ("sId2", "I-Beam", "Generate a steel I-beam stringer")
-    sId3 = ("sId3", "C-Beam", "Generate a C-channel style stringer")
-    
-    typ = EnumProperty(name = "Type",
-                       description = "Type of staircase to generate",
-                       items = [id1, id2, id3, id4])
-
-    rise = FloatProperty(name = "Rise",
-                         description = "Single tread rise",
-                         min = 0.0, max = 1024.0,
-                         default = 0.20)
-    run = FloatProperty(name = "Run",
-                        description = "Single tread run",
-                        min = 0.0, max = 1024.0,
-                        default = 0.30)
-
-    #for circular
-    rad1 = FloatProperty(name = "Inner Radius",
-                         description = "Inner radius for circular staircase",
-                         min = 0.0, max = 1024.0,
-                         soft_max = 10.0,
-                         default = 0.25)
-    rad2 = FloatProperty(name = "Outer Radius",
-                         description = "Outer radius for circular staircase",
-                         min = 0.0, max = 1024.0,
-                         soft_min = 0.015625, soft_max = 32.0,
-                         default = 1.0)
-    deg = FloatProperty(name = "Degrees",
-                        description = "Number of degrees the stairway rotates",
-                        min = 0.0, max = 92160.0, step = 5.0,
-                        default = 450.0)
-    center = BoolProperty(name = "Center Pillar",
-                          description = "Generate a central pillar",
-                          default = False)
-
-    #for treads
-    make_treads = BoolProperty(name = "Make Treads",
-                              description = "Enable tread generation",
-                              default = True)
-    tread_w = FloatProperty(name = "Tread Width",
-                            description = "Width of each generated tread",
-                            min = 0.0001, max = 1024.0,
-                            default = 1.2)
-    tread_h = FloatProperty(name = "Tread Height",
-                            description = "Height of each generated tread",
-                            min = 0.0001, max = 1024.0,
-                            default = 0.04)
-    tread_t = FloatProperty(name = "Tread Toe",
-                            description = "Toe (aka \"nosing\") of each generated tread",
-                            min = 0.0, max = 10.0,
-                            default = 0.03)
-    tread_o = FloatProperty(name = "Tread Overhang",
-                            description = "How much tread \"overhangs\" the sides",
-                            min = 0.0, max = 1024.0,
-                            default = 0.025)
-    tread_n = IntProperty(name = "Number of Treads",
-                          description = "How many treads to generate",
-                          min = 1, max = 1024,
-                          default = 10)
-    typ_t = EnumProperty(name = "Tread Type",
-                         description = "Type/style of treads to generate",
-                         items = [tId1, tId2, tId3, tId4, tId5])
-    tread_tk = FloatProperty(name = "Thickness",
-                             description = "Thickness of the treads",
-                             min = 0.0001, max = 10.0,
-                             default = 0.02)
-    tread_sec = IntProperty(name = "Sections",
-                            description = "Number of sections to use for tread",
-                            min = 1, max = 1024,
-                            default = 5)
-    tread_sp = IntProperty(name = "Spacing",
-                           description = "Total spacing between tread sections as a percentage of total tread width",
-                           min = 0, max = 80,
-                           default = 5)
-    tread_sn = IntProperty(name = "Crosses",
-                           description = "Number of cross section supports",
-                           min = 2, max = 1024,
-                           default = 4)
-    #special circular tread properties:
-    tread_slc = IntProperty(name = "Slices",
-                            description = "Number of slices each tread is composed of",
-                            min = 1, max = 1024,
-                            soft_max = 16,
-                            default = 4)
-
-    #for posts
-    make_posts = BoolProperty(name = "Make Posts",
-                              description = "Enable post generation",
-                              default = True)
-    post_d = FloatProperty(name = "Post Depth",
-                           description = "Depth of generated posts",
-                           min = 0.0001, max = 10.0,
-                           default = 0.04)
-    post_w = FloatProperty(name = "Post Width",
-                           description = "Width of generated posts",
-                           min = 0.0001, max = 10.0,
-                           default = 0.04)
-    post_n = IntProperty(name = "Number of Posts",
-                         description = "Number of posts to generated",
-                         min = 1, max = 1024,
-                         default = 5)
-
-    #for railings
-    make_railings = BoolProperty(name = "Make Railings",
-                                 description = "Generate railings",
-                                 default = True)
-    rail_w = FloatProperty(name = "Railings Width",
-                           description = "Width of railings to generate",
-                           min = 0.0001, max = 10.0,
-                           default = 0.12)
-    rail_t = FloatProperty(name = "Railings Thickness",
-                           description = "Thickness of railings to generate",
-                           min = 0.0001, max = 10.0,
-                           default = 0.03)
-    rail_h = FloatProperty(name = "Railings Height",
-                           description = "Height of railings to generate",
-                           min = 0.0001, max = 10.0,
-                           default = 0.90)
-
-    #for retainers
-    make_retainers = BoolProperty(name = "Make Retainers",
-                                  description = "Generate retainers",
-                                  default = True)
-    ret_w = FloatProperty(name = "Retainer Width",
-                          description = "Width of generated retainers",
-                          min = 0.0001, max = 10.0,
-                          default = 0.01)
-    ret_h = FloatProperty(name = "Retainer Height",
-                          description = "Height of generated retainers",
-                          min = 0.0001, max = 10.0,
-                          default = 0.01)
-    ret_n = IntProperty(name = "Number of Retainers",
-                        description = "Number of retainers to generated",
-                        min = 1, max = 1024,
-                        default = 3)
-
-    #for stringer
-    make_stringer = BoolProperty(name = "Make Stringer",
-                                 description = "Generate stair stringer",
-                                 default = True)
-    typ_s = EnumProperty(name = "Stringer Type",
-                         description = "Type/style of stringer to generate",
-                         items = [sId1, sId2, sId3])
-    string_n = IntProperty(name = "Number of Stringers",
-                           description = "Number of stringers to generate",
-                           min = 1, max = 10,
-                           default = 1)
-    string_dis = BoolProperty(name = "Distributed",
-                              description = "Use distributed stringers",
-                              default = False)
-    string_w = FloatProperty(name = "Stringer width",
-                             description = "Width of stringer as a percentage of tread width",
-                             min = 0.0001, max = 100.0,
-                             default = 15.0)
-    string_h = FloatProperty(name = "Stringer Height",
-                             description = "Height of the stringer",
-                             min = 0.0001, max = 100.0,
-                             default = 0.3)
-    string_tw = FloatProperty(name = "Web Thickness",
-                              description = "Thickness of the beam's web as a percentage of width",
-                              min = 0.0001, max = 100.0,
-                              default = 25.0)
-    string_tf = FloatProperty(name = "Flange Thickness",
-                              description = "Thickness of the flange",
-                              min = 0.0001, max = 100.0,
-                              default = 0.05)
-    string_tp = FloatProperty(name = "Flange Taper",
-                              description = "Flange thickness taper as a percentage",
-                              min = 0.0, max = 100.0,
-                              default = 0.0)
-    string_g = BoolProperty(name = "Floating",
-                            description = "Cut bottom of strigner to be a \"floating\" section",
-                            default = False)
-
-    use_original = BoolProperty(name = "Use legacy method",
-                                description = "Use the Blender 2.49 legacy method for stair generation",
-                                default = True)
-    rEnable = BoolProperty(name = "Right Details",
-                           description = "Generate right side details (posts/rails/retainers)",
-                           default = True)
-    lEnable = BoolProperty(name = "Left Details",
-                           description = "Generate left side details (posts/rails/retainers)",
-                           default = True)
-
-    # Draw the GUI:
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        box.prop(self, 'typ')
-        box = layout.box()
-        box.prop(self, 'rise')
-        if self.typ != "id4":
-            box.prop(self, 'run')
-        else:
-            box.prop(self, 'deg')
-            box.prop(self, 'rad1')
-            box.prop(self, 'rad2')
-            box.prop(self, 'center')
-        if self.typ == "id1":
-            box.prop(self, 'use_original')
-            if not self.use_original:
-                box.prop(self, 'rEnable')
-                box.prop(self, 'lEnable')
-        else:
-            self.use_original = False
-            box.prop(self, 'rEnable')
-            box.prop(self, 'lEnable')
-            
-        # Treads
-        box = layout.box()
-        box.prop(self, 'make_treads')
-        if self.make_treads:
-            if not self.use_original and self.typ != "id4":
-                box.prop(self, 'typ_t')
-            else:
-                self.typ_t = "tId1"
-            if self.typ != "id4":
-                box.prop(self, 'tread_w')
-            box.prop(self, 'tread_h')
-            box.prop(self, 'tread_t')
-            if self.typ not in ["id2", "id4"]:
-                box.prop(self, 'tread_o')
-            else:
-                self.tread_o = 0.0
-            box.prop(self, 'tread_n')
-            if self.typ_t != "tId1":
-                box.prop(self, 'tread_tk')
-                box.prop(self, 'tread_sec')
-                if self.tread_sec > 1 and self.typ_t not in ["tId3", "tId4"]:
-                    box.prop(self, 'tread_sp')
-                if self.typ_t in ["tId3", "tId4", "tId5"]:
-                    box.prop(self, 'tread_sn')
-            elif self.typ == "id4":
-                box.prop(self, "tread_slc")
-                    
-        # Posts
-        box = layout.box()
-        box.prop(self, 'make_posts')
-        if self.make_posts:
-            box.prop(self, 'post_d')
-            box.prop(self, 'post_w')
-            box.prop(self, 'post_n')
-            
-        # Railings
-        box = layout.box()
-        box.prop(self, 'make_railings')
-        if self.make_railings:
-            box.prop(self, 'rail_w')
-            box.prop(self, 'rail_t')
-            box.prop(self, 'rail_h')
-            
-        # Retainers
-        box = layout.box()
-        box.prop(self, 'make_retainers')
-        if self.make_retainers:
-            box.prop(self, 'ret_w')
-            box.prop(self, 'ret_h')
-            box.prop(self, 'ret_n')
-            
-        # Stringers
-        box = layout.box()
-        if self.typ != "id2":
-            box.prop(self, 'make_stringer')
-        else:
-            self.make_stringer = True
-        if self.make_stringer:
-            if not self.use_original:
-                box.prop(self, 'typ_s')
-            else:
-                self.typ_s = "sId1"
-            box.prop(self, 'string_w')
-            if self.typ == "id1":
-                if self.typ_s == "sId1" and not self.use_original:
-                    box.prop(self, 'string_n')
-                    box.prop(self, 'string_dis')
-                elif self.typ_s in ["sId2", "sId3"]:
-                    box.prop(self, 'string_n')
-                    box.prop(self, 'string_dis')
-                    box.prop(self, 'string_h')
-                    box.prop(self, 'string_tw')
-                    box.prop(self, 'string_tf')
-                    box.prop(self, 'string_tp')
-                    box.prop(self, 'string_g')
-            elif self.typ == "id2":
-                if self.typ_s in ["sId2", "sId3"]:
-                    box.prop(self, 'string_tw')
-                    box.prop(self, 'string_tf')
-
-        # Tread support:
-##        if self.make_stringer and typ_s in ["sId2", "sId3"]:
-
-    def execute(self, context):
-        global G
-        global typ
-        global typ_s
-        global typ_t
-        global rise
-        global run
-        typ = self.typ
-        typ_s = self.typ_s
-        typ_t = self.typ_t
-        rise = self.rise
-        run = self.run
-        G=General(rise,run,self.tread_n)
-        if self.make_treads:
-            if typ != "id4":
-                Treads(G,
-                       typ,
-                       typ_t,
-                       run,
-                       self.tread_w,
-                       self.tread_h,
-                       self.run,
-                       self.rise,
-                       self.tread_t,
-                       self.tread_o,
-                       self.tread_n,
-                       self.tread_tk,
-                       self.tread_sec,
-                       self.tread_sp,
-                       self.tread_sn)
-            else:
-                Treads(G,
-                       typ,
-                       typ_t,
-                       self.deg,
-                       self.rad2,
-                       self.tread_h,
-                       self.run,
-                       self.rise,
-                       self.tread_t,
-                       self.rad1,
-                       self.tread_n,
-                       self.tread_tk,
-                       self.tread_sec,
-                       self.tread_sp,
-                       self.tread_sn,
-                       self.tread_slc)
-        if self.make_posts and (self.rEnable or self.lEnable):
-            Posts(G,
-                  rise,
-                  run,
-                  self.post_d,
-                  self.post_w,
-                  self.tread_w,
-                  self.post_n,
-                  self.rail_h,
-                  self.rail_t,
-                  self.rEnable,
-                  self.lEnable)
-        if self.make_railings and (self.rEnable or self.lEnable):
-            Rails(G,
-                  self.rail_w,
-                  self.rail_t,
-                  self.rail_h,
-                  self.tread_t,
-                  self.post_w,
-                  self.post_d,
-                  self.tread_w,
-                  self.rEnable,
-                  self.lEnable)
-        if self.make_retainers and (self.rEnable or self.lEnable):
-            Retainers(G,
-                      self.ret_w,
-                      self.ret_h,
-                      self.post_w,
-                      self.tread_w,
-                      self.rail_h,
-                      self.ret_n,
-                      self.rEnable,
-                      self.lEnable)
-        if self.make_stringer:
-            if typ == "id1" and self.use_original:
-                Stringer(G,
-                         typ,
-                         typ_s,
-                         rise,
-                         run,
-                         self.string_w,
-                         self.string_h,
-                         self.tread_n,
-                         self.tread_h,
-                         self.tread_w,
-                         self.tread_t,
-                         self.tread_o,
-                         self.string_tw,
-                         self.string_tf,
-                         self.string_tp,
-                         not self.string_g)
-            elif typ == "id3":
-                Stringer(G,
-                         typ,
-                         typ_s,
-                         rise,
-                         run,
-                         100,
-                         self.string_h,
-                         self.tread_n,
-                         self.tread_h,
-                         self.tread_w,
-                         self.tread_t,
-                         self.tread_o,
-                         self.string_tw,
-                         self.string_tf,
-                         self.string_tp,
-                         not self.string_g,
-                         1, False, False)
-            elif typ == "id4":
-                Stringer(G,
-                         typ,
-                         typ_s,
-                         rise,
-                         self.deg,
-                         self.string_w,
-                         self.string_h,
-                         self.tread_n,
-                         self.tread_h,
-                         self.rad2 - self.rad1,
-                         self.tread_t,
-                         self.rad1,
-                         self.string_tw,
-                         self.string_tf,
-                         self.string_tp,
-                         not self.string_g,
-                         self.string_n,
-                         self.string_dis,
-                         self.use_original,
-                         self.tread_slc)
-            else:
-                Stringer(G,
-                         typ,
-                         typ_s,
-                         rise,
-                         run,
-                         self.string_w,
-                         self.string_h,
-                         self.tread_n,
-                         self.tread_h,
-                         self.tread_w,
-                         self.tread_t,
-                         self.tread_o,
-                         self.string_tw,
-                         self.string_tf,
-                         self.string_tp,
-                         not self.string_g,
-                         self.string_n,
-                         self.string_dis,
-                         self.use_original)
-        return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/stringer.py b/release/scripts/addons_contrib/add_mesh_stairs/stringer.py
deleted file mode 100644
index 99af723..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/stringer.py
+++ /dev/null
@@ -1,504 +0,0 @@
-# Stairbuilder - Stringer generation
-#
-# Generates stringer mesh for stair generation.
-#   Stair Type (typ):
-#       - id1 = Freestanding staircase
-#       - id2 = Housed-open staircase
-#       - id3 = Box staircase
-#       - id4 = Circular staircase
-#   Stringer Type (typ_s):
-#       - sId1 = Classic
-#       - sId2 = I-Beam
-#       - sId3 = C-Beam
-# 
-# Paul "BrikBot" Marshall
-# Created: September 19, 2011
-# Last Modified: January 29, 2011
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.61.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-from math import atan, cos, radians, tan
-from mathutils import Matrix, Vector
-from mathutils.geometry import (intersect_line_plane,
-                                intersect_line_line)
-
-class Stringer:
-    def  __init__(self,G,typ,typ_s,rise,run,w,h,nT,hT,wT,tT,tO,tw,tf,tp,g,
-                  nS=1,dis=False,notMulti=True,deg=4):
-        self.G = G #General
-        self.typ = typ # Stair type
-        self.typ_s = typ_s # Stringer type
-        self.rise = rise #Stair rise
-        self.run = run #Stair run. Degrees if self.typ == "id4"
-        if notMulti:
-            self.w = w / 100 #stringer width
-        else:
-            self.w = (wT * (w / 100)) / nS
-        self.h = h #stringer height
-        self.nT = nT #number of treads
-        self.hT = hT #tread height
-        self.wT = wT #tread width
-        self.tT = tT #tread toe
-        self.tO = tO #Tread overhang. Inner radius if self.typ == "id4"
-        self.tw = self.w * (tw / 100) #stringer web thickness
-        self.tf = tf #stringer flange thickness
-        self.tp = 1 - (tp / 100) #stringer flange taper
-        self.g = g #does stringer intersect the ground?
-        self.nS = nS #number of stringers
-        self.dis = dis #Use distributed stringers
-        self.deg = deg #number of sections per "slice". Only applys if self.typ == "id4"
-        # Default stringer object (classic / sId1):
-        self.faces1=[[0,1,3,2],[1,5,3],[3,5,4],[6,7,9,8],[7,11,9],[9,11,10],
-                     [0,2,8,6],[0,1,7,6],[1,5,11,7],[2,3,9,8],[3,4,10,9],[4,5,11,10]]
-        # Box stair type stringer:
-        self.faces2=[[0,1,7,6],[1,3,9,7],[3,4,10,9],[4,10,11,5],[5,11,8,2],
-                     [2,8,6,0],[0,1,2],[1,2,5,3],[3,4,5],[6,7,8],[7,8,11,9],[9,10,11]]
-        # I-beam stringer (id2 / sId2 / Taper < 100%):
-        self.faces3a=[[0,1,17,16],[1,2,18,17],[2,3,19,18],[3,4,20,19],[4,5,21,20],[5,6,22,21],
-                      [6,7,23,22],[7,8,24,23],[8,9,25,24],[9,10,26,25],[10,11,27,26],
-                      [11,12,28,27],[12,13,29,28],[13,14,30,29],[14,15,31,30],[15,0,16,31],
-                      [0,1,2,15],[2,11,14,15],[11,12,13,14],[2,3,10,11],[3,4,5,6],[3,6,7,10],
-                      [7,8,9,10],[16,17,18,31],[18,27,30,31],[27,28,29,30],[18,19,26,27],
-                      [19,20,21,22],[19,22,23,26],[23,24,25,26]]
-        # I-beam stringer (id2 / sId2 / Taper = 100%):
-        self.faces3b=[[0,1,9,8],[1,2,10,9],[2,3,11,10],[3,4,12,11],[4,5,13,12],[5,6,14,13],
-                      [6,7,15,14],[7,0,8,15],[0,1,6,7],[1,2,5,6],[2,3,4,5],[8,9,14,15],
-                      [9,10,13,14],[10,11,12,13]]
-        # I-beam stringer (id3 / sId2 / Taper < 100%):
-        self.faces3c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],
-                      [3,4,21,22],[16,17,18,23],[18,19,22,23],[19,20,21,22],
-                      [17,8,15,18],[18,15,14,19],[19,14,13,20],[8,9,10,15],
-                      [10,11,14,15],[11,12,13,14],[9,10,53,52],[10,11,54,53],
-                      [11,12,55,54],[52,53,61,60],[53,54,62,61],[54,55,63,62],
-                      [60,61,34,33],[61,62,35,34],[62,63,36,35],[32,33,34,39],
-                      [34,35,38,39],[35,36,37,38],[41,32,39,42],[42,39,38,43],
-                      [43,38,37,44],[40,41,42,47],[42,43,46,47],[43,44,45,46],
-                      [25,26,47,40],[26,27,46,47],[27,28,45,46],[24,25,26,31],
-                      [26,27,30,31],[27,28,29,30],[24,31,57,56],[31,30,58,57],
-                      [30,29,59,58],[48,49,57,56],[49,50,58,57],[50,51,59,58],
-                      [0,7,49,48],[7,6,50,49],[6,5,51,50],[0,1,16,48],[16,40,56,48],
-                      [24,25,40,56],[16,17,41,40],[8,9,52,17],[17,52,60,41],
-                      [32,33,60,41],[12,13,20,55],[20,44,63,55],[37,44,63,36],
-                      [20,21,45,44],[28,29,51,21],[21,51,59,45],[28,45,59,29],
-                      [4,5,51,21]]
-        # C-beam stringer (id3 / sId3 / Taper < 100%):
-        self.faces4c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],[3,4,21,22],
-                      [16,17,18,23],[18,19,22,23],[19,20,21,22],[17,8,15,18],[18,15,14,19],
-                      [19,14,13,20],[8,9,10,15],[10,11,14,15],[11,12,13,14],[0,24,25,7],
-                      [7,25,26,6],[6,26,27,5],[9,31,30,10],[10,30,29,11],[11,29,28,12],
-                      [24,25,30,31],[25,26,29,30],[26,27,28,29],[0,1,16,24],[16,24,31,17],
-                      [8,9,31,17],[4,5,27,21],[20,21,27,28],[12,13,20,28]]
-        self.Create()
-
-
-    def Create(self):
-        if self.typ == "id1":
-            if self.typ_s == "sId1":
-                if self.dis or self.nS == 1:
-                    offset = (self.wT / (self.nS + 1)) - (self.w / 2)
-                else:
-                    offset = 0
-                for i in range(self.nS):
-                    for j in range(self.nT):
-                        coords = []
-                        coords.append(Vector([0, offset, -self.rise]))
-                        coords.append(Vector([self.run, offset, -self.rise]))
-                        coords.append(Vector([0, offset, -self.hT]))
-                        coords.append(Vector([self.run, offset, -self.hT]))
-                        coords.append(Vector([self.run, offset, 0]))
-                        coords.append(Vector([self.run * 2, offset, 0]))
-                        for k in range(6):
-                            coords.append(coords[k]+Vector([0, self.w, 0]))
-                        for k in coords:
-                            k += j*Vector([self.run, 0, self.rise])
-                        self.G.Make_mesh(coords,self.faces1,'stringer')
-                    if self.dis or self.nS == 1:
-                        offset += self.wT / (self.nS + 1)
-                    else:
-                        offset += (self.wT - self.w) / (self.nS - 1)
-            elif self.typ_s == "sId2":
-                self.I_beam()
-        elif self.typ == "id2":
-            if self.typ_s == "sId1":
-                coords = []
-                coords.append(Vector([-self.tT, -self.w, -self.rise]))
-                coords.append(Vector([self.hT / self.G.slope, -self.w, -self.rise]))
-                coords.append(Vector([-self.tT, -self.w, 0]))
-                coords.append(Vector([self.nT * self.run, -self.w,
-                                      ((self.nT - 1) * self.rise) - self.hT]))
-                coords.append(Vector([self.nT * self.run, -self.w, self.nT * self.rise]))
-                coords.append(Vector([(self.nT * self.run) - self.tT, -self.w,
-                                      self.nT * self.rise]))
-                for i in range(6):
-                    coords.append(coords[i] + Vector([0, self.w, 0]))
-                self.G.Make_mesh(coords, self.faces2, 'stringer')
-                for i in coords:
-                    i += Vector([0, self.w + self.wT, 0])
-                self.G.Make_mesh(coords, self.faces2, 'stringer')
-            elif self.typ_s == "sId2":
-                self.housed_I_beam()
-            elif self.typ_s == "sId3":
-                self.housed_C_beam()
-        elif self.typ == "id3":
-            h = (self.rise - self.hT) - self.rise #height of top section
-            for i in range(self.nT):
-                coords = []
-                coords.append(Vector([i * self.run,0,-self.rise]))
-                coords.append(Vector([(i + 1) * self.run,0,-self.rise]))
-                coords.append(Vector([i * self.run,0,h + (i * self.rise)]))
-                coords.append(Vector([(i + 1) * self.run,0,h + (i * self.rise)]))
-                for j in range(4):
-                    coords.append(coords[j] + Vector([0,self.wT,0]))
-                self.G.Make_mesh(coords, self.G.faces, 'stringer')
-        elif self.typ == "id4":
-            offset = (self.wT / (self.nS + 1)) - (self.w / 2)
-            for s in range(self.nS):
-                base = self.tO + (offset * (s + 1))
-                start = [Vector([0, -base, -self.hT]),
-                         Vector([0, -base, -self.hT - self.rise]),
-                         Vector([0, -base - self.w, -self.hT]),
-                         Vector([0, -base - self.w, -self.hT - self.rise])]
-                self.d = radians(self.run) / self.nT
-                for i in range(self.nT):
-                    coords = []
-                    # Base faces.  Should be able to append more sections:
-                    tId4_faces = [[0, 1, 3, 2]]
-                    t_inner = Matrix.Rotation(self.d * i, 3, 'Z')
-                    coords.append((t_inner * start[0]) + Vector([0, 0, self.rise * i]))
-                    coords.append((t_inner * start[1]) + Vector([0, 0, self.rise * i]))
-                    t_outer = Matrix.Rotation(self.d * i, 3, 'Z')
-                    coords.append((t_outer * start[2]) + Vector([0, 0, self.rise * i]))
-                    coords.append((t_outer * start[3]) + Vector([0, 0, self.rise * i]))
-                    k = 0
-                    for j in range(self.deg):
-                        k = (j * 4) + 4
-                        tId4_faces.append([k, k - 4, k - 3, k + 1])
-                        tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
-                        tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
-                        tId4_faces.append([k, k - 4, k - 2, k + 2])
-                        rot = Matrix.Rotation(((self.d * (j + 1)) / self.deg) + (self.d * i), 3, 'Z')
-                        for v in start:
-                            coords.append((rot * v) + Vector([0, 0, self.rise * i]))
-                    for j in range(self.deg):
-                        k = ((j + self.deg) * 4) + 4
-                        tId4_faces.append([k, k - 4, k - 3, k + 1])
-                        tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
-                        tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
-                        tId4_faces.append([k, k - 4, k - 2, k + 2])
-                        rot = Matrix.Rotation(((self.d * ((j + self.deg) + 1)) / self.deg) + (self.d * i), 3, 'Z')
-                        for v in range(4):
-                            if v in [1, 3]:
-                                incline = (self.rise * i) + (self.rise / self.deg) * (j + 1)
-                                coords.append((rot * start[v]) + Vector([0, 0, incline]))
-                            else:
-                                coords.append((rot * start[v]) + Vector([0, 0, self.rise * i]))
-                    self.G.Make_mesh(coords, tId4_faces, 'treads')
-
-        return {'FINISHED'}
-
-
-    def I_beam(self):
-        mid = self.w / 2
-        web = self.tw / 2
-        # Bottom of the stringer:
-        baseZ = -self.rise - self.hT - self.h
-        # Top of the strigner:
-        topZ = -self.rise - self.hT
-        # Vertical taper amount:
-        taper = self.tf * self.tp
-
-        if self.dis or self.nS == 1:
-            offset = (self.wT / (self.nS + 1)) - mid
-        else:
-            offset = 0
-
-        # taper < 100%:
-        if self.tp > 0:
-            for i in range(self.nS):
-                coords = []
-                coords.append(Vector([0, offset,                baseZ]))
-                coords.append(Vector([0, offset,                baseZ + taper]))
-                coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
-                coords.append(Vector([0, offset,                topZ - taper]))
-                coords.append(Vector([0, offset,                topZ]))
-                coords.append(Vector([0, offset + (mid - web),  topZ]))
-                coords.append(Vector([0, offset + (mid + web),  topZ]))
-                coords.append(Vector([0, offset + self.w,       topZ]))
-                coords.append(Vector([0, offset + self.w,       topZ - taper]))
-                coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
-                coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + self.w,       baseZ + taper]))
-                coords.append(Vector([0, offset + self.w,       baseZ]))
-                coords.append(Vector([0, offset + (mid + web),  baseZ]))
-                coords.append(Vector([0, offset + (mid - web),  baseZ]))
-                for j in range(16):
-                    coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
-                # If the bottom meets the ground:
-                #   Bottom be flat with the xy plane, but shifted down.
-                #   Either project onto the plane along a vector (hard) or use the built in
-                #       interest found in mathutils.geometry (easy).  Using intersect:
-                if self.g:
-                    for j in range(16):
-                        coords[j] = intersect_line_plane(coords[j], coords[j + 16],
-                                                         Vector([0, 0, topZ]),
-                                                         Vector([0, 0, 1]))
-                self.G.Make_mesh(coords, self.faces3a, 'stringer')
-
-                if self.dis or self.nS == 1:
-                    offset += self.wT / (self.nS + 1)
-                else:
-                    offset += (self.wT - self.w) / (self.nS - 1)
-        # taper = 100%:
-        else:
-            for i in range(self.nS):
-                coords = []
-                coords.append(Vector([0, offset,                baseZ]))
-                coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
-                coords.append(Vector([0, offset,                topZ]))
-                coords.append(Vector([0, offset + self.w,       topZ]))
-                coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
-                coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + self.w,       baseZ]))
-                for j in range(8):
-                    coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
-                self.G.Make_mesh(coords, self.faces3b, 'stringer')
-                offset += self.wT / (self.nS + 1)
-                
-        return {'FINISHED'}
-
-
-    def housed_I_beam(self):
-        webOrth = Vector([self.rise, 0, -self.run]).normalized()
-        webHeight = Vector([self.run + self.tT, 0, -self.hT]).project(webOrth).length
-        vDelta_1 = self.tf * tan(self.G.angle)
-        vDelta_2 = (self.rise * (self.nT - 1)) - (webHeight + self.tf)
-        flange_y = (self.w - self.tw) / 2
-        front = -self.tT - self.tf
-        outer = -self.tO - self.tw - flange_y
-
-        coords = []
-        if self.tp > 0:
-            # Upper-Outer flange:
-            coords.append(Vector([front, outer, -self.rise]))
-            coords.append(Vector([-self.tT, outer, -self.rise]))
-            coords.append(Vector([-self.tT, outer, 0]))
-            coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
-                                  self.rise * (self.nT - 1)]))
-            coords.append(Vector([self.run * self.nT, outer,
-                                  self.rise * (self.nT - 1)]))
-            coords.append(Vector([self.run * self.nT, outer,
-                                  (self.rise * (self.nT - 1)) + self.tf]))
-            coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
-                                  (self.rise * (self.nT - 1)) + self.tf]))
-            coords.append(Vector([front, outer, self.tf - vDelta_1]))
-            # Lower-Outer flange:
-            coords.append(coords[0] + Vector([self.tf + webHeight, 0, 0]))
-            coords.append(coords[1] + Vector([self.tf + webHeight, 0, 0]))
-            coords.append(intersect_line_line(coords[9],
-                                              coords[9] - Vector([0, 0, 1]),
-                                              Vector([self.run, 0, -self.hT - self.tf]),
-                                              Vector([self.run * 2, 0, self.rise - self.hT - self.tf]))[0])
-            coords.append(Vector([(self.run * self.nT) - ((webHeight - self.hT) / tan(self.G.angle)),
-                                  outer, vDelta_2]))
-            coords.append(coords[4] - Vector([0, 0, self.tf + webHeight]))
-            coords.append(coords[5] - Vector([0, 0, self.tf + webHeight]))
-            coords.append(coords[11] + Vector([0, 0, self.tf]))
-            coords.append(intersect_line_line(coords[8],
-                                              coords[8] - Vector([0, 0, 1]),
-                                              Vector([self.run, 0, -self.hT]),
-                                              Vector([self.run * 2, 0, self.rise - self.hT]))[0])
-            # Outer web:
-            coords.append(coords[1] + Vector([0, flange_y, 0]))
-            coords.append(coords[8] + Vector([0, flange_y, 0]))
-            coords.append(coords[15] + Vector([0, flange_y, 0]))
-            coords.append(coords[14] + Vector([0, flange_y, 0]))
-            coords.append(coords[13] + Vector([0, flange_y, 0]))
-            coords.append(coords[4] + Vector([0, flange_y, 0]))
-            coords.append(coords[3] + Vector([0, flange_y, 0]))
-            coords.append(coords[2] + Vector([0, flange_y, 0]))
-            # Upper-Inner flange and lower-inner flange:
-            for i in range(16):
-                coords.append(coords[i] + Vector([0, self.w, 0]))
-            # Inner web:
-            for i in range(8):
-                coords.append(coords[i + 16] + Vector([0, self.tw, 0]))
-            # Mid nodes to so faces will be quads:
-            for i in [0,7,6,5,9,10,11,12]:
-                coords.append(coords[i] + Vector([0, flange_y, 0]))
-            for i in range(8):
-                coords.append(coords[i + 48] + Vector([0, self.tw, 0]))
-
-            self.G.Make_mesh(coords, self.faces3c, 'stringer')
-
-            for i in coords:
-                i += Vector([0, self.wT + self.tw, 0])
-
-            self.G.Make_mesh(coords, self.faces3c, 'stringer')
-
-        # @TODO Taper = 100%
-        
-        return {'FINISHED'}
-
-
-    def C_Beam(self):
-        mid = self.w / 2
-        web = self.tw / 2
-        # Bottom of the stringer:
-        baseZ = -self.rise - self.hT - self.h
-        # Top of the strigner:
-        topZ = -self.rise - self.hT
-        # Vertical taper amount:
-        taper = self.tf * self.tp
-
-        if self.dis or self.nS == 1:
-            offset = (self.wT / (self.nS + 1)) - mid
-        else:
-            offset = 0
-
-        # taper < 100%:
-        if self.tp > 0:
-            for i in range(self.nS):
-                coords = []
-                coords.append(Vector([0, offset,                baseZ]))
-                coords.append(Vector([0, offset,                baseZ + taper]))
-                coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
-                coords.append(Vector([0, offset,                topZ - taper]))
-                coords.append(Vector([0, offset,                topZ]))
-                coords.append(Vector([0, offset + (mid - web),  topZ]))
-                coords.append(Vector([0, offset + (mid + web),  topZ]))
-                coords.append(Vector([0, offset + self.w,       topZ]))
-                coords.append(Vector([0, offset + self.w,       topZ - taper]))
-                coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
-                coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + self.w,       baseZ + taper]))
-                coords.append(Vector([0, offset + self.w,       baseZ]))
-                coords.append(Vector([0, offset + (mid + web),  baseZ]))
-                coords.append(Vector([0, offset + (mid - web),  baseZ]))
-                for j in range(16):
-                    coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
-                # If the bottom meets the ground:
-                #   Bottom be flat with the xy plane, but shifted down.
-                #   Either project onto the plane along a vector (hard) or use the built in
-                #       interest found in mathutils.geometry (easy).  Using intersect:
-                if self.g:
-                    for j in range(16):
-                        coords[j] = intersect_line_plane(coords[j], coords[j + 16],
-                                                         Vector([0, 0, topZ]),
-                                                         Vector([0, 0, 1]))
-                self.G.Make_mesh(coords, self.faces3a, 'stringer')
-
-                if self.dis or self.nS == 1:
-                    offset += self.wT / (self.nS + 1)
-                else:
-                    offset += (self.wT - self.w) / (self.nS - 1)
-        # taper = 100%:
-        else:
-            for i in range(self.nS):
-                coords = []
-                coords.append(Vector([0, offset,                baseZ]))
-                coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
-                coords.append(Vector([0, offset,                topZ]))
-                coords.append(Vector([0, offset + self.w,       topZ]))
-                coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
-                coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
-                coords.append(Vector([0, offset + self.w,       baseZ]))
-                for j in range(8):
-                    coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
-                self.G.Make_mesh(coords, self.faces3b, 'stringer')
-                offset += self.wT / (self.nS + 1)
-                
-        return {'FINISHED'}
-
-
-    def housed_C_beam(self):
-        webOrth = Vector([self.rise, 0, -self.run]).normalized()
-        webHeight = Vector([self.run + self.tT, 0, -self.hT]).project(webOrth).length
-        vDelta_1 = self.tf * tan(self.G.angle)
-        vDelta_2 = (self.rise * (self.nT - 1)) - (webHeight + self.tf)
-        flange_y = (self.w - self.tw) / 2
-        front = -self.tT - self.tf
-        outer = -self.tO - self.tw - flange_y
-
-        coords = []
-        if self.tp > 0:
-            # Upper-Outer flange:
-            coords.append(Vector([front, outer, -self.rise]))
-            coords.append(Vector([-self.tT, outer, -self.rise]))
-            coords.append(Vector([-self.tT, outer, 0]))
-            coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
-                                  self.rise * (self.nT - 1)]))
-            coords.append(Vector([self.run * self.nT, outer,
-                                  self.rise * (self.nT - 1)]))
-            coords.append(Vector([self.run * self.nT, outer,
-                                  (self.rise * (self.nT - 1)) + self.tf]))
-            coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
-                                  (self.rise * (self.nT - 1)) + self.tf]))
-            coords.append(Vector([front, outer, self.tf - vDelta_1]))
-            # Lower-Outer flange:
-            coords.append(coords[0] + Vector([self.tf + webHeight, 0, 0]))
-            coords.append(coords[1] + Vector([self.tf + webHeight, 0, 0]))
-            coords.append(intersect_line_line(coords[9],
-                                              coords[9] - Vector([0, 0, 1]),
-                                              Vector([self.run, 0, -self.hT - self.tf]),
-                                              Vector([self.run * 2, 0, self.rise - self.hT - self.tf]))[0])
-            coords.append(Vector([(self.run * self.nT) - ((webHeight - self.hT) / tan(self.G.angle)),
-                                  outer, vDelta_2]))
-            coords.append(coords[4] - Vector([0, 0, self.tf + webHeight]))
-            coords.append(coords[5] - Vector([0, 0, self.tf + webHeight]))
-            coords.append(coords[11] + Vector([0, 0, self.tf]))
-            coords.append(intersect_line_line(coords[8],
-                                              coords[8] - Vector([0, 0, 1]),
-                                              Vector([self.run, 0, -self.hT]),
-                                              Vector([self.run * 2, 0, self.rise - self.hT]))[0])
-            # Outer web:
-            coords.append(coords[1] + Vector([0, flange_y, 0]))
-            coords.append(coords[8] + Vector([0, flange_y, 0]))
-            coords.append(coords[15] + Vector([0, flange_y, 0]))
-            coords.append(coords[14] + Vector([0, flange_y, 0]))
-            coords.append(coords[13] + Vector([0, flange_y, 0]))
-            coords.append(coords[4] + Vector([0, flange_y, 0]))
-            coords.append(coords[3] + Vector([0, flange_y, 0]))
-            coords.append(coords[2] + Vector([0, flange_y, 0]))
-            # Outer corner nodes:
-            for i in [0, 7, 6, 5, 12, 11, 10, 9]:
-                coords.append(coords[i] + Vector([0, flange_y + self.tw, 0]))
-
-            self.G.Make_mesh(coords, self.faces4c, 'stringer')
-
-            for i in range(16):
-                coords[i] += Vector([0, -outer * 2, 0])
-            for i in range(8):
-                coords[i + 16] += Vector([0, (-outer - flange_y) * 2, 0])
-            for i in coords:
-                i += Vector([0, (self.tO * 2) + self.wT, 0])
-
-            self.G.Make_mesh(coords, self.faces4c, 'stringer')
-        
-        return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_stairs/tread.py b/release/scripts/addons_contrib/add_mesh_stairs/tread.py
deleted file mode 100644
index 1a5af0c..0000000
--- a/release/scripts/addons_contrib/add_mesh_stairs/tread.py
+++ /dev/null
@@ -1,242 +0,0 @@
-# Stairbuilder - Tread generation
-#
-# Generates treads for stair generation.
-#   Stair Type (typ):
-#       - id1 = Freestanding staircase
-#       - id2 = Housed-open staircase
-#       - id3 = Box staircase
-#       - id4 = Circular staircase
-#   Tread Type (typ_t):
-#       - tId1 = Classic
-#       - tId2 = Basic Steel
-#       - tId3 = Bar 1
-#       - tId4 = Bar 2
-#       - tId5 = Bar 3
-# 
-# Paul "BrikBot" Marshall
-# Created: September 19, 2011
-# Last Modified: January 26, 2012
-# Homepage (blog): http://post.darkarsenic.com/
-#                       //blog.darkarsenic.com/
-#
-# Coded in IDLE, tested in Blender 2.61.
-# Search for "@todo" to quickly find sections that need work.
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  Stairbuilder is for quick stair generation.
-#  Copyright (C) 2011  Paul Marshall
-#
-#  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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-import mathutils
-from copy import copy
-from math import radians, sqrt
-from mathutils import Matrix, Vector
-
-class Treads:
-    def __init__(self,G,typ,typ_t,run,w,h,d,r,toe,o,n,tk,sec,sp,sn,deg=4):
-        self.G = G #General
-        self.typ = typ #Stair type
-        self.typ_t = typ_t #Tread type
-        self.run = run #Stair run.  Degrees if self.typ == "id4"
-        self.w=w #tread width.  Is outer radius if self.typ == "id4"
-        self.h=h #tread height
-        self.d=d #tread run.  Ignore for now if self.typ == "id4"
-        self.r=r #tread rise
-        self.t=toe #tread nosing
-        self.o=o #tread side overhang.  Is inner radius if self.typ == "id4"
-        self.n=n #number of treads
-        self.tk=tk #thickness of tread metal
-        self.sec=sec #metal sections for tread
-        if sec != 1 and typ_t not in ["tId4", "tId5"]:
-            self.sp=((d+toe)*(sp/100))/(sec-1) #spacing between sections (% of depth)
-        elif typ_t in ["tId4", "tId5"]:
-            self.sp=sp/100 #keep % value
-        else:
-            self.sp=0
-        self.sn=sn #number of cross sections
-        self.deg = deg #number of section per "slice".  Only applys if self.typ == "id4"
-        self.tId2_faces = [[0,1,2,3],[0,3,4,5],[4,5,6,7],[6,7,8,9],[8,9,10,11],
-                           [12,13,14,15],[12,15,16,17],[16,17,18,19],
-                           [18,19,20,21],[20,21,22,23],[0,1,13,12],[1,2,14,13],
-                           [2,3,15,14],[3,4,16,15],[4,7,19,16],[7,8,20,19],
-                           [8,11,23,20],[11,10,22,23],[10,9,21,22],[9,6,18,21],
-                           [6,5,17,18],[5,0,12,17]]
-        self.out_faces = [[0,2,3,1],[0,2,10,8],[9,11,3,1],[9,11,10,8],
-                          [2,6,7,3],[2,6,14,10],[11,15,7,3],[11,15,14,10],
-                          [0,4,5,1],[0,4,12,8],[9,13,5,1],[9,13,12,8],
-                          [4,6,7,5],[4,6,14,12],[13,15,14,12],[13,15,7,5]]
-        self.Create()
-
-    def Create(self):
-        # Setup the coordinates:
-        coords = []
-        coords2 = []
-        coords3 = []
-        cross = 0
-        cW = 0
-        depth = 0
-        offset = 0
-        height = 0
-        if self.typ in ["id1", "id2", "id3"]:
-            if self.typ_t == "tId1":
-                coords.append(Vector([-self.t,-self.o,0]))
-                coords.append(Vector([self.d,-self.o,0]))
-                coords.append(Vector([-self.t,self.w + self.o,0]))
-                coords.append(Vector([self.d,self.w + self.o,0]))
-                for i in range(4):
-                    coords.append(coords[i]+Vector([0,0,-self.h]))
-
-            elif self.typ_t == "tId2":
-                depth = (self.d + self.t - (self.sec - 1) * self.sp) / self.sec
-                inset = depth / 4
-                tDepth = depth - self.t
-                coords.append(Vector([-self.t, -self.o, -self.h]))                          #0
-                coords.append(Vector([inset - self.t, -self.o, -self.h]))           #1
-                coords.append(Vector([inset - self.t, -self.o, -self.h + self.tk])) #2
-                coords.append(Vector([self.tk - self.t, -self.o, -self.h + self.tk]))       #3
-                coords.append(Vector([self.tk - self.t, -self.o, -self.tk]))                #4
-                coords.append(Vector([-self.t, -self.o, 0]))                                #5
-                coords.append(Vector([tDepth, -self.o, 0]))                                 #6
-                coords.append(Vector([tDepth - self.tk, -self.o, -self.tk]))                #7
-                coords.append(Vector([tDepth - self.tk, -self.o, self.tk - self.h]))        #8
-                coords.append(Vector([tDepth, -self.o, -self.h]))                           #9
-                coords.append(Vector([tDepth - inset, -self.o, -self.h]))           #10
-                coords.append(Vector([tDepth - inset, -self.o, -self.h + self.tk])) #11
-                for i in range(12):
-                    coords.append(coords[i] + Vector([0, self.w + (2 * self.o), 0]))
-            
-            elif self.typ_t in ["tId3", "tId4", "tId5"]:
-                # Frame:
-                coords.append(Vector([-self.t,-self.o,-self.h]))
-                coords.append(Vector([self.d,-self.o,-self.h]))
-                coords.append(Vector([-self.t,-self.o,0]))
-                coords.append(Vector([self.d,-self.o,0]))
-                for i in range(4):
-                    if (i % 2) == 0:
-                        coords.append(coords[i] + Vector([self.tk,self.tk,0]))
-                    else:
-                        coords.append(coords[i] + Vector([-self.tk,self.tk,0]))
-                for i in range(4):
-                    coords.append(coords[i] + Vector([0,self.w + self.o,0]))
-                for i in range(4):
-                    coords.append(coords[i + 4] + Vector([0,self.w + self.o - (2 * self.tk),0]))
-
-                # Tread sections:
-                if self.typ_t == "tId3":
-                    offset = (self.tk * sqrt(2)) / 2
-                    topset = self.h - offset
-                    self.sp = ((self.d + self.t - (2 * self.tk)) - (offset * (self.sec) + topset)) / (self.sec + 1)
-                    baseX = -self.t + self.sp + self.tk
-                    coords2.append(Vector([baseX, self.tk - self.o, offset - self.h]))
-                    coords2.append(Vector([baseX + offset, self.tk - self.o, -self.h]))
-                    for i in range(2):
-                        coords2.append(coords2[i] + Vector([topset, 0, topset]))
-                    for i in range(4):
-                        coords2.append(coords2[i] + Vector([0, (self.w + self.o) - (2 * self.tk), 0]))
-                elif self.typ_t in ["tId4", "tId5"]:
-                    offset = ((self.run + self.t) * self.sp) / (self.sec + 1)
-                    topset = (((self.run + self.t) * (1 - self.sp)) - (2 * self.tk)) / self.sec
-                    baseX = -self.t + self.tk + offset
-                    baseY = self.w + self.o - 2 * self.tk
-                    coords2.append(Vector([baseX, -self.o + self.tk, -self.h / 2]))
-                    coords2.append(Vector([baseX + topset, -self.o + self.tk, -self.h / 2]))
-                    coords2.append(Vector([baseX, -self.o + self.tk, 0]))
-                    coords2.append(Vector([baseX + topset, -self.o + self.tk, 0]))
-                    for i in range(4):
-                        coords2.append(coords2[i] + Vector([0, baseY, 0]))
-
-                # Tread cross-sections:
-                if self.typ_t in ["tId3", "tId4"]:
-                    cW = self.tk
-                    cross = (self.w + (2 * self.o) - (self.sn + 2) * self.tk) / (self.sn + 1)
-                else: # tId5
-                    spacing = self.sp ** (1 / 4)
-                    cross = ((2*self.o + self.w) * spacing) / (self.sn + 1)
-                    cW = (-2*self.tk + (2*self.o + self.w) * (1 - spacing)) / self.sn
-                    self.sp = topset
-                    height = -self.h / 2
-                baseY = -self.o + self.tk + cross
-                coords3.append(Vector([-self.t + self.tk, baseY, -self.h]))
-                coords3.append(Vector([self.d - self.tk, baseY, -self.h]))
-                coords3.append(Vector([-self.t + self.tk, baseY, height]))
-                coords3.append(Vector([self.d - self.tk, baseY, height]))
-                for i in range(4):
-                    coords3.append(coords3[i] + Vector([0, cW, 0]))
-
-            # Make the treads:
-            for i in range(self.n):
-                if self.typ_t == "tId1":
-                    self.G.Make_mesh(coords,self.G.faces,'treads')
-                elif self.typ_t == "tId2":
-                    temp = []
-                    for j in coords:
-                        temp.append(copy(j))
-                    for j in range(self.sec):
-                        self.G.Make_mesh(temp, self.tId2_faces, 'treads')
-                        for k in temp:
-                            k += Vector([depth + self.sp, 0, 0])
-                elif self.typ_t in ["tId3", "tId4", "tId5"]:
-                    self.G.Make_mesh(coords,self.out_faces,'treads')
-                    temp = []
-                    for j in coords2:
-                        temp.append(copy(j))
-                    for j in range(self.sec):
-                        self.G.Make_mesh(temp,self.G.faces,'bars')
-                        for k in temp:
-                            k += Vector([offset + self.sp, 0, 0])
-                    for j in coords2:
-                        j += Vector([self.d, 0, self.r])
-                    temp = []
-                    for j in coords3:
-                        temp.append(copy(j))
-                    for j in range(self.sn):
-                        self.G.Make_mesh(temp,self.G.faces,'crosses')
-                        for k in temp:
-                            k += Vector([0, cW + cross, 0])
-                    for j in coords3:
-                        j += Vector([self.d, 0, self.r])
-                for j in coords:
-                    j += Vector([self.d,0,self.r])
-        # Circular staircase:
-        elif self.typ in ["id4"]:
-            start = [Vector([0, -self.o, 0]), Vector([0, -self.o, -self.h]),
-                     Vector([0, -self.w, 0]), Vector([0, -self.w, -self.h])]
-            self.d = radians(self.run) / self.n
-            for i in range(self.n):
-                coords = []
-                # Base faces.  Should be able to append more sections:
-                tId4_faces = [[0, 1, 3, 2]]
-                t_inner = Matrix.Rotation((-self.t / self.o) + (self.d * i), 3, 'Z')
-                coords.append((t_inner * start[0]) + Vector([0, 0, self.r * i]))
-                coords.append((t_inner * start[1]) + Vector([0, 0, self.r * i]))
-                t_outer = Matrix.Rotation((-self.t / self.w) + (self.d * i), 3, 'Z')
-                coords.append((t_outer * start[2]) + Vector([0, 0, self.r * i]))
-                coords.append((t_outer * start[3]) + Vector([0, 0, self.r * i]))
-                k = 0
-                for j in range(self.deg + 1):
-                    k = (j * 4) + 4
-                    tId4_faces.append([k, k - 4, k - 3, k + 1])
-                    tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
-                    tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
-                    tId4_faces.append([k, k - 4, k - 2, k + 2])
-                    rot = Matrix.Rotation(((self.d * j) / self.deg) + (self.d * i), 3, 'Z')
-                    for v in start:
-                        coords.append((rot * v) + Vector([0, 0, self.r * i]))
-                tId4_faces.append([k, k + 1, k + 3, k + 2])
-                self.G.Make_mesh(coords, tId4_faces, 'treads')
-        return
diff --git a/release/scripts/addons_contrib/add_mesh_walls/Blocks.py b/release/scripts/addons_contrib/add_mesh_walls/Blocks.py
deleted file mode 100644
index 213b780..0000000
--- a/release/scripts/addons_contrib/add_mesh_walls/Blocks.py
+++ /dev/null
@@ -1,1683 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you may 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.
-#   51 Franklin Street, Fifth Floor
-#   Boston, MA 02110-1301, USA
-#
-# or go online at: http://www.gnu.org/licenses/ to view license options.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-
-##
-#
-# Module notes:
-#
-# Grout needs to be implemented.
-# consider removing wedge crit for small "c" and "cl" values
-# wrap around for openings on radial stonework?
-# auto-clip wall edge to SMALL for radial and domes.
-# unregister doesn't release all references.
-# repeat for opening doesn't distribute evenly when radialized - see wrap around
-#   note above.
-# if opening width == indent*2 the edge blocks fail (row of blocks cross opening).
-# if openings overlap fills inverse with blocks - see h/v slots.
-# Negative grout width creates a pair of phantom blocks, seperated by grout
-#   width, inside the edges.
-# if block width variance is 0, and edging is on, right edge blocks create a "vertical seam".
-#
-##
-
-# <pep8-80 compliant>
-
-import bpy, time, math
-from random import random
-from math import fmod, sqrt, sin, cos, atan
-
-#A few constants
-SMALL = 0.000000000001
-NOTZERO = 0.01 # for values that must be != 0; see UI options/variables -
-# sort of a bug to be fixed.
-PI = math.pi
-
-#global variables
-
-#General masonry Settings
-settings = {'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1,
-            'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0,
-            'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln':0,
-            'wm': 0.8, 'hm': 0.3, 'dm':0.1,
-            'woff':0.0, 'woffv':0.0, 'eoff':0.3, 'eoffv':0.0, 'rwhl':1,
-            'hb':0, 'ht':0, 'ge':0, 'physics':0}
-# 'w':width 'wv':widthVariation
-# 'h':height 'hv':heightVariation
-# 'd':depth 'dv':depthVariation
-# 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation
-# 'b':bevel 'bv':bevelVariation
-# 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction
-# 't':taper
-# 'sdv':subdivision(distance or angle)
-# 'hwt':row height effect on block widths in the row (0=no effect,
-#     1=1:1 relationship, negative values allowed, 0.5 works well)
-# 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows)
-#     (currently un-used)
-# 'wm':width minimum 'hm':height minimum 'dm':depth minimum
-# 'woff':row start offset(fraction of width)
-# 'woffv':width offset variation(fraction of width)
-# 'eoff':edge offset 'eoffv':edge offset variation
-# 'rwhl':row height lock(1 is all blocks in row have same height)
-# 'hb':bottom row height 'ht': top row height 'ge': grout the edges
-# 'physics': set up for physics
-
-# dims = area of wall (face)
-dims = {'s':0, 'e':PI*3/2, 'b':0.1, 't':12.3} # radial
-# 's':start x or theta 'e':end x or theta 'b':bottom z or r 't':top z or r
-# 'w' = e-s and h = t-b; calculated to optimize for various operations/usages
-#dims = {'s':-12, 'e':15, 'w':27, 'b':-15., 't':15., 'h':30}
-#dims = {'s':-bayDim/2, 'e':bayDim/2, 'b':-5., 't':10.} # bay settings?
-
-radialized = 0 # Radiating from one point - round/disc; instead of square
-slope = 0 # Warp/slope; curved over like a vaulted tunnel
-# 'bigblock': merge adjacent blocks into single large blocks
-bigBlock = 0 # Merge blocks
-
-# Gaps in blocks for various apertures.
-#openingSpecs = []
-openingSpecs = [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0,
-                 'v':0, 'vl':0, 't':0, 'tl':0}]
-# 'w': opening width, 'h': opening height,
-# 'x': horizontal position, 'z': vertical position,
-# 'rp': make multiple openings, with a spacing of x,
-# 'b': bevel the opening, inside only, like an arrow slit.
-# 'v': height of the top arch, 'vl':height of the bottom arch,
-# 't': thickness of the top arch, 'tl': thickness of the bottom arch
-
-# Add blocks to make platforms.
-shelfExt = 0
-#shelfSpecs = []
-shelfSpecs = {'w':0.5, 'h':0.5, 'd': 0.3, 'x':0.8, 'z':2.7}
-# 'w': block width, 'h': block height, 'd': block depth (shelf size; offset from wall)
-# 'x': horizontal start position, 'z': vertical start position
-
-# Add blocks to make steps.
-stepMod = 0
-stepSpecs = {'x':0.0, 'z':-10, 'w':10.0, 'h':10.0,
-    'v':0.7, 't':1.0, 'd':1.0 }
-# 'x': horizontal start position, 'z': vertical start position,
-# 'w': step area width, 'h': step area height,
-# 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall)
-
-
-    #easier way to get to the random function
-def rnd(): return random()
-
-    #random number from -0.5 to 0.5
-def rndc(): return (random() - 0.5)
-
-    #random number from -1.0 to 1.0
-def rndd(): return (random() - 0.5)*2.0
-
-
-#Opening Test suite
-#opening test function
-
-def test(TestN = 13):
-    dims = {'s':-29., 'e':29., 'b':-6., 't':TestN*7.5}
-    openingSpecs = []
-    for i in range(TestN):
-        x = (random() - 0.5) * 6
-        z = i*7.5
-        v = .2 + i*(3./TestN)
-        vl = 3.2 - i*(3./TestN)
-        t = 0.3 + random()
-        tl = 0.3 + random()
-        rn = random()*2
-        openingSpecs += [{'w':3.1 + rn, 'h':0.3 + rn, 'x':float(x),
-                          'z':float(z), 'rp':0, 'b':0.,
-                          'v':float(v), 'vl':float(vl),
-                          't':float(t), 'tl':float(tl)}]
-    return dims, openingSpecs
-
-#dims, openingSpecs = test(15)
-
-
-#For filling a linear space with divisions
-def fill(left, right, avedst, mindst=0.0, dev=0.0, pad=(0.0,0.0), num=0,
-         center=0):
-    __doc__ = '''\
-    Fills a linear range with points and returns an ordered list of those points
-    including the end points.
-
-    left: the lower boundary
-    right: the upper boundary
-    avedst: the average distance between points
-    mindst: the minimum distance between points
-    dev: the maximum random deviation from avedst
-    pad: tends to move the points near the bounds right (positive) or
-        left (negative).
-        element 0 pads the lower bounds, element 1 pads the upper bounds
-    num: substitutes a numerical limit for the right limit.  fill will then make
-        a num+1 element list
-    center: flag to center the elements in the range, 0 == disabled
-        '''
-
-    poslist = [left]
-    curpos = left+pad[0]
-
-    # Set offset by average spacing, then add blocks (fall through);
-    # if not at right edge.
-    if center:
-        curpos += ((right-left-mindst*2)%avedst)/2+mindst
-        if curpos-poslist[-1]<mindst: curpos = poslist[-1]+mindst+rnd()*dev/2
-
-        # clip to right edge.
-        if (right-curpos<mindst) or (right-curpos< mindst-pad[1]):
-            poslist.append(right)
-            return poslist
-
-        else: poslist.append(curpos)
-
-    #unused... for now.
-    if num:
-        idx = len(poslist)
-
-        while idx<num+1:
-            curpos += avedst+rndd()*dev
-            if curpos-poslist[-1]<mindst:
-                curpos = poslist[-1]+mindst+rnd()*dev/2
-            poslist.append(curpos)
-            idx += 1
-
-        return poslist
-
-    # make block edges
-    else:
-        while True: # loop for blocks
-            curpos += avedst+rndd()*dev
-            if curpos-poslist[-1]<mindst:
-                curpos = poslist[-1]+mindst+rnd()*dev/2
-            # close off edges at limit
-            if (right-curpos<mindst) or (right-curpos< mindst-pad[1]):
-                poslist.append(right)
-                return poslist
-
-            else: poslist.append(curpos)
-
-
-#For generating block geometry
-def MakeABlock(bounds, segsize, vll=0, Offsets=None, FaceExclude=[],
-               bevel=0, xBevScl=1):
-    __doc__ = '''\
-    MakeABlock returns lists of points and faces to be made into a square
-            cornered block, subdivided along the length, with optional bevels.
-    bounds: a list of boundary positions:
-        0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front
-    segsize: the maximum size before lengthwise subdivision occurs
-    vll: the number of vertexes already in the mesh. len(mesh.verts) should
-            give this number.
-    Offsets: list of coordinate delta values.
-        Offsets are lists, [x,y,z] in
-            [
-            0:left_bottom_back,
-            1:left_bottom_front,
-            2:left_top_back,
-            3:left_top_front,
-            4:right_bottom_back,
-            5:right_bottom_front,
-            6:right_top_back,
-            7:right_top_front,
-            ]
-    FaceExclude: list of faces to exclude from the faces list.  see bounds above for indicies
-    xBevScl: how much to divide the end (+- x axis) bevel dimensions.  Set to current average radius to compensate for angular distortion on curved blocks
-    '''
-
-    slices = fill(bounds[0], bounds[1], segsize, segsize, center=1)
-    points = []
-    faces = []
-
-    if Offsets == None:
-        points.append([slices[0],bounds[4],bounds[2]])
-        points.append([slices[0],bounds[5],bounds[2]])
-        points.append([slices[0],bounds[5],bounds[3]])
-        points.append([slices[0],bounds[4],bounds[3]])
-
-        for x in slices[1:-1]:
-            points.append([x,bounds[4],bounds[2]])
-            points.append([x,bounds[5],bounds[2]])
-            points.append([x,bounds[5],bounds[3]])
-            points.append([x,bounds[4],bounds[3]])
-
-        points.append([slices[-1],bounds[4],bounds[2]])
-        points.append([slices[-1],bounds[5],bounds[2]])
-        points.append([slices[-1],bounds[5],bounds[3]])
-        points.append([slices[-1],bounds[4],bounds[3]])
-
-    else:
-        points.append([slices[0]+Offsets[0][0],bounds[4]+Offsets[0][1],bounds[2]+Offsets[0][2]])
-        points.append([slices[0]+Offsets[1][0],bounds[5]+Offsets[1][1],bounds[2]+Offsets[1][2]])
-        points.append([slices[0]+Offsets[3][0],bounds[5]+Offsets[3][1],bounds[3]+Offsets[3][2]])
-        points.append([slices[0]+Offsets[2][0],bounds[4]+Offsets[2][1],bounds[3]+Offsets[2][2]])
-
-        for x in slices[1:-1]:
-            xwt = (x-bounds[0])/(bounds[1]-bounds[0])
-            points.append([x+Offsets[0][0]*(1-xwt)+Offsets[4][0]*xwt,bounds[4]+Offsets[0][1]*(1-xwt)+Offsets[4][1]*xwt,bounds[2]+Offsets[0][2]*(1-xwt)+Offsets[4][2]*xwt])
-            points.append([x+Offsets[1][0]*(1-xwt)+Offsets[5][0]*xwt,bounds[5]+Offsets[1][1]*(1-xwt)+Offsets[5][1]*xwt,bounds[2]+Offsets[1][2]*(1-xwt)+Offsets[5][2]*xwt])
-            points.append([x+Offsets[3][0]*(1-xwt)+Offsets[7][0]*xwt,bounds[5]+Offsets[3][1]*(1-xwt)+Offsets[7][1]*xwt,bounds[3]+Offsets[3][2]*(1-xwt)+Offsets[7][2]*xwt])
-            points.append([x+Offsets[2][0]*(1-xwt)+Offsets[6][0]*xwt,bounds[4]+Offsets[2][1]*(1-xwt)+Offsets[6][1]*xwt,bounds[3]+Offsets[2][2]*(1-xwt)+Offsets[6][2]*xwt])
-
-        points.append([slices[-1]+Offsets[4][0],bounds[4]+Offsets[4][1],bounds[2]+Offsets[4][2]])
-        points.append([slices[-1]+Offsets[5][0],bounds[5]+Offsets[5][1],bounds[2]+Offsets[5][2]])
-        points.append([slices[-1]+Offsets[7][0],bounds[5]+Offsets[7][1],bounds[3]+Offsets[7][2]])
-        points.append([slices[-1]+Offsets[6][0],bounds[4]+Offsets[6][1],bounds[3]+Offsets[6][2]])
-
-    faces.append([vll,vll+3,vll+2,vll+1])
-
-    for x in range(len(slices)-1):
-        faces.append([vll,vll+1,vll+5,vll+4])
-        vll+=1
-        faces.append([vll,vll+1,vll+5,vll+4])
-        vll+=1
-        faces.append([vll,vll+1,vll+5,vll+4])
-        vll+=1
-        faces.append([vll,vll-3,vll+1,vll+4])
-        vll+=1
-
-    faces.append([vll,vll+1,vll+2,vll+3])
-
-    return points, faces
-#
-#
-#
-
-#For generating Keystone Geometry
-def MakeAKeystone(xpos, width, zpos, ztop, zbtm, thick, bevel, vll=0, FaceExclude=[], xBevScl=1):
-    __doc__ = '''\
-    MakeAKeystone returns lists of points and faces to be made into a square cornered keystone, with optional bevels.
-    xpos: x position of the centerline
-    width: x width of the keystone at the widest point (discounting bevels)
-    zpos: z position of the widest point
-    ztop: distance from zpos to the top
-    zbtm: distance from zpos to the bottom
-    thick: thickness
-    bevel: the amount to raise the back vertex to account for arch beveling
-    vll: the number of vertexes already in the mesh. len(mesh.verts) should give this number
-    faceExclude: list of faces to exclude from the faces list.  0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front
-    xBevScl: how much to divide the end (+- x axis) bevel dimensions.  Set to current average radius to compensate for angular distortion on curved blocks
-    '''
-
-    points = []
-    faces = []
-    faceinclude = [1 for x in range(6)]
-    for x in FaceExclude: faceinclude[x]=0
-    Top = zpos + ztop
-    Btm = zpos - zbtm
-    Wid = width/2.
-    Thk = thick/2.
-
-    # The front top point
-    points.append([xpos, Thk, Top])
-    # The front left point
-    points.append([xpos-Wid, Thk, zpos])
-    # The front bottom point
-    points.append([xpos, Thk, Btm])
-    # The front right point
-    points.append([xpos+Wid, Thk, zpos])
-
-    MirrorPoints = []
-    for i in points:
-        MirrorPoints.append([i[0],-i[1],i[2]])
-    points += MirrorPoints
-    points[6][2] += bevel
-
-    faces.append([3,2,1,0])
-    faces.append([4,5,6,7])
-    faces.append([4,7,3,0])
-    faces.append([5,4,0,1])
-    faces.append([6,5,1,2])
-    faces.append([7,6,2,3])
-    # Offset the vertex numbers by the number of verticies already in the list
-    for i in range(len(faces)):
-        for j in range(len(faces[i])): faces[i][j] += vll
-
-    return points, faces
-
-
-#for finding line/circle intercepts
-def circ(offs=0.,r=1.):
-    __doc__ = """\
-    offs is the distance perpendicular to the line to the center of the circle
-    r is the radius of the circle
-    circ returns the distance paralell to the line to the center of the circle at the intercept.
-    """
-    offs = abs(offs)
-    if offs > r: return None
-    elif offs == r: return 0.
-    else: return sqrt(r**2 - offs**2)
-
-
-#class openings in the wall
-class opening:
-    __doc__ = """\
-    This is the class for holding the data for the openings in the wall.
-    It has methods for returning the edges of the opening for any given position value,
-    as well as bevel settings and top and bottom positions.
-    It stores the 'style' of the opening, and all other pertinent information.
-    """
-    # x = 0. # x position of the opening
-    # z = 0. # x position of the opening
-    # w = 0. # width of the opening
-    # h = 0. # height of the opening
-    r = 0  # top radius of the arch (derived from 'v')
-    rl = 0 # lower radius of the arch (derived from 'vl')
-    rt = 0 # top arch thickness
-    rtl = 0# lower arch thickness
-    ts = 0 # Opening side thickness, if greater than average width, replaces it.
-    c = 0  # top arch corner position (for low arches), distance from the top of the straight sides
-    cl = 0 # lower arch corner position (for low arches), distance from the top of the straight sides
-    # form = 0 # arch type (unused for now)
-    # b = 0. # back face bevel distance, like an arrow slit
-    v = 0. # top arch height
-    vl = 0.# lower arch height
-    # variable "s" is used for "side" in the "edge" function.
-    # it is a signed int, multiplied by the width to get + or - of the center
-
-    def btm(self):
-        if self.vl <= self.w/2 : return self.z-self.h/2-self.vl-self.rtl
-        else: return self.z - sqrt((self.rl+self.rtl)**2 - (self.rl - self.w/2 )**2)  - self.h/2
-
-
-    def top(self):
-        if self.v <= self.w/2 : return self.z+self.h/2+self.v+self.rt
-        else: return sqrt((self.r+self.rt)**2 - (self.r - self.w/2 )**2) + self.z + self.h/2
-
-
-    #crits returns the critical split points, or discontinuities, used for making rows
-    def crits(self):
-        critlist = []
-        if self.vl>0: # for lower arch
-            # add the top point if it is pointed
-            #if self.vl >= self.w/2.: critlist.append(self.btm())
-            if self.vl < self.w/2.:#else: for low arches, with wedge blocks under them
-                #critlist.append(self.btm())
-                critlist.append(self.z-self.h/2 - self.cl)
-
-        if self.h>0: # if it has a height, append points at the top and bottom of the main square section
-            critlist += [self.z-self.h/2,self.z+self.h/2]
-        else:  # otherwise, append just one in the center
-            critlist.append(self.z)
-
-        if self.v>0:  # for the upper arch
-            if self.v < self.w/2.: # add the splits for the upper wedge blocks, if needed
-                critlist.append(self.z+self.h/2 + self.c)
-                #critlist.append(self.top())
-            #otherwise just add the top point, if it is pointed
-            #else: critlist.append(self.top())
-
-        return critlist
-
-
-    # get the side position of the opening.
-    # ht is the z position; s is the side: 1 for right, -1 for left
-    # if the height passed is above or below the opening, return None
-    #
-    def edgeS(self, ht, s):
-        # set the row radius: 1 for standard wall (flat)
-        if radialized:
-            if slope: r1 = abs(dims['t']*sin(ht*PI/(dims['t']*2)))
-            else: r1 = abs(ht)
-        else: r1 = 1
-
-        #Go through all the options, and return the correct value
-        if ht < self.btm(): #too low
-            return None
-        elif ht > self.top(): #too high
-            return None
-
-        # Check for circ returning None - prevent TypeError (script failure) with float.
-
-        # in this range, pass the lower arch info
-        elif ht <= self.z-self.h/2-self.cl:
-            if self.vl > self.w/2:
-                circVal = circ(ht-self.z+self.h/2,self.rl+self.rtl)
-                if circVal == None:
-                    return None
-                else: return self.x + s*(self.w/2.-self.rl+circVal)/r1
-            else:
-                circVal = circ(ht-self.z+self.h/2+self.vl-self.rl,self.rl+self.rtl)
-                if circVal == None:
-                    return None
-                else: return self.x + s*circVal/r1
-
-        #in this range, pass the top arch info
-        elif ht >= self.z+self.h/2+self.c:
-            if self.v > self.w/2:
-                circVal = circ(ht-self.z-self.h/2,self.r+self.rt)
-                if circVal == None:
-                    return None
-                else: return self.x + s*(self.w/2.-self.r+circVal)/r1
-            else:
-                circVal = circ(ht-(self.z+self.h/2+self.v-self.r),self.r+self.rt)
-                if circVal == None:
-                    return None
-                else: return self.x + s*circVal/r1
-
-        #in this range pass the lower corner edge info
-        elif ht <= self.z-self.h/2:
-            d = sqrt(self.rtl**2 - self.cl**2)
-            if self.cl > self.rtl/sqrt(2.): return self.x + s*(self.w/2 + (self.z - self.h/2 - ht)*d/self.cl)/r1
-            else: return self.x + s*( self.w/2 + d )/r1
-
-        #in this range pass the upper corner edge info
-        elif ht >= self.z+self.h/2:
-            d = sqrt(self.rt**2 - self.c**2)
-            if self.c > self.rt/sqrt(2.): return self.x + s*(self.w/2 + (ht - self.z - self.h/2 )*d/self.c)/r1
-            else: return self.x + s*( self.w/2 + d )/r1
-
-        #in this range, pass the middle info (straight sides)
-        else: return self.x + s*self.w/2/r1
-
-
-    # get the top or bottom of the opening
-    # ht is the x position; s is the side: 1 for top, -1 for bottom
-    #
-    def edgeV(self, ht, s):
-        dist = abs(self.x-ht)
-        def radialAdjust(dist, sideVal):
-            '''take the distance and adjust for radial geometry, return dist.
-            '''
-            if radialized:
-                if slope:
-                    dist = dist * abs(dims['t']*sin(sideVal*PI/(dims['t']*2)))
-                else:
-                    dist = dist * sideVal
-            return dist
-
-        if s > 0 :#and (dist <= self.edgeS(self.z+self.h/2+self.c,1)-self.x): #check top down
-            #hack for radialized masonry, import approx Z instead of self.top()
-            dist = radialAdjust(dist, self.top())
-
-            #no arch on top, flat
-            if not self.r: return self.z+self.h/2
-
-            #pointed arch on top
-            elif self.v > self.w/2:
-                circVal = circ(dist-self.w/2+self.r,self.r+self.rt)
-                if circVal == None:
-                    return None
-                else: return self.z+self.h/2+circVal
-
-            #domed arch on top
-            else:
-                circVal = circ(dist,self.r+self.rt)
-                if circVal == None:
-                    return None
-                else: return self.z+self.h/2+self.v-self.r+circVal
-
-        else:#and (dist <= self.edgeS(self.z-self.h/2-self.cl,1)-self.x): #check bottom up
-            #hack for radialized masonry, import approx Z instead of self.top()
-            dist = radialAdjust(dist, self.btm())
-
-            #no arch on bottom
-            if not self.rl: return self.z-self.h/2
-
-            #pointed arch on bottom
-            elif self.vl > self.w/2:
-                circVal = circ(dist-self.w/2+self.rl,self.rl+self.rtl)
-                if circVal == None:
-                    return None
-                else: return self.z-self.h/2-circVal
-
-            #old conditional? if (dist-self.w/2+self.rl)<=(self.rl+self.rtl):
-            #domed arch on bottom
-            else:
-                circVal = circ(dist,self.rl+self.rtl) # dist-self.w/2+self.rl
-                if circVal == None:
-                    return None
-                else: return self.z-self.h/2-self.vl+self.rl-circVal
-
-    # and this never happens - but, leave it as failsafe :)
-        print("got all the way out of the edgeV!  Not good!")
-        print("opening x = ", self.x, ", opening z = ", self.z)
-        return 0.0
-    #
-    def edgeBev(self, ht):
-        if ht > (self.z + self.h/2): return 0.0
-        if ht < (self.z - self.h/2): return 0.0
-        if radialized:
-            if slope: r1 = abs(dims['t']*sin(ht*PI/(dims['t']*2)))
-            else: r1 = abs(ht)
-        else: r1 = 1
-        bevel = self.b / r1
-        return bevel
-#
-##
-#
-
-    def __init__(self, xpos, zpos, width, height, archHeight=0, archThk=0,
-                 archHeightLower=0, archThkLower=0, bevel=0, edgeThk=0):
-        self.x = float(xpos)
-        self.z = float(zpos)
-        self.w = float(width)
-        self.h = float(height)
-        self.rt = archThk
-        self.rtl = archThkLower
-        self.v = archHeight
-        self.vl = archHeightLower
-        if self.w <= 0: self.w = SMALL
-
-        #find the upper arch radius
-        if archHeight >= width/2:
-            # just one arch, low long
-            self.r = (self.v**2)/self.w + self.w/4
-        elif archHeight <= 0:
-            # No arches
-            self.r = 0
-            self.v = 0
-        else:
-            # Two arches
-            self.r = (self.w**2)/(8*self.v) + self.v/2.
-            self.c = self.rt*cos(atan(self.w/(2*(self.r-self.v))))
-
-        #find the lower arch radius
-        if archHeightLower >= width/2:
-            self.rl = (self.vl**2)/self.w + self.w/4
-        elif archHeightLower <= 0:
-            self.rl = 0
-            self.vl = 0
-        else:
-            self.rl = (self.w**2)/(8*self.vl) + self.vl/2.
-            self.cl = self.rtl*cos(atan(self.w/(2*(self.rl-self.vl))))
-
-        #self.form = something?
-        self.b = float(bevel)
-        self.ts = edgeThk
-#
-#
-
-#class for the whole wall boundaries; a sub-class of "opening"
-class OpeningInv(opening):
-    #this is supposed to switch the sides of the opening
-    #so the wall will properly enclose the whole wall.
-    #We'll see if it works.
-
-    def edgeS(self, ht, s):
-        return opening.edgeS(self, ht, -s)
-
-    def edgeV(self, ht, s):
-        return opening.edgeV(self, ht, -s)
-
-#class rows in the wall
-class rowOb:
-    __doc__ = """\
-    This is the class for holding the data for individual rows of blocks.
-    each row is required to have some edge blocks, and can also have
-    intermediate sections of "normal" blocks.
-    """
-
-    #z = 0.
-    #h = 0.
-    radius = 1
-    EdgeOffset = 0.
-#    BlocksEdge = []
-#    RowSegments = []
-#    BlocksNorm = []
-
-    def FillBlocks(self):
-        # Set the radius variable, in the case of radial geometry
-        if radialized:
-            if slope: self.radius = dims['t']*(sin(self.z*PI/(dims['t']*2)))
-            else: self.radius = self.z
-
-        #initialize internal variables from global settings
-
-        SetH = settings['h']
-        SetHwt = settings['hwt']
-        SetWid = settings['w']
-        SetWidMin = settings['wm']
-        SetWidVar = settings['wv']
-        SetGrt = settings['g']
-        SetGrtVar = settings['gv']
-        SetRowHeightLink = settings['rwhl']
-        SetDepth = settings['d']
-        SetDepthVar = settings['dv']
-
-        #height weight, used for making shorter rows have narrower blocks, and vice-versa
-        hwt = ((self.h/SetH-1)*SetHwt+1)
-
-        # set variables for persistent values: loop optimization, readability, single ref for changes.
-
-        avgDist = hwt*SetWid/self.radius
-        minDist = SetWidMin/self.radius
-        deviation = hwt*SetWidVar/self.radius
-        grtOffset = SetGrt/(2*self.radius)
-
-        # init loop variables that may change...
-
-        grt = (SetGrt + rndc()*SetGrtVar)/(self.radius)
-        ThisBlockHeight = self.h+rndc()*(1-SetRowHeightLink)*SetGrtVar
-        ThisBlockDepth = rndd()*SetDepthVar+SetDepth
-
-        for segment in self.RowSegments:
-            divs = fill(segment[0]+grtOffset, segment[1]-grtOffset, avgDist, minDist, deviation)
-
-            #loop through the divisions, adding blocks for each one
-            for i in range(len(divs)-1):
-                ThisBlockx = (divs[i]+divs[i+1])/2
-                ThisBlockw = divs[i+1]-divs[i]-grt
-
-                self.BlocksNorm.append([ThisBlockx, self.z, ThisBlockw, ThisBlockHeight, ThisBlockDepth, None])
-
-                if SetDepthVar: # vary depth
-                    ThisBlockDepth = rndd()*SetDepthVar+SetDepth
-
-                if SetGrtVar: # vary grout
-                    grt = (SetGrt + rndc()*SetGrtVar)/(self.radius)
-                    ThisBlockHeight = self.h+rndc()*(1-SetRowHeightLink)*SetGrtVar
-
-
-    def __init__(self,centerheight,rowheight,edgeoffset = 0.):
-        self.z = float(centerheight)
-        self.h = float(rowheight)
-        self.EdgeOffset = float(edgeoffset)
-
-#THIS INITILIZATION IS IMPORTANT!  OTHERWISE ALL OBJECTS WILL HAVE THE SAME LISTS!
-        self.BlocksEdge = []
-        self.RowSegments = []
-        self.BlocksNorm = []
-
-#
-def arch(ra,rt,x,z, archStart, archEnd, bevel, bevAngle, vll):
-    __doc__ = '''\
-    Makes a list of faces and vertexes for arches.
-    ra: the radius of the arch, to the center of the bricks
-    rt: the thickness of the arch
-    x: x center location of the circular arc, as if the arch opening were centered on x = 0
-    z: z center location of the arch
-    anglebeg: start angle of the arch, in radians, from vertical?
-    angleend: end angle of the arch, in radians, from vertical?
-    bevel: how much to bevel the inside of the arch.
-    vll: how long is the vertex list already?
-    '''
-    avlist = []
-    aflist = []
-
-    #initialize internal variables for global settings
-#overkill?
-    SetH = settings['h']
-    SetHwt = settings['hwt']
-    SetWid = settings['w']
-    SetWidMin = settings['wm']
-    SetWidVar = settings['wv']
-    SetGrt = settings['g']
-    SetGrtVar = settings['gv']
-    SetRowHeightLink = settings['rwhl']
-    SetDepth = settings['d']
-    SetDepthVar = settings['dv']
-
-    # Init loop variables
-
-    def bevelEdgeOffset(offsets, bevel, side):
-        '''
-        Take the block offsets and modify it for the correct bevel.
-
-        offsets = the offset list. See MakeABlock
-        bevel = how much to offset the edge
-        side = -1 for left (right side), 1 for right (left side)
-        '''
-        left = (0,2,3)
-        right = (4,6,7)
-        if side == 1: pointsToAffect = right
-        else: pointsToAffect = left
-        for num in pointsToAffect:
-            offsets[num] = offsets[num][:]
-            offsets[num][0] += -bevel * side
-
-    ArchInner = ra-rt/2
-    ArchOuter = ra+rt/2-SetGrt + rndc()*SetGrtVar
-
-    DepthBack = -SetDepth/2-rndc()*SetDepthVar
-    DepthFront = SetDepth/2+rndc()*SetDepthVar
-
-    if radialized: subdivision = settings['sdv']
-    else: subdivision = 0.12
-
-    grt = (SetGrt + rndc()*SetGrtVar)/(2*ra) # init grout offset for loop
-    # set up the offsets, it will be the same for every block
-    offsets = ([[0]*2 + [bevel]] + [[0]*3]*3)*2
-
-    #make the divisions in the "length" of the arch
-    divs = fill(archStart, archEnd, settings['w']/ra, settings['wm']/ra, settings['wv']/ra)
-
-    for i in range(len(divs)-1):
-        if i == 0:
-            ThisOffset = offsets[:]
-            bevelEdgeOffset(ThisOffset, bevAngle, -1)
-        elif i == len(divs)-2:
-            ThisOffset = offsets[:]
-            bevelEdgeOffset(ThisOffset, bevAngle, 1)
-        else:
-            ThisOffset = offsets
-
-        geom = MakeABlock([divs[i]+grt, divs[i+1]-grt, ArchInner, ArchOuter, DepthBack, DepthFront],
-                          subdivision, len(avlist) + vll, ThisOffset, [], None, ra)
-
-        avlist += geom[0]
-        aflist += geom[1]
-
-        if SetDepthVar: # vary depth
-            DepthBack = -SetDepth/2-rndc()*SetDepthVar
-            DepthFront = SetDepth/2+rndc()*SetDepthVar
-
-        if SetGrtVar: # vary grout
-            grt = (settings['g'] + rndc()*SetGrtVar)/(2*ra)
-            ArchOuter = ra+rt/2-SetGrt + rndc()*SetGrtVar
-
-    for i,vert in enumerate(avlist):
-        v0 = vert[2]*sin(vert[0]) + x
-        v1 = vert[1]
-        v2 = vert[2]*cos(vert[0]) + z
-
-        if radialized==1:
-            if slope==1: r1 = dims['t']*(sin(v2*PI/(dims['t']*2)))
-            else: r1 = v2
-            v0 = v0/r1
-
-        avlist[i] = [v0,v1,v2]
-
-    return (avlist,aflist)
-
-#
-def sketch():
-    __doc__ = """\
-    The 'sketch' function creates a list of openings from the general specifications passed to it.
-    It takes curved and domed walls into account, placing the openings at the appropriate angular locations
-    """
-    boundlist = []
-    for x in openingSpecs:
-        if x['rp']:
-            if radialized: r1 = x['z']
-            else: r1 = 1
-
-            if x['x'] > (x['w'] + settings['wm']):spacing = x['x']/r1
-            else: spacing = (x['w'] + settings['wm'])/r1
-
-            minspacing = (x['w'] + settings['wm'])/r1
-
-            divs = fill(dims['s'],dims['e'],spacing,minspacing,center=1)
-
-            for posidx in range(len(divs)-2):
-                boundlist.append(opening(divs[posidx+1],x['z'],x['w'],x['h'],x['v'],x['t'],x['vl'],x['tl'],x['b']))
-
-        else: boundlist.append(opening(x['x'],x['z'],x['w'],x['h'],x['v'],x['t'],x['vl'],x['tl'],x['b']))
-        #check for overlaping edges?
-
-    return boundlist
-
-
-def wedgeBlocks(row, opening, leftPos, rightPos, edgeBinary, r1):
-    __doc__ = """\
-    Makes wedge blocks for the left and right sides, depending
-    example:
-    wedgeBlocks(row, LeftWedgeEdge, LNerEdge, LEB, r1)
-    wedgeBlocks(row, RNerEdge, RightWedgeEdge, REB, r1)
-    """
-    wedgeEdges = fill(leftPos, rightPos, settings['w']/r1, settings['wm']/r1,
-                      settings['wv']/r1)
-
-    for i in range(len(wedgeEdges)-1):
-        x = (wedgeEdges[i+1] + wedgeEdges[i])/2
-        grt = (settings['g'] + rndd()*settings['gv'])/r1
-        w = wedgeEdges[i+1] - wedgeEdges[i] - grt
-
-        ThisBlockDepth = rndd()*settings['dv']+settings['d']
-
-#edgeV may return "None" - causing TypeError for math op.
-#use 0 until wedgeBlocks operation worked out
-        edgeVal = opening.edgeV(x-w/2,edgeBinary)
-        if edgeVal == None: edgeVal = 0.0
-
-        LeftVertOffset =  -( row.z - (row.h/2)*edgeBinary - edgeVal )
-
-#edgeV may return "None" - causing TypeError for math op.
-#use 0 until wedgeBlocks operation worked out
-        edgeVal = opening.edgeV(x+w/2,edgeBinary)
-        if edgeVal == None: edgeVal = 0.0
-
-        RightVertOffset = -( row.z - (row.h/2)*edgeBinary - edgeVal )
-
-        #Wedges are on top = off, blank, off, blank
-        #Wedges are on btm = blank, off, blank, off
-        ThisBlockOffsets = [[0,0,LeftVertOffset]]*2 + [[0]*3]*2 + [[0,0,RightVertOffset]]*2
-
-        # Instert or append "blank" for top or bottom wedges.
-        if edgeBinary == 1: ThisBlockOffsets = ThisBlockOffsets + [[0]*3]*2
-        else: ThisBlockOffsets = [[0]*3]*2 + ThisBlockOffsets
-
-        row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,ThisBlockOffsets])
-
-    return None
-
-def bevelBlockOffsets(offsets, bevel, side):
-    '''
-    Take the block offsets and modify it for the correct bevel.
-
-    offsets = the offset list. See MakeABlock
-    bevel = how much to offset the edge
-    side = -1 for left (right side), 1 for right (left side)
-    '''
-#    left = (4,6)
-#    right = (0,2)
-    if side == 1: pointsToAffect = (0,2) # right
-    else: pointsToAffect = (4,6) # left
-    for num in pointsToAffect:
-        offsets[num] = offsets[num][:]
-        offsets[num][0] += bevel * side
-
-def rowProcessing(row, Thesketch, WallBoundaries):
-    __doc__ = """\
-    Take row and opening data and process a single row, adding edge and fill blocks to the row data.
-    """
-    #set end blocks
-    #check for openings, record top and bottom of row for right and left of each
-    #if both top and bottom intersect create blocks on each edge, appropriate to the size of the overlap
-    #if only one side intersects, run fill to get edge positions, but this should never happen
-    #
-
-    if radialized:#this checks for radial stonework, and sets the row radius if required
-        if slope: r1 = abs(dims['t']*sin(row.z*PI/(dims['t']*2)))
-        else: r1 = abs(row.z)
-    else: r1 = 1
-
-    # set the edge grout thickness, especially with radial stonework in mind
-    edgrt = settings['ge']*(settings['g']/2 + rndc()*settings['gv'])/(2*r1)
-
-    # Sets up a list of  intersections of top of row with openings,
-    #from left to right [left edge of opening, right edge of opening, etc...]
-    #initially just the left and right edge of the wall
-    edgetop = [[dims['s']+row.EdgeOffset/r1+edgrt,WallBoundaries], [dims['e']+row.EdgeOffset/r1-edgrt,WallBoundaries]]
-    # Same as edgetop, but for the bottms of the rows
-    edgebtm = [[dims['s']+row.EdgeOffset/r1+edgrt,WallBoundaries], [dims['e']+row.EdgeOffset/r1-edgrt,WallBoundaries]]
-
-    # set up some useful values for the top and bottom of the rows.
-    rowTop = row.z+row.h/2
-    rowBtm = row.z-row.h/2
-
-    for hole in Thesketch:
-        #check the top and bottom of the row, looking at the opening from the right
-        e = [hole.edgeS(rowTop, -1), hole.edgeS(rowBtm, -1)]
-
-        # If either one hit the opening, make split points for the left side of the opening.
-        if e[0] or e[1]:
-            e += [hole.edgeS(rowTop, 1), hole.edgeS(rowBtm, 1)]
-
-            # If one of them missed for some reason, set that value to
-            # the middle of the opening.
-            for i,pos in enumerate(e):
-                if pos == None: e[i] = hole.x
-
-            # add the intersects to the list of edge points
-            edgetop.append([e[0],hole])
-            edgetop.append([e[2],hole])
-            edgebtm.append([e[1],hole])
-            edgebtm.append([e[3],hole])
-
-    # We want to make the walls in order, so sort the intersects.
-    # This is where you would want to remove edge points that are out of order
-    # so that you don't get the "oddity where overlapping openings create blocks inversely" problem
-    edgetop.sort()
-    edgebtm.sort()
-
-    #these two loops trim the edges to the limits of the wall.  This way openings extending outside the wall don't enlarge the wall.
-    while True:
-        try:
-            if (edgetop[-1][0] > dims['e']+row.EdgeOffset/r1) or (edgebtm[-1][0] > dims['e']+row.EdgeOffset/r1):
-                edgetop[-2:] = []
-                edgebtm[-2:] = []
-            else: break
-        except IndexError: break
-    #still trimming the edges...
-    while True:
-        try:
-            if (edgetop[0][0] < dims['s']+row.EdgeOffset/r1) or (edgebtm[0][0] < dims['s']+row.EdgeOffset/r1):
-                edgetop[:2] = []
-                edgebtm[:2] = []
-            else: break
-        except IndexError: break
-
-    #make those edge blocks and rows!  Wooo!
-    #This loop goes through each section, (a pair of points in edgetop)
-    #and places the edge blocks and inbetween normal block zones into the row object
-    for OpnSplitNo in range(int(len(edgetop)/2)):
-        #left edge is edge<x>[2*OpnSplitNo], right edge edgex[2*OpnSplitNo+1]
-        leftEdgeIndex = 2*OpnSplitNo
-        rightEdgeIndex = 2*OpnSplitNo + 1
-        # get the openings, to save time and confusion
-        leftOpening = edgetop[leftEdgeIndex][1]
-        rightOpening = edgetop[rightEdgeIndex][1]
-        #find the difference between the edge top and bottom on both sides
-        LTop = edgetop[leftEdgeIndex][0]
-        LBtm = edgebtm[leftEdgeIndex][0]
-        RTop = edgetop[rightEdgeIndex][0]
-        RBtm = edgebtm[rightEdgeIndex][0]
-        LDiff = LBtm-LTop
-        RDiff = RTop-RBtm
-
-        #which is furthur out on each side, top or bottom?
-        if LDiff > 0:
-            LFarEdge = LTop #The furthest edge left
-            LNerEdge = LBtm #the nearer edge left
-            LEB = 1 #Left Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom
-        else:
-            LFarEdge = LBtm
-            LNerEdge = LTop
-            LEB = -1
-
-        if RDiff > 0:
-            RFarEdge = RTop #The furthest edge right
-            RNerEdge = RBtm #the nearer edge right
-            REB = 1 #Right Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom
-
-        else:
-            RFarEdge = RBtm #The furthest edge right
-            RNerEdge = RTop
-            REB = -1 #Right Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom
-
-        #The space between the closest edges of the openings in this section of the row
-        InnerDiff = RNerEdge - LNerEdge
-        #The mid point between the nearest edges
-        InnerMid = (RNerEdge + LNerEdge)/2
-
-        #maximum distance to span with one block
-        MaxWid = (settings['w']+settings['wv'])/r1
-        AveWid = settings['w']
-        MinWid = settings['wm']
-
-        #check the left and right sides for wedge blocks
-        #Check and run the left edge first
-        #find the edge of the correct side, offset for minimum block height.  The LEB decides top or bottom
-        ZPositionCheck = row.z + (row.h/2-settings['hm'])*LEB
-#edgeS may return "None"
-        LeftWedgeEdge = leftOpening.edgeS(ZPositionCheck,1)
-
-        if (abs(LDiff) > AveWid) or (not LeftWedgeEdge):
-            #make wedge blocks
-            if not LeftWedgeEdge: LeftWedgeEdge = leftOpening.x
-            wedgeBlocks(row, leftOpening, LeftWedgeEdge, LNerEdge, LEB, r1)
-            #set the near and far edge settings to vertical, so the other edge blocks don't interfere
-            LFarEdge , LTop , LBtm = LNerEdge, LNerEdge, LNerEdge
-            LDiff = 0
-
-        #Now do the wedge blocks for the right, same drill... repeated code?
-        #find the edge of the correct side, offset for minimum block height.  The REB decides top or bottom
-        ZPositionCheck = row.z + (row.h/2-settings['hm'])*REB
-#edgeS may return "None"
-        RightWedgeEdge = rightOpening.edgeS(ZPositionCheck,-1)
-        if (abs(RDiff) > AveWid) or (not RightWedgeEdge):
-            #make wedge blocks
-            if not RightWedgeEdge: RightWedgeEdge = rightOpening.x
-            wedgeBlocks(row, rightOpening, RNerEdge, RightWedgeEdge, REB, r1)
-            #set the near and far edge settings to vertical, so the other edge blocks don't interfere
-            RFarEdge , RTop , RBtm = RNerEdge, RNerEdge, RNerEdge
-            RDiff = 0
-
-        #Check to see if the edges are close enough toegther to warrant a single block filling it
-        if (InnerDiff < MaxWid):
-            #if this is true, then this row is just one block!
-            x = (LNerEdge + RNerEdge)/2.
-            w = InnerDiff
-            ThisBlockDepth = rndd()*settings['dv']+settings['d']
-            BtmOff = LBtm - LNerEdge
-            TopOff = LTop - LNerEdge
-            ThisBlockOffsets = [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2
-            BtmOff = RBtm - RNerEdge
-            TopOff = RTop - RNerEdge
-            ThisBlockOffsets += [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2
-            bevel = leftOpening.edgeBev(rowTop)
-            bevelBlockOffsets(ThisBlockOffsets, bevel, 1)
-            bevel = rightOpening.edgeBev(rowTop)
-            bevelBlockOffsets(ThisBlockOffsets, bevel, -1)
-            row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,ThisBlockOffsets])
-            continue
-
-        # it's not one block, must be two or more
-        # set up the offsets for the left
-        BtmOff = LBtm - LNerEdge
-        TopOff = LTop - LNerEdge
-        leftOffsets = [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2 + [[0]*3]*4
-        bevelL = leftOpening.edgeBev(rowTop)
-        bevelBlockOffsets(leftOffsets, bevelL, 1)
-        # and now for the right
-        BtmOff = RBtm - RNerEdge
-        TopOff = RTop - RNerEdge
-        rightOffsets = [[0]*3]*4 + [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2
-        bevelR = rightOpening.edgeBev(rowTop)
-        bevelBlockOffsets(rightOffsets, bevelR, -1)
-        # check to see if it is only two blocks
-        if (InnerDiff < MaxWid*2):
-        #this row is just two blocks! Left block, then right block
-            #div is the x position of the dividing point between the two bricks
-            div = InnerMid + (rndd()*settings['wv'])/r1
-            #set the grout distance, since we need grout seperation between the blocks
-            grt = (settings['g'] + rndc()*settings['gv'])/r1
-            #set the x position and width for the left block
-            x = (div + LNerEdge)/2 - grt/4
-            w = (div - LNerEdge) - grt/2
-            ThisBlockDepth = rndd()*settings['dv']+settings['d']
-            #For reference: EdgeBlocks = [[x,z,w,h,d,[corner offset matrix]],[etc.]]
-            row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,leftOffsets])
-            #Initialize for the block on the right side
-            x = (div + RNerEdge)/2 + grt/4
-            w = (RNerEdge - div) - grt/2
-            ThisBlockDepth = rndd()*settings['dv']+settings['d']
-            row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,rightOffsets])
-            continue
-
-        #program should only get here if there are more than two blocks in the row, and no wedge blocks
-
-        #make Left edge block
-        #set the grout
-        grt = (settings['g'] + rndc()*settings['gv'])/r1
-        #set the x position and width for the left block
-        widOptions = [settings['w'], bevelL + settings['wm'], leftOpening.ts]
-        baseWid = max(widOptions)
-        w = (rndd()*settings['wv']+baseWid+row.EdgeOffset)
-        widOptions[0] = settings['wm']
-        widOptions[2] = w
-        w = max(widOptions) / r1 - grt
-        x = w/2 + LNerEdge + grt/2
-        BlockRowL = x + w/2
-        ThisBlockDepth = rndd()*settings['dv']+settings['d']
-        row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,leftOffsets])
-
-        #make Right edge block
-        #set the grout
-        grt = (settings['g'] + rndc()*settings['gv'])/r1
-        #set the x position and width for the left block
-        widOptions = [settings['w'], bevelR + settings['wm'], rightOpening.ts]
-        baseWid = max(widOptions)
-        w = (rndd()*settings['wv']+baseWid+row.EdgeOffset)
-        widOptions[0] = settings['wm']
-        widOptions[2] = w
-        w = max(widOptions) / r1 - grt
-        x = RNerEdge - w/2 - grt/2
-        BlockRowR = x - w/2
-        ThisBlockDepth = rndd()*settings['dv']+settings['d']
-        row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,rightOffsets])
-
-        row.RowSegments.append([BlockRowL,BlockRowR])
-    return None
-
-
-def plan(Thesketch, oldrows = 0):
-    __doc__ = """\
-    The 'plan' function takes the data generated by the sketch function and the global settings
-    and creates a list of blocks.
-    It passes out a list of row heights, edge positions, edge blocks, and rows of blocks.
-    """
-    # if we were passed a list of rows already, use those; else make a list.
-    if oldrows: rows = oldrows
-    else:
-        #rows holds the important information common to all rows
-        #rows = [list of row objects]
-        rows = []
-
-        #splits are places where we NEED a row division, to accomidate openings
-        #add a split for the bottom row
-        splits = [dims['b']+settings['hb']]
-
-        #add a split for each critical point on each opening
-        for hole in Thesketch: splits += hole.crits()
-
-        #and, a split for the top row
-        splits.append(dims['t']-settings['ht'])
-        splits.sort()
-
-        #divs are the normal old row divisions, add them between the top and bottom split
-        divs = fill(splits[0],splits[-1],settings['h'],settings['hm']+settings['g'],settings['hv'])[1:-1]
-
-        #remove the divisions that are too close to the splits, so we don't get tiny thin rows
-        for i in range(len(divs)-1,-1,-1):
-            for j in range(len(splits)):
-                diff = abs(divs[i] - splits[j])
-                #(settings['hm']+settings['g']) is the old minimum value
-                if diff < (settings['h']-settings['hv']+settings['g']):
-                    del(divs[i])
-                    break
-
-        #now merge the divs and splits lists
-        divs += splits
-
-        #add bottom and/or top points, if bottom and/or top row heights are more than zero
-        if settings['hb']>0: divs.insert(0,dims['b'])
-        if settings['ht']>0: divs.append(dims['t'])
-
-        divs.sort()
-
-        #trim the rows to the bottom and top of the wall
-        if divs[0] < dims['b']: divs[:1] = []
-        if divs[-1] > dims['t']: divs[-1:] = []
-
-        #now, make the data for each row
-        #rows = [[center height,row height,edge offset],[etc.]]
-
-        divCount = len(divs)-1 # number of divs to check
-        divCheck = 0 # current div entry
-
-        while divCheck < divCount:
-            RowZ = (divs[divCheck]+divs[divCheck+1])/2
-            RowHeight = divs[divCheck+1]-divs[divCheck]-settings['g']+rndc()*settings['rwhl']*settings['gv']
-            EdgeOffset = settings['eoff']*(fmod(divCheck,2)-0.5)+settings['eoffv']*rndd()
-
-            # if row height is too shallow: delete next div entry, decrement total, and recheck current entry.
-            if RowHeight < settings['hm']:
-                del(divs[divCheck+1])
-                divCount -= 1 # Adjust count for removed div entry.
-                continue
-
-            rows.append(rowOb(RowZ, RowHeight, EdgeOffset))
-
-            divCheck += 1 # on to next div entry
-
-    #set up a special opening object to handle the edges of the wall
-    x = (dims['s'] + dims['e'])/2
-    z = (dims['t'] + dims['b'])/2
-    w = (dims['e'] - dims['s'])
-    h = (dims['t'] - dims['b'])
-    WallBoundaries = OpeningInv(x,z,w,h)
-
-    #Go over each row in the list, set up edge blocks and block sections
-    for rownum in range(len(rows)):
-        rowProcessing(rows[rownum], Thesketch, WallBoundaries)
-
-    #now return the things everyone needs
-    #return [rows,edgeBlocks,blockRows,Asketch]
-    return [rows,Thesketch]
-
-
-def archGeneration(hole, vlist, flist, sideSign):
-    __doc__ = """\
-    Makes arches for the top and bottom, depending on sideSign
-    example, Lower arch:
-    archGeneration(hole, vlist, flist, -1)
-    example, Upper arch:
-    archGeneration(hole, vlist, flist, 1)
-    hole is the opening object that the arch is for
-    add the verticies to vlist
-    add the faces to flist
-    sideSign is + or - 1, for the top or bottom arch. Other values may cause errors.
-    """
-
-    # working arrays for vectors and faces
-    avlist = []
-    aflist = []
-
-    # Top (1) or bottom (-1)
-    if sideSign == -1:
-        r = hole.rl #radius of the arch
-        rt = hole.rtl #thickness of the arch (stone height)
-        v = hole.vl #height of the arch
-        c = hole.cl
-    else:
-        r = hole.r #radius of the arch
-        rt = hole.rt #thickness of the arch (stone height)
-        v = hole.v #height of the arch
-        c = hole.c
-
-    ra = r + rt/2 #average radius of the arch
-    x = hole.x
-    w = hole.w
-    h = hole.h
-    z = hole.z
-    bev = hole.b
-    sideSignInv = -sideSign
-
-    if v > w/2: #two arcs, to make a pointed arch
-        # positioning
-        zpos = z + (h/2)*sideSign
-        xoffset = r - w/2
-        #left side top, right side bottom
-        #angles reference straight up, and are in radians
-        bevRad = r + bev
-        bevHt = sqrt(bevRad**2 - (bevRad - (w/2 + bev))**2)
-        midHalfAngle = atan(v/(r-w/2))
-        midHalfAngleBevel = atan(bevHt/(r-w/2))
-        bevelAngle = midHalfAngle - midHalfAngleBevel
-        anglebeg = (PI/2)*(sideSignInv)
-        angleend = (PI/2)*(sideSignInv) + midHalfAngle
-
-        avlist,aflist = arch(ra,rt,(xoffset)*(sideSign),zpos,anglebeg,angleend,bev,bevelAngle,len(vlist))
-
-        for i,vert in enumerate(avlist): avlist[i] = [vert[0]+hole.x,vert[1],vert[2]]
-        vlist += avlist
-        flist += aflist
-
-        #right side top, left side bottom
-
-        #angles reference straight up, and are in radians
-        anglebeg = (PI/2)*(sideSign) - midHalfAngle
-        angleend = (PI/2)*(sideSign)
-
-        avlist,aflist = arch(ra,rt,(xoffset)*(sideSignInv),zpos,anglebeg,angleend,bev,bevelAngle,len(vlist))
-
-        for i,vert in enumerate(avlist): avlist[i] = [vert[0]+hole.x,vert[1],vert[2]]
-
-        vlist += avlist
-        flist += aflist
-
-        #keystone
-        Dpth = settings['d']+rndc()*settings['dv']
-        Grout = settings['g'] + rndc()*settings['gv']
-        angleBevel = (PI/2)*(sideSign) - midHalfAngle
-        Wdth = (rt - Grout - bev) * 2 * sin(angleBevel) * sideSign #note, sin may be negative
-        MidZ = ((sideSign)*(bevHt + h/2.0) + z) + (rt - Grout - bev) * cos(angleBevel) #note, cos may come out negative too
-        nearCorner = sideSign*(MidZ - z) - v - h/2
-
-        if sideSign == 1:
-            TopHt = hole.top() - MidZ - Grout
-            BtmHt = nearCorner
-        else:
-            BtmHt =  - (hole.btm() - MidZ) - Grout
-            TopHt = nearCorner
-
-        # set the amout to bevel the keystone
-        keystoneBevel = (bevHt - v)*sideSign
-        if Wdth >= settings['hm']:
-            avlist,aflist = MakeAKeystone(x, Wdth, MidZ, TopHt, BtmHt, Dpth, keystoneBevel, len(vlist))
-
-            if radialized:
-                for i,vert in enumerate(avlist):
-                    if slope: r1 = dims['t']*sin(vert[2]*PI/(dims['t']*2))
-                    else: r1 = vert[2]
-                    avlist[i] = [((vert[0]-hole.x)/r1)+hole.x,vert[1],vert[2]]
-
-            vlist += avlist
-            flist += aflist
-# remove "debug note" once bevel is finalized.
-        else: print("keystone was too narrow - " + str(Wdth))
-
-    else: # only one arc - curve not peak.
-#bottom (sideSign -1) arch has poorly sized blocks...
-
-        zpos = z + (sideSign * (h/2 + v - r)) # single arc positioning
-
-        #angles reference straight up, and are in radians
-        if sideSign == -1: angleOffset = PI
-        else: angleOffset = 0.0
-
-        if v < w/2:
-            halfangle = atan(w/(2*(r-v)))
-
-            anglebeg = angleOffset - halfangle
-            angleend = angleOffset + halfangle
-        else:
-            anglebeg = angleOffset - PI/2
-            angleend = angleOffset + PI/2
-
-        avlist,aflist = arch(ra,rt,0,zpos,anglebeg,angleend,bev,0.0,len(vlist))
-
-        for i,vert in enumerate(avlist): avlist[i] = [vert[0]+x,vert[1],vert[2]]
-
-        vlist += avlist
-        flist += aflist
-
-        #Make the Side Stones
-        grt = (settings['g'] + rndc()*settings['gv'])
-        width = sqrt(rt**2 - c**2) - grt
-
-        if c > settings['hm'] + grt and c < width + grt:
-            if radialized: subdivision = settings['sdv'] * (zpos + (h/2)*sideSign)
-            else: subdivision = settings['sdv']
-
-            #set the height of the block, it should be as high as the max corner position, minus grout
-            height = c - grt*(0.5 + c/(width + grt))
-
-            #the vertical offset for the short side of the block
-            voff = sideSign * (settings['hm'] - height)
-            xstart = w/2
-            zstart = z + sideSign * (h/2 + grt/2)
-            woffset = width*(settings['hm'] + grt/2)/(c - grt/2)
-            depth = rndd()*settings['dv']+settings['d']
-
-            if sideSign == 1:
-                offsets = [[0]*3]*6 + [[0]*2 + [voff]]*2
-                topSide = zstart+height
-                btmSide = zstart
-            else:
-                offsets = [[0]*3]*4 + [[0]*2 + [voff]]*2 + [[0]*3]*2
-                topSide = zstart
-                btmSide = zstart-height
-            # Do some stuff to incorporate bev here
-            bevelBlockOffsets(offsets, bev, -1)
-
-            avlist,aflist = MakeABlock([x-xstart-width, x-xstart- woffset, btmSide, topSide, -depth/2, depth/2], subdivision, len(vlist), Offsets=offsets, xBevScl=1)
-
-# top didn't use radialized in prev version; just noting for clarity - may need to revise for "sideSign == 1"
-            if radialized:
-                for i,vert in enumerate(avlist): avlist[i] = [((vert[0]-x)/vert[2])+x,vert[1],vert[2]]
-
-            vlist += avlist
-            flist += aflist
-
-# keep sizing same - neat arches = master masons :)
-#           grt = (settings['g'] + rndc()*settings['gv'])
-#           height = c - grt*(0.5 + c/(width + grt))
-# if grout varies may as well change width too... width = sqrt(rt**2 - c**2) - grt
-#           voff = sideSign * (settings['hm'] - height)
-#           woffset = width*(settings['hm'] + grt/2)/(c - grt/2)
-
-            if sideSign == 1:
-                offsets = [[0]*3]*2 + [[0]*2 + [voff]]*2 + [[0]*3]*4
-                topSide = zstart+height
-                btmSide = zstart
-            else:
-                offsets = [[0]*2 + [voff]]*2 + [[0]*3]*6
-                topSide = zstart
-                btmSide = zstart-height
-            # Do some stuff to incorporate bev here
-            bevelBlockOffsets(offsets, bev, 1)
-
-            avlist,aflist = MakeABlock([x+xstart+woffset, x+xstart+width, btmSide, topSide, -depth/2, depth/2], subdivision, len(vlist), Offsets=offsets, xBevScl=1)
-
-# top didn't use radialized in prev version; just noting for clarity - may need to revise for "sideSign == 1"
-            if radialized:
-                for i,vert in enumerate(avlist): avlist[i] = [((vert[0]-x)/vert[2])+x,vert[1],vert[2]]
-
-            vlist += avlist
-            flist += aflist
-    return None
-
-
-def build(Aplan):
-    __doc__ = """\
-    Build creates the geometry for the wall, based on the
-    "Aplan" object from the "plan" function.  If physics is
-    enabled, then it make a number of individual blocks with
-    physics interaction enabled.  Otherwise it creates
-    geometry for the blocks, arches, etc. of the wall.
-    """
-
-    vlist = []
-    flist = []
-    rows = Aplan[0]
-
-#dead code...
-    #Physics setup is horribly broken.  Revisit when new API is in place.
-    '''if False: #settings['physics']:
-        geom = MakeABlock([-0.5,0.5,-0.5,0.5,-0.5,0.5], 3, 0, None,[], 3*settings['b']/(settings['w'] + settings['h'] + settings['d']))
-        blockmesh = Blender.Mesh.New('block')
-        vlist += geom[0]
-        flist += geom[1]
-        blockmesh.verts.extend(vlist)
-        blockmesh.faces.extend(flist)
-
-        for block in Aplan[1]:
-            x,z,w,h,d = block[:5]
-            block = scn.objects.new(blockmesh, 'block')
-            block.loc = [x, 0, z]
-            block.size = [w,d,h]
-            block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY']
-            block.rbShapeBoundType = Blender.Object.RBShapes['BOX']
-
-
-        for row in Aplan[2]:#row=[xstart,xend,z,h]
-            #currently, radial geometry is disabled for physics blocks setup
-            if radialized:
-                if slope: r1 = dims['t']*sin(row[2]*PI/(dims['t']*2))
-                else: r1 = row[2]
-
-            else: r1 = 1
-
-            divs = fill(row[0], row[1], settings['w'], settings['wm'], settings['wv'])
-            for i in range(len(divs)-1):
-                block = scn.objects.new(blockmesh, 'block')
-                block.loc = [(divs[i]+divs[i+1])/2, 0, row[2]]
-                block.size = [(divs[i + 1] - divs[i]) - settings['g'], (settings['d'] + rndd()*settings['dv'])*(1-settings['t']*((row[3]-dims['b'])/(dims['t'] - dims['b']))), row[3]]
-                block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY']
-                block.rbShapeBoundType = Blender.Object.RBShapes['BOX']
-
-        return None'''
-#end dead code...
-
-    # all the edge blocks, redacted
-    #AllBlocks = [[x,z,w,h,d,[corner offset matrix]],[etc.]]
-
-    #loop through each row, adding the normal old blocks
-    for rowidx in range(len(rows)):#row = row object
-        rows[rowidx].FillBlocks()
-
-    AllBlocks = []
-
-    #  If the wall is set to merge blocks, check all the blocks to see if you can merge any
-#seems to only merge vertical, should do horizontal too
-    if bigBlock:
-        for rowidx in range(len(rows)-1):
-            if radialized:
-                if slope: r1 = dims['t']*sin(abs(rows[rowidx].z)*PI/(dims['t']*2))
-                else: r1 = abs(rows[rowidx].z)
-            else: r1 = 1
-
-            Tollerance = settings['g']/r1
-            idxThis = len(rows[rowidx].BlocksNorm[:]) - 1
-            idxThat = len(rows[rowidx+1].BlocksNorm[:]) - 1
-
-            while True:
-                # end loop when either array idx wraps
-                if idxThis < 0 or idxThat < 0: break
-
-                blockThis = rows[rowidx].BlocksNorm[idxThis]
-                blockThat = rows[rowidx+1].BlocksNorm[idxThat]
-
-#seems to only merge vertical, should do horizontal too...
-                cx, cz, cw, ch, cd = blockThis[:5]
-                ox, oz, ow, oh, od = blockThat[:5]
-
-                if (abs(cw - ow) < Tollerance) and (abs(cx - ox) < Tollerance) :
-                    if cw > ow: BlockW = ow
-                    else: BlockW = cw
-
-                    AllBlocks.append([(cx+ox)/2,(cz+oz+(oh-ch)/2)/2,BlockW,abs(cz-oz)+(ch+oh)/2,(cd+od)/2,None])
-
-                    rows[rowidx].BlocksNorm.pop(idxThis)
-                    rows[rowidx+1].BlocksNorm.pop(idxThat)
-                    idxThis -= 1
-                    idxThat -= 1
-
-                elif cx > ox: idxThis -= 1
-                else: idxThat -= 1
-
-    #
-    #
-    # Add blocks to create a "shelf/platform".
-    # Does not account for openings (crosses gaps - which is a good thing)
-    if shelfExt:
-        SetGrtOff = settings['g']/2 # half grout for block size modifier
-
-        # Use wall block settings for shelf
-        SetBW = settings['w']
-        SetBWVar = settings['wv']
-        SetBWMin = settings['wm']
-        SetBH = settings['h']
-
-        # Shelf area settings
-        ShelfLft = shelfSpecs['x']
-        ShelfBtm = shelfSpecs['z']
-        ShelfEnd = ShelfLft + shelfSpecs['w']
-        ShelfTop = ShelfBtm + shelfSpecs['h']
-        ShelfThk = shelfSpecs['d'] * 2 # use double-depth due to offsets to position at cursor.
-
-        # Use "corners" to adjust position so not centered on depth.
-        # Facing shelf, at cursor (middle of wall blocks) - this way no gaps between platform and wall face due to wall block depth.
-        wallDepth = settings['d']/2 # offset by wall depth so step depth matches UI setting :)
-        if shelfBack: # place blocks on backside of wall
-            ShelfOffsets = [[0,ShelfThk/2,0],[0,wallDepth,0],[0,ShelfThk/2,0],[0,wallDepth,0],[0,ShelfThk/2,0],[0,wallDepth,0],[0,ShelfThk/2,0],[0,wallDepth,0]]
-        else:
-            ShelfOffsets = [[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0]]
-
-    # Add blocks for each "shelf row" in area
-        while ShelfBtm < ShelfTop:
-
-            # Make blocks for each row - based on rowOb::fillblocks
-            # Does not vary grout.
-            divs = fill(ShelfLft, ShelfEnd, SetBW, SetBWMin, SetBWVar)
-
-            #loop through the row divisions, adding blocks for each one
-            for i in range(len(divs)-1):
-                ThisBlockx = (divs[i]+divs[i+1])/2
-                ThisBlockw = divs[i+1]-divs[i]-SetGrtOff
-
-                AllBlocks.append([ThisBlockx, ShelfBtm, ThisBlockw, SetBH, ShelfThk, ShelfOffsets])
-
-            ShelfBtm += SetBH + SetGrtOff # moving up to next row...
-    #
-    #
-    # Add blocks to create "steps".
-    # Does not account for openings (crosses gaps - which is a good thing)
-    if stepMod:
-        SetGrtOff = settings['g']/2 # half grout for block size modifier
-
-        # Vary block width by wall block variations.
-        SetWidVar = settings['wv']
-        SetWidMin = settings['wm']
-
-        StepXMod = stepSpecs['t'] # width of step/tread, also sets basic block size.
-        StepZMod = stepSpecs['v']
-
-        StepLft = stepSpecs['x']
-        StepRt = stepSpecs['x'] + stepSpecs['w']
-        StepBtm = stepSpecs['z'] + StepZMod/2 # Start offset for centered blocks
-        StepWide = stepSpecs['w']
-        StepTop = StepBtm + stepSpecs['h']
-        StepThk = stepSpecs['d'] * 2 # use double-depth due to offsets to position at cursor.
-
-        # Use "corners" to adjust steps so not centered on depth.
-        # Facing steps, at cursor (middle of wall blocks) - this way no gaps between steps and wall face due to wall block depth.
-        # Also, will work fine as stand-alone if not used with wall (try block depth 0 and see what happens).
-        wallDepth = settings['d']/2 # offset by wall depth so step depth matches UI setting :)
-        if stepBack: # place blocks on backside of wall
-            StepOffsets = [[0,StepThk/2,0],[0,wallDepth,0],[0,StepThk/2,0],[0,wallDepth,0],[0,StepThk/2,0],[0,wallDepth,0],[0,StepThk/2,0],[0,wallDepth,0]]
-        else:
-            StepOffsets = [[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0]]
-
-    # Add steps for each "step row" in area (neg width is interesting but prevented)
-        while StepBtm < StepTop and StepWide > 0:
-
-            # Make blocks for each step row - based on rowOb::fillblocks
-            # Does not vary grout.
-
-            if stepOnly: # "cantilevered steps"
-                if stepLeft:
-                    stepStart = StepRt - StepXMod
-                else:
-                    stepStart = StepLft
-
-                AllBlocks.append([stepStart, StepBtm, StepXMod, StepZMod, StepThk, StepOffsets])
-            else:
-                divs = fill(StepLft, StepRt, StepXMod, SetWidMin, SetWidVar)
-
-                #loop through the row divisions, adding blocks for each one
-                for i in range(len(divs)-1):
-                    ThisBlockx = (divs[i]+divs[i+1])/2
-                    ThisBlockw = divs[i+1]-divs[i]-SetGrtOff
-
-                    AllBlocks.append([ThisBlockx, StepBtm, ThisBlockw, StepZMod, StepThk, StepOffsets])
-
-            StepBtm += StepZMod + SetGrtOff # moving up to next row...
-            StepWide -= StepXMod # reduce step width
-
-            # adjust side limit depending on direction of steps
-            if stepLeft:
-                StepRt -= StepXMod # move in from right
-            else:
-                StepLft += StepXMod # move in from left
-
-
-    #Copy all the blocks out of the rows
-    for row in rows:
-        AllBlocks += row.BlocksEdge
-        AllBlocks += row.BlocksNorm
-
-    #This loop makes individual blocks for each block specified in the plan
-    for block in AllBlocks:
-        x,z,w,h,d,corners = block
-        if radialized:
-            if slope: r1 = dims['t']*sin(z*PI/(dims['t']*2))
-            else: r1 = z
-        else: r1 = 1
-
-        geom = MakeABlock([x-w/2, x+w/2, z-h/2, z+h/2, -d/2, d/2], settings['sdv'], len(vlist), corners, None, settings['b']+rndd()*settings['bv'], r1)
-        vlist += geom[0]
-        flist += geom[1]
-
-
-    # This loop makes Arches for every opening specified in the plan.
-    for hole in Aplan[1]:
-        # lower arch stones
-        if hole.vl > 0 and hole.rtl > (settings['g'] + settings['hm']):#make lower arch blocks
-            archGeneration(hole, vlist, flist, -1)
-
-        #top arch stones
-        if hole.v > 0 and hole.rt > (settings['g'] + settings['hm']):#make upper arch blocks
-            archGeneration(hole, vlist, flist, 1)
-    #
-
-    #Warp all the points for domed stonework
-    if slope:
-        for i,vert in enumerate(vlist):
-            vlist[i] = [vert[0],(dims['t']+vert[1])*cos(vert[2]*PI/(2*dims['t'])),(dims['t']+vert[1])*sin(vert[2]*PI/(2*dims['t']))]
-
-    #Warp all the points for radial stonework
-    if radialized:
-        for i,vert in enumerate(vlist):
-            vlist[i] = [vert[2]*cos(vert[0]),vert[2]*sin(vert[0]),vert[1]]
-
-    return vlist, flist
-
-
-#The main function
-def createWall(radial, curve, openings, mergeBlox, shelf, shelfSide,
-        steps, stepDir, stepBare, stepSide):
-    __doc__ = """\
-    Call all the funcitons you need to make a wall, return the verts and faces.
-    """
-    global radialized
-    global slope
-    global openingSpecs
-    global bigBlock
-    global shelfExt
-    global stepMod
-    global stepLeft
-    global shelfBack
-    global stepOnly
-    global stepBack
-
-    # set all the working variables from passed parameters
-
-    radialized = radial
-    slope = curve
-    openingSpecs = openings
-    bigBlock = mergeBlox
-    shelfExt = shelf
-    stepMod = steps
-    stepLeft = stepDir
-    shelfBack = shelfSide
-    stepOnly = stepBare
-    stepBack = stepSide
-
-    asketch = sketch()
-    aplan = plan(asketch, 0)
-
-    return build(aplan)
-
diff --git a/release/scripts/addons_contrib/add_mesh_walls/Wallfactory.py b/release/scripts/addons_contrib/add_mesh_walls/Wallfactory.py
deleted file mode 100644
index 661e55c..0000000
--- a/release/scripts/addons_contrib/add_mesh_walls/Wallfactory.py
+++ /dev/null
@@ -1,647 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you may 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.
-#	51 Franklin Street, Fifth Floor
-#	Boston, MA 02110-1301, USA
-#
-# or go online at: http://www.gnu.org/licenses/ to view license options.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-#
-# This module contains the UI definition, display, and processing (create mesh)
-# functions.
-#
-# The routines to generate the vertices for the wall are found in the "Blocks" module.
-#
-
-
-import bpy
-import mathutils
-from bpy.props import *
-from add_mesh_walls.Blocks import *
-#from add_mesh_walls.preset_utils import *
-
-
-#
-class add_mesh_wallb(bpy.types.Operator):
-    '''Add a wall mesh.'''
-    bl_idname = "mesh.wall_add"
-    bl_label = "Add A Masonry Wall"
-    bl_options = {'REGISTER', 'UNDO'} # removes object, does not reset to "last" modification.
-    bl_description = "adds a block wall"
-
-    # UI items - API for properties - User accessable variables... 
-# not all options are via UI, and some operations just don't work yet.
-
-    # only create object when True
-    # False allows modifying several parameters without creating object
-    ConstructTog = BoolProperty(name="Construct",
-                                description="Generate the object",
-                                default = True)
-
-# need to modify so radial makes a tower (normal); want "flat" setting to make disk (alternate)
-    # make the wall circular - if not sloped it's a flat disc
-    RadialTog = BoolProperty(name="Radial",
-                             description="Make masonry radial",
-                             default = False)
-
-    # curve the wall - if radial creates dome.
-    SlopeTog = BoolProperty(name="Curved",
-                            description="Make masonry sloped, or curved",
-                            default = False)
-
-#need to review defaults and limits for all of these UI objects.
-
-    # wall area/size
-    WallStart = FloatProperty(name="Start",
-                              description="Left side, or start angle",
-                              default=-10.0, min=-100, max=100.0)
-    WallEnd = FloatProperty(name="End",
-                            description="Right side, or end angle",
-                            default=10.0, min=0.0, max=100.0)
-    WallBottom = FloatProperty(name="Bottom",
-                               description="Lower height or radius",
-                               default=0.0, min=-100, max=100)
-    WallTop = FloatProperty(name="Top",
-                            description="Upper height or radius",
-                            default=15.0, min=0.0, max=100.0)
-    EdgeOffset = FloatProperty(name="Edging",
-                               description="Block staggering on wall sides",
-                               default=0.6, min=0.0, max=100.0)
-
-    # block sizing
-    Width = FloatProperty(name="Width",
-                          description="Average width of each block",
-                          default=1.5, min=0.01, max=100.0)
-    WidthVariance = FloatProperty(name="Variance",
-                                  description="Random variance of block width",
-                                  default=0.5, min=0.0, max=100.0)
-    WidthMinimum = FloatProperty(name="Minimum",
-                                 description="Absolute minimum block width",
-                                 default=0.5, min=0.01, max=100.0)
-    Height = FloatProperty(name="Height",
-                           description="Average Height of each block",
-                           default=0.7, min=0.01, max=100.0)
-    HeightVariance = FloatProperty(name="Variance",
-                                   description="Random variance of block Height",
-                                   default=0.3, min=0.0, max=100.0)
-    HeightMinimum = FloatProperty(name="Minimum",
-                                  description="Absolute minimum block Height",
-                                  default=0.25, min=0.01, max=100.0)
-    Depth = FloatProperty(name="Depth",
-                          description="Average Depth of each block",
-                          default=2.0, min=0.01, max=100.0)
-    DepthVariance = FloatProperty(name="Variance",
-                                  description="Random variance of block Depth",
-                                  default=0.1, min=0.0, max=100.0)
-    DepthMinimum = FloatProperty(name="Minimum",
-                                 description="Absolute minimum block Depth",
-                                 default=1.0, min=0.01, max=100.0)
-    MergeBlock = BoolProperty(name="Merge Blocks",
-                              description="Make big blocks (merge closely adjoining blocks)",
-                              default = False)
-
-    # edging for blocks
-    Grout = FloatProperty(name="Thickness",
-                          description="Distance between blocks",
-                          default=0.1, min=-10.0, max=10.0)
-    GroutVariance = FloatProperty(name="Variance",
-                                  description="Random variance of block Grout",
-                                  default=0.03, min=0.0, max=100.0)
-    GroutDepth = FloatProperty(name="Depth",
-                          description="Grout Depth from the face of the blocks",
-                          default=0.1, min=0.0001, max=10.0)
-    GroutDepthVariance = FloatProperty(name="Variance",
-                                  description="Random variance of block Grout Depth",
-                                  default=0.03, min=0.0, max=100.0)
-    GroutEdge = BoolProperty(name="Edging",
-                             description="Grout perimiter",
-                             default = False)
-
-    #properties for openings
-    Opening1Tog = BoolProperty(name="Opening(s)",description="Make windows or doors", default = True)
-    Opening1Width = FloatProperty(name="Width",
-                                  description="The Width of opening 1",
-                                  default=2.5, min=0.01, max=100.0)
-    Opening1Height = FloatProperty(name="Height",
-                                   description="The Height of opening 1",
-                                   default=3.5, min=0.01, max=100.0)
-    Opening1X = FloatProperty(name="Indent",
-                              description="The x position or spacing of opening 1",
-                              default=5.0, min=-100, max=100.0)
-    Opening1Z = FloatProperty(name="Bottom",
-                              description="The z position of opening 1",
-                              default=5.0, min=-100, max=100.0)
-    Opening1Repeat = BoolProperty(name="Repeat",
-                                  description="make multiple openings, with spacing X1",
-                                  default=False)
-    Opening1TopArchTog = BoolProperty(name="Top Arch",
-                                      description="Add an arch to the top of opening 1",
-                                      default=True)
-    Opening1TopArch = FloatProperty(name="Curve",
-                                    description="Height of the arch on the top of the opening",
-                                    default=2.5, min=0.001, max=100.0)
-    Opening1TopArchThickness = FloatProperty(name="Thickness",
-                                             description="Thickness of the arch on the top of the opening",
-                                             default=0.75, min=0.001, max=100.0)
-    Opening1BtmArchTog = BoolProperty(name="Bottom Arch",
-                                      description="Add an arch to the bottom of opening 1",
-                                      default=False)
-    Opening1BtmArch = FloatProperty(name="Curve",
-                                    description="Height of the arch on the bottom of the opening",
-                                    default=1.0, min=0.01, max=100.0)
-    Opening1BtmArchThickness = FloatProperty(name="Thickness",
-                                             description="Thickness of the arch on the bottom of the opening",
-                                             default=0.5, min=0.01, max=100.0)
-    Opening1Bevel = FloatProperty(name="Bevel",
-                                             description="Angle block face",
-                                             default=0.25, min=-10.0, max=10.0)
-
-
-    # openings on top of wall.
-    CrenelTog = BoolProperty(name="Crenels",
-                             description="Make openings along top of wall",
-                             default = False)
-    CrenelXP = FloatProperty(name="Width %",
-                             description="Gap width in wall based % of wall width",
-                             default=0.25, min=0.10, max=1.0)
-    CrenelZP = FloatProperty(name="Height %",
-                             description="Crenel Height as % of wall height",
-                             default=0.10, min=0.10, max=1.0)
-
-
-    # narrow openings in wall.
-#need to prevent overlap with arch openings - though inversion is an interesting effect.
-    SlotTog = BoolProperty(name="Slots",
-                           description="Make narrow openings in wall",
-                           default = False)
-    SlotRpt = BoolProperty(name="Repeat",
-                           description="Repeat slots along wall",
-                           default = False)
-    SlotWdg = BoolProperty(name="Wedged (n/a)",
-                           description="Bevel edges of slots",
-                           default = False)
-    SlotX = FloatProperty(name="Indent",
-                          description="The x position or spacing of slots",
-                          default=0.0, min=-100, max=100.0)
-    SlotGap = FloatProperty(name="Opening",
-                            description="The opening size of slots",
-                            default=0.5, min=0.10, max=100.0)
-    SlotV = BoolProperty(name="Vertical",
-                         description="Vertical slots",
-                         default = True)
-    SlotVH = FloatProperty(name="Height",
-                           description="Height of vertical slot",
-                           default=3.5, min=0.10, max=100.0)
-    SlotVBtm = FloatProperty(name="Bottom",
-                             description="Z position for slot",
-                             default=5.00, min=-100.0, max=100.0)
-    SlotH = BoolProperty(name="Horizontal",
-                         description="Horizontal slots",
-                         default = False)
-    SlotHW = FloatProperty(name="Width",
-                           description="Width of horizontal slot",
-                           default=2.5, min=0.10, max=100.0)
-#this should offset from VBtm... maybe make a % like crenels?
-    SlotHBtm = FloatProperty(name="Bottom",
-                             description="Z position for horizontal slot",
-                             default=5.50, min=-100.0, max=100.0)
-
-
-    #properties for shelf (extend blocks in area)
-    ShelfTog = BoolProperty(name="Shelf",description="Add blocks in area by depth to make shelf/platform", default = False)
-    ShelfX = FloatProperty(name="Left",
-                              description="The x position of Shelf",
-                              default=-5.00, min=-100, max=100.0)
-    ShelfZ = FloatProperty(name="Bottom",
-                              description="The z position of Shelf",
-                              default=10.0, min=-100, max=100.0)
-    ShelfH = FloatProperty(name="Height",
-                                   description="The Height of Shelf area",
-                                   default=1.0, min=0.01, max=100.0)
-    ShelfW = FloatProperty(name="Width",
-                                  description="The Width of shelf area",
-                                  default=5.0, min=0.01, max=100.0)
-    ShelfD = FloatProperty(name="Depth",
-                          description="Depth of each block for shelf (from cursor + 1/2 wall depth)",
-                          default=2.0, min=0.01, max=100.0)
-    ShelfBack = BoolProperty(name="Backside",description="Shelf on backside of wall", default = False)
-
-
-    #properties for steps (extend blocks in area, progressive width)
-    StepTog = BoolProperty(name="Steps",description="Add blocks in area by depth with progressive width to make steps", default = False)
-    StepX = FloatProperty(name="Left",
-                              description="The x position of steps",
-                              default=-9.00, min=-100, max=100.0)
-    StepZ = FloatProperty(name="Bottom",
-                              description="The z position of steps",
-                              default=0.0, min=-100, max=100.0)
-    StepH = FloatProperty(name="Height",
-                                   description="The Height of step area",
-                                   default=10.0, min=0.01, max=100.0)
-    StepW = FloatProperty(name="Width",
-                                  description="The Width of step area",
-                                  default=8.0, min=0.01, max=100.0)
-    StepD = FloatProperty(name="Depth",
-                          description="Depth of each block for steps (from cursor + 1/2 wall depth)",
-                          default=1.0, min=0.01, max=100.0)
-    StepV = FloatProperty(name="Riser",
-                                  description="Height of each step",
-                                  default=0.70, min=0.01, max=100.0)
-    StepT = FloatProperty(name="Tread",
-                          description="Width of each step",
-                          default=1.0, min=0.01, max=100.0)
-    StepLeft = BoolProperty(name="High Left",description="Height left; else Height right", default = False)
-    StepOnly = BoolProperty(name="No Blocks",description="Steps only, no supporting blocks", default = False)
-    StepBack = BoolProperty(name="Backside",description="Steps on backside of wall", default = False)
-
-##
-##
-#####
-# Show the UI - expose the properties.
-#####
-##
-##
-    # Display the toolbox options
-
-    def draw(self, context):
-
-        layout = self.layout
-
-        box = layout.box()
-        box.prop(self, 'ConstructTog')
-
-# Wall area (size/position)
-        box = layout.box()
-        box.label(text='Wall Size (area)')
-        box.prop(self, 'WallStart')
-        box.prop(self, 'WallEnd')
-        box.prop(self, 'WallBottom')
-        box.prop(self, 'WallTop')
-        box.prop(self, 'EdgeOffset')
-
-# Wall block sizing
-        box = layout.box()
-        box.label(text='Block Sizing')
-        box.prop(self, 'MergeBlock')
-#add checkbox for "fixed" sizing (ignore variance) a.k.a. bricks.
-        box.prop(self, 'Width')
-        box.prop(self, 'WidthVariance')
-        box.prop(self, 'WidthMinimum')
-        box.prop(self, 'Height')
-        box.prop(self, 'HeightVariance')
-        box.prop(self, 'HeightMinimum')
-        box.prop(self, 'Depth')
-        box.prop(self, 'DepthVariance')
-        box.prop(self, 'DepthMinimum')
-
-# grout settings
-        box = layout.box()
-        bl_label = "Grout"
-        box.label(text='Grout')
-        box.prop(self, 'Grout')
-        box.prop(self, 'GroutVariance')
-        box.prop(self, 'GroutDepth')
-        box.prop(self, 'GroutDepthVariance')
-#		box.prop(self, 'GroutEdge')
-
-# Wall shape modifiers
-        box = layout.box()
-        box.label(text='Wall Shape')
-        box.prop(self, 'RadialTog')
-        box.prop(self, 'SlopeTog')
-
-# Openings (doors, windows; arched)
-        box = layout.box()
-        box.prop(self, 'Opening1Tog')
-        if self.properties.Opening1Tog:
-            box.prop(self, 'Opening1Width')
-            box.prop(self, 'Opening1Height')
-            box.prop(self, 'Opening1X')
-            box.prop(self, 'Opening1Z')
-            box.prop(self, 'Opening1Bevel')
-            box.prop(self, 'Opening1Repeat')
-            box.prop(self, 'Opening1TopArchTog')
-            box.prop(self, 'Opening1TopArch')
-            box.prop(self, 'Opening1TopArchThickness')
-            box.prop(self, 'Opening1BtmArchTog')
-            box.prop(self, 'Opening1BtmArch')
-            box.prop(self, 'Opening1BtmArchThickness')
-
-# Slots (narrow openings)
-        box = layout.box()
-        box.prop(self, 'SlotTog')
-        if self.properties.SlotTog:
-#		box.prop(self, 'SlotWdg')
-            box.prop(self, 'SlotX')
-            box.prop(self, 'SlotGap')
-            box.prop(self, 'SlotRpt')
-            box.prop(self, 'SlotV')
-            box.prop(self, 'SlotVH')
-            box.prop(self, 'SlotVBtm')
-            box.prop(self, 'SlotH')
-            box.prop(self, 'SlotHW')
-            box.prop(self, 'SlotHBtm')
-
-# Crenels, gaps in top of wall
-        box = layout.box()
-        box.prop(self, 'CrenelTog')
-        if self.properties.CrenelTog:
-            box.prop(self, 'CrenelXP')
-            box.prop(self, 'CrenelZP')
-
-# Shelfing (protrusions)
-        box = layout.box()
-        box.prop(self, 'ShelfTog')
-        if self.properties.ShelfTog:
-            box.prop(self, 'ShelfX')
-            box.prop(self, 'ShelfZ')
-            box.prop(self, 'ShelfH')
-            box.prop(self, 'ShelfW')
-            box.prop(self, 'ShelfD')
-            box.prop(self, 'ShelfBack')
-
-# Steps
-        box = layout.box()
-        box.prop(self, 'StepTog')
-        if self.properties.StepTog:
-            box.prop(self, 'StepX')
-            box.prop(self, 'StepZ')
-            box.prop(self, 'StepH')
-            box.prop(self, 'StepW')
-            box.prop(self, 'StepD')
-            box.prop(self, 'StepV')
-            box.prop(self, 'StepT')
-            box.prop(self, 'StepLeft')
-            box.prop(self, 'StepOnly')
-            box.prop(self, 'StepBack')
-
-##
-#####
-# Respond to UI - get the properties set by user.
-#####
-##
-    # Check and process UI settings to generate masonry
-
-    def execute(self, context):
-
-        global radialized
-        global slope
-        global openingSpecs
-        global bigBlock
-        global shelfExt
-        global stepMod
-        global stepLeft
-        global shelfBack
-        global stepOnly
-        global stepBack
-
-        # Create the wall when enabled (skip regen iterations when off)
-        if not self.properties.ConstructTog: return {'FINISHED'}
-
-        #enter the settings for the wall dimensions (area)
-# start can't be zero - min/max don't matter [if max less than end] but zero don't workie.
-# start can't exceed end.
-        if not self.properties.WallStart or self.properties.WallStart >= self.properties.WallEnd:
-            self.properties.WallStart = NOTZERO # Reset UI if input out of bounds...
-
-        dims['s'] = self.properties.WallStart
-        dims['e'] = self.properties.WallEnd
-        dims['b'] = self.properties.WallBottom
-        dims['t'] = self.properties.WallTop
-
-        settings['eoff'] = self.properties.EdgeOffset
-
-        #retrieve the settings for the wall block properties
-        settings['w'] = self.properties.Width
-        settings['wv'] = self.properties.WidthVariance
-        settings['wm'] = self.properties.WidthMinimum
-        if not radialized: settings['sdv'] = settings['w'] 
-        else: settings['sdv'] = 0.12
-
-        settings['h'] = self.properties.Height
-        settings['hv'] = self.properties.HeightVariance
-        settings['hm'] = self.properties.HeightMinimum
-
-        settings['d'] = self.properties.Depth
-        settings['dv'] = self.properties.DepthVariance
-        settings['dm'] = self.properties.DepthMinimum
-
-        if self.properties.MergeBlock:
-            bigBlock = 1
-        else: bigBlock = 0
-
-        settings['g'] = self.properties.Grout
-        settings['gv'] = self.properties.GroutVariance
-        settings['gd'] = self.properties.GroutDepth
-        settings['gdv'] = self.properties.GroutDepthVariance
-
-        if self.properties.GroutEdge: settings['ge'] = 1
-        else: settings['ge'] = 0
-
-        # set wall shape modifiers
-        if self.properties.RadialTog:
-            radialized = 1
-#eliminate to allow user control for start/completion?
-            dims['s'] = 0.0 # complete radial
-            if dims['e'] > PI*2: dims['e'] = PI*2 # max end for circle
-            if dims['b'] < settings['g']: dims['b'] = settings['g'] # min bottom for grout extension
-        else: radialized = 0
-
-        if self.properties.SlopeTog: slope = 1
-        else: slope = 0
-
-
-        shelfExt = 0
-        shelfBack = 0
-
-	# Add shelf if enabled
-        if self.properties.ShelfTog:
-            shelfExt = 1
-            shelfSpecs['h'] = self.properties.ShelfH
-            shelfSpecs['w'] = self.properties.ShelfW
-            shelfSpecs['d'] = self.properties.ShelfD
-            shelfSpecs['x'] = self.properties.ShelfX
-            shelfSpecs['z'] = self.properties.ShelfZ
-
-            if self.properties.ShelfBack:
-                shelfBack = 1
-
-
-        stepMod = 0
-        stepLeft = 0
-        stepOnly = 0
-        stepBack = 0
-
-	# Make steps if enabled
-        if self.properties.StepTog:
-            stepMod = 1
-            stepSpecs['x'] = self.properties.StepX
-            stepSpecs['z'] = self.properties.StepZ
-            stepSpecs['h'] = self.properties.StepH
-            stepSpecs['w'] = self.properties.StepW
-            stepSpecs['d'] = self.properties.StepD
-            stepSpecs['v'] = self.properties.StepV
-            stepSpecs['t'] = self.properties.StepT
-
-            if self.properties.StepLeft:
-                stepLeft = 1
-
-            if self.properties.StepOnly:
-                stepOnly = 1
-
-            if self.properties.StepBack:
-                stepBack = 1
-
-
-        #enter the settings for the openings
-#when openings overlap they create inverse stonework - interesting but not the desired effect :)
-#if opening width == indent*2 the edge blocks fail (row of blocks cross opening) - bug.
-        openingSpecs = []
-        openingIdx = 0 # track opening array references for multiple uses
-
-        # general openings with arch options - can be windows or doors.
-        if self.properties.Opening1Tog:
-            # set defaults...
-            openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
-
-            openingSpecs[openingIdx]['w'] = self.properties.Opening1Width
-            openingSpecs[openingIdx]['h'] = self.properties.Opening1Height
-            openingSpecs[openingIdx]['x'] = self.properties.Opening1X
-            openingSpecs[openingIdx]['z'] = self.properties.Opening1Z
-            openingSpecs[openingIdx]['rp'] = self.properties.Opening1Repeat
-
-            if self.properties.Opening1TopArchTog:
-                openingSpecs[openingIdx]['v'] = self.properties.Opening1TopArch
-                openingSpecs[openingIdx]['t'] = self.properties.Opening1TopArchThickness
-
-            if self.properties.Opening1BtmArchTog:
-                openingSpecs[openingIdx]['vl'] = self.properties.Opening1BtmArch
-                openingSpecs[openingIdx]['tl'] = self.properties.Opening1BtmArchThickness
-            
-            openingSpecs[openingIdx]['b'] = self.properties.Opening1Bevel
-
-            openingIdx += 1 # count window/door/arch openings
-
-        # Slots (narrow openings)
-        if self.properties.SlotTog:
-
-            if self.properties.SlotV: # vertical slots
-                # set defaults...
-                openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':0, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
-
-                openingSpecs[openingIdx]['w'] = self.properties.SlotGap
-                openingSpecs[openingIdx]['h'] = self.properties.SlotVH
-                openingSpecs[openingIdx]['x'] = self.properties.SlotX
-                openingSpecs[openingIdx]['z'] = self.properties.SlotVBtm
-                openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt
-
-                # make them pointy...
-                openingSpecs[openingIdx]['v'] = self.properties.SlotGap
-                openingSpecs[openingIdx]['t'] = self.properties.SlotGap/2
-                openingSpecs[openingIdx]['vl'] = self.properties.SlotGap
-                openingSpecs[openingIdx]['tl'] = self.properties.SlotGap/2
-
-                openingIdx += 1 # count vertical slot openings
-
-# need to handle overlap of H and V slots...
-
-            if self.properties.SlotH: # Horizontal slots
-                # set defaults...
-                openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':0, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
-
-                openingSpecs[openingIdx]['w'] = self.properties.SlotHW
-                openingSpecs[openingIdx]['h'] = self.properties.SlotGap
-                openingSpecs[openingIdx]['x'] = self.properties.SlotX
-                openingSpecs[openingIdx]['z'] = self.properties.SlotHBtm
-#horizontal repeat isn't same spacing as vertical...
-                openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt
-
-                # make them pointy...
-# want arc to go sideways... maybe wedge will be sufficient and can skip horiz arcs.
-#				openingSpecs[openingIdx]['v'] = self.properties.SlotGap
-#				openingSpecs[openingIdx]['t'] = self.properties.SlotGap/2
-#				openingSpecs[openingIdx]['vl'] = self.properties.SlotGap
-#				openingSpecs[openingIdx]['tl'] = self.properties.SlotGap/2
-
-                openingIdx += 1 # count horizontal slot openings
-
-
-        # Crenellations (top row openings)
-        if self.properties.CrenelTog:
-
-# add bottom arch option?
-# perhaps a repeat toggle...
-# if crenel opening overlaps with arch opening it fills with blocks...
-
-            # set defaults...
-            openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
-
-            wallW = self.properties.WallEnd - self.properties.WallStart
-            crenelW = wallW*self.properties.CrenelXP # Width % opening.
-
-            wallH = self.properties.WallTop - self.properties.WallBottom
-            crenelH = wallH*self.properties.CrenelZP # % proportional height.
-
-            openingSpecs[openingIdx]['w'] = crenelW
-            openingSpecs[openingIdx]['h'] = crenelH
-
-            # calculate the spacing between openings.
-            # this isn't the absolute start (left), it's opening center offset relative to cursor (space between openings)...
-            openingSpecs[openingIdx]['x'] = crenelW*2-1 # assume standard spacing
-
-            if not radialized: # normal wall?
-                # set indent 0 (center) if opening is 50% or more of wall width, no repeat.
-                if crenelW*2 >= wallW:
-                    openingSpecs[openingIdx]['x'] = 0
-                    openingSpecs[openingIdx]['rp'] = 0
-
-            openingSpecs[openingIdx]['z'] = self.properties.WallTop - (crenelH/2) # set bottom of opening (center of hole)
-
-            openingIdx += 1 # count crenel openings
-
-        #
-        # Process the user settings to generate a wall
-        #
-        # generate the list of vertices for the wall...
-        verts_array, faces_array = createWall(radialized, slope, openingSpecs, bigBlock,
-                shelfExt, shelfBack, stepMod, stepLeft, stepOnly, stepBack)
-
-        # Create new mesh
-        mesh = bpy.data.meshes.new("Wall")
-
-        # Make a mesh from a list of verts/edges/faces.
-        mesh.from_pydata(verts_array, [], faces_array)
-
-        scene = context.scene
-
-        # Deselect all objects.
-        bpy.ops.object.select_all(action='DESELECT')
-
-        mesh.update()
-
-        ob_new = bpy.data.objects.new("Wall", mesh)
-        scene.objects.link(ob_new)
-# leave this out to prevent 'Tab key" going into edit mode :):):)
-# Use rmb click to select and still modify.
-        scene.objects.active = ob_new
-        ob_new.select = True
-
-        ob_new.location = tuple(context.scene.cursor_location)
-        ob_new.rotation_quaternion = [1.0,0.0,0.0,0.0]
-
-        return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_walls/__init__.py b/release/scripts/addons_contrib/add_mesh_walls/__init__.py
deleted file mode 100644
index bdea6a3..0000000
--- a/release/scripts/addons_contrib/add_mesh_walls/__init__.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you may 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.
-#	51 Franklin Street, Fifth Floor
-#	Boston, MA 02110-1301, USA
-#
-# or go online at: http://www.gnu.org/licenses/ to view license options.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    "name": "WallFactory",
-    "author": "Jambay, Brikbot",
-    "version": (0, 6, 0),
-    "blender": (2, 6, 1),
-    "location": "View3D > Add > Mesh",
-    "description": "Adds a block/rock wall.",
-    "warning": "WIP - updates pending and API not final for Blender",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Add_Mesh/WallFactory",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=111",
-    "category": "Add Mesh"}
-
-"""
-    This script builds a wall; at current 3D-Cursor location.
-    The wall can be modified to be a disc (radial), curved (slope), or dome (radial+slope).
-    Actually, it could be a path, or a tower, or anything made with blocks.
-    Crenelations also work which can double as arrow slits or support beam holes.
-    Slots, both vertical and horizontal, can be added as openings.
-    Steps and platforms may be added as extensions to the wall.
-"""
-
-# Version History
-# v0.59 2011/09/13	Restructured as "factory" set of scripts - preparation for including rocks.
-# v0.58 2010/12/06	Added "backside" for shelf and steps, and "cantilevered step" options.
-# v0.57 2010/12/03	Minor updates for Blender SVN maintenance.
-# v0.56 2010/11/19	Revised UI for property access/display.
-# V0.55 2010/11/15	Added stairs, improved shelf, fixed plan generation.
-# V0.54 2010/11/11	Changed version number to match sourceforge check-in,
-# 			basic shelf, and, some general cleanup.
-# V0.5 2010/10/31	Converted to Blender 2.5.4
-# V0.4 2009/11/29	Converted to Blender 2.5
-# V0.3 2009/11/28	Re-did much of the internals, everything works better, 
-# 			especially edge finding.
-# V0.2 2008/03/??	Reworked nearly all the code, many new features
-# V0.1 2007/09/14	First release!
-
-
-if "bpy" in locals():
-    import imp
-    imp.reload(Wallfactory)
-else:
-    from add_mesh_walls import Wallfactory
-
-import bpy
-
-################################################################################
-##### REGISTER #####
-
-# Define "Wall" menu
-def add_mesh_wall_ops(self, context):
-    self.layout.operator(Wallfactory.add_mesh_wallb.bl_idname, text="Block Wall", icon="PLUGIN")
-#    self.layout.operator(Wallfactory.add_mesh_wallr.bl_idname, text="Rocks", icon="PLUGIN")
-#    self.layout.operator(Wallfactory.add_mesh_column.bl_idname, text="Columns", icon="PLUGIN")
-
-
-# Add "Wall" options to the "Add Mesh" menu
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_mesh_add.append(add_mesh_wall_ops)
-#    bpy.types.INFO_MT_mesh_add.append(add_mesh_rockwall_button)
-#    bpy.types.INFO_MT_mesh_add.append(add_mesh_column_button)
-
-# Remove "Wall" options from the "Add Mesh" menu
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_mesh_add.remove(add_mesh_wall_ops)
-#    bpy.types.INFO_MT_mesh_add.remove(add_mesh_rockwall_button)
-#    bpy.types.INFO_MT_mesh_add.remove(add_mesh_column_button)
-    
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/animation_motion_trail.py b/release/scripts/addons_contrib/animation_motion_trail.py
deleted file mode 100644
index 778648a..0000000
--- a/release/scripts/addons_contrib/animation_motion_trail.py
+++ /dev/null
@@ -1,1739 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-
-bl_info = {
-    'name': "Motion Trail",
-    'author': "Bart Crouch",
-    'version': (3, 1, 1),
-    'blender': (2, 6, 1),
-    'location': "View3D > Toolbar > Motion Trail tab",
-    'warning': "",
-    'description': "Display and edit motion trails in the 3d-view",
-    'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/"\
-        "Py/Scripts/Animation/Motion_Trail",
-    'tracker_url': "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=26374",
-    'category': 'Animation'}
-
-
-import bgl
-import blf
-import bpy
-from bpy_extras import view3d_utils
-import math
-import mathutils
-
-
-# fake fcurve class, used if no fcurve is found for a path
-class fake_fcurve():
-    def __init__(self, object, index, rotation=False, scale=False):
-        # location
-        if not rotation and not scale:
-            self.loc = object.location[index]
-        # scale
-        elif scale:
-            self.loc = object.scale[index]
-        # rotation
-        elif rotation == 'QUATERNION':
-            self.loc = object.rotation_quaternion[index]
-        elif rotation == 'AXIS_ANGLE':
-            self.loc = object.rotation_axis_angle[index]
-        else:
-            self.loc = object.rotation_euler[index]
-        self.keyframe_points = []
-    
-    def evaluate(self, frame):
-        return(self.loc)
-    
-    def range(self):
-        return([])
-
-
-# get location curves of the given object
-def get_curves(object, child=False):
-    if object.animation_data and object.animation_data.action:
-        action = object.animation_data.action
-        if child:
-            # posebone
-            curves = [fc for fc in action.fcurves if len(fc.data_path)>=14 \
-            and fc.data_path[-9:]=='.location' and \
-            child.name in fc.data_path.split("\"")]
-        else:
-            # normal object
-            curves = [fc for fc in action.fcurves if \
-            fc.data_path == 'location']
-    elif object.animation_data and object.animation_data.use_nla:
-        curves = []
-        strips = []
-        for track in object.animation_data.nla_tracks:
-            not_handled = [s for s in track.strips]
-            while not_handled:
-                current_strip = not_handled.pop(-1)
-                if current_strip.action:
-                    strips.append(current_strip)
-                if current_strip.strips:
-                    # meta strip
-                    not_handled += [s for s in current_strip.strips]
-        
-        for strip in strips:
-            if child:
-                # posebone
-                curves = [fc for fc in strip.action.fcurves if \
-                len(fc.data_path)>=14 and fc.data_path[-9:]=='.location' \
-                and child.name in fc.data_path.split("\"")]
-            else:
-                # normal object
-                curves = [fc for fc in strip.action.fcurves if \
-                fc.data_path == 'location']
-            if curves:
-                # use first strip with location fcurves
-                break
-    else:
-        # should not happen?
-        curves = []
-    
-    # ensure we have three curves per object
-    fcx = None
-    fcy = None
-    fcz = None
-    for fc in curves:
-        if fc.array_index == 0:
-            fcx = fc
-        elif fc.array_index == 1:
-            fcy = fc
-        elif fc.array_index == 2:
-            fcz = fc
-    if fcx == None:
-        fcx = fake_fcurve(object, 0)
-    if fcy == None:
-        fcy = fake_fcurve(object, 1)
-    if fcz == None:
-        fcz = fake_fcurve(object, 2)
-
-    return([fcx, fcy, fcz])
-
-
-# turn screen coordinates (x,y) into world coordinates vector
-def screen_to_world(context, x, y):
-    depth_vector = view3d_utils.region_2d_to_vector_3d(\
-        context.region, context.region_data, [x,y])
-    vector = view3d_utils.region_2d_to_location_3d(\
-        context.region, context.region_data, [x,y], depth_vector)
-    
-    return(vector)
-
-
-# turn 3d world coordinates vector into screen coordinate integers (x,y)
-def world_to_screen(context, vector):
-    prj = context.region_data.perspective_matrix * \
-        mathutils.Vector((vector[0], vector[1], vector[2], 1.0))
-    width_half = context.region.width / 2.0
-    height_half = context.region.height / 2.0
-
-    x = int(width_half + width_half * (prj.x / prj.w))
-    y = int(height_half + height_half * (prj.y / prj.w))
-    
-    # correction for corner cases in perspective mode
-    if prj.w < 0:
-        if x < 0:
-            x = context.region.width * 2
-        else:
-            x = context.region.width * -2
-        if y < 0:
-            y = context.region.height * 2
-        else:
-            y = context.region.height * -2
-    
-    return(x, y)
-
-
-# calculate location of display_ob in worldspace
-def get_location(frame, display_ob, offset_ob, curves):
-    if offset_ob:
-        bpy.context.scene.frame_set(frame)
-        display_mat = getattr(display_ob, "matrix", False)
-        if not display_mat:
-            # posebones have "matrix", objects have "matrix_world"
-            display_mat = display_ob.matrix_world
-        if offset_ob:
-            loc = display_mat.to_translation() + \
-                offset_ob.matrix_world.to_translation()
-        else:
-            loc = display_mat.to_translation()
-    else:
-        fcx, fcy, fcz = curves
-        locx = fcx.evaluate(frame)
-        locy = fcy.evaluate(frame)
-        locz = fcz.evaluate(frame)
-        loc = mathutils.Vector([locx, locy, locz])
-    
-    return(loc)
-
-
-# get position of keyframes and handles at the start of dragging
-def get_original_animation_data(context, keyframes):
-    keyframes_ori = {}
-    handles_ori = {}
-    
-    if context.active_object and context.active_object.mode == 'POSE':
-        armature_ob = context.active_object
-        objects = [[armature_ob, pb, armature_ob] for pb in \
-            context.selected_pose_bones]
-    else:
-        objects = [[ob, False, False] for ob in context.selected_objects]
-    
-    for action_ob, child, offset_ob in objects:
-        if not action_ob.animation_data:
-            continue
-        curves = get_curves(action_ob, child)
-        if len(curves) == 0:
-            continue
-        fcx, fcy, fcz = curves
-        if child:
-            display_ob = child
-        else:
-            display_ob = action_ob
-        
-        # get keyframe positions
-        frame_old = context.scene.frame_current
-        keyframes_ori[display_ob.name] = {}
-        for frame in keyframes[display_ob.name]:
-            loc = get_location(frame, display_ob, offset_ob, curves)
-            keyframes_ori[display_ob.name][frame] = [frame, loc]
-        
-        # get handle positions
-        handles_ori[display_ob.name] = {}
-        for frame in keyframes[display_ob.name]:
-            handles_ori[display_ob.name][frame] = {}
-            left_x = [frame, fcx.evaluate(frame)]
-            right_x = [frame, fcx.evaluate(frame)]
-            for kf in fcx.keyframe_points:
-                if kf.co[0] == frame:
-                    left_x = kf.handle_left[:]
-                    right_x = kf.handle_right[:]
-                    break
-            left_y = [frame, fcy.evaluate(frame)]
-            right_y = [frame, fcy.evaluate(frame)]
-            for kf in fcy.keyframe_points:
-                if kf.co[0] == frame:
-                    left_y = kf.handle_left[:]
-                    right_y = kf.handle_right[:]
-                    break
-            left_z = [frame, fcz.evaluate(frame)]
-            right_z = [frame, fcz.evaluate(frame)]
-            for kf in fcz.keyframe_points:
-                if kf.co[0] == frame:
-                    left_z = kf.handle_left[:]
-                    right_z = kf.handle_right[:]
-                    break
-            handles_ori[display_ob.name][frame]["left"] = [left_x, left_y,
-                left_z]
-            handles_ori[display_ob.name][frame]["right"] = [right_x, right_y,
-                right_z]
-        
-        if context.scene.frame_current != frame_old:
-            context.scene.frame_set(frame_old)
-    
-    return(keyframes_ori, handles_ori)
-
-
-# callback function that calculates positions of all things that need be drawn
-def calc_callback(self, context):
-    if context.active_object and context.active_object.mode == 'POSE':
-        armature_ob = context.active_object
-        objects = [[armature_ob, pb, armature_ob] for pb in \
-            context.selected_pose_bones]
-    else:
-        objects = [[ob, False, False] for ob in context.selected_objects]
-    if objects == self.displayed:
-        selection_change = False
-    else:
-        selection_change = True
-    
-    if self.lock and not selection_change and \
-    context.region_data.perspective_matrix == self.perspective and not \
-    context.window_manager.motion_trail.force_update:
-        return
-    
-    # dictionaries with key: objectname
-    self.paths = {} # value: list of lists with x, y, colour
-    self.keyframes = {} # value: dict with frame as key and [x,y] as value
-    self.handles = {} # value: dict of dicts
-    self.timebeads = {} # value: dict with frame as key and [x,y] as value
-    self.click = {} # value: list of lists with frame, type, loc-vector
-    if selection_change:
-        # value: editbone inverted rotation matrix or None
-        self.edit_bones = {}
-    if selection_change or not self.lock or context.window_manager.\
-    motion_trail.force_update:
-        # contains locations of path, keyframes and timebeads
-        self.cached = {"path":{}, "keyframes":{}, "timebeads_timing":{},
-            "timebeads_speed":{}}
-    if self.cached["path"]:
-        use_cache = True
-    else:
-        use_cache = False
-    self.perspective = context.region_data.perspective_matrix.copy()
-    self.displayed = objects # store, so it can be checked next time
-    context.window_manager.motion_trail.force_update = False
-   
-    global_undo = context.user_preferences.edit.use_global_undo
-    context.user_preferences.edit.use_global_undo = False
-    
-    for action_ob, child, offset_ob in objects:
-        if selection_change:
-            if not child:
-                self.edit_bones[action_ob.name] = None
-            else:
-                bpy.ops.object.mode_set(mode='EDIT')
-                editbones = action_ob.data.edit_bones
-                mat = editbones[child.name].matrix.copy().to_3x3().inverted()
-                bpy.ops.object.mode_set(mode='POSE')
-                self.edit_bones[child.name] = mat
-        
-        if not action_ob.animation_data:
-            continue
-        curves = get_curves(action_ob, child)
-        if len(curves) == 0:
-            continue
-        
-        if context.window_manager.motion_trail.path_before == 0:
-            range_min = context.scene.frame_start
-        else:
-            range_min = max(context.scene.frame_start,
-                context.scene.frame_current - \
-                context.window_manager.motion_trail.path_before)
-        if context.window_manager.motion_trail.path_after == 0:
-            range_max = context.scene.frame_end
-        else:
-            range_max = min(context.scene.frame_end,
-                context.scene.frame_current + \
-                context.window_manager.motion_trail.path_after)
-        fcx, fcy, fcz = curves
-        if child:
-            display_ob = child
-        else:
-            display_ob = action_ob
-        
-        # get location data of motion path
-        path = []
-        speeds = []
-        frame_old = context.scene.frame_current
-        step = 11 - context.window_manager.motion_trail.path_resolution
-        
-        if not use_cache:
-            if display_ob.name not in self.cached["path"]:
-                self.cached["path"][display_ob.name] = {}
-        if use_cache and range_min-1 in self.cached["path"][display_ob.name]:
-            prev_loc = self.cached["path"][display_ob.name][range_min-1]
-        else:
-            prev_loc = get_location(range_min-1, display_ob, offset_ob, curves)
-            self.cached["path"][display_ob.name][range_min-1] = prev_loc
-        
-        for frame in range(range_min, range_max + 1, step):
-            if use_cache and frame in self.cached["path"][display_ob.name]:
-                loc = self.cached["path"][display_ob.name][frame]
-            else:
-                loc = get_location(frame, display_ob, offset_ob, curves)
-                self.cached["path"][display_ob.name][frame] = loc
-            if not context.region or not context.space_data:
-                continue
-            x, y = world_to_screen(context, loc)
-            if context.window_manager.motion_trail.path_style == 'simple':
-                path.append([x, y, [0.0, 0.0, 0.0], frame, action_ob, child])
-            else:
-                dloc = (loc - prev_loc).length
-                path.append([x, y, dloc, frame, action_ob, child])
-                speeds.append(dloc)
-                prev_loc = loc
-        
-        # calculate colour of path
-        if context.window_manager.motion_trail.path_style == 'speed':
-            speeds.sort()
-            min_speed = speeds[0]
-            d_speed = speeds[-1] - min_speed
-            for i, [x, y, d_loc, frame, action_ob, child] in enumerate(path):
-                relative_speed = (d_loc - min_speed) / d_speed # 0.0 to 1.0
-                red = min(1.0, 2.0 * relative_speed)
-                blue = min(1.0, 2.0 - (2.0 * relative_speed))
-                path[i][2] = [red, 0.0, blue]
-        elif context.window_manager.motion_trail.path_style == 'acceleration':
-            accelerations = []
-            prev_speed = 0.0
-            for i, [x, y, d_loc, frame, action_ob, child] in enumerate(path):
-                accel = d_loc - prev_speed
-                accelerations.append(accel)
-                path[i][2] = accel
-                prev_speed = d_loc
-            accelerations.sort()
-            min_accel = accelerations[0]
-            max_accel = accelerations[-1]
-            for i, [x, y, accel, frame, action_ob, child] in enumerate(path):
-                if accel < 0:
-                    relative_accel = accel / min_accel # values from 0.0 to 1.0
-                    green = 1.0 - relative_accel
-                    path[i][2] = [1.0, green, 0.0]
-                elif accel > 0:
-                    relative_accel = accel / max_accel # values from 0.0 to 1.0
-                    red = 1.0 - relative_accel
-                    path[i][2] = [red, 1.0, 0.0]
-                else:
-                    path[i][2] = [1.0, 1.0, 0.0]
-        self.paths[display_ob.name] = path
-        
-        # get keyframes and handles
-        keyframes = {}
-        handle_difs = {}
-        kf_time = []
-        click = []
-        if not use_cache:
-            if display_ob.name not in self.cached["keyframes"]:
-                self.cached["keyframes"][display_ob.name] = {}
-        
-        for fc in curves:
-            for kf in fc.keyframe_points:
-                # handles for location mode
-                if context.window_manager.motion_trail.mode == 'location':
-                    if kf.co[0] not in handle_difs:
-                        handle_difs[kf.co[0]] = {"left":mathutils.Vector(),
-                            "right":mathutils.Vector(), "keyframe_loc":None}
-                    handle_difs[kf.co[0]]["left"][fc.array_index] = \
-                        (mathutils.Vector(kf.handle_left[:]) - \
-                        mathutils.Vector(kf.co[:])).normalized()[1]
-                    handle_difs[kf.co[0]]["right"][fc.array_index] = \
-                        (mathutils.Vector(kf.handle_right[:]) - \
-                        mathutils.Vector(kf.co[:])).normalized()[1]
-                # keyframes
-                if kf.co[0] in kf_time:
-                    continue
-                kf_time.append(kf.co[0])
-                co = kf.co[0]
-                
-                if use_cache and co in \
-                self.cached["keyframes"][display_ob.name]:
-                    loc = self.cached["keyframes"][display_ob.name][co]
-                else:
-                    loc = get_location(co, display_ob, offset_ob, curves)
-                    self.cached["keyframes"][display_ob.name][co] = loc
-                if handle_difs:
-                    handle_difs[co]["keyframe_loc"] = loc
-                
-                x, y = world_to_screen(context, loc)
-                keyframes[kf.co[0]] = [x, y]
-                if context.window_manager.motion_trail.mode != 'speed':
-                    # can't select keyframes in speed mode
-                    click.append([kf.co[0], "keyframe",
-                        mathutils.Vector([x,y]), action_ob, child])
-        self.keyframes[display_ob.name] = keyframes
-        
-        # handles are only shown in location-altering mode
-        if context.window_manager.motion_trail.mode == 'location' and \
-        context.window_manager.motion_trail.handle_display:
-            # calculate handle positions
-            handles = {}
-            for frame, vecs in handle_difs.items():
-                if child:
-                    # bone space to world space
-                    mat = self.edit_bones[child.name].copy().inverted()
-                    vec_left = vecs["left"] * mat
-                    vec_right = vecs["right"] * mat
-                else:
-                    vec_left = vecs["left"]
-                    vec_right = vecs["right"]
-                if vecs["keyframe_loc"] != None:
-                    vec_keyframe = vecs["keyframe_loc"]
-                else:
-                    vec_keyframe = get_location(frame, display_ob, offset_ob,
-                        curves)
-                x_left, y_left = world_to_screen(context, vec_left*2 + \
-                    vec_keyframe)
-                x_right, y_right = world_to_screen(context, vec_right*2 + \
-                    vec_keyframe)
-                handles[frame] = {"left":[x_left, y_left],
-                    "right":[x_right, y_right]}
-                click.append([frame, "handle_left",
-                    mathutils.Vector([x_left, y_left]), action_ob, child])
-                click.append([frame, "handle_right",
-                    mathutils.Vector([x_right, y_right]), action_ob, child])
-            self.handles[display_ob.name] = handles
-        
-        # calculate timebeads for timing mode
-        if context.window_manager.motion_trail.mode == 'timing':
-            timebeads = {}
-            n = context.window_manager.motion_trail.timebeads * (len(kf_time) \
-                - 1)
-            dframe = (range_max - range_min) / (n + 1)
-            if not use_cache:
-                if display_ob.name not in self.cached["timebeads_timing"]:
-                    self.cached["timebeads_timing"][display_ob.name] = {}
-            
-            for i in range(1, n+1):
-                frame = range_min + i * dframe
-                if use_cache and frame in \
-                self.cached["timebeads_timing"][display_ob.name]:
-                    loc = self.cached["timebeads_timing"][display_ob.name]\
-                        [frame]
-                else:
-                    loc = get_location(frame, display_ob, offset_ob, curves)
-                    self.cached["timebeads_timing"][display_ob.name][frame] = \
-                        loc
-                x, y = world_to_screen(context, loc)
-                timebeads[frame] = [x, y]
-                click.append([frame, "timebead", mathutils.Vector([x,y]),
-                    action_ob, child])
-            self.timebeads[display_ob.name] = timebeads
-        
-        # calculate timebeads for speed mode
-        if context.window_manager.motion_trail.mode == 'speed':
-            angles = dict([[kf, {"left":[], "right":[]}] for kf in \
-                self.keyframes[display_ob.name]])
-            for fc in curves:
-                for i, kf in enumerate(fc.keyframe_points):
-                    if i != 0:
-                        angle = mathutils.Vector([-1, 0]).angle(mathutils.\
-                            Vector(kf.handle_left) - mathutils.Vector(kf.co),
-                            0)
-                        if angle != 0:
-                            angles[kf.co[0]]["left"].append(angle)
-                    if i != len(fc.keyframe_points) - 1:
-                        angle = mathutils.Vector([1, 0]).angle(mathutils.\
-                            Vector(kf.handle_right) - mathutils.Vector(kf.co),
-                            0)
-                        if angle != 0:
-                            angles[kf.co[0]]["right"].append(angle)
-            timebeads = {}
-            kf_time.sort()
-            if not use_cache:
-                if display_ob.name not in self.cached["timebeads_speed"]:
-                    self.cached["timebeads_speed"][display_ob.name] = {}
-            
-            for frame, sides in angles.items():
-                if sides["left"]:
-                    perc = (sum(sides["left"]) / len(sides["left"])) / \
-                        (math.pi / 2)
-                    perc = max(0.4, min(1, perc * 5))
-                    previous = kf_time[kf_time.index(frame) - 1]
-                    bead_frame = frame - perc * ((frame - previous - 2) / 2)
-                    if use_cache and bead_frame in \
-                    self.cached["timebeads_speed"][display_ob.name]:
-                        loc = self.cached["timebeads_speed"][display_ob.name]\
-                            [bead_frame]
-                    else:
-                        loc = get_location(bead_frame, display_ob, offset_ob,
-                            curves)
-                        self.cached["timebeads_speed"][display_ob.name]\
-                            [bead_frame] = loc
-                    x, y = world_to_screen(context, loc)
-                    timebeads[bead_frame] = [x, y]
-                    click.append([bead_frame, "timebead", mathutils.\
-                        Vector([x,y]), action_ob, child])
-                if sides["right"]:
-                    perc = (sum(sides["right"]) / len(sides["right"])) / \
-                        (math.pi / 2)
-                    perc = max(0.4, min(1, perc * 5))
-                    next = kf_time[kf_time.index(frame) + 1]
-                    bead_frame = frame + perc * ((next - frame - 2) / 2)
-                    if use_cache and bead_frame in \
-                    self.cached["timebeads_speed"][display_ob.name]:
-                        loc = self.cached["timebeads_speed"][display_ob.name]\
-                            [bead_frame]
-                    else:
-                        loc = get_location(bead_frame, display_ob, offset_ob,
-                            curves)
-                        self.cached["timebeads_speed"][display_ob.name]\
-                            [bead_frame] = loc
-                    x, y = world_to_screen(context, loc)
-                    timebeads[bead_frame] = [x, y]
-                    click.append([bead_frame, "timebead", mathutils.\
-                        Vector([x,y]), action_ob, child])
-            self.timebeads[display_ob.name] = timebeads
-        
-        # add frame positions to click-list
-        if context.window_manager.motion_trail.frame_display:
-            path = self.paths[display_ob.name]
-            for x, y, colour, frame, action_ob, child in path:
-                click.append([frame, "frame", mathutils.Vector([x,y]),
-                    action_ob, child])
-        
-        self.click[display_ob.name] = click
-        
-        if context.scene.frame_current != frame_old:
-            context.scene.frame_set(frame_old)
-    
-    context.user_preferences.edit.use_global_undo = global_undo
-
-
-# draw in 3d-view
-def draw_callback(self, context):
-    # polling
-    if context.mode not in ['OBJECT', 'POSE'] or \
-    context.window_manager.motion_trail.enabled != 1:
-        return
-    
-    # display limits
-    if context.window_manager.motion_trail.path_before != 0:
-        limit_min = context.scene.frame_current - \
-            context.window_manager.motion_trail.path_before
-    else:
-        limit_min = -1e6
-    if context.window_manager.motion_trail.path_after != 0:
-        limit_max = context.scene.frame_current + \
-            context.window_manager.motion_trail.path_after
-    else:
-        limit_max = 1e6
-    
-    # draw motion path
-    bgl.glEnable(bgl.GL_BLEND)
-    bgl.glLineWidth(context.window_manager.motion_trail.path_width)
-    alpha = 1.0 - (context.window_manager.motion_trail.path_transparency / \
-        100.0)
-    if context.window_manager.motion_trail.path_style == 'simple':
-        bgl.glColor4f(0.0, 0.0, 0.0, alpha)
-        for objectname, path in self.paths.items():
-            bgl.glBegin(bgl.GL_LINE_STRIP)
-            for x, y, colour, frame, action_ob, child in path:
-                if frame < limit_min or frame > limit_max:
-                    continue
-                bgl.glVertex2i(x, y)
-            bgl.glEnd()
-    else:
-        for objectname, path in self.paths.items():
-            for i, [x, y, colour, frame, action_ob, child] in enumerate(path):
-                if frame < limit_min or frame > limit_max:
-                    continue
-                r, g, b = colour
-                if i != 0:
-                    prev_path = path[i-1]
-                    halfway = [(x + prev_path[0])/2, (y + prev_path[1])/2]
-                    bgl.glColor4f(r, g, b, alpha)
-                    bgl.glBegin(bgl.GL_LINE_STRIP)
-                    bgl.glVertex2i(int(halfway[0]), int(halfway[1]))
-                    bgl.glVertex2i(x, y)
-                    bgl.glEnd()
-                if i != len(path) - 1:
-                    next_path = path[i+1]
-                    halfway = [(x + next_path[0])/2, (y + next_path[1])/2]
-                    bgl.glColor4f(r, g, b, alpha)
-                    bgl.glBegin(bgl.GL_LINE_STRIP)
-                    bgl.glVertex2i(x, y)
-                    bgl.glVertex2i(int(halfway[0]), int(halfway[1]))
-                    bgl.glEnd()
-    
-    # draw frames
-    if context.window_manager.motion_trail.frame_display:
-        bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
-        bgl.glPointSize(1)
-        bgl.glBegin(bgl.GL_POINTS)
-        for objectname, path in self.paths.items():
-            for x, y, colour, frame, action_ob, child in path:
-                if frame < limit_min or frame > limit_max:
-                    continue
-                if self.active_frame and objectname == self.active_frame[0] \
-                and abs(frame - self.active_frame[1]) < 1e-4:
-                    bgl.glEnd()
-                    bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
-                    bgl.glPointSize(3)
-                    bgl.glBegin(bgl.GL_POINTS)
-                    bgl.glVertex2i(x,y)
-                    bgl.glEnd()
-                    bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
-                    bgl.glPointSize(1)
-                    bgl.glBegin(bgl.GL_POINTS)
-                else:
-                    bgl.glVertex2i(x,y)
-        bgl.glEnd()
-    
-    # time beads are shown in speed and timing modes
-    if context.window_manager.motion_trail.mode in ['speed', 'timing']:
-        bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
-        bgl.glPointSize(4)
-        bgl.glBegin(bgl.GL_POINTS)
-        for objectname, values in self.timebeads.items():
-            for frame, coords in values.items():
-                if frame < limit_min or frame > limit_max:
-                    continue
-                if self.active_timebead and \
-                objectname == self.active_timebead[0] and \
-                abs(frame - self.active_timebead[1]) < 1e-4:
-                    bgl.glEnd()
-                    bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
-                    bgl.glBegin(bgl.GL_POINTS)
-                    bgl.glVertex2i(coords[0], coords[1])
-                    bgl.glEnd()
-                    bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
-                    bgl.glBegin(bgl.GL_POINTS)
-                else:
-                    bgl.glVertex2i(coords[0], coords[1])
-        bgl.glEnd()
-    
-    # handles are only shown in location mode
-    if context.window_manager.motion_trail.mode == 'location':
-        # draw handle-lines
-        bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-        bgl.glLineWidth(1)
-        bgl.glBegin(bgl.GL_LINES)
-        for objectname, values in self.handles.items():
-            for frame, sides in values.items():
-                if frame < limit_min or frame > limit_max:
-                    continue
-                for side, coords in sides.items():
-                    if self.active_handle and \
-                    objectname == self.active_handle[0] and \
-                    side == self.active_handle[2] and \
-                    abs(frame - self.active_handle[1]) < 1e-4:
-                        bgl.glEnd()
-                        bgl.glColor4f(.75, 0.25, 0.0, 1.0)
-                        bgl.glBegin(bgl.GL_LINES)
-                        bgl.glVertex2i(self.keyframes[objectname][frame][0],
-                            self.keyframes[objectname][frame][1])
-                        bgl.glVertex2i(coords[0], coords[1])
-                        bgl.glEnd()
-                        bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-                        bgl.glBegin(bgl.GL_LINES)
-                    else:
-                        bgl.glVertex2i(self.keyframes[objectname][frame][0],
-                            self.keyframes[objectname][frame][1])
-                        bgl.glVertex2i(coords[0], coords[1])
-        bgl.glEnd()
-        
-        # draw handles
-        bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
-        bgl.glPointSize(4)
-        bgl.glBegin(bgl.GL_POINTS)
-        for objectname, values in self.handles.items():
-            for frame, sides in values.items():
-                if frame < limit_min or frame > limit_max:
-                    continue
-                for side, coords in sides.items():
-                    if self.active_handle and \
-                    objectname == self.active_handle[0] and \
-                    side == self.active_handle[2] and \
-                    abs(frame - self.active_handle[1]) < 1e-4:
-                        bgl.glEnd()
-                        bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
-                        bgl.glBegin(bgl.GL_POINTS)
-                        bgl.glVertex2i(coords[0], coords[1])
-                        bgl.glEnd()
-                        bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
-                        bgl.glBegin(bgl.GL_POINTS)
-                    else:
-                        bgl.glVertex2i(coords[0], coords[1])
-        bgl.glEnd()
-        
-    # draw keyframes
-    bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
-    bgl.glPointSize(6)
-    bgl.glBegin(bgl.GL_POINTS)
-    for objectname, values in self.keyframes.items():
-        for frame, coords in values.items():
-            if frame < limit_min or frame > limit_max:
-                continue
-            if self.active_keyframe and \
-            objectname == self.active_keyframe[0] and \
-            abs(frame - self.active_keyframe[1]) < 1e-4:
-                bgl.glEnd()
-                bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
-                bgl.glBegin(bgl.GL_POINTS)
-                bgl.glVertex2i(coords[0], coords[1])
-                bgl.glEnd()
-                bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
-                bgl.glBegin(bgl.GL_POINTS)
-            else:
-                bgl.glVertex2i(coords[0], coords[1])
-    bgl.glEnd()
-    
-    # draw keyframe-numbers
-    if context.window_manager.motion_trail.keyframe_numbers:
-        blf.size(0, 12, 72)
-        bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
-        for objectname, values in self.keyframes.items():
-            for frame, coords in values.items():
-                if frame < limit_min or frame > limit_max:
-                    continue
-                blf.position(0, coords[0] + 3, coords[1] + 3, 0)
-                text = str(frame).split(".")
-                if len(text) == 1:
-                    text = text[0]
-                elif len(text[1]) == 1 and text[1] == "0":
-                    text = text[0]
-                else:
-                    text = text[0] + "." + text[1][0]
-                if self.active_keyframe and \
-                objectname == self.active_keyframe[0] and \
-                abs(frame - self.active_keyframe[1]) < 1e-4:
-                    bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
-                    blf.draw(0, text)
-                    bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
-                else:
-                    blf.draw(0, text)
-    
-    # restore opengl defaults
-    bgl.glLineWidth(1)
-    bgl.glDisable(bgl.GL_BLEND)
-    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-    bgl.glPointSize(1)
-
-
-# change data based on mouse movement
-def drag(context, event, drag_mouse_ori, active_keyframe, active_handle,
-active_timebead, keyframes_ori, handles_ori, edit_bones):
-    # change 3d-location of keyframe
-    if context.window_manager.motion_trail.mode == 'location' and \
-    active_keyframe:
-        objectname, frame, frame_ori, action_ob, child = active_keyframe
-        if child:
-            mat = action_ob.matrix_world.copy().inverted() * \
-                edit_bones[child.name].copy().to_4x4()
-        else:
-            mat = 1
-        
-        mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
-            drag_mouse_ori[1]) * mat
-        vector = screen_to_world(context, event.mouse_region_x,
-            event.mouse_region_y) * mat
-        d = vector - mouse_ori_world
-        
-        loc_ori_ws = keyframes_ori[objectname][frame][1]
-        loc_ori_bs = loc_ori_ws * mat
-        new_loc = loc_ori_bs + d
-        curves = get_curves(action_ob, child)
-        
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if kf.co[0] == frame:
-                    kf.co[1] = new_loc[i]
-                    kf.handle_left[1] = handles_ori[objectname][frame]\
-                        ["left"][i][1] + d[i]
-                    kf.handle_right[1] = handles_ori[objectname][frame]\
-                        ["right"][i][1] + d[i]
-                    break
-    
-    # change 3d-location of handle
-    elif context.window_manager.motion_trail.mode == 'location' and \
-    active_handle:
-        objectname, frame, side, action_ob, child = active_handle
-        if child:
-            mat = action_ob.matrix_world.copy().inverted() * \
-                edit_bones[child.name].copy().to_4x4()
-        else:
-            mat = 1
-        
-        mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
-            drag_mouse_ori[1]) * mat
-        vector = screen_to_world(context, event.mouse_region_x,
-            event.mouse_region_y) * mat
-        d = vector - mouse_ori_world
-        curves = get_curves(action_ob, child)
-        
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if kf.co[0] == frame:
-                    if side == "left":
-                        # change handle type, if necessary
-                        if kf.handle_left_type in ['AUTO', 'AUTO_CLAMPED',
-                        'ANIM_CLAMPED']:
-                            kf.handle_left_type = 'ALIGNED'
-                        elif kf.handle_left_type == 'VECTOR':
-                            kf.handle_left_type = 'FREE'
-                        # change handle position(s)
-                        kf.handle_left[1] = handles_ori[objectname][frame]\
-                            ["left"][i][1] + d[i]
-                        if kf.handle_left_type in ['ALIGNED', 'ANIM_CLAMPED',
-                        'AUTO', 'AUTO_CLAMPED']:
-                            dif = (abs(handles_ori[objectname][frame]["right"]\
-                                [i][0] - kf.co[0]) / abs(kf.handle_left[0] - \
-                                kf.co[0])) * d[i]
-                            kf.handle_right[1] = handles_ori[objectname]\
-                                [frame]["right"][i][1] - dif
-                    elif side == "right":
-                        # change handle type, if necessary
-                        if kf.handle_right_type in ['AUTO', 'AUTO_CLAMPED',
-                        'ANIM_CLAMPED']:
-                            kf.handle_left_type = 'ALIGNED'
-                            kf.handle_right_type = 'ALIGNED'
-                        elif kf.handle_right_type == 'VECTOR':
-                            kf.handle_left_type = 'FREE'
-                            kf.handle_right_type = 'FREE'
-                        # change handle position(s)
-                        kf.handle_right[1] = handles_ori[objectname][frame]\
-                            ["right"][i][1] + d[i]
-                        if kf.handle_right_type in ['ALIGNED', 'ANIM_CLAMPED',
-                        'AUTO', 'AUTO_CLAMPED']:
-                            dif = (abs(handles_ori[objectname][frame]["left"]\
-                                [i][0] - kf.co[0]) / abs(kf.handle_right[0] - \
-                                kf.co[0])) * d[i]
-                            kf.handle_left[1] = handles_ori[objectname]\
-                                [frame]["left"][i][1] - dif
-                    break
-    
-    # change position of all keyframes on timeline
-    elif context.window_manager.motion_trail.mode == 'timing' and \
-    active_timebead:
-        objectname, frame, frame_ori, action_ob, child = active_timebead
-        curves = get_curves(action_ob, child)
-        ranges = [val for c in curves for val in c.range()]
-        ranges.sort()
-        range_min = round(ranges[0])
-        range_max = round(ranges[-1])
-        range = range_max - range_min
-        dx_screen = -(mathutils.Vector([event.mouse_region_x,
-            event.mouse_region_y]) - drag_mouse_ori)[0]
-        dx_screen = dx_screen / context.region.width * range
-        new_frame = frame + dx_screen
-        shift_low = max(1e-4, (new_frame - range_min) / (frame - range_min))
-        shift_high = max(1e-4, (range_max - new_frame) / (range_max - frame))
-        
-        new_mapping = {}
-        for i, curve in enumerate(curves):
-            for j, kf in enumerate(curve.keyframe_points):
-                frame_map = kf.co[0]
-                if frame_map < range_min + 1e-4 or \
-                frame_map > range_max - 1e-4:
-                    continue
-                frame_ori = False
-                for f in keyframes_ori[objectname]:
-                    if abs(f - frame_map) < 1e-4:
-                        frame_ori = keyframes_ori[objectname][f][0]
-                        value_ori = keyframes_ori[objectname][f]
-                        break
-                if not frame_ori:
-                    continue
-                if frame_ori <= frame:
-                    frame_new = (frame_ori - range_min) * shift_low + \
-                        range_min
-                else:
-                    frame_new = range_max - (range_max - frame_ori) * \
-                        shift_high
-                frame_new = max(range_min + j, min(frame_new, range_max - \
-                    (len(curve.keyframe_points)-j)+1))
-                d_frame = frame_new - frame_ori
-                if frame_new not in new_mapping:
-                    new_mapping[frame_new] = value_ori
-                kf.co[0] = frame_new
-                kf.handle_left[0] = handles_ori[objectname][frame_ori]\
-                    ["left"][i][0] + d_frame
-                kf.handle_right[0] = handles_ori[objectname][frame_ori]\
-                    ["right"][i][0] + d_frame
-        del keyframes_ori[objectname]
-        keyframes_ori[objectname] = {}
-        for new_frame, value in new_mapping.items():
-            keyframes_ori[objectname][new_frame] = value
-    
-    # change position of active keyframe on the timeline
-    elif context.window_manager.motion_trail.mode == 'timing' and \
-    active_keyframe:
-        objectname, frame, frame_ori, action_ob, child = active_keyframe
-        if child:
-            mat = action_ob.matrix_world.copy().inverted() * \
-                edit_bones[child.name].copy().to_4x4()
-        else:
-            mat = action_ob.matrix_world.copy().inverted()
-        
-        mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
-            drag_mouse_ori[1]) * mat
-        vector = screen_to_world(context, event.mouse_region_x,
-            event.mouse_region_y) * mat
-        d = vector - mouse_ori_world
-        
-        locs_ori = [[f_ori, coords] for f_mapped, [f_ori, coords] in \
-            keyframes_ori[objectname].items()]
-        locs_ori.sort()
-        direction = 1
-        range = False
-        for i, [f_ori, coords] in enumerate(locs_ori):
-            if abs(frame_ori - f_ori) < 1e-4:
-                if i == 0:
-                    # first keyframe, nothing before it
-                    direction = -1
-                    range = [f_ori, locs_ori[i+1][0]]
-                elif i == len(locs_ori) - 1:
-                    # last keyframe, nothing after it
-                    range = [locs_ori[i-1][0], f_ori]
-                else:
-                    current = mathutils.Vector(coords)
-                    next = mathutils.Vector(locs_ori[i+1][1])
-                    previous = mathutils.Vector(locs_ori[i-1][1])
-                    angle_to_next = d.angle(next - current, 0)
-                    angle_to_previous = d.angle(previous-current, 0)
-                    if angle_to_previous < angle_to_next:
-                        # mouse movement is in direction of previous keyframe
-                        direction = -1
-                    range = [locs_ori[i-1][0], locs_ori[i+1][0]]
-                break
-        direction *= -1 # feels more natural in 3d-view
-        if not range:
-            # keyframe not found, is impossible, but better safe than sorry
-            return(active_keyframe, active_timebead, keyframes_ori)
-        # calculate strength of movement
-        d_screen = mathutils.Vector([event.mouse_region_x,
-            event.mouse_region_y]) - drag_mouse_ori
-        if d_screen.length != 0:
-            d_screen = d_screen.length / (abs(d_screen[0])/d_screen.length*\
-                context.region.width + abs(d_screen[1])/d_screen.length*\
-                context.region.height)
-            d_screen *= direction  # d_screen value ranges from -1.0 to 1.0
-        else:
-            d_screen = 0.0
-        new_frame = d_screen * (range[1] - range[0]) + frame_ori
-        max_frame = range[1]
-        if max_frame == frame_ori:
-            max_frame += 1
-        min_frame = range[0]
-        if min_frame == frame_ori:
-            min_frame -= 1
-        new_frame = min(max_frame - 1, max(min_frame + 1, new_frame))
-        d_frame = new_frame - frame_ori
-        curves = get_curves(action_ob, child)
-        
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if abs(kf.co[0] - frame) < 1e-4:
-                    kf.co[0] = new_frame
-                    kf.handle_left[0] = handles_ori[objectname][frame_ori]\
-                        ["left"][i][0] + d_frame
-                    kf.handle_right[0] = handles_ori[objectname][frame_ori]\
-                        ["right"][i][0] + d_frame
-                    break
-        active_keyframe = [objectname, new_frame, frame_ori, action_ob, child]
-    
-    # change position of active timebead on the timeline, thus altering speed
-    elif context.window_manager.motion_trail.mode == 'speed' and \
-    active_timebead:
-        objectname, frame, frame_ori, action_ob, child = active_timebead
-        if child:
-            mat = action_ob.matrix_world.copy().inverted() * \
-                edit_bones[child.name].copy().to_4x4()
-        else:
-            mat = 1
-        
-        mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
-            drag_mouse_ori[1]) * mat
-        vector = screen_to_world(context, event.mouse_region_x,
-            event.mouse_region_y) * mat
-        d = vector - mouse_ori_world
-        
-        # determine direction (to next or previous keyframe)
-        curves = get_curves(action_ob, child)
-        fcx, fcy, fcz = curves
-        locx = fcx.evaluate(frame_ori)
-        locy = fcy.evaluate(frame_ori)
-        locz = fcz.evaluate(frame_ori)
-        loc_ori = mathutils.Vector([locx, locy, locz]) # bonespace
-        keyframes = [kf for kf in keyframes_ori[objectname]]
-        keyframes.append(frame_ori)
-        keyframes.sort()
-        frame_index = keyframes.index(frame_ori)
-        kf_prev = keyframes[frame_index - 1]
-        kf_next = keyframes[frame_index + 1]
-        vec_prev = (mathutils.Vector(keyframes_ori[objectname][kf_prev][1]) \
-            * mat - loc_ori).normalized()
-        vec_next = (mathutils.Vector(keyframes_ori[objectname][kf_next][1]) \
-            * mat - loc_ori).normalized()
-        d_normal = d.copy().normalized()
-        dist_to_next = (d_normal - vec_next).length
-        dist_to_prev = (d_normal - vec_prev).length
-        if dist_to_prev < dist_to_next:
-            direction = 1
-        else:
-            direction = -1
-        
-        if (kf_next - frame_ori) < (frame_ori - kf_prev):
-            kf_bead = kf_next
-            side = "left"
-        else:
-            kf_bead = kf_prev
-            side = "right"
-        d_frame = d.length * direction * 2 # *2 to make it more sensitive
-        
-        angles = []
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if abs(kf.co[0] - kf_bead) < 1e-4:
-                    if side == "left":
-                        # left side
-                        kf.handle_left[0] = min(handles_ori[objectname]\
-                            [kf_bead]["left"][i][0] + d_frame, kf_bead - 1)
-                        angle = mathutils.Vector([-1, 0]).angle(mathutils.\
-                            Vector(kf.handle_left) - mathutils.Vector(kf.co),
-                            0)
-                        if angle != 0:
-                            angles.append(angle)
-                    else:
-                        # right side
-                        kf.handle_right[0] = max(handles_ori[objectname]\
-                            [kf_bead]["right"][i][0] + d_frame, kf_bead + 1)
-                        angle = mathutils.Vector([1, 0]).angle(mathutils.\
-                            Vector(kf.handle_right) - mathutils.Vector(kf.co),
-                            0)
-                        if angle != 0:
-                            angles.append(angle)
-                    break
-        
-        # update frame of active_timebead
-        perc = (sum(angles) / len(angles)) / (math.pi / 2)
-        perc = max(0.4, min(1, perc * 5))
-        if side == "left":
-            bead_frame = kf_bead - perc * ((kf_bead - kf_prev - 2) / 2)
-        else:
-            bead_frame = kf_bead + perc * ((kf_next - kf_bead - 2) / 2)
-        active_timebead = [objectname, bead_frame, frame_ori, action_ob, child]
-    
-    return(active_keyframe, active_timebead, keyframes_ori)
-
-
-# revert changes made by dragging
-def cancel_drag(context, active_keyframe, active_handle, active_timebead,
-keyframes_ori, handles_ori, edit_bones):
-    # revert change in 3d-location of active keyframe and its handles
-    if context.window_manager.motion_trail.mode == 'location' and \
-    active_keyframe:
-        objectname, frame, frame_ori, active_ob, child = active_keyframe
-        curves = get_curves(active_ob, child)
-        loc_ori = keyframes_ori[objectname][frame][1]
-        if child:
-            loc_ori = loc_ori * edit_bones[child.name] * \
-                active_ob.matrix_world.copy().inverted()
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if kf.co[0] == frame:
-                    kf.co[1] = loc_ori[i]
-                    kf.handle_left[1] = handles_ori[objectname][frame]\
-                        ["left"][i][1]
-                    kf.handle_right[1] = handles_ori[objectname][frame]\
-                        ["right"][i][1]
-                    break
-    
-    # revert change in 3d-location of active handle
-    elif context.window_manager.motion_trail.mode == 'location' and \
-    active_handle:
-        objectname, frame, side, active_ob, child = active_handle
-        curves = get_curves(active_ob, child)
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if kf.co[0] == frame:
-                    kf.handle_left[1] = handles_ori[objectname][frame]\
-                        ["left"][i][1]
-                    kf.handle_right[1] = handles_ori[objectname][frame]\
-                        ["right"][i][1]
-                    break
-    
-    # revert position of all keyframes and handles on timeline
-    elif context.window_manager.motion_trail.mode == 'timing' and \
-    active_timebead:
-        objectname, frame, frame_ori, active_ob, child = active_timebead
-        curves = get_curves(active_ob, child)
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                for kf_ori, [frame_ori, loc] in keyframes_ori[objectname].\
-                items():
-                    if abs(kf.co[0] - kf_ori) < 1e-4:
-                        kf.co[0] = frame_ori
-                        kf.handle_left[0] = handles_ori[objectname]\
-                            [frame_ori]["left"][i][0]
-                        kf.handle_right[0] = handles_ori[objectname]\
-                            [frame_ori]["right"][i][0]
-                        break
-    
-    # revert position of active keyframe and its handles on the timeline
-    elif context.window_manager.motion_trail.mode == 'timing' and \
-    active_keyframe:
-        objectname, frame, frame_ori, active_ob, child = active_keyframe
-        curves = get_curves(active_ob, child)
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if abs(kf.co[0] - frame) < 1e-4:
-                    kf.co[0] = keyframes_ori[objectname][frame_ori][0]
-                    kf.handle_left[0] = handles_ori[objectname][frame_ori]\
-                        ["left"][i][0]
-                    kf.handle_right[0] = handles_ori[objectname][frame_ori]\
-                        ["right"][i][0]
-                    break
-        active_keyframe = [objectname, frame_ori, frame_ori, active_ob, child]
-    
-    # revert position of handles on the timeline
-    elif context.window_manager.motion_trail.mode == 'speed' and \
-    active_timebead:
-        objectname, frame, frame_ori, active_ob, child = active_timebead
-        curves = get_curves(active_ob, child)
-        keyframes = [kf for kf in keyframes_ori[objectname]]
-        keyframes.append(frame_ori)
-        keyframes.sort()
-        frame_index = keyframes.index(frame_ori)
-        kf_prev = keyframes[frame_index - 1]
-        kf_next = keyframes[frame_index + 1]
-        if (kf_next - frame_ori) < (frame_ori - kf_prev):
-            kf_frame = kf_next
-        else:
-            kf_frame = kf_prev
-        for i, curve in enumerate(curves):
-            for kf in curve.keyframe_points:
-                if kf.co[0] == kf_frame:
-                    kf.handle_left[0] = handles_ori[objectname][kf_frame]\
-                        ["left"][i][0]
-                    kf.handle_right[0] = handles_ori[objectname][kf_frame]\
-                        ["right"][i][0]
-                    break
-        active_timebead = [objectname, frame_ori, frame_ori, active_ob, child]
-    
-    return(active_keyframe, active_timebead)
-
-
-# return the handle type of the active selection
-def get_handle_type(active_keyframe, active_handle):
-    if active_keyframe:
-        objectname, frame, side, action_ob, child = active_keyframe
-        side = "both"
-    elif active_handle:
-        objectname, frame, side, action_ob, child = active_handle
-    else:
-        # no active handle(s)
-        return(False)
-    
-    # properties used when changing handle type
-    bpy.context.window_manager.motion_trail.handle_type_frame = frame
-    bpy.context.window_manager.motion_trail.handle_type_side = side
-    bpy.context.window_manager.motion_trail.handle_type_action_ob = \
-        action_ob.name
-    if child:
-        bpy.context.window_manager.motion_trail.handle_type_child = child.name
-    else:
-        bpy.context.window_manager.motion_trail.handle_type_child = ""
-    
-    curves = get_curves(action_ob, child=child)
-    for c in curves:
-        for kf in c.keyframe_points:
-            if kf.co[0] == frame:
-                if side in ["left", "both"]:
-                    return(kf.handle_left_type)
-                else:
-                    return(kf.handle_right_type)
-    
-    return("AUTO")
-
-
-# turn the given frame into a keyframe
-def insert_keyframe(self, context, frame):
-    objectname, frame, frame, action_ob, child = frame
-    curves = get_curves(action_ob, child)
-    for c in curves:
-        y = c.evaluate(frame)
-        if c.keyframe_points:
-            c.keyframe_points.insert(frame, y)
-    
-    bpy.context.window_manager.motion_trail.force_update = True
-    calc_callback(self, context)
-
-
-# change the handle type of the active selection
-def set_handle_type(self, context):
-    if not context.window_manager.motion_trail.handle_type_enabled:
-        return
-    if context.window_manager.motion_trail.handle_type_old == \
-    context.window_manager.motion_trail.handle_type:
-        # function called because of selection change, not change in type
-        return
-    context.window_manager.motion_trail.handle_type_old = \
-        context.window_manager.motion_trail.handle_type
-    
-    frame = bpy.context.window_manager.motion_trail.handle_type_frame
-    side = bpy.context.window_manager.motion_trail.handle_type_side
-    action_ob = bpy.context.window_manager.motion_trail.handle_type_action_ob
-    action_ob = bpy.data.objects[action_ob]
-    child = bpy.context.window_manager.motion_trail.handle_type_child
-    if child:
-        child = action_ob.pose.bones[child]
-    new_type = context.window_manager.motion_trail.handle_type
-    
-    curves = get_curves(action_ob, child=child)
-    for c in curves:
-        for kf in c.keyframe_points:
-            if kf.co[0] == frame:
-                # align if necessary
-                if side in ["right", "both"] and new_type in \
-                ["AUTO", "AUTO_CLAMPED", "ALIGNED"]:
-                    # change right handle
-                    normal = (kf.co - kf.handle_left).normalized()
-                    size = (kf.handle_right[0] - kf.co[0]) / normal[0]
-                    normal = normal*size + kf.co
-                    kf.handle_right[1] = normal[1]
-                elif side == "left" and new_type in ["AUTO", "AUTO_CLAMPED",
-                "ALIGNED"]:
-                    # change left handle
-                    normal = (kf.co - kf.handle_right).normalized()
-                    size = (kf.handle_left[0] - kf.co[0]) / normal[0]
-                    normal = normal*size + kf.co
-                    kf.handle_left[1] = normal[1]
-                # change type
-                if side in ["left", "both"]:
-                    kf.handle_left_type = new_type
-                if side in ["right", "both"]:
-                    kf.handle_right_type = new_type
-    
-    context.window_manager.motion_trail.force_update = True
-
-
-class MotionTrailOperator(bpy.types.Operator):
-    '''Edit motion trails in 3d-view'''
-    bl_idname = "view3d.motion_trail"
-    bl_label = "Motion Trail"
-    
-    _handle1 = None
-    _handle2 = None
-    
-    def modal(self, context, event):
-        if context.window_manager.motion_trail.enabled == -1:
-            context.window_manager.motion_trail.enabled = 0
-            try:
-                context.region.callback_remove(self._handle1)
-            except:
-                pass
-            try:
-                context.region.callback_remove(self._handle2)
-            except:
-                pass
-            context.area.tag_redraw()
-            return {'FINISHED'}
-        
-        if not context.area:
-            return {'PASS_THROUGH'}
-        if not context.region or event.type == 'NONE':
-            context.area.tag_redraw()
-            return {'PASS_THROUGH'}
-        
-        select = context.user_preferences.inputs.select_mouse
-        if not context.active_object or not context.active_object.mode in \
-        ['OBJECT', 'POSE']:
-            if self.drag:
-                self.drag = False
-                self.lock = True
-                context.window_manager.motion_trail.force_update = True
-            # default hotkeys should still work
-            if event.type == self.transform_key and event.value == 'PRESS':
-                if bpy.ops.transform.translate.poll():
-                    bpy.ops.transform.translate('INVOKE_DEFAULT')
-            elif event.type == select + 'MOUSE' and event.value == 'PRESS' \
-            and not self.drag and not event.shift and not event.alt \
-            and not event.ctrl:
-                if bpy.ops.view3d.select.poll():
-                    bpy.ops.view3d.select('INVOKE_DEFAULT')
-            elif event.type == 'LEFTMOUSE' and event.value == 'PRESS' and not\
-            event.alt and not event.ctrl and not event.shift:
-                if eval("bpy.ops."+self.left_action+".poll()"):
-                    eval("bpy.ops."+self.left_action+"('INVOKE_DEFAULT')")
-            return {'PASS_THROUGH'}
-        # check if event was generated within 3d-window, dragging is exception
-        if not self.drag:
-            if not (0 < event.mouse_region_x < context.region.width) or \
-            not (0 < event.mouse_region_y < context.region.height):
-                return {'PASS_THROUGH'}
-        
-        if event.type == self.transform_key and event.value == 'PRESS' and \
-        (self.active_keyframe or self.active_handle or self.active_timebead \
-        or self.active_frame):
-            # override default translate()
-            if not self.drag:
-                # start drag
-                if self.active_frame:
-                    insert_keyframe(self, context, self.active_frame)
-                    self.active_keyframe = self.active_frame
-                    self.active_frame = False
-                self.keyframes_ori, self.handles_ori = \
-                    get_original_animation_data(context, self.keyframes)
-                self.drag_mouse_ori = mathutils.Vector([event.mouse_region_x,
-                    event.mouse_region_y])
-                self.drag = True
-                self.lock = False
-            else:
-                # stop drag
-                self.drag = False
-                self.lock = True
-                context.window_manager.motion_trail.force_update = True
-        elif event.type == self.transform_key and event.value == 'PRESS':
-            # call default translate()
-            if bpy.ops.transform.translate.poll():
-                bpy.ops.transform.translate('INVOKE_DEFAULT')
-        elif (event.type == 'ESC' and self.drag and event.value == 'PRESS') \
-        or (event.type == 'RIGHTMOUSE' and self.drag and event.value == \
-        'PRESS'):
-            # cancel drag
-            self.drag = False
-            self.lock = True
-            context.window_manager.motion_trail.force_update = True
-            self.active_keyframe, self.active_timebead = cancel_drag(context,
-                self.active_keyframe, self.active_handle,
-                self.active_timebead, self.keyframes_ori, self.handles_ori,
-                self.edit_bones)
-        elif event.type == 'MOUSEMOVE' and self.drag:
-            # drag
-            self.active_keyframe, self.active_timebead, self.keyframes_ori = \
-                drag(context, event, self.drag_mouse_ori,
-                self.active_keyframe, self.active_handle,
-                self.active_timebead, self.keyframes_ori, self.handles_ori,
-                self.edit_bones)
-        elif event.type == select + 'MOUSE' and event.value == 'PRESS' and \
-        not self.drag and not event.shift and not event.alt and not \
-        event.ctrl:
-            # select
-            treshold = 10
-            clicked = mathutils.Vector([event.mouse_region_x,
-                event.mouse_region_y])
-            self.active_keyframe = False
-            self.active_handle = False
-            self.active_timebead = False
-            self.active_frame = False
-            context.window_manager.motion_trail.force_update = True
-            context.window_manager.motion_trail.handle_type_enabled = True
-            found = False
-            
-            if context.window_manager.motion_trail.path_before == 0:
-                frame_min = context.scene.frame_start
-            else:
-                frame_min = max(context.scene.frame_start,
-                    context.scene.frame_current - \
-                    context.window_manager.motion_trail.path_before)
-            if context.window_manager.motion_trail.path_after == 0:
-                frame_max = context.scene.frame_end
-            else:
-                frame_max = min(context.scene.frame_end,
-                    context.scene.frame_current + \
-                    context.window_manager.motion_trail.path_after)
-            
-            for objectname, values in self.click.items():
-                if found:
-                    break
-                for frame, type, coord, action_ob, child in values:
-                    if frame < frame_min or frame > frame_max:
-                        continue
-                    if (coord - clicked).length <= treshold:
-                        found = True
-                        if type == "keyframe":
-                            self.active_keyframe = [objectname, frame, frame,
-                                action_ob, child]
-                        elif type == "handle_left":
-                            self.active_handle = [objectname, frame, "left",
-                                action_ob, child]
-                        elif type == "handle_right":
-                            self.active_handle = [objectname, frame, "right",
-                                action_ob, child]
-                        elif type == "timebead":
-                            self.active_timebead = [objectname, frame, frame,
-                                action_ob, child]
-                        elif type == "frame":
-                            self.active_frame = [objectname, frame, frame,
-                                action_ob, child]
-                        break
-            if not found:
-                context.window_manager.motion_trail.handle_type_enabled = False
-                # no motion trail selections, so pass on to normal select()
-                if bpy.ops.view3d.select.poll():
-                    bpy.ops.view3d.select('INVOKE_DEFAULT')
-            else:
-                handle_type = get_handle_type(self.active_keyframe,
-                    self.active_handle)
-                if handle_type:
-                    context.window_manager.motion_trail.handle_type_old = \
-                        handle_type
-                    context.window_manager.motion_trail.handle_type = \
-                        handle_type
-                else:
-                    context.window_manager.motion_trail.handle_type_enabled = \
-                        False
-        elif event.type == 'LEFTMOUSE' and event.value == 'PRESS' and \
-        self.drag:
-            # stop drag
-            self.drag = False
-            self.lock = True
-            context.window_manager.motion_trail.force_update = True
-        elif event.type == 'LEFTMOUSE' and event.value == 'PRESS' and not\
-        event.alt and not event.ctrl and not event.shift:
-            if eval("bpy.ops."+self.left_action+".poll()"):
-                eval("bpy.ops."+self.left_action+"('INVOKE_DEFAULT')")
-        
-        if context.area: # not available if other window-type is fullscreen
-            context.area.tag_redraw()
-        
-        return {'PASS_THROUGH'}
-
-    def invoke(self, context, event):
-        if context.area.type == 'VIEW_3D':
-            # get clashing keymap items
-            select = context.user_preferences.inputs.select_mouse
-            kms = [bpy.context.window_manager.keyconfigs.active.\
-                keymaps['3D View'], bpy.context.window_manager.keyconfigs.\
-                active.keymaps['Object Mode']]
-            kmis = []
-            self.left_action = None
-            self.right_action = None
-            for km in kms:
-                for kmi in km.keymap_items:
-                    if kmi.idname == "transform.translate" and \
-                    kmi.map_type == 'KEYBOARD' and not \
-                    kmi.properties.texture_space:
-                        kmis.append(kmi)
-                        self.transform_key = kmi.type
-                    elif (kmi.type == 'ACTIONMOUSE' and select == 'RIGHT') \
-                    and not kmi.alt and not kmi.any and not kmi.ctrl \
-                    and not kmi.shift:
-                        kmis.append(kmi)
-                        self.left_action = kmi.idname
-                    elif kmi.type == 'SELECTMOUSE' and not kmi.alt and not \
-                    kmi.any and not kmi.ctrl and not kmi.shift:
-                        kmis.append(kmi)
-                        if select == 'RIGHT':
-                            self.right_action = kmi.idname
-                        else:
-                            self.left_action = kmi.idname
-                    elif kmi.type == 'LEFTMOUSE' and not kmi.alt and not \
-                    kmi.any and not kmi.ctrl and not kmi.shift:
-                        kmis.append(kmi)
-                        self.left_action = kmi.idname
-            
-            if context.window_manager.motion_trail.enabled == 0:
-                # enable
-                context.window_manager.motion_trail.enabled = 1
-                self.active_keyframe = False
-                self.active_handle = False
-                self.active_timebead = False
-                self.active_frame = False
-                self.click = {}
-                self.drag = False
-                self.lock = True
-                self.perspective = context.region_data.perspective_matrix
-                self.displayed = []
-                context.window_manager.motion_trail.force_update = True
-                context.window_manager.motion_trail.handle_type_enabled = False
-                self.cached = {"path":{}, "keyframes":{},
-                    "timebeads_timing":{}, "timebeads_speed":{}}
-                
-                for kmi in kmis:
-                    kmi.active = False
-                
-                context.window_manager.modal_handler_add(self)
-                self._handle1 = context.region.callback_add(calc_callback,
-                    (self, context), 'POST_VIEW')
-                self._handle2 = context.region.callback_add(draw_callback,
-                    (self, context), 'POST_PIXEL')
-                if context.area:
-                    context.area.tag_redraw()
-            else:
-                # disable
-                context.window_manager.motion_trail.enabled = -1
-                for kmi in kmis:
-                    kmi.active = True
-            
-            return {'RUNNING_MODAL'}
-        
-        else:
-            self.report({'WARNING'}, "View3D not found, cannot run operator")
-            return {'CANCELLED'}
-
-
-class MotionTrailPanel(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_label = "Motion Trail"
-
-    @classmethod
-    def poll(cls, context):
-        if not context.active_object:
-            return(False)
-        return(context.active_object.mode in ['OBJECT', 'POSE'])
-    
-    def draw(self, context):
-        col = self.layout.column()
-        if context.window_manager.motion_trail.enabled != 1:
-            col.operator("view3d.motion_trail", text="Enable motion trail")
-        else:
-            col.operator("view3d.motion_trail", text="Disable motion trail")
-        
-        box = self.layout.box()
-        box.prop(context.window_manager.motion_trail, "mode")
-        #box.prop(context.window_manager.motion_trail, "calculate")
-        if context.window_manager.motion_trail.mode in ['timing']:
-            box.prop(context.window_manager.motion_trail, "timebeads")
-        
-        box = self.layout.box()
-        col = box.column()
-        row = col.row()
-        if context.window_manager.motion_trail.path_display:
-            row.prop(context.window_manager.motion_trail, "path_display",
-                icon="DOWNARROW_HLT", text="", emboss=False)
-        else:
-            row.prop(context.window_manager.motion_trail, "path_display",
-                icon="RIGHTARROW", text="", emboss=False)
-        row.label("Path options")
-        if context.window_manager.motion_trail.path_display:
-            col.prop(context.window_manager.motion_trail, "path_style",
-                text="Style")
-            grouped = col.column(align=True)
-            grouped.prop(context.window_manager.motion_trail, "path_width",
-                text="Width")
-            grouped.prop(context.window_manager.motion_trail,
-                "path_transparency", text="Transparency")
-            grouped.prop(context.window_manager.motion_trail,
-                "path_resolution")
-            row = grouped.row(align=True)
-            row.prop(context.window_manager.motion_trail, "path_before")
-            row.prop(context.window_manager.motion_trail, "path_after")
-            col = col.column(align=True)
-            col.prop(context.window_manager.motion_trail, "keyframe_numbers")
-            col.prop(context.window_manager.motion_trail, "frame_display")
-        
-        if context.window_manager.motion_trail.mode in ['location']:
-            box = self.layout.box()
-            col = box.column(align=True)
-            col.prop(context.window_manager.motion_trail, "handle_display",
-                text="Handles")
-            if context.window_manager.motion_trail.handle_display:
-                row = col.row()
-                row.enabled = context.window_manager.motion_trail.\
-                    handle_type_enabled
-                row.prop(context.window_manager.motion_trail, "handle_type")
-
-
-class MotionTrailProps(bpy.types.PropertyGroup):
-    def internal_update(self, context):
-        context.window_manager.motion_trail.force_update = True
-        if context.area:
-            context.area.tag_redraw()
-    
-    # internal use
-    enabled = bpy.props.IntProperty(default=0)
-    force_update = bpy.props.BoolProperty(name="internal use",
-        description="Force calc_callback to fully execute",
-        default=False)
-    handle_type_enabled = bpy.props.BoolProperty(default=False)
-    handle_type_frame = bpy.props.FloatProperty()
-    handle_type_side = bpy.props.StringProperty()
-    handle_type_action_ob = bpy.props.StringProperty()
-    handle_type_child = bpy.props.StringProperty()
-    handle_type_old = bpy.props.EnumProperty(items=(("AUTO", "", ""), 
-        ("AUTO_CLAMPED", "", ""), ("VECTOR", "", ""), ("ALIGNED", "", ""), 
-        ("FREE", "", "")), default='AUTO',)
-    
-    # visible in user interface
-    calculate = bpy.props.EnumProperty(name="Calculate",
-        items=(("fast", "Fast", "Recommended setting, change if the "\
-            "motion path is positioned incorrectly"),
-            ("full", "Full", "Takes parenting and modifiers into account, "\
-            "but can be very slow on complicated scenes")),
-        description="Calculation method for determining locations",
-        default='full',
-        update=internal_update)
-    frame_display = bpy.props.BoolProperty(name="Frames",
-        description="Display frames, \n test",
-        default=True,
-        update=internal_update)
-    handle_display = bpy.props.BoolProperty(name="Display",
-        description="Display handles",
-        default=True,
-        update=internal_update)
-    handle_type = bpy.props.EnumProperty(name="Type",
-        items=(("AUTO", "Automatic", ""),
-            ("AUTO_CLAMPED", "Auto Clamped", ""),
-            ("VECTOR", "Vector", ""),
-            ("ALIGNED", "Aligned", ""),
-            ("FREE", "Free", "")),
-        description="Set handle type for the selected handle",
-        default='AUTO',
-        update=set_handle_type)
-    keyframe_numbers = bpy.props.BoolProperty(name="Keyframe numbers",
-        description="Display keyframe numbers",
-        default=False,
-        update=internal_update)
-    mode = bpy.props.EnumProperty(name="Mode",
-        items=(("location", "Location", "Change path that is followed"),
-            ("speed", "Speed", "Change speed between keyframes"),
-            ("timing", "Timing", "Change position of keyframes on timeline")),
-        description="Enable editing of certain properties in the 3d-view",
-        default='location',
-        update=internal_update)
-    path_after = bpy.props.IntProperty(name="After",
-        description="Number of frames to show after the current frame, "\
-            "0 = display all",
-        default=50,
-        min=0,
-        update=internal_update)
-    path_before = bpy.props.IntProperty(name="Before",
-        description="Number of frames to show before the current frame, "\
-            "0 = display all",
-        default=50,
-        min=0,
-        update=internal_update)
-    path_display = bpy.props.BoolProperty(name="Path options",
-        description="Display path options",
-        default=True)
-    path_resolution = bpy.props.IntProperty(name="Resolution",
-        description="10 is smoothest, but could be "\
-        "slow when adjusting keyframes, handles or timebeads",
-        default=10,
-        min=1,
-        max=10,
-        update=internal_update)
-    path_style = bpy.props.EnumProperty(name="Path style",
-        items=(("acceleration", "Acceleration", "Gradient based on relative "\
-                "acceleration"),
-            ("simple", "Simple", "Black line"),
-            ("speed", "Speed", "Gradient based on relative speed")),
-        description="Information conveyed by path colour",
-        default='simple',
-        update=internal_update)
-    path_transparency = bpy.props.IntProperty(name="Path transparency",
-        description="Determines visibility of path",
-        default=0,
-        min=0,
-        max=100,
-        subtype='PERCENTAGE',
-        update=internal_update)
-    path_width = bpy.props.IntProperty(name="Path width",
-        description="Width in pixels",
-        default=1,
-        min=1,
-        soft_max=5,
-        update=internal_update)
-    timebeads = bpy.props.IntProperty(name="Time beads",
-        description="Number of time beads to display per segment",
-        default=5,
-        min=1,
-        soft_max = 10,
-        update=internal_update)
-
-
-classes = [MotionTrailProps,
-    MotionTrailOperator,
-    MotionTrailPanel]
-
-
-def register():
-    for c in classes:
-        bpy.utils.register_class(c)
-    bpy.types.WindowManager.motion_trail = bpy.props.PointerProperty(\
-        type=MotionTrailProps)
-
-
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-    del bpy.types.WindowManager.motion_trail
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/btrace/__init__.py b/release/scripts/addons_contrib/btrace/__init__.py
deleted file mode 100644
index e2dac1d..0000000
--- a/release/scripts/addons_contrib/btrace/__init__.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#BEGIN GPL LICENSE BLOCK
-
-#This program is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public License
-#as published by the Free Software Foundation; either version 2
-#of the License, or (at your option) any later version.
-
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-#GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, write to the Free Software Foundation,
-#Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-#END GPL LICENCE BLOCK
-
-bl_info = {
-    'name': "Btrace",
-    'author': "liero, crazycourier, Atom, Meta-Androcto, MacKracken",
-    'version': (1, 1, ),
-    'blender': (2, 62),
-    'location': "View3D > Tools",
-    'description': "Tools for converting/animating objects/particles into curves",
-    'warning': "Still under development, bug reports appreciated",
-    'wiki_url': "",
-    'tracker_url': "http://projects.blender.org/tracker/?func=detail&atid=468&aid=29563&group_id=153",
-    'category': "Add Curve"
-    }
-
-import bpy
-from .bTrace import *
-import selection_utils
-from bpy.props import FloatProperty, EnumProperty, IntProperty, BoolProperty, FloatVectorProperty
-
-### Define Classes to register
-classes = [
-    TracerProperties,
-    TracerPropertiesMenu,
-    addTracerObjectPanel,
-    OBJECT_OT_convertcurve,
-    OBJECT_OT_objecttrace,
-    OBJECT_OT_objectconnect,
-    OBJECT_OT_writing,
-    OBJECT_OT_particletrace,
-    OBJECT_OT_traceallparticles,
-    OBJECT_OT_curvegrow,
-    OBJECT_OT_reset,
-    OBJECT_OT_fcnoise,
-    OBJECT_OT_meshfollow,
-    OBJECT_OT_materialChango,
-    OBJECT_OT_clearColorblender
-    ]
-
-def register():
-    for c in classes:
-        bpy.utils.register_class(c)
-    bpy.types.WindowManager.curve_tracer = bpy.props.PointerProperty(type=TracerProperties)
-    bpy.types.WindowManager.btrace_menu = bpy.props.PointerProperty(type=TracerPropertiesMenu, update=deselect_others)
-
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-    del bpy.types.WindowManager.curve_tracer
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/btrace/bTrace.py b/release/scripts/addons_contrib/btrace/bTrace.py
deleted file mode 100644
index c4769e8..0000000
--- a/release/scripts/addons_contrib/btrace/bTrace.py
+++ /dev/null
@@ -1,1564 +0,0 @@
-#BEGIN GPL LICENSE BLOCK
-
-#This program is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public License
-#as published by the Free Software Foundation; either version 2
-#of the License, or (at your option) any later version.
-
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-#GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, write to the Free Software Foundation,
-#Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-#END GPL LICENCE BLOCK
-
-bl_info = {
-    'name': "Btrace",
-    'author': "liero, crazycourier, Atom, Meta-Androcto, MacKracken",
-    'version': (1, 1, ),
-    'blender': (2, 62),
-    'location': "View3D > Tools",
-    'description': "Tools for converting/animating objects/particles into curves",
-    'warning': "Still under development, bug reports appreciated",
-    'wiki_url': "",
-    'tracker_url': "http://projects.blender.org/tracker/?func=detail&atid=468&aid=29563&group_id=153",
-    'category': "Add Curve"
-    }
-
-#### TO DO LIST ####
-### [   ]  Add more options to curve radius/modulation plus cyclic/connect curve option
-
-import bpy
-import selection_utils
-from bpy.props import FloatProperty, EnumProperty, IntProperty, BoolProperty, FloatVectorProperty
-
-
-def deselect_others(ob, context):
-    '''For tool menu select, deselects others if one selected'''
-    selected = addTracerObjectPanel.selected
-    ob[selected] = False
-    keys = [key for key in ob.keys() if ob[key]]  # all the True keys
-    if len(keys) <= 0:
-        ob[selected] = True  # reselect
-        return None
-    for key in keys:
-        addTracerObjectPanel.selected = key
-        ob[key] = True
-
-
-# Class for properties panel
-class TracerPropertiesMenu(bpy.types.PropertyGroup):
-    '''Toolbar show/hide booleans for tool options'''
-    tool_objectTrace = BoolProperty(name="Object Trace", default=False, description="Trace selected mesh object with a curve", update=deselect_others)
-    tool_objectsConnect = BoolProperty(name="Objects Connect", default=False, description="Connect objects with a curve controlled by hooks", update=deselect_others)
-    tool_particleTrace = BoolProperty(name="Particle Trace", default=False, description="Trace particle path with a  curve", update=deselect_others)
-    tool_meshFollow = BoolProperty(name="Mesh Follow", default=False, description="Follow selection items on animated mesh object", update=deselect_others)
-    tool_particleConnect = BoolProperty(name="Particle Connect", default=False, description="Connect particles with a curves and animated over particle lifetime", update=deselect_others)
-    tool_growCurve = BoolProperty(name="Grow Curve", default=False, description="Animate curve bevel over time by keyframing points radius", update=deselect_others)
-    tool_handwrite = BoolProperty(name="Handwriting", default=False, description="Create and Animate curve using the grease pencil", update=deselect_others)
-    tool_fcurve = BoolProperty(name="F-Curve Noise", default=False, description="Add F-Curve noise to selected objects", update=deselect_others)
-    tool_colorblender = BoolProperty(name="Color Blender", default=False, description="Add F-Curve noise to selected objects", update=deselect_others)
-
-
-# Class to define properties
-class TracerProperties(bpy.types.PropertyGroup):
-    '''Options for tools'''
-    curve_spline = EnumProperty(name="Spline", items=(("POLY", "Poly", "Use Poly spline type"),  ("NURBS", "Nurbs", "Use Nurbs spline type"), ("BEZIER", "Bezier", "Use Bezier spline type")), description="Choose which type of spline to use when curve is created", default="BEZIER")
-    curve_handle = EnumProperty(name="Handle", items=(("ALIGNED", "Aligned", "Use Aligned Handle Type"), ("AUTOMATIC", "Automatic", "Use Auto Handle Type"), ("FREE_ALIGN", "Free Align", "Use Free Handle Type"), ("VECTOR", "Vector", "Use Vector Handle Type")), description="Choose which type of handle to use when curve is created",  default="VECTOR")
-    curve_resolution = IntProperty(name="Bevel Resolution", min=1, max=32, default=4, description="Adjust the Bevel resolution")
-    curve_depth = FloatProperty(name="Bevel Depth", min=0.0, max=100.0, default=0.1, description="Adjust the Bevel depth")
-    curve_u = IntProperty(name="Resolution U", min=0, max=64, default=12, description="Adjust the Surface resolution")
-    curve_join = BoolProperty(name="Join Curves", default=False, description="Join all the curves after they have been created")
-    curve_smooth = BoolProperty(name="Smooth", default=True, description="Render curve smooth")
-    # Option to Duplicate Mesh
-    object_duplicate = BoolProperty(name="Apply to Copy", default=False, description="Apply curve to a copy of object")
-    # Distort Mesh options
-    distort_modscale = IntProperty(name="Modulation Scale", min=0, max=50, default=2, description="Add a scale to modulate the curve at random points, set to 0 to disable")
-    distort_noise = FloatProperty(name="Mesh Noise", min=0.0, max=50.0, default=0.00, description="Adjust noise added to mesh before adding curve")
-    # Particle Options
-    particle_step = IntProperty(name="Step Size", min=1, max=50, default=5, description="Sample one every this number of frames")
-    particle_auto = BoolProperty(name='Auto Frame Range', default=True, description='Calculate Frame Range from particles life')
-    particle_f_start = IntProperty(name='Start Frame', min=1, max=5000, default=1, description='Start frame')
-    particle_f_end = IntProperty(name='End Frame', min=1, max=5000, default=250, description='End frame')
-    # F-Curve Modifier Properties
-    fcnoise_rot = BoolProperty(name="Rotation", default=False, description="Affect Rotation")
-    fcnoise_loc = BoolProperty(name="Location", default=True, description="Affect Location")
-    fcnoise_scale = BoolProperty(name="Scale", default=False, description="Affect Scale")
-    fcnoise_amp = IntProperty(name="Amp", min=1, max=500, default=5, description="Adjust the amplitude")
-    fcnoise_timescale = FloatProperty(name="Time Scale", min=1, max=500, default=50, description="Adjust the time scale")
-    fcnoise_key = BoolProperty(name="Add Keyframe", default=True, description="Keyframe is needed for tool, this adds a LocRotScale keyframe")
-    show_curve_settings = BoolProperty(name="Curve Settings", default=False, description="Change the curve settings for the created curve")
-    material_settings = BoolProperty(name="Material Settings", default=False, description="Change the material settings for the created curve")
-    particle_settings = BoolProperty(name="Particle Settings", default=False, description="Show the settings for the created curve")
-    animation_settings = BoolProperty(name="Animation Settings", default=False, description="Show the settings for the Animations")
-    distort_curve = BoolProperty(name="Add Distortion", default=False, description="Set options to distort the final curve")
-    connect_noise = BoolProperty(name="F-Curve Noise", default=False, description="Adds F-Curve Noise Modifier to selected objects")
-    settings_objectTrace = BoolProperty(name="Object Trace Settings", default=False, description="Trace selected mesh object with a curve")
-    settings_objectsConnect = BoolProperty(name="Objects Connect Settings", default=False, description="Connect objects with a curve controlled by hooks")
-    settings_objectTrace = BoolProperty(name="Object Trace Settings", default=False, description="Trace selected mesh object with a curve")
-    respect_order = BoolProperty(name="Order", default=False, description="Remember order objects were selected")
-    settings_particleTrace = BoolProperty(name="Particle Trace Settings", default=False, description="Trace particle path with a  curve")
-    settings_particleConnect = BoolProperty(name="Particle Connect Settings", default=False, description="Connect particles with a curves and animated over particle lifetime")
-    settings_growCurve = BoolProperty(name="Grow Curve Settings", default=False, description="Animate curve bevel over time by keyframing points radius")
-    settings_fcurve = BoolProperty(name="F-Curve Settings", default=False, description="F-Curve Settings")
-    settings_toggle = BoolProperty(name="Settings", default=False, description="Toggle Settings")
-    # Animation Options
-    anim_auto = BoolProperty(name='Auto Frame Range', default=True, description='Automatically calculate Frame Range')
-    anim_f_start = IntProperty(name='Start', min=1, max=2500, default=1, description='Start frame / Hidden object')
-    anim_length = IntProperty(name='Duration', min=1, soft_max=1000, max=2500, default=100, description='Animation Length')
-    anim_f_fade = IntProperty(name='Fade After', min=0, soft_max=250, max=2500, default=10, description='Fade after this frames / Zero means no fade')
-    anim_delay = IntProperty(name='Grow', min=0, max=50, default=5, description='Frames it takes a point to grow')
-    anim_tails = BoolProperty(name='Tails on endpoints', default=True, description='Set radius to zero for open splines endpoints')
-    anim_keepr = BoolProperty(name='Keep Radius', default=True, description='Try to keep radius data from original curve')
-    animate = BoolProperty(name="Animate Result", default=False, description='Animate the final curve objects')
-    # Convert to Curve options
-    convert_conti = BoolProperty(name='Continuous', default=True, description='Create a continuous curve using verts from mesh')
-    convert_everyedge = BoolProperty(name='Every Edge', default=False, description='Create a curve from all verts in a mesh')
-    convert_edgetype = EnumProperty(name="Edge Type for Curves",
-        items=(("CONTI", "Continuous", "Create a continuous curve using verts from mesh"),  ("EDGEALL", "All Edges", "Create a curve from every edge in a mesh")),
-        description="Choose which type of spline to use when curve is created", default="CONTI")
-    convert_joinbefore = BoolProperty(name="Join objects before convert", default=False, description='Join all selected mesh to one object before converting to mesh')
-    # Mesh Follow Options
-    fol_edge_select = BoolProperty(name='Edge', default=False, description='Grow from edges')
-    fol_vert_select = BoolProperty(name='Vertex', default=False, description='Grow from verts')
-    fol_face_select = BoolProperty(name='Face', default=True, description='Grow from faces')
-    fol_mesh_type = EnumProperty(name='Mesh type', default='VERTS', description='Mesh feature to draw cruves from', items=(
-        ("VERTS", "Verts", "Draw from Verts"), ("EDGES", "Edges", "Draw from Edges"), ("FACES", "Faces", "Draw from Faces"), ("OBJECT", "Object", "Draw from Object origin")))
-    fol_start_frame = IntProperty(name="Start Frame", min=1, max=2500, default=1, description="Start frame for range to trace")
-    fol_end_frame = IntProperty(name="End Frame", min=1, max=2500, default=250, description="End frame for range to trace")
-    fol_perc_verts = FloatProperty(name="Reduce selection by", min=0.001, max=1.000, default=0.5, description="percentage of total verts to trace")
-    fol_sel_option = EnumProperty(name="Selection type", description="Choose which objects to follow", default="RANDOM", items=(
-        ("RANDOM", "Random", "Follow Random items"),  ("CUSTOM", "Custom Select", "Follow selected items"), ("ALL", "All", "Follow all items")))
-    trace_mat_color = FloatVectorProperty(name="Material Color", description="Choose material color", min=0, max=1, default=(0.0,0.3,0.6), subtype="COLOR")
-    trace_mat_random = BoolProperty(name="Random Color", default=False, description='Make the material colors random')
-
-    # Material custom Properties properties
-    mat_simple_adv_toggle = EnumProperty(name="Material Options", items=(("SIMPLE", "Simple", "Show Simple Material Options"), ("ADVANCED", "Advanced", "Show Advanced Material Options")), description="Choose which Material Options to show", default="SIMPLE")
-    mat_run_color_blender = BoolProperty(name="Run Color Blender", default=False, description="Generate colors from a color scheme")
-    mmColors = bpy.props.EnumProperty(
-        items=(("RANDOM", "Random", "Use random colors"),
-                ("CUSTOM", "Custom", "Use custom colors"),
-                ("BW", "Black/White", "Use Black and White"),
-                ("BRIGHT", "Bright Colors", "Use Bright colors"),
-                ("EARTH", "Earth", "Use Earth colors"),
-                ("GREENBLUE", "Green to Blue", "Use Green to Blue colors")),
-        description="Choose which type of colors the materials uses",
-        default="BRIGHT",
-        name="Define a color palette")
-    # Custom property for how many keyframes to skip
-    mmSkip = bpy.props.IntProperty(name="frames", min=1, max=500, default=20, description="Number of frames between each keyframes")
-    # Custom property to enable/disable random order for the 
-    mmBoolRandom = bpy.props.BoolProperty(name="Random Order", default=False, description="Randomize the order of the colors")
-    # Custom Color properties
-    mmColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.8, 0.8), description="Custom Color 1", subtype="COLOR")
-    mmColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.8, 0.3), description="Custom Color 2", subtype="COLOR")
-    mmColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.5, 0.6), description="Custom Color 3", subtype="COLOR")
-    mmColor4 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.2, 0.8, 0.289), description="Custom Color 4", subtype="COLOR")
-    mmColor5 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0, 0.348, 0.8), description="Custom Color 5", subtype="COLOR")
-    mmColor6 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.4, 0.67, 0.8), description="Custom Color 6", subtype="COLOR")
-    mmColor7 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.66, 0.88, 0.8), description="Custom Color 7", subtype="COLOR")
-    mmColor8 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.38, 0.22), description="Custom Color 8", subtype="COLOR")
-    # BW Color properties
-    bwColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.0,0.0,0.0), description="Black/White Color 1", subtype="COLOR")
-    bwColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0,1.0,1.0), description="Black/White Color 2", subtype="COLOR")
-    # Bright Color properties
-    brightColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0, 0.0, 0.75), description="Bright Color 1", subtype="COLOR")
-    brightColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.0,1.0,1.0), description="Bright Color 2", subtype="COLOR")
-    brightColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.0,1.0,0.0), description="Bright Color 3", subtype="COLOR")
-    brightColor4 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0,1.0,0.0), description="Bright Color 4", subtype="COLOR")
-    # Earth Color Properties
-    earthColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.068, 0.019, 0.014), description="Earth Color 1", subtype="COLOR")
-    earthColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.089, 0.060, 0.047), description="Earth Color 2", subtype="COLOR")
-    earthColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.188, 0.168, 0.066), description="Earth Color 3", subtype="COLOR")
-    earthColor4 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.445, 0.296, 0.065), description="Earth Color 4", subtype="COLOR")
-    earthColor5 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.745, 0.332, 0.065), description="Earth Color 5", subtype="COLOR")
-    # Green to Blue Color properties
-    greenblueColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.296, 0.445, 0.074), description="Green/Blue Color 1", subtype="COLOR")
-    greenblueColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.651, 1.0, 0.223), description="Green/Blue Color 2", subtype="COLOR")
-    greenblueColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.037, 0.047, 0.084), description="Green/Blue Color 3", subtype="COLOR")
-
-
-############################
-## Draw Brush panel in Toolbar
-############################
-class addTracerObjectPanel(bpy.types.Panel):
-    bl_label = "Btrace: Panel"
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_context = 'objectmode'
-    selected = "tool_objectTrace"
-
-    def draw(self, context):
-        layout = self.layout
-        Btrace = bpy.context.window_manager.curve_tracer
-        btracemenu = props = bpy.context.window_manager.btrace_menu
-        obj = bpy.context.object
-
-
-        ############################
-        ## Color Blender Panel options
-        ############################
-        def color_blender():
-            '''Buttons for Color Blender'''
-            row = box.row()
-            row.label("Color palette")
-            row.prop(Btrace, 'mmColors', text="")
-            # Show Custom Colors if selected
-            if Btrace.mmColors == 'CUSTOM':
-                row = box.row(align=True)
-                row.prop(Btrace, 'mmColor1', text="")
-                row.prop(Btrace, 'mmColor2', text="")
-                row.prop(Btrace, 'mmColor3', text="")
-                row.prop(Btrace, 'mmColor4', text="")
-                row.prop(Btrace, 'mmColor5', text="")
-                row.prop(Btrace, 'mmColor6', text="")
-                row.prop(Btrace, 'mmColor7', text="")
-                row.prop(Btrace, 'mmColor8', text="")
-            # Show Earth Colors
-            elif Btrace.mmColors == 'BW':
-                row = box.row(align=True)
-                row.prop(Btrace, 'bwColor1', text="")
-                row.prop(Btrace, 'bwColor2', text="")
-            # Show Earth Colors
-            elif Btrace.mmColors == 'BRIGHT':
-                row = box.row(align=True)
-                row.prop(Btrace, 'brightColor1', text="")
-                row.prop(Btrace, 'brightColor2', text="")
-                row.prop(Btrace, 'brightColor3', text="")
-                row.prop(Btrace, 'brightColor4', text="")
-            # Show Earth Colors
-            elif Btrace.mmColors == 'EARTH':
-                row = box.row(align=True)
-                row.prop(Btrace, 'earthColor1', text="")
-                row.prop(Btrace, 'earthColor2', text="")
-                row.prop(Btrace, 'earthColor3', text="")
-                row.prop(Btrace, 'earthColor4', text="")
-                row.prop(Btrace, 'earthColor5', text="")
-            # Show Earth Colors
-            elif Btrace.mmColors == 'GREENBLUE':
-                row = box.row(align=True)
-                row.prop(Btrace, 'greenblueColor1', text="")
-                row.prop(Btrace, 'greenblueColor2', text="")
-                row.prop(Btrace, 'greenblueColor3', text="")
-            elif Btrace.mmColors == 'RANDOM':
-                row = box.row()
-
-        ############################
-        ## Curve Panel options
-        ############################
-        def curve_settings():
-            '''Button for curve options'''
-            row = self.layout.row()
-            row = box.row(align=True)
-
-            row.prop(Btrace, 'show_curve_settings', icon='CURVE_BEZCURVE', text="Curve Settings")
-            row.prop(Btrace, 'material_settings', icon='MATERIAL_DATA', text="Material Settings")
-            if Btrace.material_settings:
-                row = box.row()
-                row.label(text="Material Settings", icon='COLOR')
-                row = box.row()
-                row.prop(Btrace, "trace_mat_random")
-                if not Btrace.trace_mat_random:
-                    row = box.row()
-                    row.prop(Btrace, "trace_mat_color", text="")
-                else:
-                    row.prop(Btrace, "mat_run_color_blender")
-                    if Btrace.mat_run_color_blender:
-                        row = box.row()
-                        row.operator("object.colorblenderclear", text="Reset Material Keyframes", icon="KEY_DEHLT")
-                        row.prop(Btrace, 'mmSkip', text="Keyframe every")
-                      
-                    color_blender()
-                row = box.row()
-            if Btrace.show_curve_settings:
-                #if  or btracemenu.tool_handwrite:
-                if len(bpy.context.selected_objects) > 0 and obj.type == 'CURVE': # selected curve options
-                    col = box.column(align=True)
-                    col.label(text="Edit Curves for", icon='CURVE_BEZCURVE')
-                    col.label(text="Selected Curve Bevel Options")
-                    row = col.row(align=True)
-                    row.prop(obj.data, 'bevel_depth', text="Depth")
-                    row.prop(obj.data, 'bevel_resolution', text="Resolution")
-                    row = col.row(align=True)
-                    row.prop(obj.data, 'resolution_u')
-                else: # For new curve
-                    box.label(text="New Curve Settings", icon='CURVE_BEZCURVE')
-                    box.prop(Btrace, "curve_spline")
-                    box.prop(Btrace, "curve_handle")
-                    box.label(text="Bevel Options")
-                    col = box.column(align=True)
-                    row = col.row(align=True)
-                    row.prop(Btrace, "curve_depth", text="Depth")
-                    row.prop(Btrace, "curve_resolution", text="Resolution")
-                    row = col.row(align=True)
-                    row.prop(Btrace, "curve_u")
-
-        ############################
-        ## Grow Animation Panel options
-        ############################
-        def add_grow():
-            '''Button for grow animation option'''
-            row = box.row()
-            row.label(text="Animate Final Curve")
-            row = box.row()
-            row.prop(Btrace, "animate", text="Add Grow Curve Animation", icon="META_BALL")
-            row.label("")
-            if Btrace.animate:
-                box.label(text='Frame Animation Settings:', icon="META_BALL")
-                col = box.column(align=True)
-                col.prop(Btrace, 'anim_auto')
-                if not Btrace.anim_auto:
-                    row = col.row(align=True)
-                    row.prop(Btrace, 'anim_f_start')
-                    row.prop(Btrace, 'anim_length')
-                row = col.row(align=True)
-                row.prop(Btrace, 'anim_delay')
-                row.prop(Btrace, 'anim_f_fade')
-
-                box.label(text='Additional Settings')
-                row = box.row()
-                row.prop(Btrace, 'anim_tails')
-                row.prop(Btrace, 'anim_keepr')
-
-        ##################################################################
-        ## Start Btrace Panel
-        ##################################################################
-        col = self.layout.column(align=True)
-        #col.label(text="Trace Tools")
-        row = col.row()
-        row.prop(btracemenu, "tool_objectTrace", text="Ojbect Trace", icon="FORCE_MAGNETIC")
-        row.prop(btracemenu, "tool_objectsConnect", text="Object Connect", icon="OUTLINER_OB_EMPTY")
-        row = col.row()
-        row.prop(btracemenu, "tool_meshFollow", text="Mesh Follow", icon="DRIVER")
-        row.prop(btracemenu, "tool_handwrite", text="Handwriting", icon='BRUSH_DATA')
-        row = col.row()   
-        row.prop(btracemenu, "tool_particleTrace", icon="PARTICLES", text="Particle Trace")
-        row.prop(btracemenu, "tool_particleConnect", icon="MOD_PARTICLES", text="Particle Connect")
-        row = layout.row()
-        col = layout.column(align=True)
-        row = col.row()
-        row.prop(btracemenu, "tool_growCurve", icon="META_BALL", text="Grow Animation")
-        row.prop(btracemenu, "tool_fcurve", text="Fcurve Noise", icon='RNDCURVE')
-        row = col.row()
-        row.prop(btracemenu, "tool_colorblender", text="Color Blender", icon="COLOR")
-        row.label(text="")
-        row = layout.row()
-
-        ##########################
-        ## Start  Object Tools
-        ##########################
-        sel = bpy.context.selected_objects
-        ############################
-        ### Object Trace
-        ############################
-        if btracemenu.tool_objectTrace:
-            row = layout.row()
-            row.label(text="  Trace Tool:", icon="FORCE_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="Object Trace", icon="FORCE_MAGNETIC")
-            row.operator("object.btobjecttrace", text="Run!", icon="PLAY")
-            row = box.row()
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            myselected = "Selected %d" % len(bpy.context.selected_objects)
-            row.label(text=myselected)
-            if Btrace.settings_toggle:
-                row = box.row()
-                row.label(text='Edge Draw Method')
-                row = box.row(align=True)
-                row.prop(Btrace, 'convert_edgetype')
-                box.prop(Btrace, "object_duplicate")
-                if len(sel) > 1:
-                    box.prop(Btrace, 'convert_joinbefore')
-                else:
-                    Btrace.convert_joinbefore = False
-                row = box.row()
-                row.prop(Btrace, "distort_curve")
-                if Btrace.distort_curve:
-                    col = box.column(align=True)
-                    col.prop(Btrace, "distort_modscale")
-                    col.prop(Btrace, "distort_noise")
-                row = box.row()
-                curve_settings()  # Show Curve/material settings
-                add_grow()  # Grow settings here
-
-        ############################
-        ### Objects Connect
-        ############################
-        if btracemenu.tool_objectsConnect:
-            row = layout.row()
-            row.label(text="  Trace Tool:", icon="FORCE_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="Objects Connect", icon="OUTLINER_OB_EMPTY")
-            row.operator("object.btobjectsconnect", text="Run!", icon="PLAY")
-            row = box.row()
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            row.label(text="")
-            if Btrace.settings_toggle:
-                row = box.row()
-                row.prop(Btrace, "respect_order", text="Selection Options")
-                if Btrace.respect_order:
-                    box.operator("object.select_order", text="Click to start order selection", icon='UV_SYNC_SELECT')
-                row = box.row()
-                row.prop(Btrace, "connect_noise", text="Add F-Curve Noise")
-                if Btrace.connect_noise:
-                    row = box.row()
-                    row.label(text="F-Curve Noise", icon='RNDCURVE')
-                    row = box.row(align=True)
-                    row.prop(Btrace, "fcnoise_rot")
-                    row.prop(Btrace, "fcnoise_loc")
-                    row.prop(Btrace, "fcnoise_scale")
-                    col = box.column(align=True)
-                    col.prop(Btrace, "fcnoise_amp")
-                    col.prop(Btrace, "fcnoise_timescale")
-                    box.prop(Btrace, "fcnoise_key")
-                curve_settings()  # Show Curve/material settings
-                add_grow()  # Grow settings here
-
-        ############################
-        ### Mesh Follow
-        ############################
-        if btracemenu.tool_meshFollow:
-            row = layout.row()
-            row.label(text="  Trace Tool:", icon="FORCE_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="Mesh Follow", icon="DRIVER")
-            row.operator("object.btmeshfollow", text="Run!", icon="PLAY")
-            row = box.row()
-            if Btrace.fol_mesh_type == 'OBJECT':
-                a, b = "Trace Object", "SNAP_VOLUME"
-            if Btrace.fol_mesh_type == 'VERTS':
-                a, b = "Trace Verts", "SNAP_VERTEX"
-            if Btrace.fol_mesh_type == 'EDGES':
-                a, b = "Trace Edges", "SNAP_EDGE"
-            if Btrace.fol_mesh_type == 'FACES':
-               a, b = "Trace Faces", "SNAP_FACE"
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            row.label(text=a, icon=b)
-            if Btrace.settings_toggle:
-                col = box.column(align=True)
-                row = col.row(align=True)
-                row.prop(Btrace, "fol_mesh_type", expand=True)
-                row = col.row(align=True)
-                if Btrace.fol_mesh_type != 'OBJECT':
-                    row.prop(Btrace, "fol_sel_option", expand=True)
-                    row = box.row()
-                    if Btrace.fol_sel_option == 'RANDOM':
-                        row.label("Random Select of Total")
-                        row.prop(Btrace, "fol_perc_verts", text="%")
-                    if Btrace.fol_sel_option == 'CUSTOM':
-                        row.label("Choose selection in Edit Mode")
-                    if Btrace.fol_sel_option == 'ALL':
-                        row.label("Select All items")
-                col = box.column(align=True)
-                col.label("Time Options", icon="TIME")
-                col.prop(Btrace, "particle_step")
-                row = col.row(align=True)
-                row.prop(Btrace, "fol_start_frame")
-                row.prop(Btrace, "fol_end_frame")
-                curve_settings()  # Show Curve/material settings
-                add_grow()  # Grow settings here
-
-         ############################
-        ### Handwriting Tools
-        ############################
-        if btracemenu.tool_handwrite:
-            row = layout.row()
-            row.label(text="  Trace Tool:", icon="FORCE_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text='Handwriting', icon='BRUSH_DATA')
-            row.operator("curve.btwriting", text="Run!", icon='PLAY')
-            row = box.row()
-            row = box.row()
-            row.label(text='Grease Pencil Writing Tools')
-            col = box.column(align=True)
-            row = col.row(align=True)
-            row.operator("gpencil.draw", text="Draw", icon='BRUSH_DATA').mode = 'DRAW'
-            row.operator("gpencil.draw", text="Poly", icon='VPAINT_HLT').mode = 'DRAW_POLY'
-            row = col.row(align=True)
-            row.operator("gpencil.draw", text="Line", icon='ZOOMOUT').mode = 'DRAW_STRAIGHT'
-            row.operator("gpencil.draw", text="Erase", icon='TPAINT_HLT').mode = 'ERASER'
-            row = box.row()
-            row.operator("gpencil.data_unlink", text="Delete Grease Pencil Layer", icon="CANCEL")
-            row = box.row()
-            curve_settings()  # Show Curve/material settings
-            add_grow()  # Grow settings here
-
-        ############################
-        ### Particle Trace
-        ############################
-        if btracemenu.tool_particleTrace:
-            row = layout.row()
-            row.label(text="  Trace Tool:", icon="FORCE_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="Particle Trace", icon="PARTICLES")
-            row.operator("particles.particletrace", text="Run!", icon="PLAY")
-            row = box.row()
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            row.label(text="")
-            if Btrace.settings_toggle:
-                box.prop(Btrace, "particle_step")
-                row = box.row()
-                row.prop(Btrace, "curve_join")
-                curve_settings()  # Show Curve/material settings
-                add_grow()  # Grow settings here
-
-        ############################
-        ### Connect Particles
-        ############################
-        if btracemenu.tool_particleConnect:
-            row = layout.row()
-            row.label(text="  Trace Tool:", icon="FORCE_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text='Particle Connect', icon='MOD_PARTICLES')
-            row.operator("particles.connect", icon="PLAY", text='Run!')
-            row = box.row()
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            row.label(text="")
-            if Btrace.settings_toggle:
-                box.prop(Btrace, "particle_step")
-                row = box.row()
-                row.prop(Btrace, 'particle_auto')
-                if not Btrace.particle_auto:
-                    row = box.row(align=True)
-                    row.prop(Btrace, 'particle_f_start')
-                    row.prop(Btrace, 'particle_f_end')
-                curve_settings()  # Show Curve/material settings
-                add_grow()  # Grow settings here
-
-        #######################
-        #### Grow Animation ####
-        #######################
-        if btracemenu.tool_growCurve:
-            row = layout.row()
-            row.label(text="  Curve Tool:", icon="OUTLINER_OB_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="Grow Curve", icon="META_BALL")
-            row.operator('curve.btgrow', text='Run!', icon='PLAY')
-            row = box.row()
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            row.operator('object.btreset',  icon='KEY_DEHLT')
-            if Btrace.settings_toggle:
-                box.label(text='Frame Animation Settings:')
-                col = box.column(align=True)
-                col.prop(Btrace, 'anim_auto')
-                if not Btrace.anim_auto:
-                    row = col.row(align=True)
-                    row.prop(Btrace, 'anim_f_start')
-                    row.prop(Btrace, 'anim_length')
-                row = col.row(align=True)
-                row.prop(Btrace, 'anim_delay')
-                row.prop(Btrace, 'anim_f_fade')
-
-                box.label(text='Additional Settings')
-                row = box.row()
-                row.prop(Btrace, 'anim_tails')
-                row.prop(Btrace, 'anim_keepr')
-
-        #######################
-        #### F-Curve Noise Curve ####
-        #######################
-        if btracemenu.tool_fcurve:
-            row = layout.row()
-            row.label(text="  Curve Tool:", icon="OUTLINER_OB_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="F-Curve Noise", icon='RNDCURVE')
-            row.operator("object.btfcnoise", icon='PLAY', text="Run!")
-            row = box.row()
-            row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
-            row.operator('object.btreset',  icon='KEY_DEHLT')
-            if Btrace.settings_toggle:
-                row = box.row(align=True)
-                row.prop(Btrace, "fcnoise_rot")
-                row.prop(Btrace, "fcnoise_loc")
-                row.prop(Btrace, "fcnoise_scale")
-                col = box.column(align=True)
-                col.prop(Btrace, "fcnoise_amp")
-                col.prop(Btrace, "fcnoise_timescale")
-                box.prop(Btrace, "fcnoise_key")
-
-        #######################
-        #### Color Blender ####
-        #######################
-        if btracemenu.tool_colorblender:
-            row = layout.row()
-            row.label(text="  Curve/Object Tool:", icon="OUTLINER_OB_CURVE")
-            box = self.layout.box()
-            row = box.row()
-            row.label(text="Color Blender", icon="COLOR")
-            row.operator("object.colorblender", icon='PLAY', text="Run!")
-            row = box.row()
-            row.operator("object.colorblenderclear", text="Reset Keyframes", icon="KEY_DEHLT")
-            row.prop(Btrace, 'mmSkip', text="Keyframe every")
-            color_blender()
-
-###### END PANEL ##############
-###############################
-
-
-################## ################## ################## ############
-## Object Trace
-## creates a curve with a modulated radius connecting points of a mesh
-################## ################## ################## ############
-
-class OBJECT_OT_objecttrace(bpy.types.Operator):
-    bl_idname = "object.btobjecttrace"
-    bl_label = "Btrace: Object Trace"
-    bl_description = "Trace selected mesh object with a curve with the option to animate"
-    bl_options = {'REGISTER', 'UNDO'}
-
-
-    @classmethod
-    def poll(cls, context):
-        return (context.object and context.object.type in {'MESH', 'FONT'})
-
-    def invoke(self, context, event):
-        import bpy
-
-        # Run through each selected object and convert to to a curved object
-        brushObj = bpy.context.selected_objects
-        Btrace = bpy.context.window_manager.curve_tracer
-        # Duplicate Mesh
-        if Btrace.object_duplicate:
-            bpy.ops.object.duplicate_move()
-            brushObj = bpy.context.selected_objects
-        # Join Mesh
-        if Btrace.convert_joinbefore:
-            if len(brushObj) > 1:  # Only run if multiple objects selected
-                bpy.ops.object.join()
-                brushObj = bpy.context.selected_objects
-
-        for i in brushObj:
-            bpy.context.scene.objects.active = i
-            if i and i.type != 'CURVE':
-                bpy.ops.object.btconvertcurve()
-                addtracemat(bpy.context.object.data)
-            if Btrace.animate:
-                bpy.ops.curve.btgrow()
-        return{"FINISHED"}
-
-
-################## ################## ################## ############
-## Objects Connect
-## connect selected objects with a curve + hooks to each node
-## possible handle types: 'FREE' 'AUTO' 'VECTOR' 'ALIGNED'
-################## ################## ################## ############
-
-class OBJECT_OT_objectconnect(bpy.types.Operator):
-    bl_idname = "object.btobjectsconnect"
-    bl_label = "Btrace: Objects Connect"
-    bl_description = "Connect selected objects with a curve and add hooks to each node"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        return len(bpy.context.selected_objects) > 1
-
-    def invoke(self, context, event):
-        import bpy, selection_utils
-        list = []
-        Btrace = bpy.context.window_manager.curve_tracer
-        curve_handle = Btrace.curve_handle
-        if curve_handle == 'AUTOMATIC':  # hackish because of naming conflict in api
-            curve_handle = 'AUTO'
-        # Check if Btrace group exists, if not create
-        bgroup = bpy.data.groups.keys()
-        if 'Btrace' not in bgroup:
-            bpy.ops.group.create(name="Btrace")
-        #  check if noise
-        if Btrace.connect_noise:
-            bpy.ops.object.btfcnoise()
-        # check if respect order is checked, create list of objects
-        if Btrace.respect_order == True:
-            selobnames = selection_utils.selected
-            obnames = []
-            for ob in selobnames:
-                obnames.append(bpy.data.objects[ob])
-        else:
-            obnames = bpy.context.selected_objects  # No selection order
-
-        for a in obnames:
-            list.append(a)
-            a.select = False
-
-        # trace the origins
-        tracer = bpy.data.curves.new('tracer', 'CURVE')
-        tracer.dimensions = '3D'
-        spline = tracer.splines.new('BEZIER')
-        spline.bezier_points.add(len(list) - 1)
-        curve = bpy.data.objects.new('curve', tracer)
-        bpy.context.scene.objects.link(curve)
-
-        # render ready curve
-        tracer.resolution_u = Btrace.curve_u
-        tracer.bevel_resolution = Btrace.curve_resolution  # Set bevel resolution from Panel options
-        tracer.fill_mode = 'FULL'
-        tracer.bevel_depth = Btrace.curve_depth  # Set bevel depth from Panel options
-
-        # move nodes to objects
-        for i in range(len(list)):
-            p = spline.bezier_points[i]
-            p.co = list[i].location
-            p.handle_right_type = curve_handle
-            p.handle_left_type = curve_handle
-
-        bpy.context.scene.objects.active = curve
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-        # place hooks
-        for i in range(len(list)):
-            list[i].select = True
-            curve.data.splines[0].bezier_points[i].select_control_point = True
-            bpy.ops.object.mode_set(mode='EDIT')
-            bpy.ops.object.hook_add_selob()
-            bpy.ops.object.mode_set(mode='OBJECT')
-            curve.data.splines[0].bezier_points[i].select_control_point = False
-            list[i].select = False
-
-        bpy.ops.object.select_all(action='DESELECT')
-        curve.select = True # selected curve after it's created
-        addtracemat(bpy.context.object.data) # Add material
-        if Btrace.animate: # Add Curve Grow it?
-            bpy.ops.curve.btgrow()
-        bpy.ops.object.group_link(group="Btrace") # add to Btrace group
-        if Btrace.animate:
-            bpy.ops.curve.btgrow() # Add grow curve
-        return{"FINISHED"}
-
-
-################## ################## ################## ############
-## Particle Trace
-## creates a curve from each particle of a system
-################## ################## ################## ############
-def  curvetracer(curvename, splinename):
-    Btrace = bpy.context.window_manager.curve_tracer
-    tracer = bpy.data.curves.new(splinename, 'CURVE')
-    tracer.dimensions = '3D'
-    curve = bpy.data.objects.new(curvename, tracer)
-    bpy.context.scene.objects.link(curve)
-    try:
-        tracer.fill_mode = 'FULL'
-    except:
-        tracer.use_fill_front = tracer.use_fill_back = False
-    tracer.bevel_resolution = Btrace.curve_resolution
-    tracer.bevel_depth = Btrace.curve_depth
-    tracer.resolution_u = Btrace.curve_u
-    return tracer, curve
-
-
-class OBJECT_OT_particletrace(bpy.types.Operator):
-    bl_idname = "particles.particletrace"
-    bl_label = "Btrace: Particle Trace"
-    bl_description = "Creates a curve from each particle of a system. Keeping particle amount under 250 will make this run faster"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        return (bpy.context.object and bpy.context.object.particle_systems)
-
-    def execute(self, context):
-        Btrace = bpy.context.window_manager.curve_tracer
-        particle_step = Btrace.particle_step    # step size in frames
-        obj = bpy.context.object
-        ps = obj.particle_systems.active
-        curvelist = []
-        curve_handle = Btrace.curve_handle
-        if curve_handle == 'AUTOMATIC':  # hackish naming conflict
-            curve_handle = 'AUTO'
-        if curve_handle == 'FREE_ALIGN':  # hackish naming conflict
-            curve_handle = 'FREE'
-
-        # Check if Btrace group exists, if not create
-        bgroup = bpy.data.groups.keys()
-        if 'Btrace' not in bgroup:
-            bpy.ops.group.create(name="Btrace")
-
-        if Btrace.curve_join:
-            tracer = curvetracer('Tracer', 'Splines')
-        for x in ps.particles:
-            if not Btrace.curve_join:
-                tracer = curvetracer('Tracer.000', 'Spline.000')
-            spline = tracer[0].splines.new('BEZIER')
-            spline.bezier_points.add((x.lifetime - 1) // particle_step)  # add point to spline based on step size
-            for t in list(range(int(x.lifetime))):
-                bpy.context.scene.frame_set(t + x.birth_time)
-                if not t % particle_step:
-                    p = spline.bezier_points[t // particle_step]
-                    p.co = x.location
-                    p.handle_right_type = curve_handle
-                    p.handle_left_type = curve_handle
-            particlecurve = tracer[1]
-            curvelist.append(particlecurve)
-        # add to group
-        bpy.ops.object.select_all(action='DESELECT')
-        for curveobject in curvelist:
-            curveobject.select = True
-            bpy.context.scene.objects.active = curveobject
-            bpy.ops.object.group_link(group="Btrace")
-            addtracemat(curveobject.data)  # Add material
-        
-        if Btrace.animate:
-            bpy.ops.curve.btgrow()  # Add grow curve
-
-        return{"FINISHED"}
-
-
-###########################################################################
-## Particle Connect
-## connect all particles in active system with a continuous animated curve
-###########################################################################
-
-class OBJECT_OT_traceallparticles(bpy.types.Operator):
-    bl_idname = 'particles.connect'
-    bl_label = 'Connect Particles'
-    bl_description = 'Create a continuous animated curve from particles in active system'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        return (bpy.context.object and bpy.context.object.particle_systems)
-
-    def execute(self, context):
-        
-        obj = bpy.context.object
-        ps = obj.particle_systems.active
-        set = ps.settings
-
-        # Grids distribution not supported
-        if set.distribution == 'GRID':
-            self.report('INFO',"Grid distribution mode for particles not supported.")
-            return{'FINISHED'}
-        
-        Btrace = bpy.context.window_manager.curve_tracer
-        particle_f_start = Btrace.particle_f_start # Get frame start
-        particle_f_end = Btrace.particle_f_end # Get frame end
-        curve_handle = Btrace.curve_handle
-        if curve_handle == 'AUTOMATIC': # hackish because of naming conflict in api
-            curve_handle = 'AUTO'
-        if curve_handle == 'FREE_ALIGN':
-            curve_handle = 'FREE'        
-        tracer = bpy.data.curves.new('Splines','CURVE') # define what kind of object to create
-        curve = bpy.data.objects.new('Tracer',tracer) # Create new object with settings listed above
-        bpy.context.scene.objects.link(curve) # Link newly created object to the scene
-        spline = tracer.splines.new('BEZIER')  # add a new Bezier point in the new curve
-        spline.bezier_points.add(set.count-1)
-		
-        tracer.dimensions = '3D'
-        tracer.resolution_u = Btrace.curve_u
-        tracer.bevel_resolution = Btrace.curve_resolution
-        tracer.fill_mode = 'FULL'
-        tracer.bevel_depth = Btrace.curve_depth
-
-        if Btrace.particle_auto:
-            f_start = int(set.frame_start)
-            f_end = int(set.frame_end + set.lifetime)
-        else:
-            if particle_f_end <= particle_f_start:
-                 particle_f_end = particle_f_start + 1
-            f_start = particle_f_start
-            f_end = particle_f_end
-
-        for bFrames in range(f_start, f_end):
-            bpy.context.scene.frame_set(bFrames)
-            if not (bFrames-f_start) % Btrace.particle_step:
-                for bFrames in range(set.count):
-                    if ps.particles[bFrames].alive_state != 'UNBORN': 
-                        e = bFrames
-                    bp = spline.bezier_points[bFrames]
-                    pt = ps.particles[e]
-                    bp.co = pt.location
-                    #bp.handle_left = pt.location
-                    #bp.handle_right = pt.location
-                    bp.handle_right_type = curve_handle
-                    bp.handle_left_type = curve_handle 
-                    bp.keyframe_insert('co')
-                    bp.keyframe_insert('handle_left')
-                    bp.keyframe_insert('handle_right')
-        # Select new curve
-        bpy.ops.object.select_all(action='DESELECT')
-        curve.select = True
-        bpy.context.scene.objects.active = curve
-        addtracemat(curve.data) #Add material
-        if Btrace.animate:
-            bpy.ops.curve.btgrow()
-        return{'FINISHED'}
-
-################## ################## ################## ############
-## Writing Tool
-## Writes a curve by animating its point's radii
-## 
-################## ################## ################## ############
-class OBJECT_OT_writing(bpy.types.Operator):
-    bl_idname = 'curve.btwriting'
-    bl_label = 'Write'
-    bl_description = 'Use Grease Pencil to write and convert to curves'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    # @classmethod  ### Removed so panel still draws if nothing is selected
-    # def poll(cls, context):
-    #     return (context.scene.grease_pencil or context.object.grease_pencil != None)
-
-    def execute(self, context):
-        Btrace = bpy.context.window_manager.curve_tracer
-        obj = bpy.context.object
-        gactive = bpy.context.active_object # set selected object before convert
-        bpy.ops.gpencil.convert(type='CURVE')
-        gactiveCurve = bpy.context.active_object # get curve after convert
-        # render ready curve
-        gactiveCurve.data.resolution_u = Btrace.curve_u
-        gactiveCurve.data.bevel_resolution = Btrace.curve_resolution  # Set bevel resolution from Panel options
-        gactiveCurve.data.fill_mode = 'FULL'
-        gactiveCurve.data.bevel_depth = Btrace.curve_depth  # Set bevel depth from Panel options
-
-        writeObj = bpy.context.selected_objects
-        if Btrace.animate:
-            for i in writeObj:
-                bpy.context.scene.objects.active = i
-                bpy.ops.curve.btgrow()
-                addtracemat(bpy.context.object.data) #Add material
-        else:
-            for i in writeObj:
-                bpy.context.scene.objects.active = i
-                addtracemat(bpy.context.object.data) #Add material
-
-        # Delete grease pencil strokes
-        bpy.context.scene.objects.active = gactive
-        bpy.ops.gpencil.data_unlink()
-        bpy.context.scene.objects.active = gactiveCurve
-        # Smooth object
-        bpy.ops.object.shade_smooth()
-        # Return to first frame
-        bpy.context.scene.frame_set(Btrace.anim_f_start)
-        
-        return{'FINISHED'}
-
-################## ################## ################## ############
-## Create Curve
-## Convert mesh to curve using either Continuous, All Edges, or Sharp Edges
-## Option to create noise
-################## ################## ################## ############
-
-class OBJECT_OT_convertcurve(bpy.types.Operator):
-    bl_idname = "object.btconvertcurve"
-    bl_label = "Btrace: Create Curve"
-    bl_description = "Convert mesh to curve using either Continuous, All Edges, or Sharp Edges"
-    bl_options = {'REGISTER', 'UNDO'}
-        
-    def execute(self, context):
-        import bpy, random, mathutils
-        from mathutils import Vector
-
-        Btrace = bpy.context.window_manager.curve_tracer
-        traceobjects = bpy.context.selected_objects # create a list with all the selected objects
-
-        obj = bpy.context.object
-        
-        ### Convert Font
-        if obj.type == 'FONT':
-            bpy.ops.object.mode_set(mode='OBJECT')
-            bpy.ops.object.convert(target='CURVE') # Convert edges to curve
-            bpy.context.object.data.dimensions = '3D'
-            
-        # make a continuous edge through all vertices
-        if obj.type == 'MESH':
-            # Add noise to mesh
-            if Btrace.distort_curve:
-                for v in obj.data.vertices:
-                    for u in range(3):
-                        v.co[u] += Btrace.distort_noise * (random.uniform(-1,1))
-
-            if Btrace.convert_edgetype == 'CONTI':
-                ## Start Continuous edge
-                bpy.ops.object.mode_set(mode='EDIT')
-                bpy.ops.mesh.select_all(action='SELECT')
-                bpy.ops.mesh.delete(type='EDGE_FACE')
-                bpy.ops.mesh.select_all(action='DESELECT')
-                verts = bpy.context.object.data.vertices
-                bpy.ops.object.mode_set(mode='OBJECT')
-                li = []
-                p1 = random.randint(0,len(verts)-1) 
-                
-                for v in verts: 
-                    li.append(v.index)
-                li.remove(p1)
-                for z in range(len(li)):
-                    x = []
-                    for px in li:
-                        d = verts[p1].co - verts[px].co # find distance from first vert
-                        x.append(d.length)
-                    p2 = li[x.index(min(x))] # find the shortest distance list index
-                    verts[p1].select = verts[p2].select = True
-                    bpy.ops.object.mode_set(mode='EDIT')
-                    bpy.context.tool_settings.mesh_select_mode = [True, False, False]
-                    bpy.ops.mesh.edge_face_add()
-                    bpy.ops.mesh.select_all(action='DESELECT')
-                    bpy.ops.object.mode_set(mode='OBJECT')
-                    # verts[p1].select = verts[p2].select = False #Doesn't work after Bmesh merge
-                    li.remove(p2)  # remove item from list.
-                    p1 = p2
-                # Convert edges to curve
-                bpy.ops.object.mode_set(mode='OBJECT')
-                bpy.ops.object.convert(target='CURVE') 
-            
-            if Btrace.convert_edgetype == 'EDGEALL':
-                ## Start All edges
-                bpy.ops.object.mode_set(mode='EDIT')
-                bpy.ops.mesh.select_all(action='SELECT')
-                bpy.ops.mesh.delete(type='ONLY_FACE')
-                bpy.ops.object.mode_set()
-                bpy.ops.object.convert(target='CURVE')
-                for sp in obj.data.splines:
-                    sp.type = Btrace.curve_spline
-
-        obj = bpy.context.object
-        # Set spline type to custom property in panel
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.curve.spline_type_set(type=Btrace.curve_spline) 
-        # Set handle type to custom property in panel
-        bpy.ops.curve.handle_type_set(type=Btrace.curve_handle) 
-        bpy.ops.object.editmode_toggle()
-        obj.data.fill_mode = 'FULL'
-        # Set resolution to custom property in panel
-        obj.data.bevel_resolution = Btrace.curve_resolution 
-        obj.data.resolution_u = Btrace.curve_u 
-        # Set depth to custom property in panel
-        obj.data.bevel_depth = Btrace.curve_depth 
-        # Smooth object
-        bpy.ops.object.shade_smooth()
-        # Modulate curve radius and add distortion
-        if Btrace.distort_curve: 
-            scale = Btrace.distort_modscale
-            if scale == 0:
-                return{"FINISHED"}
-            for u in obj.data.splines:
-                for v in u.bezier_points:
-                    v.radius = scale*round(random.random(),3) 
-        return{"FINISHED"}
-
-
-################## ################## ################## ############
-## Mesh Follow, trace vertex or faces
-## Create curve at center of selection item, extruded along animation
-## Needs to be animated mesh!!!
-################## ################## ################## ############
-
-class OBJECT_OT_meshfollow(bpy.types.Operator):
-    bl_idname = "object.btmeshfollow"
-    bl_label = "Btrace: Vertex Trace"
-    bl_description = "Trace Vertex or Face on an animated mesh"
-    bl_options = {'REGISTER', 'UNDO'}
-        
-    
-    @classmethod
-    def poll(cls, context):
-        return (context.object and context.object.type in {'MESH'})
-
-    def execute(self, context):
-        import bpy, random
-        from mathutils import Vector
-
-        Btrace = bpy.context.window_manager.curve_tracer
-        distort_curve = Btrace.distort_curve    # modulate the resulting curve
-        stepsize = Btrace.particle_step
-        traceobjects = bpy.context.selected_objects  # create a list with all the selected objects
-
-        obj = bpy.context.object
-        scn = bpy.context.scene
-        meshdata = obj.data
-        cursor = bpy.context.scene.cursor_location.copy()  # Store the location to restore at end of script
-        drawmethod = Btrace.fol_mesh_type  # Draw from Edges, Verts, or Faces
-        if drawmethod == 'VERTS':
-            meshobjs = obj.data.vertices
-        if drawmethod == 'FACES':
-            meshobjs = obj.data.polygons  # untested
-        if drawmethod == 'EDGES':
-            meshobjs = obj.data.edges  # untested
-
-        # Frame properties
-        start_frame, end_frame = Btrace.fol_start_frame, Btrace.fol_end_frame
-        if start_frame > end_frame:  # Make sure the math works
-            startframe = end_frame - 5  # if start past end, goto (end - 5)
-        frames = int((end_frame - start_frame) / stepsize)
-
-        def getsel_option():  # Get selection objects.
-            sel = []
-            seloption, fol_mesh_type = Btrace.fol_sel_option, Btrace.fol_mesh_type  # options = 'random', 'custom', 'all'
-            if fol_mesh_type == 'OBJECT':
-                pass
-            else:
-                if seloption == 'CUSTOM':
-                    for i in meshobjs:
-                        if i.select == True:
-                            sel.append(i.index)
-                if seloption == 'RANDOM':
-                    for i in list(meshobjs):
-                        sel.append(i.index)
-                    finalsel = int(len(sel) * Btrace.fol_perc_verts)
-                    remove = len(sel) - finalsel
-                    for i in range(remove):
-                        sel.pop(random.randint(0, len(sel) - 1))
-                if seloption == 'ALL':
-                    for i in list(meshobjs):
-                        sel.append(i.index)
-
-            return sel
-
-        def get_coord(objindex):
-            obj_co = []  # list of vector coordinates to use
-            frame_x = start_frame
-            for i in range(frames):  # create frame numbers list
-                scn.frame_set(frame_x)
-                if drawmethod != 'OBJECT':
-                    followed_item = meshobjs[objindex]
-                    if drawmethod == 'VERTS':
-                        g_co = obj.matrix_local * followed_item.co  # find Vert vector
-
-                    if drawmethod == 'FACES':
-                        g_co = obj.matrix_local * followed_item.normal  # find Face vector
-
-                    if drawmethod == 'EDGES':
-                        v1 = followed_item.vertices[0]
-                        v2 = followed_item.vertices[1]
-                        co1 = bpy.context.object.data.vertices[v1]
-                        co2 = bpy.context.object.data.vertices[v2]
-                        localcenter = co1.co.lerp(co2.co, 0.5)
-                        g_co = obj.matrix_world * localcenter
-
-                if drawmethod == 'OBJECT':
-                    g_co = objindex.location.copy()
-
-                obj_co.append(g_co)
-                frame_x = frame_x + stepsize
-
-            scn.frame_set(start_frame)
-            return obj_co
-
-        def make_curve(co_list):
-            Btrace = bpy.context.window_manager.curve_tracer
-            tracer = bpy.data.curves.new('tracer','CURVE')
-            tracer.dimensions = '3D'
-            spline = tracer.splines.new('BEZIER')
-            spline.bezier_points.add(len(co_list)-  1)
-            curve = bpy.data.objects.new('curve',tracer)
-            scn.objects.link(curve)
-            curvelist.append(curve)
-            # render ready curve
-            tracer.resolution_u = Btrace.curve_u
-            tracer.bevel_resolution = Btrace.curve_resolution  # Set bevel resolution from Panel options
-            tracer.fill_mode = 'FULL'
-            tracer.bevel_depth = Btrace.curve_depth  # Set bevel depth from Panel options
-            curve_handle = Btrace.curve_handle
-            if curve_handle == 'AUTOMATIC': # hackish AUTOMATIC doesn't work here
-                curve_handle = 'AUTO'
-
-            # move bezier points to objects
-            for i in range(len(co_list)):
-                p = spline.bezier_points[i]
-                p.co = co_list[i]
-                p.handle_right_type = curve_handle
-                p.handle_left_type = curve_handle
-            return curve
-
-        # Run methods
-        # Check if Btrace group exists, if not create
-        bgroup = bpy.data.groups.keys()
-        if 'Btrace' not in bgroup:
-            bpy.ops.group.create(name="Btrace") 
-
-        Btrace = bpy.context.window_manager.curve_tracer
-        sel = getsel_option()  # Get selection
-        curvelist = []  # list to use for grow curve
-        
-        if Btrace.fol_mesh_type == 'OBJECT':
-            vector_list = get_coord(obj)
-            curvelist.append(make_curve(vector_list))
-        else:
-            for i in sel:
-                vector_list = get_coord(i)
-                curvelist.append(make_curve(vector_list))
-        # Select new curves and add to group
-        bpy.ops.object.select_all(action='DESELECT')
-        for curveobject in curvelist:
-            if curveobject.type == 'CURVE':
-                curveobject.select = True
-                bpy.context.scene.objects.active = curveobject
-                bpy.ops.object.group_link(group="Btrace")
-                addtracemat(curveobject.data)
-                curveobject.select = False
-
-        if Btrace.animate:  # Add grow curve
-            for curveobject in curvelist:
-                curveobject.select = True
-            bpy.ops.curve.btgrow()
-            for curveobject in curvelist:
-                curveobject.select = False
-
-        obj.select = False  # Deselect original object
-        return {'FINISHED'}
-
-###################################################################
-#### Add Tracer Material
-###################################################################
-
-def addtracemat(matobj):
-    # Need to add cycles or BI render material options
-    # if engine == 'CYCLES':
-        # Add cycles mat
-    # if engine == 'BLENDER_RENDER':
-        # Add blender interal mat
-    matslots = bpy.context.object.data.materials.items()  # Check if a material exists, skip if it does
-    if len(matslots) < 1:  # Make sure there is only one material slot
-        engine = bpy.context.scene.render.engine
-        Btrace = bpy.context.window_manager.curve_tracer
-        if not Btrace.mat_run_color_blender:  # Check if color blender is to be run
-            if Btrace.trace_mat_random:  # Create Random color for each item
-                # Use random color from chosen palette, assign color lists for each palette
-                import random
-                brightColors  = [Btrace.brightColor1, Btrace.brightColor2, Btrace.brightColor3, Btrace.brightColor4]
-                bwColors = [Btrace.bwColor1, Btrace.bwColor2]
-                customColors = [Btrace.mmColor1, Btrace.mmColor2, Btrace.mmColor3, Btrace.mmColor4, Btrace.mmColor5, Btrace.mmColor6, Btrace.mmColor7, Btrace.mmColor8]
-                earthColors = [Btrace.earthColor1, Btrace.earthColor2, Btrace.earthColor3, Btrace.earthColor4, Btrace.earthColor5]
-                greenblueColors = [Btrace.greenblueColor1, Btrace.greenblueColor2, Btrace.greenblueColor3]
-                if Btrace.mmColors == 'BRIGHT':
-                    #print(random.randint(0, len(brightColors) - 1))
-                    mat_color = brightColors[random.randint(0, len(brightColors) - 1)]
-                if Btrace.mmColors == 'BW':
-                    mat_color = bwColors[random.randint(0, len(bwColors) - 1)]
-                if Btrace.mmColors == 'CUSTOM':
-                    mat_color = customColors[random.randint(0, len(customColors) - 1)]
-                if Btrace.mmColors == 'EARTH':
-                    mat_color = earthColors[random.randint(0, len(earthColors) - 1)]
-                if Btrace.mmColors == 'GREENBLUE':
-                    mat_color = greenblueColors[random.randint(0, len(greenblueColors) - 1)]
-                if Btrace.mmColors == 'RANDOM':
-                    mat_color = (random.random(), random.random(), random.random())
-            else:  # Choose Single color
-                mat_color = Btrace.trace_mat_color
-            # mat_color = Btrace.trace_mat_color
-            TraceMat = bpy.data.materials.new('TraceMat')
-            TraceMat.diffuse_color = mat_color
-            TraceMat.specular_intensity = 0.5
-            matobj.materials.append(bpy.data.materials.get(TraceMat.name))
-
-        else:  # Run color blender operator
-            bpy.ops.object.colorblender()
-
-    return {'FINISHED'}
-
-###################################################################
-#### Add Color Blender Material
-###################################################################
-
-# This is the magical material changer!
-class OBJECT_OT_materialChango(bpy.types.Operator):
-    bl_idname = 'object.colorblender'
-    bl_label = 'Color Blender'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def execute(self, context):
-
-        import bpy, random
-        Btrace = bpy.context.window_manager.curve_tracer  # properties panel
-        colorObjects = bpy.context.selected_objects
-
-        # Set color lists
-        brightColors  = [Btrace.brightColor1, Btrace.brightColor2, Btrace.brightColor3, Btrace.brightColor4]
-        bwColors = [Btrace.bwColor1, Btrace.bwColor2]
-        customColors = [Btrace.mmColor1, Btrace.mmColor2, Btrace.mmColor3, Btrace.mmColor4, Btrace.mmColor5, Btrace.mmColor6, Btrace.mmColor7, Btrace.mmColor8]
-        earthColors = [Btrace.earthColor1, Btrace.earthColor2, Btrace.earthColor3, Btrace.earthColor4, Btrace.earthColor5]
-        greenblueColors = [Btrace.greenblueColor1, Btrace.greenblueColor2, Btrace.greenblueColor3]
-
-        colorList = Btrace.mmColors
-
-        # Go through each selected object and run the operator
-        for i in colorObjects:
-            theObj = i
-            # Check to see if object has materials
-            checkMaterials = len(theObj.data.materials)
-            if checkMaterials == 0:
-                # Add a material
-                materialName = "colorblendMaterial"
-                madMat = bpy.data.materials.new(materialName)
-                theObj.data.materials.append(madMat)
-            else:                
-                pass # pass since we have what we need
-                
-            # assign the first material of the object to "mat"
-            mat = theObj.data.materials[0] 
-
-            # Numbers of frames to skip between keyframes
-            skip = Btrace.mmSkip
-
-            # Random material function
-            def colorblenderRandom():
-                for crazyNumber in range(3):
-                    mat.diffuse_color[crazyNumber] = random.random()
-            
-            def colorblenderCustom():
-                mat.diffuse_color = random.choice(customColors)
-                
-            # Black and white color        
-            def colorblenderBW():
-                mat.diffuse_color = random.choice(bwColors)
-            
-            # Bright colors
-            def colorblenderBright():
-                mat.diffuse_color = random.choice(brightColors)
-                
-            # Earth Tones
-            def colorblenderEarth():
-                mat.diffuse_color = random.choice(earthColors)
-                
-            # Green to Blue Tones
-            def colorblenderGreenBlue():
-                mat.diffuse_color = random.choice(greenblueColors)
-             
-            # define frame start/end variables
-            scn = bpy.context.scene       
-            start = scn.frame_start
-            end = scn.frame_end           
-            # Go to each frame in iteration and add material
-            while start<=(end+(skip-1)):
-               
-                bpy.ops.anim.change_frame(frame=start)
-                
-                # Check what colors setting is checked and run the appropriate function
-                if Btrace.mmColors=='RANDOM':
-                    colorblenderRandom()
-                elif Btrace.mmColors=='CUSTOM':
-                    colorblenderCustom()
-                elif Btrace.mmColors=='BW':
-                    colorblenderBW()
-                elif Btrace.mmColors=='BRIGHT':
-                    colorblenderBright()
-                elif Btrace.mmColors=='EARTH':
-                    colorblenderEarth()
-                elif Btrace.mmColors=='GREENBLUE':
-                    colorblenderGreenBlue()
-                else:
-                    pass
-                
-                # Add keyframe to material
-                mat.keyframe_insert('diffuse_color')
-                
-                # Increase frame number
-                start += skip
-        return{'FINISHED'}
-    
-###### This clears the keyframes ######
-class OBJECT_OT_clearColorblender(bpy.types.Operator):
-    bl_idname = 'object.colorblenderclear'
-    bl_label = 'Clear colorblendness'
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    def invoke(self, context, event):
-        
-        import bpy, random
-        mcolorblend = context.window_manager.colorblender_operator # properties panel
-        colorObjects = bpy.context.selected_objects
-        
-        # Go through each selected object and run the operator
-        for i in colorObjects:
-            theObj = i    
-            # assign the first material of the object to "mat"
-            matCl = theObj.data.materials[0] 
-            
-            # define frame start/end variables
-            scn = bpy.context.scene       
-            start = scn.frame_start
-            end = scn.frame_end
-
-            # Remove all keyframes from diffuse_color, super sloppy need to find better way
-            while start <= (end * 2):
-                bpy.ops.anim.change_frame(frame=start)
-                matCl.keyframe_delete('diffuse_color')
-                start += 1
-            
-        return{'FINISHED'}
-
-
-################## ################## ################## ############
-## F-Curve Noise
-## will add noise modifiers to each selected object f-curves
-## change type to: 'rotation' | 'location' | 'scale' | '' to effect all
-## first record a keyframe for this to work (to generate the f-curves)
-################## ################## ################## ############
-
-class OBJECT_OT_fcnoise(bpy.types.Operator):
-    bl_idname = "object.btfcnoise"
-    bl_label = "Btrace: F-curve Noise"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    def execute(self, context):
-        import bpy, random
-        
-        Btrace = bpy.context.window_manager.curve_tracer
-        amp = Btrace.fcnoise_amp
-        timescale = Btrace.fcnoise_timescale
-        addkeyframe = Btrace.fcnoise_key
-        
-        # This sets properties for Loc, Rot and Scale if they're checked in the Tools window
-        noise_rot = 'rotation'
-        noise_loc = 'location'
-        noise_scale = 'scale'
-        if not Btrace.fcnoise_rot:
-            noise_rot = 'none'
-        if not Btrace.fcnoise_loc:
-            noise_loc = 'none'
-        if not Btrace.fcnoise_scale:
-            noise_scale = 'none'
-            
-        type = noise_loc, noise_rot, noise_scale # Add settings from panel for type of keyframes
-        amplitude = amp
-        time_scale = timescale
-        
-        for i in bpy.context.selected_objects:
-            # Add keyframes, this is messy and should only add keyframes for what is checked
-            if addkeyframe == True:
-                bpy.ops.anim.keyframe_insert(type="LocRotScale")         
-            for obj in bpy.context.selected_objects:
-                if obj.animation_data:
-                    for c in obj.animation_data.action.fcurves:
-                        if c.data_path.startswith(type):
-                            # clean modifiers
-                            for m in c.modifiers : 
-                                c.modifiers.remove(m)
-                            # add noide modifiers
-                            n = c.modifiers.new('NOISE')
-                            n.strength = amplitude
-                            n.scale = time_scale
-                            n.phase = random.randint(0,999)
-        return{"FINISHED"}
-
-################## ################## ################## ############
-## Curve Grow Animation
-## Animate curve radius over length of time
-################## ################## ################## ############     
-class OBJECT_OT_curvegrow(bpy.types.Operator):
-    bl_idname = 'curve.btgrow'
-    bl_label = 'Run Script'
-    bl_description = 'Keyframe points radius'
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    @classmethod
-    def poll(cls, context):
-        return (context.object and context.object.type in {'CURVE'})
-    
-    def execute(self, context):
-        Btrace = bpy.context.window_manager.curve_tracer
-        anim_f_start, anim_length, anim_auto = Btrace.anim_f_start, Btrace.anim_length, Btrace.anim_auto
-        curve_resolution, curve_depth = Btrace.curve_resolution, Btrace.curve_depth
-        # make the curve visible
-        objs = bpy.context.selected_objects
-        for i in objs: # Execute on multiple selected objects
-            bpy.context.scene.objects.active = i
-            obj = bpy.context.active_object
-            try:
-                obj.data.fill_mode = 'FULL'
-            except:
-                obj.data.dimensions = '3D'
-                obj.data.fill_mode = 'FULL'
-            if not obj.data.bevel_resolution:
-                obj.data.bevel_resolution = curve_resolution
-            if not obj.data.bevel_depth:
-                obj.data.bevel_depth = curve_depth
-            if anim_auto:
-                anim_f_start = bpy.context.scene.frame_start
-                anim_length = bpy.context.scene.frame_end
-            # get points data and beautify
-            actual, total = anim_f_start, 0
-            for sp in obj.data.splines:
-                total += len(sp.points) + len(sp.bezier_points)
-            step = anim_length / total
-            for sp in obj.data.splines:
-                sp.radius_interpolation = 'BSPLINE'
-                po = [p for p in sp.points] + [p for p in sp.bezier_points]
-                if not Btrace.anim_keepr:
-                    for p in po:
-                        p.radius = 1
-                if Btrace.anim_tails and not sp.use_cyclic_u:
-                    po[0].radius = po[-1].radius = 0
-                    po[1].radius = po[-2].radius = .65
-                ra = [p.radius for p in po]
-
-                # record the keyframes
-                for i in range(len(po)):
-                    po[i].radius = 0
-                    po[i].keyframe_insert('radius', frame=actual)
-                    actual += step
-                    po[i].radius = ra[i]
-                    po[i].keyframe_insert('radius', frame=(actual + Btrace.anim_delay))
-
-                    if Btrace.anim_f_fade:
-                        po[i].radius = ra[i]
-                        po[i].keyframe_insert('radius', frame=(actual + Btrace.anim_f_fade - step))
-                        po[i].radius = 0
-                        po[i].keyframe_insert('radius', frame=(actual + Btrace.anim_delay + Btrace.anim_f_fade))
-
-            bpy.context.scene.frame_set(Btrace.anim_f_start)
-        return{'FINISHED'}
-
-################## ################## ################## ############
-## Remove animation and curve radius data
-################## ################## ################## ############
-class OBJECT_OT_reset(bpy.types.Operator):
-    bl_idname = 'object.btreset'
-    bl_label = 'Clear animation'
-    bl_description = 'Remove animation / curve radius data'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def execute(self, context):
-        objs = bpy.context.selected_objects
-        for i in objs: # Execute on multiple selected objects
-            bpy.context.scene.objects.active = i
-            obj = bpy.context.active_object
-            obj.animation_data_clear()
-            if obj.type == 'CURVE':
-                for sp in obj.data.splines:
-                    po = [p for p in sp.points] + [p for p in sp.bezier_points]
-                    for p in po:
-                        p.radius = 1
-        return{'FINISHED'}
-
-### Define Classes to register
-classes = [
-    TracerProperties,
-    TracerPropertiesMenu,
-    addTracerObjectPanel,
-    OBJECT_OT_convertcurve,
-    OBJECT_OT_objecttrace,
-    OBJECT_OT_objectconnect,
-    OBJECT_OT_writing,
-    OBJECT_OT_particletrace,
-    OBJECT_OT_traceallparticles,
-    OBJECT_OT_curvegrow,
-    OBJECT_OT_reset,
-    OBJECT_OT_fcnoise,
-    OBJECT_OT_meshfollow,
-    OBJECT_OT_materialChango,
-    OBJECT_OT_clearColorblender
-    ]
-
-def register():
-    for c in classes:
-        bpy.utils.register_class(c)
-    bpy.types.WindowManager.curve_tracer = bpy.props.PointerProperty(type=TracerProperties)
-    bpy.types.WindowManager.btrace_menu = bpy.props.PointerProperty(type=TracerPropertiesMenu, update=deselect_others)
-
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-    del bpy.types.WindowManager.curve_tracer
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py b/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py
deleted file mode 100644
index b586dc7..0000000
--- a/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 3
-#  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8-80 compliant>
-
-# This script was developed with financial support from the Foundation for
-# Science and Technology of Portugal, under the grant SFRH/BD/66452/2009.
-
-
-bl_info = {
-    'name': "Carnegie Mellon University Mocap Library Browser",
-    'author': "Daniel Monteiro Basso <daniel at basso.inf.br>",
-    'version': (2011, 10, 30, 1),
-    'blender': (2, 6, 0),
-    'location': "View3D > Tools",
-    'description': "Assistant for using CMU Motion Capture data",
-    'warning': '',
-    'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-                "Scripts/3D_interaction/CMU_Mocap_Library_Browser",
-    'tracker_url': "http://projects.blender.org/tracker/index.php?"\
-                   "func=detail&aid=29086&group_id=153&atid=467",
-    'category': '3D View'}
-
-
-import os
-import bpy
-import bgl
-import blf
-import math
-from . import library
-
-
-def initialize_subjects():
-    """
-        Initializes the main object and the subjects (actors) list
-    """
-    while bpy.data.scenes[0].cmu_mocap_lib.subject_list:
-        bpy.data.scenes[0].cmu_mocap_lib.subject_list.remove(0)
-    for k, v in library.subjects.items():
-        n = bpy.data.scenes[0].cmu_mocap_lib.subject_list.add()
-        n.name = "{:d} - {}".format(k, v['desc'])
-        n.idx = k
-
-
-def update_motions(self, context):
-    """
-        Updates the motions list after a subject is selected
-    """
-    sidx = -1
-    if self.subject_active != -1:
-        sidx = self.subject_list[self.subject_active].idx
-    while self.motion_list:
-        self.motion_list.remove(0)
-    if sidx != -1:
-        for k, v in library.subjects[sidx]["motions"].items():
-            n = self.motion_list.add()
-            n.name = "{:d} - {}".format(k, v["desc"])
-            n.idx = k
-        self.motion_active = -1
-
-
-class ListItem(bpy.types.PropertyGroup):
-    name = bpy.props.StringProperty()
-    idx = bpy.props.IntProperty()
-
-
-class CMUMocapLib(bpy.types.PropertyGroup):
-    local_storage = bpy.props.StringProperty(
-        name="Local Storage",
-        subtype='DIR_PATH',
-        description="Location to store downloaded resources",
-        default="~/cmu_mocap_lib")
-    follow_structure = bpy.props.BoolProperty(
-        name="Follow Library Folder Structure",
-        description="Store resources in subfolders of the local storage",
-        default=True)
-    automatically_import = bpy.props.BoolProperty(
-        name="Automatically Import after Download",
-        description="Import the resource after the download is finished",
-        default=True)
-    subject_list = bpy.props.CollectionProperty(
-        name="subjects", type=ListItem)
-    subject_active = bpy.props.IntProperty(
-        name="subject_idx", default=-1, update=update_motions)
-    subject_import_name = bpy.props.StringProperty(
-        name="Armature Name",
-        description="Identifier of the imported subject's armature",
-        default="Skeleton")
-    motion_list = bpy.props.CollectionProperty(name="motions", type=ListItem)
-    motion_active = bpy.props.IntProperty(name="motion_idx", default=-1)
-    frame_skip = bpy.props.IntProperty(name="Fps Divisor", default=4,
-    # usually the sample rate is 120, so the default 4 gives you 30fps
-                          description="Frame supersampling factor", min=1)
-    cloud_scale = bpy.props.FloatProperty(name="Marker Cloud Scale",
-                          description="Scale the marker cloud by this value",
-                          default=1., min=0.0001, max=1000000.0,
-                          soft_min=0.001, soft_max=100.0)
-
-
-def draw_callback(self, context):
-    mid = int(360 * self.recv / self.fsize)
-    cx = 200
-    cy = 30
-    blf.position(0, 230, 23, 0)
-    blf.size(0, 20, 72)
-    blf.draw(0, "{0:2d}% of {1}".format(
-        100 * self.recv // self.fsize, self.hfsize))
-
-    bgl.glEnable(bgl.GL_BLEND)
-    bgl.glColor4f(.7, .7, .7, 0.8)
-    bgl.glBegin(bgl.GL_TRIANGLE_FAN)
-    bgl.glVertex2i(cx, cy)
-    for i in range(mid):
-        x = cx + 20 * math.sin(math.radians(float(i)))
-        y = cy + 20 * math.cos(math.radians(float(i)))
-        bgl.glVertex2f(x, y)
-    bgl.glEnd()
-
-    bgl.glColor4f(.0, .0, .0, 0.6)
-    bgl.glBegin(bgl.GL_TRIANGLE_FAN)
-    bgl.glVertex2i(cx, cy)
-    for i in range(mid, 360):
-        x = cx + 20 * math.sin(math.radians(float(i)))
-        y = cy + 20 * math.cos(math.radians(float(i)))
-        bgl.glVertex2f(x, y)
-    bgl.glEnd()
-
-    bgl.glDisable(bgl.GL_BLEND)
-    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-
-
-class CMUMocapDownloadImport(bpy.types.Operator):
-    bl_idname = "mocap.download_import"
-    bl_label = "Download and Import a file"
-
-    remote_file = bpy.props.StringProperty(
-        name="Remote File",
-        description="Location from where to download the file data")
-    local_file = bpy.props.StringProperty(
-        name="Local File",
-        description="Destination where to save the file data")
-    do_import = bpy.props.BoolProperty(
-        name="Manual Import",
-        description="Import the resource non-automatically",
-        default=False)
-
-    timer = None
-    fout = None
-    src = None
-    fsize = 0
-    recv = 0
-    cloud_scale = 1
-
-    def modal(self, context, event):
-        context.area.tag_redraw()
-        if event.type == 'ESC':
-            self.fout.close()
-            os.unlink(self.local_file)
-            return self.cancel(context)
-        if event.type == 'TIMER':
-            to_read = min(self.fsize - self.recv, 100 * 2 ** 10)
-            data = self.src.read(to_read)
-            self.fout.write(data)
-            self.recv += to_read
-            if self.fsize == self.recv:
-                self.fout.close()
-                return self.cancel(context)
-        return {'PASS_THROUGH'}
-
-    def cancel(self, context):
-        context.window_manager.event_timer_remove(self.timer)
-        context.region.callback_remove(self.handle)
-        if os.path.exists(self.local_file):
-            self.import_or_open()
-        return {'CANCELLED'}
-
-    def execute(self, context):
-        cml = bpy.data.scenes[0].cmu_mocap_lib
-        if not os.path.exists(self.local_file):
-            try:
-                os.makedirs(os.path.split(self.local_file)[0])
-            except:
-                pass
-            from urllib.request import urlopen
-            self.src = urlopen(self.remote_file)
-            info = self.src.info()
-            self.fsize = int(info["Content-Length"])
-            m = int(math.log10(self.fsize) // 3)
-            self.hfsize = "{:.1f}{}".format(
-                self.fsize * math.pow(10, -m * 3),
-                ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Eb', 'Pb'][m])  # :-p
-            self.fout = open(self.local_file, 'wb')
-            self.recv = 0
-            context.window_manager.modal_handler_add(self)
-            self.handle = context.region.\
-                callback_add(draw_callback, (self, context), 'POST_PIXEL')
-            self.timer = context.window_manager.\
-                event_timer_add(0.001, context.window)
-            return {'RUNNING_MODAL'}
-        else:
-            self.import_or_open()
-        return {"FINISHED"}
-
-    def import_or_open(self):
-        cml = bpy.data.scenes[0].cmu_mocap_lib
-        if cml.automatically_import or self.do_import:
-            if self.local_file.endswith("mpg"):
-                bpy.ops.wm.path_open(filepath=self.local_file)
-            elif self.local_file.endswith("asf"):
-                bpy.ops.import_anim.asf(
-                    filepath=self.local_file,
-                    from_inches=True,
-                    use_rot_x=True, use_rot_z=True,
-                    armature_name=cml.subject_import_name)
-            elif self.local_file.endswith("amc"):
-                ob = bpy.context.active_object
-                if not ob or ob.type != 'ARMATURE' or \
-                    'source_file_path' not in ob:
-                    self.report({'ERROR'}, "Please select a CMU Armature.")
-                    return
-                bpy.ops.import_anim.amc(
-                    filepath=self.local_file,
-                    frame_skip=cml.frame_skip)
-            elif self.local_file.endswith("c3d"):
-                bpy.ops.import_anim.c3d(
-                    filepath=self.local_file,
-                    from_inches=False,
-                    auto_scale=True,
-                    scale=cml.cloud_scale,
-                    show_names=False,
-                    frame_skip=cml.frame_skip)
-
-
-class CMUMocapConfig(bpy.types.Panel):
-    bl_idname = "object.cmu_mocap_config"
-    bl_label = "CMU Mocap Browser Configuration"
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    def draw(self, context):
-        if not bpy:
-            return
-        cml = bpy.data.scenes[0].cmu_mocap_lib
-        layout = self.layout
-        layout.operator("wm.url_open",
-            text="Carnegie Mellon University Mocap Library",
-            icon='URL').url = 'http://mocap.cs.cmu.edu/'
-        layout.prop(cml, "local_storage")
-        layout.prop(cml, "follow_structure")
-        layout.prop(cml, "automatically_import")
-
-
-class CMUMocapSubjectBrowser(bpy.types.Panel):
-    bl_idname = "object.cmu_mocap_subject_browser"
-    bl_label = "CMU Mocap Subject Browser"
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    def draw(self, context):
-        if not bpy:
-            return
-        layout = self.layout
-        cml = bpy.data.scenes[0].cmu_mocap_lib
-        # spare space... layout.label("Subjects")
-        layout.template_list(cml, "subject_list", cml, "subject_active")
-        layout.prop(cml, "subject_import_name")
-        if cml.subject_active != -1:
-            sidx = cml.subject_list[cml.subject_active].idx
-            remote_fname = library.skeleton_url.format(sidx)
-            tid = "{0:02d}".format(sidx)
-            local_path = os.path.expanduser(cml.local_storage)
-            if cml.follow_structure:
-                local_path = os.path.join(local_path, tid)
-            local_fname = os.path.join(local_path, tid + ".asf")
-            do_import = False
-            if os.path.exists(local_fname):
-                label = "Import Selected"
-                do_import = True
-            elif cml.automatically_import:
-                label = "Download and Import Selected"
-            else:
-                label = "Download Selected"
-
-            props = layout.operator("mocap.download_import",
-                                    text=label, icon='ARMATURE_DATA')
-            props.remote_file = remote_fname
-            props.local_file = local_fname
-            props.do_import = do_import
-
-
-class CMUMocapMotionBrowser(bpy.types.Panel):
-    bl_idname = "object.cmu_mocap_motion_browser"
-    bl_label = "CMU Mocap Motion Browser"
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    def draw(self, context):
-        if not bpy:
-            return
-        layout = self.layout
-        cml = bpy.data.scenes[0].cmu_mocap_lib
-        # spare space... layout.label("Motions for selected subject")
-        layout.template_list(cml, "motion_list", cml, "motion_active")
-        if cml.motion_active == -1:
-            return
-        sidx = cml.subject_list[cml.subject_active].idx
-        midx = cml.motion_list[cml.motion_active].idx
-        motion = library.subjects[sidx]['motions'][midx]
-        fps = motion['fps']
-        ifps = fps // cml.frame_skip
-        # layout.label("Original capture frame rate: {0:d} fps.".format(fps))
-        # layout.label("Importing frame rate: {0:d} fps.".format(ifps))
-        row = layout.row()
-        row.column().label("Original: {0:d} fps.".format(fps))
-        row.column().label("Importing: {0:d} fps.".format(ifps))
-        layout.prop(cml, "frame_skip")
-        layout.prop(cml, "cloud_scale")
-        remote_fname = library.motion_url.format(sidx, midx)
-        tid = "{0:02d}".format(sidx)
-        local_path = os.path.expanduser(cml.local_storage)
-        if cml.follow_structure:
-            local_path = os.path.join(local_path, tid)
-        for target, icon, ext in (
-                ('Motion Data', 'POSE_DATA', 'amc'),
-                ('Marker Cloud', 'EMPTY_DATA', 'c3d'),
-                ('Movie', 'FILE_MOVIE', 'mpg')):
-            action = "Import" if ext != 'mpg' else "Open"
-            fname = "{0:02d}_{1:02d}.{2}".format(sidx, midx, ext)
-            local_fname = os.path.join(local_path, fname)
-            do_import = False
-            if os.path.exists(local_fname):
-                label = "{0} {1}".format(action, target)
-                do_import = True
-            elif cml.automatically_import:
-                label = "Download and {0} {1}".format(action, target)
-            else:
-                label = "Download {0}".format(target)
-            row = layout.row()
-            props = row.operator("mocap.download_import", text=label, icon=icon)
-            props.remote_file = remote_fname + ext
-            props.local_file = local_fname
-            props.do_import = do_import
-            row.active = ext in motion['files']
-
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.Scene.cmu_mocap_lib = bpy.props.PointerProperty(type=CMUMocapLib)
-    initialize_subjects()
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/cmu_mocap_browser/library.py b/release/scripts/addons_contrib/cmu_mocap_browser/library.py
deleted file mode 100644
index 68c255a..0000000
--- a/release/scripts/addons_contrib/cmu_mocap_browser/library.py
+++ /dev/null
@@ -1,7487 +0,0 @@
-#!/usr/bin/env python3
-#-*- coding:utf-8 -*-
-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 3
-#  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-# This script was developed with financial support from the Foundation for
-# Science and Technology of Portugal, under the grant SFRH/BD/66452/2009.
-
-
-skeleton_url = "http://mocap.cs.cmu.edu:8080/subjects/{0:02d}/{0:02d}.asf"
-motion_url = "http://mocap.cs.cmu.edu:8080/subjects/{0:02d}/{0:02d}_{1:02d}."
-search_url = "http://mocap.cs.cmu.edu/search.php?subjectnumber=%&motion=%"
-
-# Carnegie Mellon University Mocap Library - http://mocap.cs.cmu.edu
-
-subjects = {1: {'desc': 'climb, swing, hang on playground equipment',
-     'motions': {1: {'desc': 'playground - forward jumps, turn around',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'playground - climb',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'playground - climb, hang, swing',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'playground - climb',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'playground - climb, go under',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'playground - climb, sit, dangle legs, descend',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'playground - climb, sit, dangle legs, jump down',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'playground - climb, sit, dangle legs, rock back, lower self to ground',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'playground - climb, hang, hold self up with arms straight, swing, drop, sit, dangle legs, go under',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'playground - climb, swing, lean back, drop',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 11: {'desc': 'playground - climb, hang, lean over, jump down',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 12: {'desc': 'playground - climb, pull up, dangle, sit, lower self to ground',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 13: {'desc': 'playground - climb, go under, jump down',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 14: {'desc': 'playground - climb, jump down, dangle, legs push off against',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 2: {'desc': 'various expressions and human behaviors',
-     'motions': {1: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'run/jog',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'jump, balance',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'punch/strike',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'bend over, scoop up, rise, lift arm',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'swordplay',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'swordplay',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'swordplay',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'wash self',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 3: {'desc': 'walk on uneven terrain',
-     'motions': {1: {'desc': 'walk on uneven terrain',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'walk on uneven terrain',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'walk on uneven terrain',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'walk on uneven terrain',
-                     'files': ['c3d', 'amc', 'avi'],
-                     'fps': 120}}},
- 5: {'desc': 'modern dance',
-     'motions': {1: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'dance - expressive arms, pirouette',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'dance - sideways arabesque, turn step, folding arms',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'dance - sideways arabesque, folding arms, bending back',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'dance - quasi-cou-de-pied, raised leg above hip-height, jete en tourant',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'dance - cartwheel-like start, pirouettes, jete',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'dance - small jetes, attitude/arabesque, shifted-axis pirouette, turn',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'dance - rond de jambe in the air, jete, turn',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'dance - glissade devant, glissade derriere, attitude/arabesque',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'dance - glissade devant, glissade derriere, attitude/arabesque',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 11: {'desc': 'dance - sideways steps, pirouette',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 12: {'desc': 'dance - arms held high, pointe tendue a terre, upper body rotation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 13: {'desc': 'dance - small jetes, pirouette',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 14: {'desc': 'dance - retire derriere, attitude/arabesque',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 15: {'desc': 'dance - retire derriere, attitude/arabesque',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 16: {'desc': 'dance - coupe dessous, jete en tourant',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 17: {'desc': 'dance - coupe dessous, grand jete en tourant',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 18: {'desc': 'dance - attitude/arabesque, jete en tourant, bending back',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 19: {'desc': 'dance - attitude/arabesque, jete en tourant, bending back',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 20: {'desc': 'dance - attitude/arabesque, jete en tourant, bending back',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 6: {'desc': 'dribble, shoot basketball',
-     'motions': {1: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'basketball - forward dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'basketball - forward dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'basketball - forward dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'basketball - forward dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'basketball - backward dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'basketball - backward dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'basketball - sideways dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'basketball - sideways dribble',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'basketball - forward dribble, 90-degree left turns',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 11: {'desc': 'basketball - forward dribble, 90-degree right turns',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 12: {'desc': 'basketball - forward dribble, 90-degree right turns, crossover dribble',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 13: {'desc': 'basketball - low, fast free style dribble, dribble through legs',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 14: {'desc': 'basketball - crossover dribble, shoot',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 15: {'desc': 'basketball - dribble, shoot',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 7: {'desc': 'walk',
-     'motions': {1: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'walk',
-                     'files': ['c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'slow walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'slow walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                 11: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                 12: {'desc': 'brisk walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 8: {'desc': 'walk',
-     'motions': {1: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'slow walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'walk/stride',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'walk, exaggerated stride',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'walk',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 11: {'desc': 'slow walk/stride',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 9: {'desc': 'run',
-     'motions': {1: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 2: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 3: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 4: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 5: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 6: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 7: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 8: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 9: {'desc': 'run',
-                     'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                     'fps': 120},
-                 10: {'desc': 'run',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 11: {'desc': 'run',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                 12: {'desc': 'navigate - walk forward, backward, sideways',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 10: {'desc': 'kick soccer ball',
-      'motions': {1: {'desc': 'soccer - kick ball',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'soccer - kick ball',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'soccer - kick ball',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'soccer - kick ball',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'soccer - kick ball',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 11: {'desc': 'kick soccer ball',
-      'motions': {1: {'desc': 'soccer - kick ball',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 12: {'desc': 'tai chi, walk',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'tai chi',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 13: {'desc': 'various everyday behaviors',
-      'motions': {1: {'desc': 'sit on high stool, stand up',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'sit on high stool, stand up',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'sit on high stool, stand up',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'sit on stepstool, chin in hand',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'sit on stepstool, hands against chin, fidget, stand up',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'sit on stepstool, hands against chin, elbow out, stand up',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'unscrew bottlecap, drink soda',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'unscrew bottlecap, drink soda, screw on bottlecap',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'drink soda',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'jump up to grab, reach for, tiptoe',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'forward jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'jump up to grab, reach for, tiptoe',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'forward jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'laugh',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'laugh',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'laugh',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'boxing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'boxing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'forward jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'wash windows',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'wash windows',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'wash windows',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'sweep floor',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'sweep floor',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'sweep floor',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'direct traffic, wave',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'direct traffic, wave, point',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'direct traffic, wave, point',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'jumping jacks, side twists, bend over, squats',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'jumping jacks, side twists, squats, jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'jumping jacks, side twists, bend over, jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'forward jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'climb ladder',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'climb ladder',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  38: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  39: {'desc': 'jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  40: {'desc': 'jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  41: {'desc': 'jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  42: {'desc': 'jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 14: {'desc': 'various everyday behaviors',
-      'motions': {1: {'desc': 'boxing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'boxing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'boxing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'drink soda, screw on bottlecap',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'unscrew bottlecap, drink soda',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'jumping jacks, jog, squats, side twists, stretches',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'jump up to grab, reach for, tiptoe',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'jump up to grab, reach for, tiptoe',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'jump up to grab, reach for, tiptoe',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'wash windows',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'wash windows',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'wash windows',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'mop floor',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'jumping jacks, jog, squats, side twists, stretches',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'mop floor',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'sweep floor',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'laugh',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'laugh',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'laugh',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'jumping jacks, side twists, reach up, bend over',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'climb 3 steps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'direct traffic, wave, point',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'direct traffic, wave, point',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'direct traffic, wave, point',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'sit on high stool, stand up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'sit on high stool, stand up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'sit on stepstool, stand up, swing legs',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'sit on stepstool, ankle on other knee, hand on chin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'sit on stepstool, stand up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'sit on stepstool, stand up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'climb ladder',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'climb ladder',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'climb ladder',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'sit on stepstool, stand up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'drink soda',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 15: {'desc': 'various everyday behaviors, dance moves',
-      'motions': {1: {'desc': 'walk/wander',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'climb, step over, sit on, stand on stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk/wander',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'wash windows, paint; hand signals; dance - Egyptian walk, the Dive, the Twist, the Cabbage Patch; boxing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'wash windows, paint; hand signals; dance - Egyptian walk, the Dive, the Twist, the Cabbage Patch; boxing',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'lean forward, reach for',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'lean forward, tiptoe, reach for',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'hand signals - horizontally revolve forearms',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walk/wander',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'sit on high stool, stand up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'wash windows, paint figure eights; hand signals',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'wash windows; basketball - dribble, lay-up shot, pass; throw ball; dance - Egyptian walk, the Dive, the Twist; strew',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'boxing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk/wander',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 16: {'desc': 'run, jump, walk',
-      'motions': {1: {'desc': 'jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'high jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'high jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'forward jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'forward jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'forward jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'run/jog, sudden stop',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'forward jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'forward jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'walk, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'walk, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'walk, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'walk, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'walk, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'walk, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'walk, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'walk, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'walk, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'walk, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'walk, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'walk, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'walk, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'walk, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'walk, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'slow walk, stop',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'slow walk, stop',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'run/jog, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  38: {'desc': 'run/jog, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  39: {'desc': 'run/jog, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  40: {'desc': 'run/jog, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  41: {'desc': 'run/jog, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  42: {'desc': 'run/jog, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  43: {'desc': 'run/jog, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  44: {'desc': 'run/jog, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  45: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  46: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  47: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  48: {'desc': 'run, veer left',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  49: {'desc': 'run, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  50: {'desc': 'run, veer right',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  51: {'desc': 'run, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  52: {'desc': 'run, 90-degree left turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  53: {'desc': 'run, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  54: {'desc': 'run, 90-degree right turn',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  55: {'desc': 'run',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  56: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  57: {'desc': 'run/jog, sudden stop',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  58: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 17: {'desc': 'different walking styles',
-      'motions': {1: {'desc': 'walk with anger, frustration',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk with anger, frustration',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk stealthily',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk stealthily',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'walk/hobble',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'whistle, walk jauntily',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'whistle, walk jauntily',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': "muscular, heavyset person's walk",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': "muscular, heavyset person's walk",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'boxing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 18: {'desc': 'human interaction and communication (2 subjects - subject A)',
-      'motions': {1: {'desc': 'walk, shake hands (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk, shake hands (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'A pulls B; B resists (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'A pulls B; B resists (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'navigate busy sidewalk; A leads the way, takes B by the arm (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'conversation - explain with hand gestures (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'conversation - explain with hand gestures, walk (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'quarrel - angry hand gestures (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'quarrel - angry hand gestures (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'friends meet, hang out; A sits, B joins A (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'run, scramble for last seat (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'run, scramble for last seat (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'chicken dance (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 19: {'desc': 'human interaction and communication (2 subjects - subject B)',
-      'motions': {1: {'desc': 'walk, shake hands (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk, shake hands (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'A pulls B; B resists (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'A pulls B; B resists (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'navigate busy sidewalk; A leads the way, takes B by the arm (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'conversation - explain with hand gestures (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'conversation - explain with hand gestures, walk (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'quarrel - angry hand gestures (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'quarrel - angry hand gestures (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'friends meet, hang out; A sits, B joins A (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'run, scramble for last seat (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'run, scramble for last seat (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'chicken dance (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 20: {'desc': 'human interaction - at play, formations (2 subjects - subject A)',
-      'motions': {1: {'desc': 'chicken dance (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'link arms, walk (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'link arms, walk (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'synchronized walk (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'synchronized walk (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'soldiers march (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'soldiers march (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'zombie march (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'nursery rhyme - ring around the rosey (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': '360-degree two-person whip (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'high-five, walk (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'low-five, walk (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': "blind man's bluff (blindfold tag) (2 subjects - subject A)",
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 21: {'desc': 'human interaction - at play, formations (2 subjects - subject B)',
-      'motions': {1: {'desc': 'chicken dance (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'link arms, walk (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'link arms, walk (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'synchronized walk (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'synchronized walk (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'soldiers march (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'soldiers march (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'zombie march (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'nursery rhyme - ring around the rosey (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': '360-degree two-person whip (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'high-five, walk (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'low-five, walk (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': "blind man's bluff (blindfold tag) (2 subjects - subject B)",
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 22: {'desc': 'human interaction (2 subjects - subject A)',
-      'motions': {1: {'desc': 'B sits; A pulls up B (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'A sits; B pulls up A (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'A sits, holds face in hands; B kneels, comforts A (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': "B comforts A, puts one hand on A's shoulder (2 subjects - subject A)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': "A comforts B, puts both hands on B's shoulders (2 subjects - subject A)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': "B comforts A, puts both hands on A's shoulders (2 subjects - subject A)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': "A comforts B, puts one hand on B's shoulder (2 subjects - subject A)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'hold hands, swing arms, walk (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'A gives B a shoulder rub; B sits, A stands (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'A shelters B, a younger child, from harm (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'B shelters A, a younger child, from harm (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'A stumbles into B (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'A passes soda to B; both drink (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'alternating squats (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'alternating jumping jacks (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'synchronized jumping jacks (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'rush up, arm wrestle (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'A stares down B, leans with hands on high stool (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'B stares down A, leans with hands on high stool (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'violence - A picks up high stool, threatens to strike B (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'conversation - B pounds high stool, points at A (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'walk; B catches keys thrown by A (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'walk; A catches keys thrown by B (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'walk; B catches wallet thrown by A (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'walk; A catches wallet thrown by B (2 subjects - subject A)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 23: {'desc': 'human interaction (2 subjects - subject B)',
-      'motions': {1: {'desc': 'B sits; A pulls up B (subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'A sits; B pulls up A (subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'A sits, holds face in hands; B kneels, comforts A (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': "B comforts A, puts one hand on A's shoulder (2 subjects - subject B)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': "A comforts B, puts both hands on B's shoulders (2 subjects - subject B)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': "B comforts A, puts both hands on A's shoulders (2 subjects - subject B)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': "A comforts B, puts one hand on B's shoulder (2 subjects - subject B)",
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'hold hands, swing arms, walk (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'A gives B a shoulder rub; B sits, A stands (subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'A shelters B, a younger child, from harm (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'B shelters A, a younger child, from harm (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'A stumbles into B (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'A passes soda to B; both drink (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'alternating squats (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'alternating jumping jacks (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'synchronized jumping jacks (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'rush up, arm wrestle (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'A stares down B, leans with hands on high stool (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'B stares down A, leans with hands on high stool (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'violence - A picks up high stool, threatens to strike B (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'conversation - B pounds high stool, points at A (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'walk; B catches keys thrown by A (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'walk; A catches keys thrown by B (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'walk; B catches wallet thrown by A (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'walk; A catches wallet thrown by B (2 subjects - subject B)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 24: {'desc': 'nursery rhymes',
-      'motions': {1: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 25: {'desc': 'nursery rhymes',
-      'motions': {1: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg'],
-                      'fps': 120}}},
- 26: {'desc': 'nursery rhymes, basketball, bending',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'Alaska vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'Alaska vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'bend, pick up',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'bend, lift',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'bend, lift',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 27: {'desc': 'recreation, nursery rhymes',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'nursery rhyme - Cock Robin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 28: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'prairie dog (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'whale (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'snake (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'mouse (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'cat (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'elephant (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'dinosaur (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 29: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'nursery rhyme - Cock Robin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'whale (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'cat (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'fish (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'elephant (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'mouse (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'dinosaur (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'snake (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 30: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'nursery rhyme - Cock Robin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'whale (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'cat (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'elephant (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'mouse (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'snake (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'Tyrannosaurus rex (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 31: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'whale (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'cat (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'elephant (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'Tyrannosaurus rex (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'mouse (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'snake (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 32: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'nursery rhyme - Cock Robin',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'basketball signals',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Alaskan vacation',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'nursery rhyme - Cock Robin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'Alaskan vacation',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'cat (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'elephant (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'mouse (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'Tyrannosaurus rex (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'snake (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 33: {'desc': 'throw and catch football (2 subjects - subject A)',
-      'motions': {1: {'desc': 'football - throw, catch (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'football - throw, catch, jump around (2 subjects - subject A)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60}}},
- 34: {'desc': 'throw and catch football (2 subjects - subject B)',
-      'motions': {1: {'desc': 'football - throw, catch (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'football - throw, catch, jump around (2 subjects - subject B)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60}}},
- 35: {'desc': 'walk, run',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'run/jog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'navigate around obstacles',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 36: {'desc': 'walk on uneven terrain',
-      'motions': {1: {'desc': 'walk on uneven terrain',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk forward, turn around, walk back',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk forward, turn around, walk back',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk on uneven terrain',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'walk on uneven terrain',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'walk on uneven terrain',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'walk on uneven terrain',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'walk on uneven terrain',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walk forward, turn around, walk back',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'walk on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'jump/hop on uneven terrain',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 37: {'desc': 'walk',
-      'motions': {1: {'desc': 'slow walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 38: {'desc': 'walk, run',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'run around in a circle',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk around, frequent turns, cyclic walk along a line',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 39: {'desc': 'climb, swing, hang on playground equipment',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'walk forward, turn around, walk back',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 40: {'desc': 'navigate from corner to corner, interact with stepstool',
-      'motions': {2: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'climb, step over, sit on, jump over stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'climb, step over, jump over stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'climb, step over, jump over stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'climb, step over, jump over stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'wait for bus',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'wait for bus',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'basketball signals',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 41: {'desc': 'navigate from corner to corner, interact with stepstool',
-      'motions': {2: {'desc': 'navigate - walk forward, backward, sideways, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'navigate - walk forward, backward, sideways, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'navigate - walk forward, backward, on a diagonal',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'climb, step over, jump over, navigate around stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'climb, step over, jump over, navigate around stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'climb, step over, jump over, navigate around stepstool',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'basketball signals',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'basketball signals',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 42: {'desc': 'stretch',
-      'motions': {1: {'desc': 'stretch - rotate head, shoulders, arms, legs',
-                      'files': ['tvd', 'c3d', 'amc'],
-                      'fps': 60}}},
- 43: {'desc': 'swing on playground equipment',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'playground - grip bar, swing body',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'playground - grip bar, swing body',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 45: {'desc': 'walk',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 46: {'desc': 'walk',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 47: {'desc': 'walk',
-      'motions': {1: {'desc': 'walk forward, turn around, walk back',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 49: {'desc': 'modern dance, gymnastics',
-      'motions': {1: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'jump up and down, hop on one foot',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'jump up and down, hop on one foot',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'run, leap',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'run, leap',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'cartwheels',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'dance - arms held high, side arabesque',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'dance - fold in from side arabesque, curl inwards',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'dance - fold in from side arabesque, curl inwards',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'dance - lean forward, bring back leg forward, arching arms',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'dance - fold in from side arabesque, curl inwards',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'dance - lean forward, bring back leg forward, arching arms',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'static dance pose - folded in, head lowered, leg bent',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'dance - fold in from side arabesque, curl inwards',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'dance - lean forward, bring back leg forward, arching arms',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'balance on one leg, outstretched arms',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'balance on one leg, outstretched arms',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'balance on one leg, outstretched arms',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'acrobatics - spin/twirl, hang on ropes',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'dance - lean back on bent leg, balance, bend elbow by ear',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 54: {'desc': 'animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'monkey (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'bear (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'penguin (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'pterosaur (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'pterosaur (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'pterosaur (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'prairie dog (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'roadrunner (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'insect/praying mantis (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'ghost (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'penguin (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'dragon (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'dragon (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'superhero',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'squirrel (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'squirrel (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'squirrel - robotic like motion (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'follow path, walk around obstacles',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'follow path, walk around obstacles',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'follow path, walk around obstacles',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'hummingbird (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'chicken (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 55: {'desc': 'animal behaviors (pantomime - human subject)',
-      'motions': {1: {'desc': 'dance, whirl',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'lambada dance',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'genie (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'hummingbird (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'chicken (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'chicken (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'monkey (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'monkey (human subject)',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'hummingbird (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'animal (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'dancing bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'insect/praying mantis (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'prairie dog (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'roadrunner (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'panda (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'ghost (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'penguin (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'dragon (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'hippo ballerina (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'pterosaur (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'superhero',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'devil',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'various animals (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'dancing animal (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'monkey (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'dancing ant (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'monkey/bear (human subject)',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 56: {'desc': 'vignettes - locomotion, upper-body motions (focus: motion transitions)',
-      'motions': {1: {'desc': 'walk around',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'vignettes - fists up, wipe window, yawn, stretch, angrily grab, smash against wall',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'vignettes - fists up, wipe window, yawn, stretch, angrily grab, smash against wall, lift open window, throw punches, skip',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'vignettes - fists up, wipe window, grab, lift open window, throw punches, yawn, stretch, walk, jump',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'vignettes - walk, drink water, run/jog, jump, wipe window, lift open window, throw punches, yawn, stretch',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'vignettes - throw punches, grab, skip, yawn, stretch, leap, lift open window, walk, jump/bound',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'vignettes - yawn, stretch, walk, run/jog, angrily grab, jump, skip, halt',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'vignettes - lift open window, smash against wall, hop, walk, run/jog, yawn, stretch',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 60: {'desc': 'salsa',
-      'motions': {1: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60}}},
- 61: {'desc': 'salsa',
-      'motions': {1: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'salsa dance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'salsa dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60}}},
- 62: {'desc': 'construction work, random motions',
-      'motions': {1: {'desc': 'bolt loosening, wrench',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'bolt tightening, wrench',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'sawing, hand saw',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'screwing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'screwing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'unscrewing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'hammering a nail',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'hammering a nail',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'pulling a nail',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'hammering sequence',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'cleaning up',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'hard days drink',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'moving a stool',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'opening umbrella',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'opening umbrella',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  16: {'desc': 'closing umbrella',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  17: {'desc': 'opening and closing umbrella',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  18: {'desc': 'closing a box',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  19: {'desc': 'opening a box',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  20: {'desc': 'closing, moving and opening a box',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  21: {'desc': 'coiling a rope',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  22: {'desc': 'dynamic calibration',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  23: {'desc': 'bolt tightening',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  24: {'desc': 'bolt tightening, with putting bolt in',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  25: {'desc': 'bolt loosening, wrench',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60}}},
- 63: {'desc': 'golf',
-      'motions': {1: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120}}},
- 64: {'desc': 'golf',
-      'motions': {1: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Swing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'Swing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'Putt',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'Putt',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'Putt',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'Putt',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'Putt',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'Placing Tee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'Placing Tee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'Placing Tee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'Placing Tee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'Placing Tee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'Placing Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'Placing Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'Placing Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'Placing Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'Placing Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'Picking up Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'Picking up Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'Picking up Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'Picking up Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'Picking up Ball',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 120}}},
- 69: {'desc': 'walking',
-      'motions': {1: {'desc': 'walk forward',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk forward',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk forward',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk forward',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'walk forward',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'walk and turn (repeated)',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'walk and turn (repeated)',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'walk and turn (repeated)',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walk and turn (repeated)',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'walk and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'walk and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'walk and turn both directions (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'walk, turn in place (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk, turn in place (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'walk, turn in place (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'turn in place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'turn in place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'turn in place (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'turn in place (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'walk forward 90 degree right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'walk forward 90 degree right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'walk forward 90 degree right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'walk forward 90 degree right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'walk forward 90 degree left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'walk forward 90 degree left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'walk forward 90 degree left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'walk forward 90 degree left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'walk forward 90 degree smooth right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'walk forward 90 degree smooth right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'walk forward 90 degree smooth right turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'walk forward 90 degree smooth left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'walk forward 90 degree smooth left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'walk forward 90 degree smooth left turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  38: {'desc': 'walk backwards and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  39: {'desc': 'walk backward, turn in place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  40: {'desc': 'walk backward, turn in place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  41: {'desc': 'walk backward, turn in place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  42: {'desc': 'walk sideways and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  43: {'desc': 'walk sideways and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  44: {'desc': 'walk sideways and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  45: {'desc': 'walk sideways and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  46: {'desc': 'walk sideways and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  47: {'desc': 'walk sideways and turn (repeated)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  48: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  49: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  50: {'desc': 'walk sideways and backwards',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  51: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  52: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  53: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  54: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  55: {'desc': 'walk backwards and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  56: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  57: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  58: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  59: {'desc': 'walk sideways and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  60: {'desc': 'walk sideways and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  61: {'desc': 'walk sideways and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  62: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  63: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  64: {'desc': 'walk sideways and turn (opposite direction)',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  65: {'desc': 'walk sideways and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  66: {'desc': 'walk sideways and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  67: {'desc': 'walk sideways and turn',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  68: {'desc': 'walk forward and pick up object, set down object',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  69: {'desc': 'walk forward and pick up object, carry back object',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  70: {'desc': 'walk up to object, squat, pick up object, set down in another place.',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  71: {'desc': 'walk up to object, squat, pick up object, set down in another place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  72: {'desc': 'walk up to object, pick up object, set down in another place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  73: {'desc': 'walk up to object, lean over, pick up object, set down in another place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  74: {'desc': 'walk up to object, lean over, pick up object, set down in another place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  75: {'desc': 'walk up to object, squat, pick up object, set down in another place',
-                       'files': ['amc', 'avi'],
-                       'fps': 120}}},
- 70: {'desc': 'suitcase',
-      'motions': {1: {'desc': 'carry 5.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'carry 5.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'carry 19.5lb suitcase',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'carry 12.5lb suitcase',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'carry 12.5lb suitcase',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'carry 12.5lb suitcase',
-                       'files': ['amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'carry 12.5lb suitcase',
-                       'files': ['amc', 'avi'],
-                       'fps': 120}}},
- 74: {'desc': 'kicks and walking on slopes',
-      'motions': {1: {'desc': 'stiff walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'stiff walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'lifting up',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'lifting up',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  9: {'desc': '',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'peeping',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'peeping',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'thinker',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'Range of motion',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'slope 1',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'slope1',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  16: {'desc': 'slope 2',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  17: {'desc': 'slope 2',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  18: {'desc': 'slope 3',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  19: {'desc': 'slope 3',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  20: {'desc': 'stiff walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60}}},
- 75: {'desc': 'jumps; hopscotch; sits',
-      'motions': {1: {'desc': 'run jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'run jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'run jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'wide leg run',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'cross leg run',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  6: {'desc': '180 jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'angle jumps',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  8: {'desc': '360 jumps',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  9: {'desc': '360 jump',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  10: {'desc': '2 jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  11: {'desc': '2 jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'box jump',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'hopscotch',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'hopscotch',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'long jumps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  16: {'desc': 'jump kick',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  17: {'desc': 'medium sit',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  18: {'desc': 'high sit',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  19: {'desc': 'medium sit',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  20: {'desc': 'low sit',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60}}},
- 76: {'desc': 'avoidance',
-      'motions': {1: {'desc': 'walk backwards then attack with a punch',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk backwards, feign a few attacks, then attack',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'avoid attacker',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'defensive guard pose',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'swatting at pesky bug',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'avoid stepping on something',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'careful stepping over things',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walking backwards',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'turning',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'quick large steps backwards',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 77: {'desc': 'careful actions',
-      'motions': {1: {'desc': 'looking around',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'standing',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'ready stance',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'Looking around',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'look around with flashlight',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'searching ground',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'poking ground',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'investigating thing on ground with two hands',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'duck to avoid flying object',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'careful run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'careful run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'careful run in circle',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'careful run in figure eight',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'careful creeping',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'careful creeping',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  16: {'desc': 'laying down, getting up, careful ready pose',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  17: {'desc': 'laying down, getting up, careful ready pose',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  18: {'desc': 'laying down on back, getting up, careful ready pose',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  19: {'desc': 'limping, hurt right leg',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  20: {'desc': 'limping, hurt right leg',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  21: {'desc': 'stretching',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  22: {'desc': 'limping, hurt right leg',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  23: {'desc': 'limping, hurt right leg',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  24: {'desc': 'limping, hurt right leg',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  25: {'desc': 'careful walk and search',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  26: {'desc': 'careful walk and search',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  27: {'desc': 'careful walk and search',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  28: {'desc': 'careful walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  29: {'desc': 'creeping walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  30: {'desc': 'creeping walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  31: {'desc': 'silent walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  32: {'desc': 'creeping walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  33: {'desc': 'creeping with limp',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  34: {'desc': 'creep and pause, repeat',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60}}},
- 78: {'desc': 'walking',
-      'motions': {1: {'desc': 'LeftTightTurn         CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'RightWideTurn            CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'LeftWideTurn     CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'SuperTightLeft        CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'SuperTightRight         CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'RunningStraight       CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'RunningWideRight       CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'RunningWideLeft      CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'RunningTigherLeft      CleanedGRS',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'RunningTighterRight      CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'calibration',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'RunningNoBall     CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'OffensiveMoveSpinLeft            CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'OffensiveMoveSpinLeft      CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'OffensiveMoveGoRight     CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'OffensiveMoveGoLeft         CleanedGRs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'OffensiveMoveSpinRight             CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'WalkEvasiveLeft      CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'WalkEvasiveRight              CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'FeintLeftMoveRight            CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'FeintRightMoveLeft      CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'FakeShotBreakRight     CleanedGRs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'FakeShotBreakLeft            CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'DefensiveStraightNoStop          CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'DefensiveStraightWithStop          CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'DefensiveRightStopToStop           CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'DefensiveLeftStopToStop              CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'DefensiveMoveZigZag           CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'DefensiveMoveSideToSide           CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'DefensiveMoveSideToSide           CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'Pivoting     CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'SraightDriveFromStop          Cleaned GRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'RightDrive (left then right)    Cleaned GRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'LeftDrive (right then left)    Cleaned GRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'RightTightTurn    CleanedGRS',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 79: {'desc': 'actor everyday activities',
-      'motions': {1: {'desc': 'chopping wood',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'swimming',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'swimming',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'digging',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'sewing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'hand shake',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'lost marker',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'boxing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'slicing bread',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'chopping onions',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'Subject calibration',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'eating dinner',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'mixing batter',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'making dough',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'eating a sandwich',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  16: {'desc': 'buying something',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  17: {'desc': 'playing violin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  18: {'desc': 'playing drums',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  19: {'desc': 'playing piano',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  20: {'desc': 'hanging a picture',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  21: {'desc': 'putting on a pull over',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  22: {'desc': 'range of motion',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  23: {'desc': 'putting on a jacket',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  24: {'desc': 'putting on button up sweater',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  25: {'desc': 'moving heavy box',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  26: {'desc': 'planting a tree',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  27: {'desc': 'planting a plant',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  28: {'desc': 'putting on a ball cap',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  29: {'desc': 'putting on a dress',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  30: {'desc': 'pushing a swing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  31: {'desc': 'writing on a chalkboard',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  32: {'desc': 'writing on a chalkboard',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  33: {'desc': 'chug a beer',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  34: {'desc': 'fishing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  35: {'desc': 'fishing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  36: {'desc': 'answering the phone',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  37: {'desc': 'dialing phone',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  38: {'desc': 'drinking water',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  39: {'desc': 'sipping martinee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  40: {'desc': 'drinking a soda',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  41: {'desc': 'sipping coffee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  42: {'desc': 'eating soup',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  43: {'desc': 'painting',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  44: {'desc': 'washing a window',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  45: {'desc': 'bear',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  46: {'desc': 'bear',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  47: {'desc': 'chicken',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  48: {'desc': 'elephant',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  49: {'desc': 'monkey',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  50: {'desc': 'mouse',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  51: {'desc': 'chipmunk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  52: {'desc': 'prairie dog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  53: {'desc': 'dog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  54: {'desc': 'snake',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  55: {'desc': 'sweeping',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  56: {'desc': 'T-rex',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  57: {'desc': 'fish',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  58: {'desc': 'bird',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  59: {'desc': 'cat',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  60: {'desc': 'chicken',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  61: {'desc': 'cow',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  62: {'desc': 'chicken',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  63: {'desc': 'tiger',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  64: {'desc': 'penguin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  65: {'desc': 'horse',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  66: {'desc': 'movie and trial dont match',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  67: {'desc': 'no movie',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 60},
-                  68: {'desc': 'cold',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  69: {'desc': 'very happy',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  70: {'desc': 'laughing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  71: {'desc': 'sad',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  72: {'desc': 'crying',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  73: {'desc': 'scared',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  74: {'desc': 'upset',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  75: {'desc': 'channel surfing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  76: {'desc': 'driving',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  77: {'desc': 'vacuuming',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  78: {'desc': 'taking a movie',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  79: {'desc': 'putting on headphones',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  80: {'desc': 'using a palm pilot',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  81: {'desc': 'brushing teeth',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  82: {'desc': 'putting on deoderant',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  83: {'desc': 'shaving',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  84: {'desc': 'combing hair',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  85: {'desc': 'typing on a laptop',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  86: {'desc': 'shooting bow and arrow',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  87: {'desc': 'raking',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  88: {'desc': 'swatting at a fly',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  89: {'desc': 'holding a baby',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  90: {'desc': 'washing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  91: {'desc': 'football',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  92: {'desc': 'frisbee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  93: {'desc': 'weight lifting',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  94: {'desc': 'flexing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  95: {'desc': 'rowing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  96: {'desc': 'shooting a gun',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60}}},
- 80: {'desc': 'assorted motions',
-      'motions': {1: {'desc': 'shaking hands',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'chopping onions',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'shooting a gun',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'sewing',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'digging a hole',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'paying for something',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'hanging picture',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'picking up something',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'planting a flower',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'boxing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'putting on a sweater',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  12: {'desc': 'fishing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  13: {'desc': 'drumming',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  14: {'desc': 'teaching',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  15: {'desc': 'putting on a coat',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  16: {'desc': 'mixing batter',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  17: {'desc': 'hand mixing dough',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  18: {'desc': 'vacuuming',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  19: {'desc': 'pushing broom',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  20: {'desc': 'planting',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  21: {'desc': 'pushing swing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  22: {'desc': 'putting on a hat',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  23: {'desc': 'putting on a skirt',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  24: {'desc': 'eating',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  25: {'desc': 'answering a phone',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  26: {'desc': 'dialing phone',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  27: {'desc': 'setting glass of water',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  28: {'desc': 'drinking and smoking',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  29: {'desc': 'chugging',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  30: {'desc': 'range of motion',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  31: {'desc': 'making coffee',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  32: {'desc': 'slicing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  33: {'desc': 'eating soup',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  34: {'desc': 'rake leaves',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  35: {'desc': 'putting on headphones',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  36: {'desc': 'violin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  37: {'desc': 'TV',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  38: {'desc': 'driving',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  39: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  40: {'desc': 'drinking from bottle',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  41: {'desc': 'freezing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  42: {'desc': 'freezing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  43: {'desc': 'happy',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  44: {'desc': 'laughing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  45: {'desc': 'crying',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  46: {'desc': 'crying',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  47: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  48: {'desc': 'arguing',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  49: {'desc': 'gorilla',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  50: {'desc': 'cleaning window',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  51: {'desc': 'chicken',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  52: {'desc': 'dog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  53: {'desc': 'elephant',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  54: {'desc': 'monkey',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  55: {'desc': 'mouse',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  56: {'desc': 'chip monk',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  57: {'desc': 'prairie dog',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  58: {'desc': 'snake',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  59: {'desc': 'panther',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  60: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  61: {'desc': 'sweeping',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  62: {'desc': 'bird',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  63: {'desc': 'chicken',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  64: {'desc': 'cat',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  65: {'desc': 'fish',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  66: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  67: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  68: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  69: {'desc': 'painting',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  70: {'desc': 'piano',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  71: {'desc': 'chopping wood',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  72: {'desc': 'swimming',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  73: {'desc': 'shaking hands',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60}}},
- 81: {'desc': 'pushing a box; jumping off a ledge; walks',
-      'motions': {1: {'desc': 'fix hair and walk forward',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk forward',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walk',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walk at a brisk pace',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'push heavy object',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'push heavy box',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'pull heavy object',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'drag heavy object',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'drag heavy object',
-                      'files': ['tvd', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'push object that is high in air',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'push object that is high in air',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'jump backwards off ledge',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'jump backwards off ledge',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'climb backwards off ledge',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'climb backwards off ledge',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'walk forward',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'adjust hair walk forward',
-                       'files': ['tvd', 'amc', 'avi'],
-                       'fps': 120}}},
- 82: {'desc': 'jumping; pushing; emotional walks',
-      'motions': {1: {'desc': 'Static pose',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'Jump off ledge',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'Jump off ledge',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'Jump off ledge',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'sitting on ground relaxing',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'Pushing on heavy object',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'Pushing on heavy object',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'stand still; casual walk forward',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'confident walk forward',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'sad walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'normal walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'happy or fast walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'normal walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'walk forward and slow down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'walk forward and turn sideways',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'bang on high object',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'bang on high object',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'static pose',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 83: {'desc': 'steps',
-      'motions': {1: {'desc': 'large sidestep to right',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'sidestep to the right and up a ledge',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'large step to a short ledge',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'large sidestep to right',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'very large sidestep to right',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'very large sidestep to right and down',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'short sidestep to right and down',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'medium step forward and down',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'short step forward and down',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'medium step forward and down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'static pose',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'medium sidestep to right and down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'large sidestep to right',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'short sidestep to left and down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'short step forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'medium sidestep to left and down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'medium step to left and down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'short step to left and forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'medium sidestep to left',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'medium step forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'large step to left and forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'stretching',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'short sidestep to left and up',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'medium step to left and up',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'short step forward and up',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'medium step to left, forward, and up',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'walk forward stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'walk forward stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'walk forward stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'walk forward stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'walk forward stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'walk forward stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'sidestep to right then back to left',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'walk forward and up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'walk forward and stepping up stairs',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'walk forward turn 90 degrees left walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'walk forward turn 90 degrees right walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  38: {'desc': 'walk forward turn 90 degrees left walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  39: {'desc': 'walk forward turn 90 degrees right walk forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  40: {'desc': 'hop forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  41: {'desc': 'hop forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  42: {'desc': 'long jump forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  43: {'desc': 'long jump forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  44: {'desc': 'medium step forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  45: {'desc': 'hop forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  46: {'desc': 'medium hop forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  47: {'desc': 'long jump forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  48: {'desc': 'short hop forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  49: {'desc': 'medium hop forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  50: {'desc': 'long jump forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  51: {'desc': 'hop turn 90 degrees left in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  52: {'desc': 'hop turn 90 degrees left in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  53: {'desc': 'hop turn 90 degrees left in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  54: {'desc': 'hop turn 180 degrees left in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  55: {'desc': 'medium sidestep to right',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  56: {'desc': 'hop turn left 180 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  57: {'desc': 'hop turn left 180 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  58: {'desc': 'hop turn left 270 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  59: {'desc': 'hop turn left 270 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  60: {'desc': 'hop turn left 270 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  61: {'desc': 'hop turn 360 degrees left in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  62: {'desc': 'hop turn left 360 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  63: {'desc': 'large sidestep to right and forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  64: {'desc': 'hop and turn right 360 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  65: {'desc': 'hop and turn right 360 degrees in air',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  66: {'desc': 'short sidestep to right',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  67: {'desc': 'short sidestep to the right',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  68: {'desc': 'medium sidestep to right',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 85: {'desc': 'jumps; flips; breakdance',
-      'motions': {1: {'desc': 'JumpTwist',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'JumpTwist',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'UpRightSequence',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'FancyFootWork',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'HandStandKicks',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'KickFlip',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'KickFlipStumble',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'Helicopter',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'motorcycle pose',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'EndofBreakDance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'UpRightSequence',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'LongSequenceGood',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'BadStartSequnce',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'BreakSequencewithFlips',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': '90TwistsFall',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 86: {'desc': 'sports and various activities',
-      'motions': {1: {'desc': 'jumps kicks and punches',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'walk, squats, run, stretch, jumps, punches, and drinking',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'walking, running, jumping, kicking, and stretching',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'walking, stretching, punching, chopping, and drinking',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'walking, jumping, jumping jacks,  jumping on one foot, punching, chopping,',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'walking, running, kicking, punching, knee kicking, and stretching',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'walking, swinging arms, stretching, jumping on one leg, and jumping',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'walking, squats, stretching, kicking, and punching',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'walking, sitting, looking, stand up',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'walk around, sit, stand up, and running',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'walking, stretching, walking and turning',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'walking, dragging, sweeping, dustpan, wipe window, and wipe mirror',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'walking around, walk up ladder, step down ladder',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'bouncing basketball, shooting basketball, dribble basketball, two handed dribble',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'walking, sitting, hand motions',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 87: {'desc': 'acrobatics',
-      'motions': {1: {'desc': 'Jump with kick and spin',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'T-Pose',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'Backflip',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'backflip',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'cartwheels',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60}}},
- 88: {'desc': 'acrobatics',
-      'motions': {1: {'desc': 'backflip',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'backflips, jump onto platform, handstands, vertical pushups',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'motorcycle pose',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'stretches, cartwheels, flips, spin kicks, spins, and fall',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'cartwheel into backflip',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'jump and spin kick',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  7: {'desc': 'cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  8: {'desc': 'crouch and flip backward on hands',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  9: {'desc': 'stretch and cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  10: {'desc': 'stretch and spin',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60},
-                  11: {'desc': 'stretches and jumps',
-                       'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                       'fps': 60}}},
- 89: {'desc': 'acrobatics',
-      'motions': {1: {'desc': 'balance object on forehead',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  2: {'desc': 'motorcycle pose',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  3: {'desc': 'flip and stand on one hand',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  4: {'desc': 'spins, flips, stand on one hand',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  5: {'desc': 'spin upside down, handstand, flips',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60},
-                  6: {'desc': 'balance beam',
-                      'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
-                      'fps': 60}}},
- 90: {'desc': 'cartwheels; acrobatics; dances',
-      'motions': {1: {'desc': 'bkwd summersult',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'cartwheel',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'jump kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'jump kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'jump kick',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'side flip',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'Flip forward onto hands and back again',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                  11: {'desc': 'hand spring',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'bck flp twst fall',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'bck flp twst fall',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'front hand flip',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'front hand flip',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'fall on face',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'BannanaPeelSlip',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'RugPullFall',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'monkey backflip',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'monkey sequence',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'monkey sequence',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'straight walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'straight walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'ball mount',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'fwd ball walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'fwd ball walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'bwk ball walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'breakdance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'sequesnce',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'russian dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'russian dance',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'moonwalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'arm up wide leg roll',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'wide leg roll',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'wide leg roll',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'wide leg roll',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 91: {'desc': 'walks and turns',
-      'motions': {1: {'desc': 'Walk digital figure eight',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'WalkStraight',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'Walk figure eight',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'Walking',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'Mummy Walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'Motorcycle Pose',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'mummy8',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'mummyDigital8',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': 'DrunkWalk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': 'SlowWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': 'LavishWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': 'TooCoolWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': 'SadWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': 'DepressedWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': 'ClumsyWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': 'Limp',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  17: {'desc': 'QuickWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  18: {'desc': 'CarefulWalk LookingAround',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  19: {'desc': 'March',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  20: {'desc': 'ShyWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  21: {'desc': 'acheyWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  22: {'desc': 'CasualQuickWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  23: {'desc': 'CoolWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  24: {'desc': 'HurtLegWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  25: {'desc': 'DragBadLegWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  26: {'desc': 'HurtStomachWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  27: {'desc': 'SlowWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  28: {'desc': 'GhettoWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  29: {'desc': 'NormalWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  30: {'desc': 'SexyWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  31: {'desc': 'NormalWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  32: {'desc': 'ScaredWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  33: {'desc': 'MachoWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  34: {'desc': 'NormalWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  35: {'desc': 'TrafficWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  36: {'desc': 'WalkStraight',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  37: {'desc': 'Forward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  38: {'desc': 'SmallForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  39: {'desc': 'JumpForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  40: {'desc': 'JumpForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  41: {'desc': 'JumpForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  42: {'desc': 'JumpForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  43: {'desc': 'JumpSmallForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  44: {'desc': 'JumpSmallForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  45: {'desc': 'JumpForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  46: {'desc': 'Jump Turn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  47: {'desc': 'Jump Turn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  48: {'desc': 'JumpTurn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  49: {'desc': 'Jump Turn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  50: {'desc': 'JumpTurn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  51: {'desc': 'FurtherJumpTurn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  52: {'desc': 'SmallJumpTurn',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  53: {'desc': '180 degree jump',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  54: {'desc': '180',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  55: {'desc': '180',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  56: {'desc': '90',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  57: {'desc': 'WalkForward',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  58: {'desc': '270',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  59: {'desc': '360 smallStumble',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  60: {'desc': '360',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  61: {'desc': '360',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  62: {'desc': 'walkFigure8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 93: {'desc': 'Charleston Dance',
-      'motions': {1: {'desc': 'Motorcycle Pose',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': 'rangeOfMotion',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': 'charleston_01',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': 'charleston_side_by_side_female',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': 'charleston_side_by_side_male',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': 'lindyHop2',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': 'Casual Walk',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': 'xtra fancY charleston',
-                      'files': ['tvd', 'c3d', 'amc', 'avi'],
-                      'fps': 120}}},
- 94: {'desc': 'indian dance',
-      'motions': {1: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  2: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  3: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  4: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  5: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  6: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  7: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  8: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  9: {'desc': '',
-                      'files': ['c3d', 'amc', 'avi'],
-                      'fps': 120},
-                  10: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  11: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  12: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  13: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  14: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  15: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                  16: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 102: {'desc': 'Basketball',
-       'motions': {1: {'desc': 'RightWideTurn',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   2: {'desc': 'LeftWideTurn',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   3: {'desc': 'SuperTightLeft',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   4: {'desc': 'SuperTightRight',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   5: {'desc': 'RunningStraight',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   6: {'desc': 'RunningWideRight',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   7: {'desc': 'RunningWideLeft',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   8: {'desc': 'RunningTighterRight',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   9: {'desc': 'calibration',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   10: {'desc': 'RunningNoBall',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   11: {'desc': 'OffensiveMoveSpinLeft',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   12: {'desc': 'OffensiveMoveSpinLeft',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   13: {'desc': 'OffensiveMoveGoRight',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   14: {'desc': 'OffensiveMoveGoLeft',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   15: {'desc': 'OffensiveMoveSpinRight',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   16: {'desc': 'WalkEvasiveLeft',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   17: {'desc': 'WalkEvasiveRight',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   18: {'desc': 'FeintLeftMoveRight',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   19: {'desc': 'FeintRightMoveLeft',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   20: {'desc': 'FakeShotBreakRight',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   21: {'desc': 'FakeShotBreakLeft',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   22: {'desc': 'DefensiveStraightNoStop',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   23: {'desc': 'DefensiveStraightWithStop',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   24: {'desc': 'DefensiveRightStopToStop',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   25: {'desc': 'DefensiveLeftStopToStop',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   26: {'desc': 'DefensiveMoveZigZag',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   27: {'desc': 'DefensiveMoveSideToSide',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   28: {'desc': 'DefensiveMoveSideToSide',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   29: {'desc': 'Pivoting',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   30: {'desc': 'SraightDriveFromStop',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   31: {'desc': 'RightDrive (left then right)',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   32: {'desc': 'LeftDrive (right then left)',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   33: {'desc': 'RightTightTurn',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120}}},
- 103: {'desc': 'Charelston Dancing',
-       'motions': {1: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'rangeOfMotion_01',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'charleston_01',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'charleston_side_by_side_female',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'charleston_side_by_side_male',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'lindyHop2',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Casual Walk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'xtra fancY charleston',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 104: {'desc': 'motion',
-       'motions': {1: {'desc': 'JogThrough',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'neutral Male walk, exact footfalls',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Frankenstein male walk, exact footfalls',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'JogThrough',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'StartJog',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'StartJog',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'JogStop',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'JogStop',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'HappyGoLuckWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'ExcitedWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'StumbleWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'HappyStartWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'SpasticWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'SpasticStop',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'SpasticStop',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'CasualWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'RegularWalk8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'RegularWalkRightAngleTurns',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'SternWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'SternWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'SternWalk8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'SternWalkRightAngleTurns',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'SlowWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'SlowWalk8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'RunThrough',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'SlowWalkRightAngleTurns',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'ZombieWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'ZombieWalk8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   43: {'desc': 'ZombieWalkRightAngleTurns',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   44: {'desc': 'AttitudeWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   45: {'desc': 'AttitudeWalk8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   46: {'desc': 'AttitudeWalkRightAngleTurns',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   47: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   48: {'desc': 'RunThrough',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   49: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   50: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   51: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   52: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   53: {'desc': 'StartRun',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   54: {'desc': 'StartRun',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   55: {'desc': 'StartRun',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   56: {'desc': 'RunStop',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   57: {'desc': 'RunStop',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 105: {'desc': 'motion',
-       'motions': {1: {'desc': 'WalkDigital8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'WalkStraight',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Walk8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Digital8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'mummyWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'MotorCyclePose',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'mummy8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'mummyDigital8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'DrunkWalk',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'SlowWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'LavishWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'TooCoolWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'SadWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'DepressedWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'ClumsyWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Limp',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'QuickWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'CarefulWalk LookingAround',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'March',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'ShyWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'acheyWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'CasualQuickWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'CoolWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'HurtLegWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'DragBadLegWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'HurtStomachWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'SlowWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'GhettoWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'NormalWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'SexyWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'NormalWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'ScaredWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'MachoWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'NormalWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'TrafficWalk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'WalkStraight',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Forward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'SmallForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'JumpForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'JumpForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'JumpForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'JumpForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   43: {'desc': 'JumpSmallForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   44: {'desc': 'JumpSmallForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   45: {'desc': 'JumpForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   46: {'desc': 'Jump Turn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   47: {'desc': 'Jump Turn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   48: {'desc': 'JumpTurn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   49: {'desc': 'Jump Turn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   50: {'desc': 'JumpTurn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   51: {'desc': 'FurtherJumpTurn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   52: {'desc': 'SmallJumpTurn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   53: {'desc': '180',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   54: {'desc': '180',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   55: {'desc': '180',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   56: {'desc': '90',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   57: {'desc': 'WalkForward',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   58: {'desc': '270',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   59: {'desc': '360 smallStumble',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   60: {'desc': '360',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   61: {'desc': '360',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   62: {'desc': 'walkFigure8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 106: {'desc': 'Female General Subject',
-       'motions': {1: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   2: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   3: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   4: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   5: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   6: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   7: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   8: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   9: {'desc': 'clean',
-                       'files': ['tvd', 'c3d', 'amc'],
-                       'fps': 120},
-                   10: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   11: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   12: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   13: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   14: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   15: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   16: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   17: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   18: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   19: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   20: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   21: {'desc': 'bad AMC',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   22: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   23: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   24: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   25: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   26: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   27: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   28: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   29: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   30: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   31: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   32: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   33: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120},
-                   34: {'desc': 'clean',
-                        'files': ['tvd', 'c3d', 'amc'],
-                        'fps': 120}}},
- 107: {'desc': 'Walking with obstacles 1',
-       'motions': {1: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': '',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': '',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 108: {'desc': 'Walking with obstacles 2',
-       'motions': {1: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': '',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 111: {'desc': 'Pregnant Woman',
-       'motions': {1: {'desc': 'Walk backwards',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Bow',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Crawling',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Curtsey',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Dance',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Get up from floor',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Get up from floor',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Get up from floor',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Get up from chair',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'get up from chair',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'get up from chair',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Lay down',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'March',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Mope',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Peekaboo',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Pick up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Pick up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Punch Kick',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Ring around the rosie',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Roll over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Range of motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Shrug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Walk sideways',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Walking up stairs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Standing still',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Stepping over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Stepping over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Stepping up / stepping down',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Stretch and yawn',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Throwing',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'Walk and carry',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Wave',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'Yoga',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'Yoga',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'Yoga',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'Yoga',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 113: {'desc': 'Post pregnant woman',
-       'motions': {1: {'desc': 'Walk backwards',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Bow',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Curtsey',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Dance',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Walk digital 8',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Walk figure 8',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Lay down and get up',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'March',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Walk, mope around',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Peekaboo',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Punch and kick',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Ring around the rosie',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Sit in chair and get up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Shrug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Walk sideway',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Walk sideways',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Walking up and down stairs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Walk up and down stairs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Standing Still',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Step over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Stretch and yawn',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Throw',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Walk and carry',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Wave',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Yoga',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Yoga',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 114: {'desc': 'Pregnant Woman',
-       'motions': {1: {'desc': 'Motorcycle',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Getting up from laying down',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Range of motion',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Getting up from chair',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Sitting in chair',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Getting up from chair',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Walking up and down stairs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Walking up and down stairs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Walking up and down stairs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Stretching',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Laying down and getting up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Stretching',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Sit down and stretch',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 115: {'desc': 'Bending over',
-       'motions': {1: {'desc': 'Pick up box, bend from waist',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Pick box up, bend from waist',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Pick box up, bend from waist',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Pick box up, bend from waist',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Pick box up, bend from waist',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Picking box up, bending knees',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Picking box up, bending knees',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Picking box up, bending knees',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Picking box up, bending knees',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Pick box up, bend from waist',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 118: {'desc': 'Jumping',
-       'motions': {1: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Range of motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 120: {'desc': 'Various Style Walks',
-       'motions': {1: {'desc': 'Alien Turn',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Gorilla',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Mickey cast spell',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Mickey Conducting',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Mickey Dance',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Mickey Dance',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Mickey Dance',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Mickey sneaky walk',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Mickey sneaking walk',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Mickey sneaking walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Mickey sneaking walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Mickey sneaking walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Mickey sneaking walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Mickey sneaking walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Mickey Surprised',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Mickey Surprised',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Mickey Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Mickey Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Walk slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Robot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Zombie',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 122: {'desc': 'Varying Height and Length Steps',
-       'motions': {1: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'clean',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': '',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   43: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   44: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   45: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   46: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   47: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   48: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   49: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   50: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   51: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   52: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   53: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   54: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   55: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   56: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   57: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   58: {'desc': 'cleaned',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   59: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   60: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   61: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   62: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   63: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   64: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   65: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   66: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   67: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   68: {'desc': 'clean',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 123: {'desc': 'Carry Suitcase with Varying Weights',
-       'motions': {1: {'desc': '15.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': '15.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': '19.5lb',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': '19.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': '19.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': '19.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': '12.5lb',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': '12.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': '12.5 lbs',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': '12.5lb',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': '15.5 lbs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': '15.5 lbs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': '15.5 lbs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 124: {'desc': 'Sports Related Motions',
-       'motions': {1: {'desc': 'Baseball Pitch',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Baseball Pitch',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Basketball Shoot',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Basketball Free Throw',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Basketball Jump Shot',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Basketball Lay Up',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Baseball Swing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Baseball Bunt',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Frisbee',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': '2 Foot Jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Underhand Toss',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Underhand Fast Pitch',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 125: {'desc': 'Swimming',
-       'motions': {1: {'desc': 'Breast Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Breast Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Break Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Breast Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Butterfly',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Free Style',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Motorcycle',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 126: {'desc': 'Swimming 2',
-       'motions': {1: {'desc': 'Back Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Back Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Breast Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Breast Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Breast Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Fly Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Fly Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Fly Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Fly Stroke',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Free Style',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Free Style',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Free Style',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Range of Motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 127: {'desc': 'Action Adventure Obstacles, running, jumping, ducking, rolling',
-       'motions': {1: {'desc': 'Motorcycle',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Range of Motion',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Walk to Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Run to Quick Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Run Right',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Run Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Run Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Run Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Run Side Step Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Run Side Step Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Run Turn Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Run Turn Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Run Stop Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Run Stop Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Run Quick Stop Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Run Quick Stop Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Run Jump Stop Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Run Jump Stop Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Run Dive Over Roll Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Run Dive Over Roll Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Run Jump Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Run Jump Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Run Jump Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Run Jump Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Run Duck Underneath',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Run Duck Underneath',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Run Duck Underneath',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Run Duck Underneath',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Run Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Run Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'Run Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'Run Over',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Run Duck Underneath',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'Run Duck Underneath',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 128: {'desc': 'Action Adventure Motions running, ducking, rolling, stopping',
-       'motions': {1: {'desc': 'Motorcycle',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Run Left',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Run Right',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Run Duck Underneath',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Run Stop Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Run Stop Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Run Stop Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Run Stop Run',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Run Roll Underneath',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Run Dive Over Roll Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Run Dive Over Roll Run',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 131: {'desc': 'Michael Jackson Styled Motions',
-       'motions': {1: {'desc': 'Start Walk Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Start Walk Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Start Hop Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Start Hop Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Start Duck Underneath Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Start Duck Underneath Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Jump Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Jump Stop',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Start Walk Left',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Start Walk Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Start Walk Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Start Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Start Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Start Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 132: {'desc': 'Varying Weird Walks',
-       'motions': {1: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Walk With Arms Out,  balancing',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Walk With Arms Out,  balancing',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Walk With Arms Out,  balancing',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Walk With Arms Out,  balancing',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Walk Backwards',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Walk Duck Footed',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Walk With Knees Bent',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Walk Crossover',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Walk Fast',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Walk Fast',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Walk Fast',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Walk Fast',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Walk Fast',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Walk Fast',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Hop on left foot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Hop on left foot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Hop on left foot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Hop on left foot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Hop on left foot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Hop on left foot',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Bouncy Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Bouncy Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Bouncy Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Bouncy Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Bouncy Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Bouncy Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'Walk Leaning To The Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'Walk Leaning To The Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Marching',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'Pigeon Toed Walking',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'Walk With Stiff Arms',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'Walk With Stiff Arms',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'Walk Swinging Shoulders',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   43: {'desc': 'Walk Swinging Shoulders',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   44: {'desc': 'Walk Swinging Shoulders',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   45: {'desc': 'Walk Slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   46: {'desc': 'Walk Slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   47: {'desc': 'Walk Slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   48: {'desc': 'Walk Slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   49: {'desc': 'Walk Slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   50: {'desc': 'Walk Slow',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   51: {'desc': 'Tpose',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   52: {'desc': 'Range of Motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   53: {'desc': 'Walk With Legs Apart',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   54: {'desc': 'Walk With Wild Arms',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   55: {'desc': 'Walk With Wild Legs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   56: {'desc': 'Walk With Wild Legs',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 133: {'desc': 'Baby Styled Walk',
-       'motions': {1: {'desc': 'Walk Crawl',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Walk Crawl',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Walk Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Walk Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Walk Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Walk Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Walk Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Stretch Walk',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Stretch Walk',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Stretch Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Walk Stop Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Walk Stop Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Walk Stop Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Walk Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Walk Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Walk Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Walk Right',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Walk ZigZag',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Range of Motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 134: {'desc': 'Skateboard Motions',
-       'motions': {1: {'desc': 'Duck Under',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Go Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Lean Turn Right',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Motorcycle',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Pump Jump',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Push Turn Left',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Push Turn Left',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Push Turn Right',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Push Turn Right',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Start',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Start',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Stop and Go',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Stop and Go',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Stop ang Go',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Lean Turn Left',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 135: {'desc': 'Martial Arts Walks',
-       'motions': {1: {'desc': 'Bassai',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Empi',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Empi',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Front Kick',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Gedanbarai',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Heiansyodan',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Mawashigeri',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Motorcycle',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Oiduki',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Syutouuke',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Yokogeri',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 136: {'desc': 'Weird Walks',
-       'motions': {1: {'desc': 'Walk Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Walk Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Walk Backwards Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Walk Backwards Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Walk on Toes Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Walk on Toes Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Walk Backward on Toes Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Walk Backward on Toes Bent Forward',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Walk Crouched',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Walk Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Walk Backwards Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Walk Backwards Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Walk on Toes Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Walk on Toes Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Walk Backwards on Toes Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Walk Backwards on Toes Crouched',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Flamingo, lift legs high',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Flamingo, lift legs high',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Motorcycle',
-                        'files': ['amc', 'avi'],
-                        'fps': 60},
-                   20: {'desc': 'Normal Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Normal Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Normal Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Normal Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Normal Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Normal Walk Backwards',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Normal Walk Backwards',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Walk on Toes',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Walk on Toes',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Walk Backwards on Toes',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Walk Backwards on Toes',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Quail, quick little steps',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Quail, quick little steps',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Range of Motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 137: {'desc': 'Stylized Motions',
-       'motions': {1: {'desc': 'Cat Coffee Mug',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Cat Pick Up',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Cat Wait',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Cat Walk',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Chicken Coffee Mug',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Chicken Pick Up',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Chicken Wait',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Chicken Walk',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Dinosaur Coffee Mug',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Dinosaur Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Dinosaur Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Dinosaur Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Drunk Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Drunk Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Drunk Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Drunk Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Gangly Teen Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Gangly Teen Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Gangly Teen Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Gangly Teen Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Graceful Lady Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Graceful Lady Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Graceful Lady Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Graceful Lady Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Motorcycle',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Normal Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Normal Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Normal Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Normal Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Old Man Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Old Man Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Old Man Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Old Man Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Range of Motion',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'Sexy Lady Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'Sexy Lady Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Sexy Lady Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'Sexy Lady Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'Strong Man Coffee Mug',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'Strong Man Pick Up',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'Strong Man Wait',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'Strong Man Walk',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 138: {'desc': 'Marching, Walking and Talking',
-       'motions': {1: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Marching',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Marching',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   43: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   44: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   45: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   46: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   47: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   48: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   49: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   50: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   51: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   52: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   53: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   54: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   55: {'desc': 'Story',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 139: {'desc': 'Action Walks, sneaking, wounded, looking around',
-       'motions': {1: {'desc': 'Looking Around',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Shifting Weight',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Looking Around',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Looking Around',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Pulling a Gun',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Poking Around On The Ground',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Poking Around On The Ground',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Poking Around On The Ground',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Ducking',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Run',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Run To Sneak',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Run in Circles',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Run in Circles',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Sneak Sideways',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Sneak Sideways',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Get Up From Ground',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Get Up From Ground',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Get Up From Ground Laying on Back',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Walk Wounded Leg',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Walk Wounded Leg',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Range Of Motion',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Walk Wounded Leg',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Walk Wounded Leg',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Walk Wounded Leg',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Giving Directions',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Looking Around',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Looking Around',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Walking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Sneaking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Walking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Sneaking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Sneaking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Sneaking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Sneaking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 140: {'desc': 'Getting Up From Ground',
-       'motions': {1: {'desc': 'Get Up Face Down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Get Up Face Down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Get Up Laying on Side',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Get Up Laying on Side',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Motorcycle',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Idle',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Idle',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Get Up From Ground Laying on Back',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Get Up From Ground Laying on Back',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120}}},
- 141: {'desc': 'General Subject Capture',
-       'motions': {1: {'desc': 'Run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Jump Distances',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Jump Sideways',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Jump Twist',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Walk Up and Over',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Steop On Walk Down',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Step Over',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Toss and Catch',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Throw and Catch',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Dance, Twist',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Stretch and Yawn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Punch and Kick',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Range of Motion',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Wave Hello',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Sit on Stool',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Peek a Boo',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Walk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Waiting',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Shrug',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'High Five',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Shake Hands',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Around the world High Five Low',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Walk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Curtsey',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Mope',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Slap Hands, Throw it Back',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Random Walk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Random Walk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Walk Backwards',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Walk Sideways, Cross Legs',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Walk Sideways, Foot to Foot',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Run',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 142: {'desc': 'Stylized Walks',
-       'motions': {1: {'desc': 'Childish',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Clumsy',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Clumsy',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Cool',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Depressed',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Elated',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Elderlyman',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Happy',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Joy',
-                       'files': ['c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Lavish',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Marching',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Painfulleftknee',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Relaxed',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Rushed',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Sad',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Scared',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Scared',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Sexy',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Shy',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Singing in the rain jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Singing in the rain jump',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Sneaky',
-                        'files': ['c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 143: {'desc': 'General Subject Capture',
-       'motions': {1: {'desc': 'Run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   2: {'desc': 'Run to Stop',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   3: {'desc': 'Start to Run',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   4: {'desc': 'Run Figure 8',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   5: {'desc': 'Jumping Distances',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   6: {'desc': 'Jumping Heights',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   7: {'desc': 'Jumping Sideways',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   8: {'desc': 'Jumping Twists',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   9: {'desc': 'Jumping Twists',
-                       'files': ['tvd', 'c3d', 'amc', 'avi'],
-                       'fps': 120},
-                   10: {'desc': 'Walk And Pick up Tool Box',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   11: {'desc': 'Walk And Pick up Box',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   12: {'desc': 'Walk And Pick up Toolbox',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   13: {'desc': 'Walk and Pick up Laundry Basket',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   14: {'desc': 'Walk And Step Over',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   15: {'desc': 'Walk And Step Over',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   16: {'desc': 'Walk And Step Over',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   17: {'desc': 'Walk Up Stairs And Over',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   18: {'desc': 'Sit Down And Get Up',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   19: {'desc': 'Sit On Stool And Get Up',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   20: {'desc': 'Catch And Throw',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   21: {'desc': 'Range Of Motion',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   22: {'desc': 'Catch And Throw Football',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   23: {'desc': 'Punching',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   24: {'desc': 'Kicking',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   25: {'desc': 'Waving',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   26: {'desc': 'Washing Window',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   27: {'desc': 'Washing Window',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   28: {'desc': 'Sweeping, Push Broom',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   29: {'desc': 'Pacing',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   30: {'desc': 'Stretch And Yawn',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   31: {'desc': 'Hopscotch',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   32: {'desc': 'Walk',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   33: {'desc': 'Peek A Boo',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   34: {'desc': 'Chicken Dance',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   35: {'desc': 'Macarena Dance',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   36: {'desc': 'Airplane',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   37: {'desc': 'Climb Up And Down Ladder',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   38: {'desc': 'Walk Digital 8',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   39: {'desc': 'Walk Backwards',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   40: {'desc': 'Walk Sideways',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   41: {'desc': 'Sneak',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120},
-                   42: {'desc': 'Run',
-                        'files': ['tvd', 'c3d', 'amc', 'avi'],
-                        'fps': 120}}},
- 144: {'desc': 'punching female',
-       'motions': {1: {'desc': 'Cartwheels',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   2: {'desc': 'Cartwheels001',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   3: {'desc': 'Figure8s',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   4: {'desc': 'Figure8s001',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   5: {'desc': 'Front_Kicking',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   6: {'desc': 'Front_Kicking001',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   7: {'desc': 'Left_Blocks',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   8: {'desc': 'Left_Blocks001',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   9: {'desc': 'Left_Front_Kicking',
-                       'files': ['c3d', 'amc'],
-                       'fps': 120},
-                   10: {'desc': 'Left_Front_Kicking001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   11: {'desc': 'Left_Lunges',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   12: {'desc': 'Left_Lunges001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   13: {'desc': 'Left_Punch_Sequence001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   14: {'desc': 'Left_Punch_Sequence002',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   15: {'desc': 'Left_Spin_reach001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   16: {'desc': 'Left_Spin_reach002',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   17: {'desc': 'Lunges',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   18: {'desc': 'Lunges001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   19: {'desc': 'motorcycle pose',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   20: {'desc': 'Punch_Sequence',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   21: {'desc': 'Punch_Sequence001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   22: {'desc': 'Reach_Left001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   23: {'desc': 'Reach_Left002',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   24: {'desc': 'Reach_Right',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   25: {'desc': 'Reach_Right001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   26: {'desc': 'Right_Blocks',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   27: {'desc': 'Right_Blocks001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   28: {'desc': 'Right_Spin_reach',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   29: {'desc': 'Right_Spin_reach001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   30: {'desc': 'Sun Salutation',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   31: {'desc': 'Sun Salutation001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   32: {'desc': 'Sun Salutation002',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   33: {'desc': 'Walking',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120},
-                   34: {'desc': 'Walking001',
-                        'files': ['c3d', 'amc'],
-                        'fps': 120}}}}
-
-# End of Mocap Library
-
-if __name__ == '__main__':
-    # The following is the code that compiled the data above.
-    # If you execute this file it should output to stdout the exact same code.
-
-    import re
-    import os
-    from pprint import pformat
-    from urllib.request import urlopen
-
-    subjects_re = re.compile(
-        r"(?ms)909090.*?Subject\ \#(?P<subjno>\d+)\s+(?P<desc>[^<]*).*?"
-        r"(?P<subjskel>http.*?asf).*?BGCOLOR(?P<motionBlock>.*?)/TR>\n")
-    motions_re = re.compile(
-        r"(?ms)<TD>(?P<motno>\d+)</TD><TD>(?P<desc>[^<].*?)"
-        r"</TD>(?P<urls>.*?)<TD>(?P<fps>\d+)</TD>")
-    urls_re = re.compile('(http.*?)(...)"')
-    myself_re = re.compile(r"(?ms)(.*# Carnegie.*?\n).*?(# End of.*$)")
-
-    subjects = {}
-    if not os.path.exists("search.html"):
-        src = urlopen(search_url)
-        data = src.read()
-        with open("search.html", 'wb') as out:
-            out.write(data)
-    for match in subjects_re.finditer(open("search.html", 'rt').read()):
-        d = match.groupdict()
-        sub = subjects.setdefault(int(d['subjno']), {})
-        sub['desc'] = d['desc'][1:-2]
-        assert(d['subjskel'] == skeleton_url.format(int(d['subjno'])))
-        sub['motions'] = {}
-        for m2 in motions_re.finditer(d['motionBlock']):
-            d2 = m2.groupdict()
-            mot = sub['motions'].setdefault(int(d2['motno']), {})
-            mot['desc'] = d2['desc'].strip()
-            mot['fps'] = int(d2['fps'])
-            for u in urls_re.finditer(d2['urls']):
-                murl = motion_url.format(int(d['subjno']), int(d2['motno']))
-                assert(u.group(1) == murl)
-                mot.setdefault('files', []).append(u.group(2))
-
-    m = myself_re.match(open(__file__).read())
-    print("{0}\nsubjects={1}\n\n{2}".format(
-            m.group(1), pformat(subjects), m.group(2)), end='')
diff --git a/release/scripts/addons_contrib/cursor_control/__init__.py b/release/scripts/addons_contrib/cursor_control/__init__.py
deleted file mode 100644
index 73a9737..0000000
--- a/release/scripts/addons_contrib/cursor_control/__init__.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- coding: utf-8 -*-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-
-# Blender Add-Ons menu registration (in User Prefs)
-bl_info = {
-    'name': 'Cursor Control',
-    'author': 'Morgan Mörtsell (Seminumerical)',
-    'version': (0, 7, 0),
-    'blender': (2, 5, 9),
-    'location': 'View3D > Properties > Cursor',
-    'description': 'Control the Cursor',
-    'warning': '', # used for warning icon and text in addons panel
-    'wiki_url': 'http://blenderpythonscripts.wordpress.com/',
-    'tracker_url': '',
-    'category': '3D View'}
-
-
-
-import bpy
-
-# To support reload properly, try to access a package var, if it's there, reload everything
-if "local_var" in locals():
-    import imp
-    imp.reload(data)
-    imp.reload(ui)
-    imp.reload(operators)
-    imp.reload(history)
-    imp.reload(memory)
-else:
-    from cursor_control import data
-    from cursor_control import ui
-    from cursor_control import operators
-    from cursor_control import history
-    from cursor_control import memory
-
-local_var = True
-
-def register():
-    bpy.utils.register_module(__name__)
-    # Register Cursor Control Structure
-    bpy.types.Scene.cursor_control = bpy.props.PointerProperty(type=data.CursorControlData, name="")
-    bpy.types.Scene.cursor_history = bpy.props.PointerProperty(type=history.CursorHistoryData, name="")
-    bpy.types.Scene.cursor_memory  = bpy.props.PointerProperty(type=memory.CursorMemoryData, name="")
-    # Register menu
-    bpy.types.VIEW3D_MT_snap.append(ui.menu_callback)
-
-def unregister():
-    # Register menu
-    bpy.types.VIEW3D_MT_snap.remove(ui.menu_callback)
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/cursor_control/data.py b/release/scripts/addons_contrib/cursor_control/data.py
deleted file mode 100644
index fcd82d1..0000000
--- a/release/scripts/addons_contrib/cursor_control/data.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# -*- coding: utf-8 -*-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-
-"""
-  TODO:
-
-      IDEAS:
-
-      LATER:
-
-      ISSUES:
-          Bugs:
-          Mites:
-
-      QUESTIONS:
-
-
-"""
-
-
-
-import bpy
-import bgl
-import math
-from mathutils import Vector, Matrix
-from mathutils import geometry
-from misc_utils import *
-from constants_utils import *
-from cursor_utils import *
-from ui_utils import *
-from geometry_utils import *
-
-
-PRECISION = 4
-
-
-class CursorControlData(bpy.types.PropertyGroup):
-    # Step length properties
-    stepLengthEnable = bpy.props.BoolProperty(name="Use step length",description="Use step length",default=0)
-    stepLengthMode = bpy.props.EnumProperty(items=[
-        ("Mode", "Mode", "Mode"),
-        ("Absolute", "Absolute", "Absolute"),
-        ("Proportional", "Proportional", "Proportional")],
-        default="Proportional")
-    stepLengthValue = bpy.props.FloatProperty(name="",precision=PRECISION,default=PHI)
-    # Property for linex result select...
-    linexChoice = bpy.props.IntProperty(name="",default=-1)
-    deltaVector = bpy.props.FloatVectorProperty(name="",precision=PRECISION,default=(1,0,0))
-
-    def hideLinexChoice(self):
-        self.linexChoice = -1
-
-    def cycleLinexCoice(self,limit):
-        qc = self.linexChoice + 1
-        if qc<0:
-            qc = 1
-        if qc>=limit:
-            qc = 0
-        self.linexChoice = qc
-  
-    def setCursor(self,v):
-        if self.stepLengthEnable:
-            c = CursorAccess.getCursor()
-            if((Vector(c)-Vector(v)).length>0):
-                if self.stepLengthMode=='Absolute':
-                    v = Vector(v)-Vector(c)
-                    v.normalize()
-                    v = v*self.stepLengthValue + Vector(c)
-                if self.stepLengthMode=='Proportional':
-                    v = (Vector(v)-Vector(c))*self.stepLengthValue + Vector(c)
-        CursorAccess.setCursor(Vector(v))
-        
-    def guiStates(self,context):
-        tvs = 0
-        tes = 0
-        tfs = 0
-        edit_mode = False
-        obj = context.active_object
-        if (context.mode == 'EDIT_MESH'):
-            if (obj and obj.type=='MESH' and obj.data):
-                tvs = obj.data.total_vert_sel
-
-                tes = obj.data.total_edge_sel
-                tfs = obj.data.total_face_sel
-                edit_mode = True
-        return (tvs, tes, tfs, edit_mode)
-
-    def invertDeltaVector(self):
-        self.deltaVector = Vector([0,0,0])-Vector(self.deltaVector)
-
-    def normalizeDeltaVector(self):
-        q = Vector(self.deltaVector)
-        q.normalize()
-        self.deltaVector = q
-
-    def addDeltaVectorToCursor(self):
-        c = CursorAccess.getCursor()
-        CursorAccess.setCursor(Vector(c)+Vector(self.deltaVector))
-
-    def subDeltaVectorToCursor(self):
-        c = CursorAccess.getCursor()
-        CursorAccess.setCursor(Vector(c)-Vector(self.deltaVector))
diff --git a/release/scripts/addons_contrib/cursor_control/history.py b/release/scripts/addons_contrib/cursor_control/history.py
deleted file mode 100644
index d720683..0000000
--- a/release/scripts/addons_contrib/cursor_control/history.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# -*- coding: utf-8 -*-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-
-"""
-  TODO:
-
-      IDEAS:
-
-      LATER:
-
-      ISSUES:
-          Bugs:
-              Seg-faults when unregistering addon...
-          Mites:
-            * History back button does not light up on first cursor move.
-              It does light up on the second, or when mouse enters the tool-area
-            * Switching between local and global view triggers new cursor position in history trace.
-            * Each consecutive click on the linex operator triggers new cursor position in history trace.
-                 (2011-01-16) Was not able to fix this because of some strange script behaviour
-                              while trying to clear linexChoice from addHistoryLocation
-
-      QUESTIONS:
-
-
-
-"""
-
-
-
-import bpy
-import bgl
-import math
-from mathutils import Vector, Matrix
-from mathutils import geometry
-from misc_utils import *
-from constants_utils import *
-from cursor_utils import *
-from ui_utils import *
-
-
-
-class CursorHistoryData(bpy.types.PropertyGroup):
-    # History tracker
-    historyDraw = bpy.props.BoolProperty(description="Draw history trace in 3D view",default=1)
-    historyDepth = 144
-    historyWindow = 12
-    historyPosition = [-1] # Integer must be in a list or else it can not be written to
-    historyLocation = []
-    #historySuppression = [False] # Boolean must be in a list or else it can not be written to
-
-    def addHistoryLocation(self, l):
-        if(self.historyPosition[0]==-1):
-            self.historyLocation.append(l.copy())
-            self.historyPosition[0]=0
-            return
-        if(l==self.historyLocation[self.historyPosition[0]]):
-            return
-        #if self.historySuppression[0]:
-            #self.historyPosition[0] = self.historyPosition[0] - 1
-        #else:
-            #self.hideLinexChoice()
-        while(len(self.historyLocation)>self.historyPosition[0]+1):
-            self.historyLocation.pop(self.historyPosition[0]+1)
-        #self.historySuppression[0] = False
-        self.historyLocation.append(l.copy())
-        if(len(self.historyLocation)>self.historyDepth):
-            self.historyLocation.pop(0)
-        self.historyPosition[0] = len(self.historyLocation)-1
-        #print (self.historyLocation)
-
-    #def enableHistorySuppression(self):
-        #self.historySuppression[0] = True
-
-    def previousLocation(self):
-        if(self.historyPosition[0]<=0):
-            return
-        self.historyPosition[0] = self.historyPosition[0] - 1
-        CursorAccess.setCursor(self.historyLocation[self.historyPosition[0]].copy())
-
-    def nextLocation(self):
-        if(self.historyPosition[0]<0):
-            return
-        if(self.historyPosition[0]+1==len(self.historyLocation)):
-            return
-        self.historyPosition[0] = self.historyPosition[0] + 1
-        CursorAccess.setCursor(self.historyLocation[self.historyPosition[0]].copy())
-
-
-
-class VIEW3D_OT_cursor_previous(bpy.types.Operator):
-    '''Previous cursor location'''
-    bl_idname = "view3d.cursor_previous"
-    bl_label = "Previous cursor location"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_history
-        cc.previousLocation()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_next(bpy.types.Operator):
-    '''Next cursor location'''
-    bl_idname = "view3d.cursor_next"
-    bl_label = "Next cursor location"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_history
-        cc.nextLocation()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_history_show(bpy.types.Operator):
-    '''Show cursor trace'''
-    bl_idname = "view3d.cursor_history_show"
-    bl_label = "Show cursor trace"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_history
-        cc.historyDraw = True
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_history_hide(bpy.types.Operator):
-    '''Hide cursor trace'''
-    bl_idname = "view3d.cursor_history_hide"
-    bl_label = "Hide cursor trace"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_history
-        cc.historyDraw = False
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_PT_cursor_history(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Cursor History"
-    bl_default_closed = True
-
-    @classmethod
-    def poll(self, context):
-        # Display in object or edit mode.
-        cc = context.scene.cursor_history
-        cc.addHistoryLocation(CursorAccess.getCursor())
-        if (context.area.type == 'VIEW_3D' and
-            (context.mode == 'EDIT_MESH'
-            or context.mode == 'OBJECT')):
-            return 1
-
-        return 0
-
-    def draw_header(self, context):
-        layout = self.layout
-        cc = context.scene.cursor_history
-        if cc.historyDraw:
-            GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_OFF', "view3d.cursor_history_hide", False)
-        else:
-            GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_ON' , "view3d.cursor_history_show", False)
-
-    def draw(self, context):
-        layout = self.layout
-        sce = context.scene
-        cc = context.scene.cursor_history
-
-        row = layout.row()
-        row.label("Navigation: ")
-        GUI.drawIconButton(cc.historyPosition[0]>0, row, 'PLAY_REVERSE', "view3d.cursor_previous")
-        #if(cc.historyPosition[0]<0):
-            #row.label("  --  ")
-        #else:
-            #row.label("  "+str(cc.historyPosition[0])+"  ")
-        GUI.drawIconButton(cc.historyPosition[0]<len(cc.historyLocation)-1, row, 'PLAY', "view3d.cursor_next")
-
-        row = layout.row()
-        col = row.column()
-        col.prop(CursorAccess.findSpace(), "cursor_location")
-
-  
-                
-
-class VIEW3D_PT_cursor_history_init(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Register callback"
-    bl_default_closed = True
-
-    initDone = False
-
-    @classmethod
-    def poll(cls, context):
-        if VIEW3D_PT_cursor_history_init.initDone:
-            return 0
-        print ("Cursor History draw-callback registration...")
-        sce = context.scene
-        if context.area.type == 'VIEW_3D':
-            for reg in context.area.regions:
-                if reg.type == 'WINDOW':
-                    # Register callback for SL-draw
-                    reg.callback_add(
-                        cursor_history_draw,
-                        (cls,context),
-                        'POST_PIXEL')
-                    VIEW3D_PT_cursor_history_init.initDone = True
-                    print ("Cursor History draw-callback registered")
-                    # Unregister to prevent double registration...
-                    # Started to fail after v2.57
-                    # bpy.types.unregister(VIEW3D_PT_cursor_history_init)
-        else:
-            print("View3D not found, cannot run operator")
-        return 0
-
-    def draw_header(self, context):
-        pass
-
-    def draw(self, context):
-        pass
-
-
-
-def cursor_history_draw(cls,context):
-    cc = context.scene.cursor_history
-
-    draw = 0
-    if hasattr(cc, "historyDraw"):
-        draw = cc.historyDraw
-
-    if(draw):
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glShadeModel(bgl.GL_FLAT)
-        alpha = 1-PHI_INV
-        # History Trace
-        if cc.historyPosition[0]<0:
-            return
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        ccc = 0
-        for iii in range(cc.historyWindow+1):
-            ix_rel = iii - int(cc.historyWindow / 2)
-            ix = cc.historyPosition[0] + ix_rel
-            if(ix<0 or ix>=len(cc.historyLocation)):
-                continue
-            ppp = region3d_get_2d_coordinates(context, cc.historyLocation[ix])
-            if(ix_rel<=0):
-                bgl.glColor4f(0, 0, 0, alpha)
-            else:
-                bgl.glColor4f(1, 0, 0, alpha)
-            bgl.glVertex2f(ppp[0], ppp[1])
-            ccc = ccc + 1
-        bgl.glEnd()
diff --git a/release/scripts/addons_contrib/cursor_control/memory.py b/release/scripts/addons_contrib/cursor_control/memory.py
deleted file mode 100644
index 9597a39..0000000
--- a/release/scripts/addons_contrib/cursor_control/memory.py
+++ /dev/null
@@ -1,307 +0,0 @@
-# -*- coding: utf-8 -*-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-
-"""
-  TODO:
-
-      IDEAS:
-	  Add/Subtract
-	  
-      LATER:
-
-      ISSUES:
-          Bugs:
-          Mites:
-	      CTRL-Z forces memory to world origin (0,0,0)... why??
-		  Happens only if undo reaches 'default world state'
-		  How to Reproduce:
-		      1. File->New
-		      2. Move 3D-cursor
-		      3. Set memory
-		      4. Move cube
-		      5. CTRL-Z
-
-      QUESTIONS:
-  
-  
-"""
-
-
-
-import bpy
-import bgl
-import math
-from mathutils import Vector, Matrix
-from mathutils import geometry
-from misc_utils import *
-from constants_utils import *
-from cursor_utils import *
-from ui_utils import *
-
-
-
-PRECISION = 4
-
-
-
-class CursorMemoryData(bpy.types.PropertyGroup):
-
-    savedLocationDraw = bpy.props.BoolProperty(description="Draw SL cursor in 3D view",default=1)
-    savedLocation = bpy.props.FloatVectorProperty(name="",description="Saved Location",precision=PRECISION)
-
-
-class VIEW3D_OT_cursor_memory_save(bpy.types.Operator):
-    '''Save cursor location'''
-    bl_idname = "view3d.cursor_memory_save"
-    bl_label = "Save cursor location"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_memory
-        cc.savedLocation = CursorAccess.getCursor()
-        CursorAccess.setCursor(cc.savedLocation)
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_memory_swap(bpy.types.Operator):
-    '''Swap cursor location'''
-    bl_idname = "view3d.cursor_memory_swap"
-    bl_label = "Swap cursor location"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        location = CursorAccess.getCursor().copy()
-        cc = context.scene.cursor_memory
-        CursorAccess.setCursor(cc.savedLocation)
-        cc.savedLocation = location
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_memory_recall(bpy.types.Operator):
-    '''Recall cursor location'''
-    bl_idname = "view3d.cursor_memory_recall"
-    bl_label = "Recall cursor location"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_memory
-        CursorAccess.setCursor(cc.savedLocation)
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_memory_show(bpy.types.Operator):
-    '''Show cursor memory'''
-    bl_idname = "view3d.cursor_memory_show"
-    bl_label = "Show cursor memory"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_memory
-        cc.savedLocationDraw = True
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_memory_hide(bpy.types.Operator):
-    '''Hide cursor memory'''
-    bl_idname = "view3d.cursor_memory_hide"
-    bl_label = "Hide cursor memory"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_memory
-        cc.savedLocationDraw = False
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_PT_cursor_memory(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Cursor Memory"
-    bl_default_closed = True
-
-    @classmethod
-    def poll(self, context):
-        # Display in object or edit mode.
-        if (context.area.type == 'VIEW_3D' and
-            (context.mode == 'EDIT_MESH'
-            or context.mode == 'OBJECT')):
-            return 1
-
-        return 0
-
-    def draw_header(self, context):
-        layout = self.layout
-        cc = context.scene.cursor_memory
-        if cc.savedLocationDraw:
-            GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_OFF', "view3d.cursor_memory_hide", False)
-        else:
-            GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_ON' , "view3d.cursor_memory_show", False)
-        #layout.prop(sce, "cursor_memory.savedLocationDraw")
-
-    def draw(self, context):
-        layout = self.layout
-        sce = context.scene
-        cc = context.scene.cursor_memory
-
-        row = layout.row()
-        col = row.column()
-        row2 = col.row()
-        GUI.drawIconButton(True, row2, 'FORWARD', "view3d.cursor_memory_save")
-        row2 = col.row()
-        GUI.drawIconButton(True, row2, 'FILE_REFRESH', "view3d.cursor_memory_swap")
-        row2 = col.row()
-        GUI.drawIconButton(True, row2, 'BACK'        , "view3d.cursor_memory_recall")
-        col = row.column()
-        col.prop(cc, "savedLocation")
-
-
-
-class VIEW3D_PT_cursor_memory_init(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Register callback"
-    bl_default_closed = True
-
-    initDone = False
-
-    @classmethod
-    def poll(cls, context):
-        if VIEW3D_PT_cursor_memory_init.initDone:
-            return 0
-        print ("Cursor Memory draw-callback registration...")
-        sce = context.scene
-        if context.area.type == 'VIEW_3D':
-            for reg in context.area.regions:
-                if reg.type == 'WINDOW':
-                    # Register callback for SL-draw
-                    reg.callback_add(
-                        cursor_memory_draw,
-                        (cls,context),
-                        'POST_PIXEL')
-                    VIEW3D_PT_cursor_memory_init.initDone = True
-                    print ("Cursor Memory draw-callback registered")
-                    # Unregister to prevent double registration...
-                    # Started to fail after v2.57
-                    # bpy.types.unregister(VIEW3D_PT_cursor_memory_init)
-        else:
-            print("View3D not found, cannot run operator")
-        return 0
-
-    def draw_header(self, context):
-        pass
-
-    def draw(self, context):
-        pass
-
-
-
-def cursor_memory_draw(cls,context):
-    cc = context.scene.cursor_memory
-
-    draw = 0
-    if hasattr(cc, "savedLocationDraw"):
-        draw = cc.savedLocationDraw
-
-    if(draw):
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glShadeModel(bgl.GL_FLAT)
-        p1 = Vector(cc.savedLocation)
-        location = region3d_get_2d_coordinates(context, p1)
-        alpha = 1-PHI_INV
-        # Circle
-        color = ([0.33, 0.33, 0.33],
-            [1, 1, 1],
-            [0.33, 0.33, 0.33],
-            [1, 1, 1],
-            [0.33, 0.33, 0.33],
-            [1, 1, 1],
-            [0.33, 0.33, 0.33],
-            [1, 1, 1],
-            [0.33, 0.33, 0.33],
-            [1, 1, 1],
-            [0.33, 0.33, 0.33],
-            [1, 1, 1],
-            [0.33, 0.33, 0.33],
-            [1, 1, 1])
-        offset = ([-4.480736161291701, -8.939966636005579],
-            [-0.158097634992133, -9.998750178787843],
-            [4.195854066857877, -9.077158622037636],
-            [7.718765411993642, -6.357724476147943],
-            [9.71288060283854, -2.379065025383466],
-            [9.783240669628, 2.070797430975971],
-            [7.915909938224691, 6.110513059466902],
-            [4.480736161291671, 8.939966636005593],
-            [0.15809763499209872, 9.998750178787843],
-            [-4.195854066857908, 9.077158622037622],
-            [-7.718765411993573, 6.357724476148025],
-            [-9.712880602838549, 2.379065025383433],
-            [-9.783240669627993, -2.070797430976005],
-            [-7.915909938224757, -6.110513059466818])
-        bgl.glBegin(bgl.GL_LINE_LOOP)
-        for i in range(14):
-            bgl.glColor4f(color[i][0], color[i][1], color[i][2], alpha)
-            bgl.glVertex2f(location[0]+offset[i][0], location[1]+offset[i][1])
-        bgl.glEnd()
-
-        # Crosshair
-        offset2 = 20
-        offset = 5
-        bgl.glColor4f(0, 0, 0, alpha)
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex2f(location[0]-offset2, location[1])
-        bgl.glVertex2f(location[0]- offset, location[1])
-        bgl.glEnd()
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex2f(location[0]+ offset, location[1])
-        bgl.glVertex2f(location[0]+offset2, location[1])
-        bgl.glEnd()
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex2f(location[0], location[1]-offset2)
-        bgl.glVertex2f(location[0], location[1]- offset)
-        bgl.glEnd()
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex2f(location[0], location[1]+ offset)
-        bgl.glVertex2f(location[0], location[1]+offset2)
-        bgl.glEnd()
-        
-       
diff --git a/release/scripts/addons_contrib/cursor_control/operators.py b/release/scripts/addons_contrib/cursor_control/operators.py
deleted file mode 100644
index 1d2bd7c..0000000
--- a/release/scripts/addons_contrib/cursor_control/operators.py
+++ /dev/null
@@ -1,895 +0,0 @@
-# -*- coding: utf-8 -*-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-
-"""
-  TODO:
-
-      IDEAS:
-
-      LATER:
-
-      ISSUES:
-          Bugs:
-          Mites:
-
-      QUESTIONS:
-
-
-"""
-
-
-
-import bpy
-import bgl
-import math
-from mathutils import Vector, Matrix
-from mathutils import geometry
-from misc_utils import *
-from constants_utils import *
-from cursor_utils import *
-from ui_utils import *
-from geometry_utils import *
-
-
-class VIEW3D_OT_cursor_to_origin(bpy.types.Operator):
-    '''Move to world origin'''
-    bl_idname = "view3d.cursor_to_origin"
-    bl_label = "Move to world origin"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        cc.setCursor([0,0,0])
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_to_active_object_center(bpy.types.Operator):
-    '''Move to active object origin'''
-    bl_idname = "view3d.cursor_to_active_object_center"
-    bl_label = "Move to active object origin"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        cc.setCursor(context.active_object.location)
-        return {'FINISHED'}
-
-
-
-#class VIEW3D_OT_cursor_to_nearest_object(bpy.types.Operator):
-    #'''Move to center of nearest object'''
-    #bl_idname = "view3d.cursor_to_nearest_object"
-    #bl_label = "Move to center of nearest object"
-    #bl_options = {'REGISTER'}
-
-    #def modal(self, context, event):
-        #return {'FINISHED'}
-
-    #def execute(self, context):
-        #cc.setCursor(context.active_object.location)
-        #return {'FINISHED'}
-
-
-
-#class VIEW3D_OT_cursor_to_selection_midpoint(bpy.types.Operator):
-    #'''Move to active objects median'''
-    #bl_idname = "view3d.cursor_to_selection_midpoint"
-    #bl_label = "Move to active objects median"
-    #bl_options = {'REGISTER'}
-
-    #def modal(self, context, event):
-        #return {'FINISHED'}
-
-    #def execute(self, context):
-        #location = Vector((0,0,0))
-        #n = 0
-        #for obj in context.selected_objects:
-            #location = location + obj.location
-            #n += 1
-        #if (n==0):
-            #return {'CANCELLED'}
-        #location = location / n
-        #cc.setCursor(location)
-        #return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_to_sl(bpy.types.Operator):
-    '''Move to saved location'''
-    bl_idname = "view3d.cursor_to_sl"
-    bl_label = "Move to saved location"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        if hasattr(context.scene, "cursor_memory"):
-            cm = context.scene.cursor_memory
-            cc.hideLinexChoice()
-            cc.setCursor(cm.savedLocation)
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_to_sl_mirror(bpy.types.Operator):
-    '''Mirror cursor around SL or selection'''
-    bl_idname = "view3d.cursor_to_sl_mirror"
-    bl_label = "Mirror cursor around SL or selection"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def mirror(self, cc, p):
-        v = p - Vector(CursorAccess.getCursor())
-        cc.setCursor(p + v)
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        obj = context.active_object
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        
-        if obj==None or obj.data.total_vert_sel==0:
-            if hasattr(context.scene, "cursor_memory"):
-                cm = context.scene.cursor_memory
-                self.mirror(cc, Vector(cm.savedLocation))
-            return {'FINISHED'}
-
-        mat = obj.matrix_world
-
-        if obj.data.total_vert_sel==1:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            self.mirror(cc, mat*Vector(sf[0].co))
-            return {'FINISHED'}
-
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-
-        if obj.data.total_vert_sel==2:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            p = G3.closestP2L(c, Vector(sf[0].co), Vector(sf[1].co))
-            self.mirror(cc, mat*p)
-            return {'FINISHED'}
-            
-        if obj.data.total_vert_sel==3:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            normal = (v1-v0).cross(v2-v0)
-            normal.normalize();            
-            p = G3.closestP2S(c, v0, normal)
-            self.mirror(cc, mat*p)
-            return {'FINISHED'}
-              
-        if obj.data.total_face_sel==1:
-            sf = [f for f in obj.data.faces if f.select == 1]
-            v0 = Vector(obj.data.vertices[sf[0].vertices[0]].co)
-            v1 = Vector(obj.data.vertices[sf[0].vertices[1]].co)
-            v2 = Vector(obj.data.vertices[sf[0].vertices[2]].co)
-            normal = (v1-v0).cross(v2-v0)
-            normal.normalize();            
-            p = G3.closestP2S(c, v0, normal)
-            self.mirror(cc, mat*p)
-            return {'FINISHED'}
-
-        return {'CANCELLED'}
-
-
-class VIEW3D_OT_cursor_to_vertex(bpy.types.Operator):
-    '''Move to closest vertex'''
-    bl_idname = "view3d.cursor_to_vertex"
-    bl_label = "Move to closest vertex"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = context.active_object
-        mat = obj.matrix_world
-        mati = mat.copy()
-        mati.invert()
-        vs = obj.data.vertices
-        c = mati*Vector(CursorAccess.getCursor())
-        v = None
-        d = -1
-        for vv in vs:
-            if not vv.select:
-                continue
-            w = Vector(vv.co)
-            dd = G3.distanceP2P(c, w)
-            if d<0 or dd<d:
-                v = w
-                d = dd
-        if v==None:
-            return
-        cc.setCursor(mat*v)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_line(bpy.types.Operator):
-    '''Move to closest point on line'''
-    bl_idname = "view3d.cursor_to_line"
-    bl_label = "Move to closest point on line"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mat = obj.matrix_world
-        if obj.data.total_vert_sel==2:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            p = CursorAccess.getCursor()
-            v0 = mat*sf[0].co
-            v1 = mat*sf[1].co
-            q = G3.closestP2L(p, v0, v1)
-            cc.setCursor(q)
-            return {'FINISHED'}
-        if obj.data.total_edge_sel<2:
-            return {'CANCELLED'}
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-        q = None
-        d = -1
-        for ee in obj.data.edges:
-            if not ee.select:
-                continue
-            e1 = Vector(obj.data.vertices[ee.vertices[0]].co)
-            e2 = Vector(obj.data.vertices[ee.vertices[1]].co)
-            qq = G3.closestP2L(c, e1, e2)
-            dd = G3.distanceP2P(c, qq)
-            if d<0 or dd<d:
-                q = qq
-                d = dd
-        if q==None:
-            return {'CANCELLED'}
-        cc.setCursor(mat*q)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_edge(bpy.types.Operator):
-    '''Move to closest point on edge'''
-    bl_idname = "view3d.cursor_to_edge"
-    bl_label = "Move to closest point on edge"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mat = obj.matrix_world
-        if obj.data.total_vert_sel==2:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            p = CursorAccess.getCursor()
-            v0 = mat*sf[0].co
-            v1 = mat*sf[1].co
-            q = G3.closestP2E(p, v0, v1)
-            cc.setCursor(q)
-            return {'FINISHED'}
-        if obj.data.total_edge_sel<2:
-            return {'CANCELLED'}
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-        q = None
-        d = -1
-        for ee in obj.data.edges:
-            if not ee.select:
-                continue
-            e1 = Vector(obj.data.vertices[ee.vertices[0]].co)
-            e2 = Vector(obj.data.vertices[ee.vertices[1]].co)
-            qq = G3.closestP2E(c, e1, e2)
-            dd = G3.distanceP2P(c, qq)
-            if d<0 or dd<d:
-                q = qq
-                d = dd
-        if q==None:
-            return {'CANCELLED'}
-        cc.setCursor(mat*q)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_plane(bpy.types.Operator):
-    '''Move to closest point on a plane'''
-    bl_idname = "view3d.cursor_to_plane"
-    bl_label = "Move to closest point on a plane"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mesh = obj.data.vertices
-        mat = obj.matrix_world
-        if obj.data.total_vert_sel==3:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            normal = (v1-v0).cross(v2-v0)
-            normal.normalize();
-            p = CursorAccess.getCursor()
-            n = mat*normal-obj.location
-            v = mat*v0
-            k = - (p-v).dot(n) / n.dot(n)
-            q = p+n*k
-            cc.setCursor(q)
-            return {'FINISHED'}
-
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-        q = None
-        d = -1
-        for ff in obj.data.faces:
-            if not ff.select:
-                continue
-            qq = G3.closestP2S(c, Vector(obj.data.vertices[ff.vertices[0]].co), ff.normal)
-            dd = G3.distanceP2P(c, qq)
-            if d<0 or dd<d:
-                q = qq
-                d = dd
-        if q==None:
-            return {'CANCELLED'}
-        cc.setCursor(mat*q)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_face(bpy.types.Operator):
-    '''Move to closest point on a face'''
-    bl_idname = "view3d.cursor_to_face"
-    bl_label = "Move to closest point on a face"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mesh = obj.data.vertices
-        mat = obj.matrix_world
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-        if obj.data.total_vert_sel==3:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            fv = [v0, v1, v2]
-            normal = (v1-v0).cross(v2-v0)
-            normal.normalize();
-            q = G3.closestP2F(c, fv, normal)
-            cc.setCursor(mat*q)
-            return {'FINISHED'}
-
-        #visual = True
-
-        qqq = []
-        q = None
-        d = -1
-        for ff in obj.data.faces:
-            if not ff.select:
-                continue
-            fv=[]
-            for vi in ff.vertices:
-                fv.append(Vector(obj.data.vertices[vi].co))
-            qq = G3.closestP2F(c, fv, ff.normal)
-            #if visual:
-                #qqq.append(qq)
-            dd = G3.distanceP2P(c, qq)
-            if d<0 or dd<d:
-                q = qq
-                d = dd
-        if q==None:
-            return {'CANCELLED'}
-
-        #if visual:
-            #ci = MeshEditor.addVertex(c)
-            #for qq in qqq:
-                #qqi = MeshEditor.addVertex(qq)
-                #MeshEditor.addEdge(ci, qqi)
-
-        cc.setCursor(mat*q)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_vertex_median(bpy.types.Operator):
-    '''Move to median of vertices'''
-    bl_idname = "view3d.cursor_to_vertex_median"
-    bl_label = "Move to median of vertices"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = context.active_object
-        mat = obj.matrix_world
-        vs = obj.data.vertices
-        selv = [v for v in vs if v.select == 1]
-        location = Vector((0,0,0))
-        for v in selv:
-            location = location + v.co
-        n = len(selv)
-        if (n==0):
-            return {'CANCELLED'}
-        location = location / n
-        cc.setCursor(mat*location)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_linex(bpy.types.Operator):
-    '''Alternate between closest encounter points of two lines'''
-    bl_idname = "view3d.cursor_to_linex"
-    bl_label = "Alternate between to closest encounter points of two lines"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        obj = bpy.context.active_object
-        mat = obj.matrix_world
-
-        se = [e for e in obj.data.edges if (e.select == 1)]
-        e1v1 = obj.data.vertices[se[0].vertices[0]].co
-        e1v2 = obj.data.vertices[se[0].vertices[1]].co
-        e2v1 = obj.data.vertices[se[1].vertices[0]].co
-        e2v2 = obj.data.vertices[se[1].vertices[1]].co
-
-        qq = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)
-
-        q = None
-        if len(qq)==0:
-            #print ("lx 0")
-            return {'CANCELLED'}
-
-        if len(qq)==1:
-            #print ("lx 1")
-            q = qq[0]
-        
-        if len(qq)==2:
-            cc = context.scene.cursor_control
-            cc.cycleLinexCoice(2)
-            q = qq[cc.linexChoice]
-
-        #q = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)[qc] * mat
-        #i2 = geometry.intersect_line_line (e2v1, e2v2, e1v1, e1v2)[0] * mat
-        cc.setCursor(mat*q)
-        return {'FINISHED'}
-
-
-class VIEW3D_OT_cursor_to_cylinderaxis(bpy.types.Operator):
-    '''Move to closest point on cylinder axis'''
-    bl_idname = "view3d.cursor_to_cylinderaxis"
-    bl_label = "Move to closest point on cylinder axis"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mesh = obj.data.vertices
-        mat = obj.matrix_world
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-
-        sf = [f for f in obj.data.vertices if f.select == 1]
-        v0 = Vector(sf[0].co)
-        v1 = Vector(sf[1].co)
-        v2 = Vector(sf[2].co)
-        fv = [v0, v1, v2]
-        q = G3.closestP2CylinderAxis(c, fv)
-        if(q==None):
-            return {'CANCELLED'}
-        cc.setCursor(mat*q)
-        return {'FINISHED'}     
-
-
-class VIEW3D_OT_cursor_to_spherecenter(bpy.types.Operator):
-    '''Move to center of cylinder or sphere'''
-    bl_idname = "view3d.cursor_to_spherecenter"
-    bl_label = "Move to center of cylinder or sphere"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mesh = obj.data.vertices
-        mat = obj.matrix_world
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-
-        if obj.data.total_vert_sel==3:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            fv = [v0, v1, v2]
-            q = G3.closestP2CylinderAxis(c, fv)
-            #q = G3.centerOfSphere(fv)
-            if(q==None):
-                return {'CANCELLED'}
-            cc.setCursor(mat*q)
-            return {'FINISHED'}
-        if obj.data.total_vert_sel==4:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            v3 = Vector(sf[3].co)
-            fv = [v0, v1, v2, v3]
-            q = G3.centerOfSphere(fv)
-            if(q==None):
-                return {'CANCELLED'}
-            cc.setCursor(mat*q)
-            return {'FINISHED'}
-        return {'CANCELLED'}
-
-
-
-class VIEW3D_OT_cursor_to_perimeter(bpy.types.Operator):
-    '''Move to perimeter of cylinder or sphere'''
-    bl_idname = "view3d.cursor_to_perimeter"
-    bl_label = "Move to perimeter of cylinder or sphere"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mesh = obj.data.vertices
-        mat = obj.matrix_world
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-
-        if obj.data.total_vert_sel==3:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            fv = [v0, v1, v2]
-            q = G3.closestP2Cylinder(c, fv)
-            if(q==None):
-                return {'CANCELLED'}
-            #q = G3.centerOfSphere(fv)
-            cc.setCursor(mat*q)
-            return {'FINISHED'}
-        if obj.data.total_vert_sel==4:
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            v2 = Vector(sf[2].co)
-            v3 = Vector(sf[3].co)
-            fv = [v0, v1, v2, v3]
-            q = G3.closestP2Sphere(c, fv)
-            if(q==None):
-                return {'CANCELLED'}
-            cc.setCursor(mat*q)
-            return {'FINISHED'}
-        return {'CANCELLED'}
-
-
-
-#class VIEW3D_OT_cursor_offset_from_radius(bpy.types.Operator):
-    #'''Calculate offset from radius'''
-    #bl_idname = "view3d.cursor_offset_from_radius"
-    #bl_label = "Calculate offset from radius"
-    #bl_options = {'REGISTER'}
-
-    #def modal(self, context, event):
-        #return {'FINISHED'}
-
-    #def execute(self, context):
-        #BlenderFake.forceUpdate()
-        #cc = context.scene.cursor_control
-        #cc.hideLinexChoice()
-        #obj = bpy.context.active_object
-        #mesh = obj.data.vertices
-        #mat = obj.matrix_world
-        #mati = mat.copy()
-        #mati.invert()
-        #c = mati*Vector(CursorAccess.getCursor())
-
-        #if obj.data.total_vert_sel==3:
-            #sf = [f for f in obj.data.vertices if f.select == 1]
-            #v0 = Vector(sf[0].co)
-            #v1 = Vector(sf[1].co)
-            #v2 = Vector(sf[2].co)
-            #fv = [v0, v1, v2]
-            #q = G3.centerOfSphere(fv)
-            #d = (v0-q).length
-            #cc.stepLengthValue = d
-            #return {'FINISHED'}
-        #if obj.data.total_vert_sel==4:
-            #sf = [f for f in obj.data.vertices if f.select == 1]
-            #v0 = Vector(sf[0].co)
-            #v1 = Vector(sf[1].co)
-            #v2 = Vector(sf[2].co)
-            #v3 = Vector(sf[3].co)
-            #fv = [v0, v1, v2, v3]
-            #q = G3.centerOfSphere(fv)
-            #d = (v0-q).length
-            #cc.stepLengthValue = d
-            #return {'FINISHED'}
-        #return {'CANCELLED'}
-
-
-
-class VIEW3D_OT_cursor_stepval_phinv(bpy.types.Operator):
-    '''Set step value to 1/Phi'''
-    bl_idname = "view3d.cursor_stepval_phinv"
-    bl_label = "Set step value to 1/Phi"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.stepLengthValue = PHI_INV
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_stepval_phi(bpy.types.Operator):
-    '''Set step value to Phi'''
-    bl_idname = "view3d.cursor_stepval_phi"
-    bl_label = "Set step value to Phi"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.stepLengthValue = PHI
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_stepval_phi2(bpy.types.Operator):
-    '''Set step value to Phi²'''
-    bl_idname = "view3d.cursor_stepval_phi2"
-    bl_label = "Set step value to Phi²"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.stepLengthValue = PHI_SQR
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_cursor_stepval_vvdist(bpy.types.Operator):
-    '''Set step value to distance vertex-vertex'''
-    bl_idname = "view3d.cursor_stepval_vvdist"
-    bl_label = "Set step value to distance vertex-vertex"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        cc.hideLinexChoice()
-        obj = bpy.context.active_object
-        mesh = obj.data.vertices
-        mat = obj.matrix_world
-        mati = mat.copy()
-        mati.invert()
-        c = mati*Vector(CursorAccess.getCursor())
-
-        sf = [f for f in obj.data.vertices if f.select == 1]
-        v0 = Vector(sf[0].co)
-        v1 = Vector(sf[1].co)
-        q = (v0-v1).length
-        cc.stepLengthValue = q
-
-        BlenderFake.forceRedraw()
-        return {'FINISHED'}
-
-
-
-
-class VIEW3D_OT_ccdelta_invert(bpy.types.Operator):
-    '''Invert delta vector'''
-    bl_idname = "view3d.ccdelta_invert"
-    bl_label = "Invert delta vector"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.invertDeltaVector()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_ccdelta_normalize(bpy.types.Operator):
-    '''Normalize delta vector'''
-    bl_idname = "view3d.ccdelta_normalize"
-    bl_label = "Normalize delta vector"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.normalizeDeltaVector()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_ccdelta_add(bpy.types.Operator):
-    '''Add delta vector to 3D cursor'''
-    bl_idname = "view3d.ccdelta_add"
-    bl_label = "Add delta vector to 3D cursor"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.addDeltaVectorToCursor()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_ccdelta_sub(bpy.types.Operator):
-    '''Subtract delta vector to 3D cursor'''
-    bl_idname = "view3d.ccdelta_sub"
-    bl_label = "Subtract delta vector to 3D cursor"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        cc = context.scene.cursor_control
-        cc.subDeltaVectorToCursor()
-        return {'FINISHED'}
-
-
-
-class VIEW3D_OT_ccdelta_vvdist(bpy.types.Operator):
-    '''Set delta vector from selection'''
-    bl_idname = "view3d.ccdelta_vvdist"
-    bl_label = "Set delta vector from selection"
-    bl_options = {'REGISTER'}
-
-    def modal(self, context, event):
-        return {'FINISHED'}
-
-    def execute(self, context):
-        BlenderFake.forceUpdate()
-        cc = context.scene.cursor_control
-        obj = bpy.context.active_object
-        if obj.data.total_vert_sel==0:
-            if hasattr(context.scene, "cursor_memory"):
-                cm = context.scene.cursor_memory
-                
-                mesh = obj.data.vertices
-                mat = obj.matrix_world
-                mati = mat.copy()
-                mati.invert()
-                c = mati*Vector(CursorAccess.getCursor())
-                
-                v0 = Vector(cm.savedLocation)
-                v1 = Vector(c)
-                cc.deltaVector = v0-v1
-                
-                
-        if obj.data.total_vert_sel==1:
-            mesh = obj.data.vertices
-            mat = obj.matrix_world
-            mati = mat.copy()
-            mati.invert()
-            c = mati*Vector(CursorAccess.getCursor())
-
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(c)
-            cc.deltaVector = v0-v1
-
-        if obj.data.total_vert_sel==2:
-            #mesh = obj.data.vertices
-            #mat = obj.matrix_world
-            #mati = mat.copy()
-            #mati.invert()
-            #c = mati*Vector(CursorAccess.getCursor())
-
-            sf = [f for f in obj.data.vertices if f.select == 1]
-            v0 = Vector(sf[0].co)
-            v1 = Vector(sf[1].co)
-            cc.deltaVector = v1-v0
-
-        return {'FINISHED'}
-
-
-
-
diff --git a/release/scripts/addons_contrib/cursor_control/ui.py b/release/scripts/addons_contrib/cursor_control/ui.py
deleted file mode 100644
index 340dc44..0000000
--- a/release/scripts/addons_contrib/cursor_control/ui.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# -*- coding: utf-8 -*-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-
-"""
-  TODO:
-
-      IDEAS:
-
-      LATER:
-
-      ISSUES:
-          Bugs:
-          Mites:
-
-      QUESTIONS:
-
-
-"""
-
-
-
-import bpy
-import bgl
-import math
-from mathutils import Vector, Matrix
-from mathutils import geometry
-from misc_utils import *
-from constants_utils import *
-from cursor_utils import *
-from ui_utils import *
-from geometry_utils import *
-
-
-class VIEW3D_PT_cursor(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Cursor Target"
-    bl_default_closed = True
-
-    @classmethod
-    def poll(self, context):
-        # Display in object or edit mode.
-        if (context.area.type == 'VIEW_3D' and
-            (context.mode == 'EDIT_MESH'
-            or context.mode == 'OBJECT')):
-            return 1
-
-        return 0
-
-    def draw_header(self, context):
-        pass
- 
-    def draw(self, context):
-        layout = self.layout
-        sce = context.scene
-
-        cc = context.scene.cursor_control
-        (tvs,tes,tfs,edit_mode) = cc.guiStates(context)
-
-        # Mesh data elements
-        if(edit_mode):
-            row = layout.row()
-            GUI.drawIconButton(tvs>=1          , row, 'STICKY_UVS_DISABLE', "view3d.cursor_to_vertex")
-            GUI.drawIconButton(tvs==2 or tes>=1, row, 'MESH_DATA'         , "view3d.cursor_to_line")
-            GUI.drawIconButton(tvs==2 or tes>=1, row, 'OUTLINER_OB_MESH'  , "view3d.cursor_to_edge")
-            GUI.drawIconButton(tvs==3 or tfs>=1, row, 'SNAP_FACE'         , "view3d.cursor_to_plane")
-            GUI.drawIconButton(tvs==3 or tfs>=1, row, 'FACESEL'           , "view3d.cursor_to_face")
-
-        # Geometry from mesh
-        if(edit_mode):
-            row = layout.row()
-            GUI.drawIconButton(tvs<=3 or tfs==1 , row, 'MOD_MIRROR'  , "view3d.cursor_to_sl_mirror")
-            GUI.drawIconButton(tes==2, row, 'PARTICLE_TIP', "view3d.cursor_to_linex")
-            GUI.drawIconButton(tvs>1 , row, 'ROTATECENTER', "view3d.cursor_to_vertex_median")  #EDITMODE_HLT
-            GUI.drawIconButton(tvs==3 or tvs==4, row, 'FORCE_FORCE'  , "view3d.cursor_to_spherecenter")
-            GUI.drawIconButton(tvs==3 or tvs==4, row, 'MATERIAL'  , "view3d.cursor_to_perimeter")
-
-        # Objects
-        #row = layout.row()
-
-        #GUI.drawIconButton(context.active_object!=None    , row, 'ROTATE'          , "view3d.cursor_to_active_object_center")
-        #GUI.drawIconButton(len(context.selected_objects)>1, row, 'ROTATECOLLECTION', "view3d.cursor_to_selection_midpoint")
-        #GUI.drawIconButton(len(context.selected_objects)>1, row, 'ROTATECENTER'    , "view3d.cursor_to_selection_midpoint")
-
-        # References World Origin, Object Origin, SL and CL
-        row = layout.row()
-        GUI.drawIconButton(True                       , row, 'WORLD_DATA'    , "view3d.cursor_to_origin")
-        GUI.drawIconButton(context.active_object!=None, row, 'ROTACTIVE'       , "view3d.cursor_to_active_object_center")
-        GUI.drawIconButton(True                       , row, 'CURSOR'        , "view3d.cursor_to_sl")
-        #GUI.drawIconButton(True, row, 'GRID'          , "view3d.cursor_sl_recall")
-        #GUI.drawIconButton(True, row, 'SNAP_INCREMENT', "view3d.cursor_sl_recall")
-        #row.label("("+str(cc.linexChoice)+")")
-        cc = context.scene.cursor_control
-        if cc.linexChoice>=0:
-            col = row.column()
-            col.enabled = False
-            col.prop(cc, "linexChoice")
-
-        # Limit/Clamping Properties
-        row = layout.row()
-        row.prop(cc, "stepLengthEnable")
-        if (cc.stepLengthEnable):
-            row = layout.row()
-            row.prop(cc, "stepLengthMode")
-            row.prop(cc, "stepLengthValue")
-            row = layout.row()
-            GUI.drawTextButton(True, row, '1/Phi'      , "view3d.cursor_stepval_phinv")
-            GUI.drawTextButton(True, row, 'Phi'      , "view3d.cursor_stepval_phi")
-            GUI.drawTextButton(True, row, 'Phi²'      , "view3d.cursor_stepval_phi2")
-            GUI.drawIconButton(tvs==2, row, 'EDGESEL'      , "view3d.cursor_stepval_vvdist")
-
-
-
-class VIEW3D_PT_ccDelta(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Cursor Delta"
-    bl_default_closed = True
-
-    @classmethod
-    def poll(self, context):
-        # Display in object or edit mode.
-        if (context.area.type == 'VIEW_3D' and
-            (context.mode == 'EDIT_MESH'
-            or context.mode == 'OBJECT')):
-            return 1
-
-        return 0
-
-    def draw_header(self, context):
-        pass
- 
-    def draw(self, context):
-        layout = self.layout
-        #sce = context.scene
-
-        cc = context.scene.cursor_control
-        (tvs,tes,tfs,edit_mode) = cc.guiStates(context)
-        
-        row = layout.row()
-        col = row.column();
-        GUI.drawIconButton(True , col, 'FF'  , "view3d.ccdelta_add")
-        GUI.drawIconButton(True , col, 'REW'  , "view3d.ccdelta_sub")
-        GUI.drawIconButton(tvs<=2 , col, 'FORWARD'  , "view3d.ccdelta_vvdist")
-        
-        col = row.column();
-        col.prop(cc, "deltaVector")
-
-        col = row.column();
-        GUI.drawIconButton(True , col, 'MOD_MIRROR'  , "view3d.ccdelta_invert")
-        GUI.drawIconButton(True , col, 'SNAP_NORMAL'  , "view3d.ccdelta_normalize")
-
-
-  
-class CursorControlMenu(bpy.types.Menu):
-    """menu"""
-    bl_idname = "cursor_control_calls"
-    bl_label = "Cursor Control"
-    
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        #layout.operator(VIEW3D_OT_cursor_to_vertex.bl_idname, text = "Vertex")
-        #layout.operator(VIEW3D_OT_cursor_to_line.bl_idname, text = "Line")
-        #obj = context.active_object
-        #if (context.mode == 'EDIT_MESH'):
-            #if (obj and obj.type=='MESH' and obj.data):
-        cc = context.scene.cursor_control
-        (tvs,tes,tfs,edit_mode) = cc.guiStates(context)
-        
-        if(edit_mode):
-            if(tvs>=1):
-                layout.operator(VIEW3D_OT_cursor_to_vertex.bl_idname, text = "Closest Vertex")
-            if(tvs==2 or tes>=1):
-                layout.operator(VIEW3D_OT_cursor_to_line.bl_idname, text = "Closest Line")
-            if(tvs==2 or tes>=1):
-                layout.operator(VIEW3D_OT_cursor_to_edge.bl_idname, text = "Closest Edge")
-            if(tvs==3 or tfs>=1):
-                layout.operator(VIEW3D_OT_cursor_to_plane.bl_idname, text = "Closest Plane")
-            if(tvs==3 or tfs>=1):
-                layout.operator(VIEW3D_OT_cursor_to_face.bl_idname, text = "Closest Face")
-
-        if(edit_mode):
-            if(tvs<=3 or tfs==1):
-                layout.operator(VIEW3D_OT_cursor_to_sl_mirror.bl_idname, text = "Mirror")
-            if(tes==2):
-                layout.operator(VIEW3D_OT_cursor_to_linex.bl_idname, text = "Line Intersection")
-            if(tvs>1):
-                layout.operator(VIEW3D_OT_cursor_to_vertex_median.bl_idname, text = "Vertex Median")
-            if(tvs==3 or tvs==4):
-                layout.operator(VIEW3D_OT_cursor_to_spherecenter.bl_idname, text = "Circle Center")
-            if(tvs==3 or tvs==4):
-                layout.operator(VIEW3D_OT_cursor_to_perimeter.bl_idname, text = "Circle Perimeter")
-        
-        layout.operator(VIEW3D_OT_cursor_to_origin.bl_idname, text = "World Origin")
-        layout.operator(VIEW3D_OT_cursor_to_active_object_center.bl_idname, text = "Active Object")
-        layout.operator(VIEW3D_OT_cursor_to_sl.bl_idname, text = "Cursor Memory")
-
-
-
-def menu_callback(self, context):
-    #obj = context.active_object
-    #if (context.mode == 'EDIT_MESH'):
-        #if (obj and obj.type=='MESH' and obj.data):
-    self.layout.menu(CursorControlMenu.bl_idname, icon="PLUGIN")
-
diff --git a/release/scripts/addons_contrib/curve_tools.py b/release/scripts/addons_contrib/curve_tools.py
deleted file mode 100644
index 23c02e5..0000000
--- a/release/scripts/addons_contrib/curve_tools.py
+++ /dev/null
@@ -1,1354 +0,0 @@
-# #####BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# #####END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Curve Tools",
-    "author": "Zak",
-    "version": (0, 1, 5),
-    "blender": (2, 5, 9),
-    "location": "Properties > Object data",
-    "description": "Creates driven Lofts or Birails between curves",
-    "warning": "may be buggy or incomplete",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Curve/Curve_Tools",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=27720",
-    "category": "Add Curve"}
-
-### UPDATES
-#1.5
-
-#-Fixed birail function
-#-Added Curve Snap to W key specials menu.
-#-Removed some functions that arent needed and wrapped into the operators.
-#-nurbs with weights for loft and birail
-#-Panel Moved to view 3d tools
-#-inserted TODO comments
-#-tried to implement live tension and bias for Hermite interpolation by driving the mesh but
-#i dont know why, the code is executed all the time even if you dont change the variables.
-#-snap to curves affects all the curves on the scene
-#-i was able to preserve handle types when split or subdivide
-
-
-#1.4
-#-incorporate curve snap
-#assign a copy transform to helper
-#-nurbs implemented (in progress)
-
-import bpy
-from mathutils import *
-from bpy.props import *
-
-print("----------")
-
-
-### PROPERTIES
-class sprops(bpy.types.PropertyGroup):
-    pass
-
-
-bpy.utils.register_class(sprops)
-
-#bpy.selection will store objects names in the order they were selected
-bpy.selection=[]
-
-
-#dodriver a simple checker to chosse whether  you want a driven mesh or not.
-bpy.types.Scene.dodriver = BoolProperty(name = "dodriver",                                      default=False)
-
-#interpolation types
-myitems = (('0','Linear', ''),('1','Cubic',''),('2','Catmull',''), ('3','Hermite',''))
-bpy.types.Scene.intype = EnumProperty(name="intype", items = myitems, default='3')
-
-#number of steps and spans to be created
-bpy.types.Scene.steps = IntProperty(name="steps", default=12, min=2)
-bpy.types.Scene.spans = IntProperty(name="spans", default=12, min=2)
-
-#parameters for Hermite interpolation
-bpy.types.Scene.tension = FloatProperty(name = "tension", min=0.0, default=0.0)
-bpy.types.Scene.bias = FloatProperty(name = "bias", min=0.0, default = 0.5)
-
-#proportional birail
-bpy.types.Scene.proportional = BoolProperty(name="proportional", default=False)
-
-#this stores the result of calculating the curve length
-bpy.types.Scene.clen = FloatProperty(name="clen", default=0.0, precision=5)
-
-#minimun distance for merge curve tool
-bpy.types.Scene.limit = FloatProperty(name="limit", default=0.1, precision=3)
-
-
-### SELECT BY ORDER BLOCK
-
-#i dont know what to do with this. Im not using it yet.
-def selected_points(curve):
-
-    selp = []
-    for spl in curve.splines:
-        if spl.type=="BEZIER":
-            points = spl.bezier_points
-            for p in points:
-                if p.select_control_point:
-                    selp.append(p)
-
-        elif spl.type=="NURBS":
-            points = spl.points
-            for p in points:
-                if p.select:
-                    selp.append(p)
-    return selp
-
-#writes bpy.selection when a new object is selected or deselected
-#it compares bpy.selection with bpy.context.selected_objects
-
-def select():
-
-    #print(bpy.context.mode)
-    if bpy.context.mode=="OBJECT":
-        obj = bpy.context.object
-        sel = len(bpy.context.selected_objects)
-
-        if sel==0:
-            bpy.selection=[]
-        else:
-            if sel==1:
-                bpy.selection=[]
-                bpy.selection.append(obj)
-            elif sel>len(bpy.selection):
-                for sobj in bpy.context.selected_objects:
-                    if (sobj in bpy.selection)==False:
-                        bpy.selection.append(sobj)
-
-            elif sel<len(bpy.selection):
-                for it in bpy.selection:
-                    if (it in bpy.context.selected_objects)==False:
-                        bpy.selection.remove(it)
-
-    #on edit mode doesnt work well
-
-
-#executes selection by order at 3d view
-class Selection(bpy.types.Header):
-    bl_label = "Selection"
-    bl_space_type = "VIEW_3D"
-
-    def __init__(self):
-        #print("hey")
-        select()
-
-    def draw(self, context):
-        layout = self.layout
-        row = layout.row()
-        row.label("Sel: "+str(len(bpy.selection)))
-
-### GENERAL CURVE FUNCTIONS
-
-#distance between 2 points
-def dist(p1, p2):
-    return (p2-p1).magnitude
-
-#sets cursors position for debugging porpuses
-def cursor(pos):
-    bpy.context.scene.cursor_location = pos
-
-#cuadratic bezier value
-def quad(p, t):
-    return p[0]*(1.0-t)**2.0 + 2.0*t*p[1]*(1.0-t) + p[2]*t**2.0
-
-#cubic bezier value
-def cubic(p, t):
-    return p[0]*(1.0-t)**3.0 + 3.0*p[1]*t*(1.0-t)**2.0 + 3.0*p[2]*(t**2.0)*(1.0-t) + p[3]*t**3.0
-
-#gets a bezier segment's control points on global coordinates
-def getbezpoints(spl, mt, seg=0):
-    points = spl.bezier_points
-    p0 = mt * points[seg].co
-    p1 = mt * points[seg].handle_right
-    p2 = mt * points[seg+1].handle_left
-    p3 = mt * points[seg+1].co
-    return p0, p1, p2, p3
-
-#gets nurbs polygon control points on global coordinates
-def getnurbspoints(spl, mw):
-    pts = []
-    ws = []
-    for p in spl.points:
-        v = Vector(p.co[0:3])*mw
-        pts.append(v)
-        ws.append(p.weight)
-    return pts , ws
-
-#calcs a nurbs knot vector
-def knots(n, order, type=0):#0 uniform 1 endpoints 2 bezier
-
-    kv = []
-
-    t = n+order
-    if type==0:
-        for i in range(0, t):
-            kv.append(1.0*i)
-
-    elif type==1:
-        k=0.0
-        for i in range(1, t+1):
-            kv.append(k)
-            if i>=order and i<=n:
-                k+=1.0
-    elif type==2:
-        if order==4:
-            k=0.34
-            for a in range(0,t):
-                if a>=order and a<=n: k+=0.5
-                kv.append(floor(k))
-                k+=1.0/3.0
-
-        elif order==3:
-            k=0.6
-            for a in range(0, t):
-                if a >=order and a<=n: k+=0.5
-                kv.append(floor(k))
-
-    ##normalize the knot vector
-    for i in range(0, len(kv)):
-        kv[i]=kv[i]/kv[-1]
-
-    return kv
-
-#nurbs curve evaluation
-def C(t, order, points, weights, knots):
-    #c = Point([0,0,0])
-    c = Vector()
-    rational = 0
-    i = 0
-    while i < len(points):
-        b = B(i, order, t, knots)
-        p = points[i] * (b * weights[i])
-        c = c + p
-        rational = rational + b*weights[i]
-        i = i + 1
-
-    return c * (1.0/rational)
-
-#nurbs basis function
-def B(i,k,t,knots):
-    ret = 0
-    if k>0:
-        n1 = (t-knots[i])*B(i,k-1,t,knots)
-        d1 = knots[i+k] - knots[i]
-        n2 = (knots[i+k+1] - t) * B(i+1,k-1,t,knots)
-        d2 = knots[i+k+1] - knots[i+1]
-        if d1 > 0.0001 or d1 < -0.0001:
-            a = n1 / d1
-        else:
-            a = 0
-        if d2 > 0.0001 or d2 < -0.0001:
-            b = n2 / d2
-        else:
-            b = 0
-        ret = a + b
-        #print "B i = %d, k = %d, ret = %g, a = %g, b = %g\n"%(i,k,ret,a,b)
-    else:
-        if knots[i] <= t and t <= knots[i+1]:
-            ret = 1
-        else:
-            ret = 0
-    return ret
-
-#calculates a global parameter t along all control points
-#t=0 begining of the curve
-#t=1 ending of the curve
-
-def calct(obj, t):
-
-    spl=None
-    mw = obj.matrix_world
-    if obj.data.splines.active==None:
-        if len(obj.data.splines)>0:
-            spl=obj.data.splines[0]
-    else:
-        spl = obj.data.splines.active
-
-    if spl==None:
-        return False
-
-    if spl.type=="BEZIER":
-        points = spl.bezier_points
-        nsegs = len(points)-1
-
-        d = 1.0/nsegs
-        seg = int(t/d)
-        t1 = t/d - int(t/d)
-
-        if t==1:
-            seg-=1
-            t1 = 1.0
-
-        p = getbezpoints(spl,mw, seg)
-
-        coord = cubic(p, t1)
-
-        return coord
-
-    elif spl.type=="NURBS":
-        data = getnurbspoints(spl, mw)
-        pts = data[0]
-        ws = data[1]
-        order = spl.order_u
-        n = len(pts)
-        ctype = spl.use_endpoint_u
-        kv = knots(n, order, ctype)
-
-        coord = C(t, order-1, pts, ws, kv)
-
-        return coord
-
-#length of the curve
-def arclength(objs):
-    length = 0.0
-
-    for obj in objs:
-        if obj.type=="CURVE":
-            prec = 1000 #precision
-            inc = 1/prec #increments
-
-            ### TODO: set a custom precision value depending the number of curve points
-            #that way it can gain on accuracy in less operations.
-
-            #subdivide the curve in 1000 lines and sum its magnitudes
-            for i in range(0, prec):
-                ti = i*inc
-                tf = (i+1)*inc
-                a = calct(obj, ti)
-                b = calct(obj, tf)
-                r = (b-a).magnitude
-                length+=r
-
-    return length
-
-
-class ArcLengthOperator(bpy.types.Operator):
-
-    bl_idname = "curve.arc_length_operator"
-    bl_label = "Measures the length of a curve"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        objs = context.selected_objects
-        context.scene.clen = arclength(objs)
-        return {'FINISHED'}
-
-### LOFT INTERPOLATIONS
-
-#objs = selected objects
-#i = object index
-#t = parameter along u direction
-#tr = parameter along v direction
-
-#linear
-def intl(objs, i, t, tr):
-    p1 = calct(objs[i],t)
-    p2 = calct(objs[i+1], t)
-
-    r = p1 + (p2 - p1)*tr
-
-    return r
-
-#tipo = interpolation type
-#tension and bias are for hermite interpolation
-#they can be changed to obtain different lofts.
-
-#cubic
-def intc(objs, i, t, tr, tipo=3, tension=0.0, bias=0.0):
-
-    ncurves =len(objs)
-
-    #if 2 curves go to linear interpolation regardless the one you choose
-    if ncurves<3:
-        return intl(objs, i, t, tr)
-    else:
-
-        #calculates the points to be interpolated on each curve
-        if i==0:
-            p0 = calct(objs[i], t)
-            p1 = p0
-            p2 = calct(objs[i+1], t)
-            p3 = calct(objs[i+2], t)
-        else:
-            if ncurves-2 == i:
-                p0 = calct(objs[i-1], t)
-                p1 = calct(objs[i], t)
-                p2 = calct(objs[i+1], t)
-                p3 = p2
-            else:
-                p0 = calct(objs[i-1], t)
-                p1 = calct(objs[i], t)
-                p2 = calct(objs[i+1], t)
-                p3 = calct(objs[i+2], t)
-
-
-    #calculates the interpolation between those points
-    #i used methods from this page: http://paulbourke.net/miscellaneous/interpolation/
-
-    if tipo==0:
-        #linear
-        return intl(objs, i, t, tr)
-    elif tipo == 1:
-        #natural cubic
-        t2 = tr*tr
-        a0 = p3-p2-p0+p1
-        a1 = p0-p1-a0
-        a2 = p2-p0
-        a3 = p1
-        return a0*tr*t2 + a1*t2+a2*tr+a3
-    elif tipo == 2:
-        #catmull it seems to be working. ill leave it for now.
-        t2 = tr*tr
-        a0 = -0.5*p0 +1.5*p1 -1.5*p2 +0.5*p3
-        a1 = p0 - 2.5*p1 + 2*p2 -0.5*p3
-        a2 = -0.5*p0 + 0.5 *p2
-        a3 = p1
-        return a0*tr*tr + a1*t2+a2*tr+a3
-
-    elif tipo == 3:
-        #hermite
-        tr2 = tr*tr
-        tr3 = tr2*tr
-        m0 = (p1-p0)*(1+bias)*(1-tension)/2
-        m0+= (p2-p1)*(1-bias)*(1-tension)/2
-        m1 = (p2-p1)*(1+bias)*(1-tension)/2
-        m1+= (p3-p2)*(1-bias)*(1-tension)/2
-        a0 = 2*tr3 - 3*tr2 + 1
-        a1 = tr3 - 2 * tr2+ tr
-        a2 = tr3 - tr2
-        a3 = -2*tr3 + 3*tr2
-
-        return a0*p1+a1*m0+a2*m1+a3*p2
-
-
-#handles loft driver expression
-#example: loftdriver('Loft', 'BezierCurve;BezierCurve.001;BezierCurve.002', 3)
-
-#name: its the name of the mesh to be driven
-#objs: the  names of the curves that drives the mesh
-#3 interpolation type
-
-def loftdriver(name, objs, intype):
-    #print("ejecutando "+name)
-    intype = int(intype)
-
-    tension = 0.0
-    bias = 0.5
-    #if the loft object still exists proceed normal
-    try:
-        resobj = bpy.data.objects[name]
-        spans = resobj["spans"]
-        steps = resobj["steps"]
-        if intype==3: #hermite
-            tension = resobj['tension']
-            bias = resobj['bias']
-
-    #if not delete the driver
-    except:
-        curve = bpy.context.object
-        for it in curve.keys():
-            if it == "driver":
-                curve.driver_remove('["driver"]')
-        return False
-
-    objs = objs.split(";")
-    #objs = objs[0:-1]
-
-
-    #retrieves the curves from the objs string
-    for i, l in enumerate(objs):
-        objs[i] = bpy.data.objects[l]
-
-
-
-    #calcs the new vertices coordinates if we change the curves.
-    vxs = loft(objs, steps, spans, intype, tension, bias)
-
-    #apply the new cordinates to the loft object
-    me = resobj.data
-
-    for i in range(0, len(me.vertices)):
-        me.vertices[i].co = vxs[i]
-    me.update()
-    return spans
-
-#NOTES:
-#loftdriver function will fail or produce weird results if:
-#the user changes resobj["spans"] or resobj["steps"]
-#if we delete any vertex from the loft object
-
-### TODO:check if thats the case to remove the drivers
-
-#creates the drivers expressions for each curve
-def createloftdriver(objs, res, intype):
-
-    line = ""
-    for obj in objs:
-        line+=obj.name+";"
-    line=line[0:-1]
-    name = res.name
-
-    interp = str(intype)
-
-    for obj in objs:
-        obj["driver"] = 1.0
-
-        obj.driver_add('["driver"]')
-        obj.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")"
-
-
-    ### creating this driver will execute loft all the time without reason,
-    #and if i cant drive the mesh i cannot implement live tension and bias
-
-#   res['driver'] = 1.0
-#   if res.animation_data==None:
-#       res.animation_data_create()
-#   res.driver_add('["driver"]')
-#   res.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")"
-
-#calculates the vertices position of the loft object
-def loft(objs, steps, spans, interpolation=1, tension=0.0, bias=0.5):
-    verts=[]
-
-    for i in range(0, len(objs)):
-
-        for j in range(0,steps+1):
-            t = 1.0*j/steps
-            verts.append(calct(objs[i], t))
-
-        temp2=[]
-        if i<len(objs)-1:
-            for l in range(1, spans):
-                tr = 1.0*l/spans
-                for k in range(0, steps+1):
-                    t=1.0*k/steps
-                    if interpolation:
-                        pos = intc(objs, i, t, tr, interpolation, tension, bias)
-                    else:
-                        pos = intl(objs,i, t, tr)
-
-                    temp2.append(pos)
-            verts.extend(temp2)
-    return verts
-
-
-#loft operator
-
-class LoftOperator(bpy.types.Operator):
-    '''Tooltip'''
-    bl_idname = "mesh.loft_operator"
-    bl_label = "Loft between bezier curves"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        #retrieves the curves in the order they were selected
-        objs = bpy.selection
-
-        spans = context.scene.spans
-        steps = context.scene.steps
-
-        intype = int(context.scene.intype)
-
-        verts = loft(objs, steps, spans, intype)
-
-        nfaces = steps*spans*(len(objs)-1)
-        faces=[]
-        for i in range(0, nfaces):
-            d = int(i/steps)
-            f = [i+d,i+d+1, i+d+steps+2, i+d+steps+1]
-            #inverts normals
-            #f = [i+d,i+d+steps+1, i+d+steps+2, i+d+1]
-            faces.append(f)
-
-
-        me = bpy.data.meshes.new("Loft")
-        me.from_pydata(verts,[], faces)
-        me.update()
-        newobj = bpy.data.objects.new("Loft", me)
-        #newobj.data = me
-        scn = context.scene
-        scn.objects.link(newobj)
-        scn.objects.active = newobj
-        newobj.select = True
-        bpy.ops.object.shade_smooth()
-
-        #the object stores its own steps and spans
-        #this way the driver will know how to deform the mesh
-        newobj["steps"] = steps
-        newobj["spans"] = spans
-
-        if intype==3:
-            newobj['tension'] = context.scene.tension
-            newobj['bias'] = context.scene.bias
-
-
-        if context.scene.dodriver:
-            createloftdriver(objs, newobj, intype)
-
-        return {'FINISHED'}
-
-class UpdateFix(bpy.types.Operator):
-    '''Tooltip'''
-    bl_idname = "mesh.update_fix"
-    bl_label = "Update fix"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        #print("------------")
-#       for it in bpy.app.driver_namespace:
-#           print(it)
-        bpy.app.driver_namespace['loftdriver'] = loftdriver
-        bpy.app.driver_namespace['birail1driver'] = birail1driver
-        for obj in context.scene.objects:
-            if obj.type=="CURVE" and obj.animation_data!=None and len(obj.animation_data.drivers)>0:
-                for drv in obj.animation_data.drivers:
-                    if drv.data_path=='["driver"]':
-                        cad = drv.driver.expression
-                        drv.driver.expression = ""
-                        drv.driver.expression = cad
-
-        return {'FINISHED'}
-
-
-#derives a curve at a given parameter
-def deriv(curve, t, unit=False):
-
-    a = t + 0.001
-    if t==1: a=t-0.001
-
-    pos = calct(curve, t)
-    der = (pos-calct(curve, a))/(t-a)
-    if unit:
-        der = der/der.magnitude
-    return der
-
-### BIRAIL1 BLOCK
-
-
-#see explanation video about the construction
-#http://vimeo.com/25455967
-
-#calculates birail vertices
-
-### TODO: when the 3 curves are coplanar it should fail, cause the cross product. check that
-def birail1(objs, steps, spans, proportional):
-
-    profile=objs[0]
-    ### TODO: identify which path is left or right
-    path1 = objs[1]
-    path2 = objs[2]
-
-    trans = []
-
-    r0 = [calct(path1,0), calct(path2, 0)]
-    r0mag = (r0[1]-r0[0]).magnitude
-
-    for i in range(0, steps):
-        u = i/(steps-1)
-        appr0 = r0[0]+(r0[1]-r0[0])*u
-        trans.append(calct(profile, u)-appr0)
-
-    der10 = deriv(path1, 0)
-    der20 = deriv(path2, 0)
-
-    verts = []
-
-    mult = 1.0
-
-    for i in range(0, spans):
-        v = i/(spans-1)
-        r = [calct(path1, v),calct(path2, v)]
-        rmag = (r[1]-r[0]).magnitude
-
-        der1 = deriv(path1, v)
-        der2 = deriv(path2, v)
-
-        angle1 = der10.angle(der1)
-        angle2 = der20.angle(der2)
-
-        #if angle1!=0.0 and angle2!=0: we can avoid some operations by doing this check but im lazy
-        cr1 = der1.cross(der10)
-        rot1 = Matrix().Rotation(-angle1, 3, cr1)
-
-        cr2 = der2.cross(der20)
-        rot2 = Matrix().Rotation(-angle2, 3, cr2)
-
-        if proportional:
-            mult = rmag/r0mag
-
-        for j in range(0, steps):
-            u = j/(steps-1)
-
-            app = r[0]+(r[1]-r[0])*u
-
-            newtr1 = trans[j].copy()
-            newtr1.rotate(rot1)
-
-            newtr2 = trans[j].copy()
-            newtr2.rotate(rot2)
-
-            r1 = (newtr1-trans[j])*(1-u)
-            r2 = (newtr2-trans[j])*(u)
-
-            res = r1+r2+app+mult*trans[j]
-
-            verts.append(res)
-
-    return verts
-
-
-#same as loft driver
-### TODO check if it is registered
-def birail1driver(name, objs):
-
-    objs = objs.split(";")
-    #objs = objs[0:-1]
-
-    for i, l in enumerate(objs):
-        objs[i] = bpy.data.objects[l]
-
-    try:
-        resobj = bpy.data.objects[name]
-        spans = resobj["spans"]
-        steps = resobj["steps"]
-        prop = resobj["prop"]
-
-    except:
-        curve = bpy.context.object
-        curve.driver_remove('["driver"]')
-        return False
-
-    vxs = birail1(objs, steps, spans, prop)
-
-    me = resobj.data
-
-    for i in range(0, len(me.vertices)):
-        me.vertices[i].co = vxs[i]
-    me.update()
-    return spans
-
-def createbirail1driver(objs, res):
-
-    line = ""
-    for obj in objs:
-        line+=obj.name+";"
-    line=line[0:-1]
-    for obj in objs:
-        obj["driver"] = 1.0
-        obj.driver_add('["driver"]')
-        obj.animation_data.drivers[0].driver.expression = "birail1driver('"+ res.name +"', '" + line + "')"
-
-### TODO: check polls and if initial variables are ok to perform the birail
-class Birail1Operator(bpy.types.Operator):
-
-    bl_idname = "mesh.birail1_operator"
-    bl_label = "Birail between 3 bezier curves"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-
-        objs = bpy.selection
-
-        if len(objs)!=3:
-            self.report("ERROR","Please select 3 curves")
-            return {'FINISHED'}
-
-        scn = context.scene
-        spans = scn.spans
-        steps = scn.steps
-        prop = scn.proportional
-
-        verts = birail1(objs, steps, spans, prop)
-
-        if verts!=[]:
-            faces=[]
-
-            nfaces = (steps-1)*(spans-1)
-
-            for i in range(0, nfaces):
-                d = int(i/(steps-1))
-                f = [i+d+1, i+d, i+d+steps, i+d+steps+1 ]
-                faces.append(f)
-
-            me = bpy.data.meshes.new("Birail")
-            me.from_pydata(verts,[], faces)
-            me.update()
-            newobj = bpy.data.objects.new("Birail", me)
-            newobj.data = me
-
-            scn.objects.link(newobj)
-            scn.objects.active = newobj
-            newobj.select = True
-            bpy.ops.object.shade_smooth()
-            newobj['steps']=steps
-            newobj['spans']=spans
-            newobj['prop']=prop
-
-            if scn.dodriver:
-                createbirail1driver(objs, newobj)
-
-        return {'FINISHED'}
-
-#register the drivers
-bpy.app.driver_namespace['loftdriver'] = loftdriver
-bpy.app.driver_namespace['birail1driver'] = birail1driver
-
-### MERGE SPLINES BLOCK
-
-#reads spline points
-#spl spline to read
-#rev reads the spline forward or backwards
-def readspline(spl, rev=0):
-    res = []
-
-    if spl.type=="BEZIER":
-        points = spl.bezier_points
-        for p in points:
-            if rev:
-                h2 = p.handle_left
-                h1 = p.handle_right
-                h2type = p.handle_left_type
-                h1type = p.handle_right_type
-            else:
-                h1 = p.handle_left
-                h2 = p.handle_right
-                h1type = p.handle_left_type
-                h2type = p.handle_right_type
-
-            co = p.co
-            res.append([h1, co, h2, h1type, h2type])
-    if rev:
-        res.reverse()
-
-    return res
-
-#returns a new merged spline
-#cu curve object
-#pts1 points from the first spline
-#pts2 points from the second spline
-
-def merge(cu, pts1, pts2):
-    newspl = cu.data.splines.new(type="BEZIER")
-    for i, p in enumerate(pts1):
-
-        if i>0: newspl.bezier_points.add()
-        newspl.bezier_points[i].handle_left = p[0]
-        newspl.bezier_points[i].co = p[1]
-        newspl.bezier_points[i].handle_right = p[2]
-        newspl.bezier_points[i].handle_left_type = p[3]
-        newspl.bezier_points[i].handle_right_type = p[4]
-
-    newspl.bezier_points[-1].handle_right_type="FREE"
-    newspl.bezier_points[-1].handle_left_type="FREE"
-
-    newspl.bezier_points[-1].handle_right = pts2[0][2]
-
-
-    for j in range(1, len(pts2)):
-
-        newspl.bezier_points.add()
-        newspl.bezier_points[-1].handle_left = pts2[j][0]
-        newspl.bezier_points[-1].co = pts2[j][1]
-        newspl.bezier_points[-1].handle_right = pts2[j][2]
-        newspl.bezier_points[-1].handle_left_type = pts2[j][3]
-        newspl.bezier_points[-1].handle_right_type = pts2[j][4]
-
-    return newspl
-
-#looks if the splines first and last points are close to another spline
-### TODO: Check if the objects selected are valid
-### if possible implement nurbs
-
-class MergeSplinesOperator(bpy.types.Operator):
-
-    bl_idname = "curve.merge_splines"
-    bl_label = "Merges spline points inside a limit"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        curves = []
-        limit = context.scene.limit
-        print("merguing")
-        for obj in context.selected_objects:
-            if obj.type=="CURVE":
-                curves.append(obj)
-
-        for cu in curves:
-            splines = []
-            for spl in cu.data.splines:
-                splines.append(spl)
-            print(splines)
-            #compares all the splines inside a curve object
-            for spl1 in splines:
-                for spl2 in splines:
-                    print(spl1, spl2)
-                    if spl1!=spl2 and spl1.type==spl2.type=="BEZIER" and spl1.use_cyclic_u==spl2.use_cyclic_u==False:
-                        print("not cyclic")
-                        if len(spl1.bezier_points)>1  and len(spl2.bezier_points)>1:
-
-                            #edges of the 2 splines
-                            p1i = spl1.bezier_points[0].co
-                            p1f = spl1.bezier_points[-1].co
-                            p2i = spl2.bezier_points[0].co
-                            p2f = spl2.bezier_points[-1].co
-
-                            if dist(p1i, p2i)<limit:
-                                print("join p1i p2i")
-
-                                p1 = readspline(spl2, 1)
-                                p2 = readspline(spl1)
-                                res=merge(cu, p1, p2)
-                                cu.data.splines.remove(spl1)
-                                cu.data.splines.remove(spl2)
-                                splines.append(res)
-                                break
-                            elif dist(p1i, p2f)<limit:
-                                print("join p1i p2f")
-                                p1 = readspline(spl2)
-                                p2 = readspline(spl1)
-                                res = merge(cu, p1, p2)
-                                cu.data.splines.remove(spl1)
-                                cu.data.splines.remove(spl2)
-                                splines.append(res)
-                                break
-                            elif dist(p1f, p2i)<limit:
-                                print("join p1f p2i")
-                                p1 = readspline(spl1)
-                                p2 = readspline(spl2)
-                                res = merge(cu, p1, p2)
-                                cu.data.splines.remove(spl1)
-                                cu.data.splines.remove(spl2)
-                                splines.append(res)
-                                break
-                            elif dist(p1f, p2f)<limit:
-                                print("unir p1f p2f")
-                                p1 = readspline(spl1)
-                                p2 = readspline(spl2, 1)
-                                res = merge(cu, p1, p2)
-                                cu.data.splines.remove(spl1)
-                                cu.data.splines.remove(spl2)
-                                splines.append(res)
-                                break
-
-        #splines.remove(spl1)
-        return {'FINISHED'}
-
-### NURBS WEIGHTS
-
-class NurbsWeightsPanel(bpy.types.Panel):
-    bl_label = "Nurbs Weights"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    #bl_context = "data"
-
-    @classmethod
-    def poll(cls, context):
-        if context.active_object != None and context.active_object.type =="CURVE" and context.active_object.data.splines.active!=None and context.active_object.data.splines.active.type=="NURBS":
-            return True
-        else:
-            return False
-
-
-    def draw(self, context):
-        layout = self.layout
-
-        obj = context.object
-
-        for p in obj.data.splines.active.points:
-            if p.select:
-                row = layout.row()
-                row.prop(p,  "weight")
-
-### CUT / SUBDIVIDE CURVE
-#obj curve object
-#t parameter to perform the cut or split
-#method True = subdivide, Flase= Split
-
-def cutcurve(obj, t, method=True):
-
-    #flocal to global transforms or viceversa
-
-
-    #retrieves the active spline or the first spline if there no one active
-
-    spline=None
-    if obj.data.splines.active==None:
-        for sp in obj.data.splines:
-            if sp.type=="BEZIER":
-                spline= sp
-                break
-    else:
-        if obj.data.splines.active.type!="BEZIER":
-            return False
-        else:
-            spline=obj.data.splines.active
-
-    if spline==None: return False
-
-    points = spline.bezier_points
-    nsegs = len(points)-1
-
-    #transform global t into local t1
-    d = 1.0/nsegs
-    seg = int(t/d)
-    t1 = t/d-int(t/d)
-    if t>=1.0:
-        t=1.0
-        seg-=1
-        t1 = 1.0
-
-    #if t1 is not inside a segment dont perform any action
-    if t1>0.0 and t1<1.0:
-        mw = obj.matrix_world
-        mwi = obj.matrix_world.copy().inverted()
-
-        pts = getbezpoints(spline, mw, seg)
-
-        #position on the curve to perform the action
-        pos = calct(obj, t)
-
-        #De Casteljau's algorithm to get the handles
-        #http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
-        h1 = pts[0]+(pts[1]-pts[0])*t1
-        h4 = pts[2]+(pts[3]-pts[2])*t1
-        r = pts[1]+(pts[2]-pts[1])*t1
-        h2 = h1+(r-h1)*t1
-        h3 = r+(h4-r)*t1
-
-
-        if method:
-            #SUBDIVIDE
-            splp = []
-            type = "ALIGNED"
-            for i, p in enumerate(points):
-                ph1 = p.handle_left*mw
-                pco = p.co*mw
-                ph2 = p.handle_right*mw
-                ph1type = p.handle_left_type
-                ph2type = p.handle_right_type
-                splp.append([ph1, pco, ph2, ph1type, ph2type])
-                p.handle_left_type = type
-                p.handle_right_type = type
-
-                if i==seg:
-                    splp[-1][2]=h1
-                    splp.append([h2, pos, h3, type, type])
-
-                if i==seg+1:
-                    splp[-1][0]=h4
-                    splp[-1][3]=type
-                    splp[-1][4]=type
-                #if i dont set all the handles to "FREE"
-                #it returns weirds result
-                ### TODO: find out how to preserve handle's types
-
-            points.add()
-            for i, p in enumerate(points):
-                p.handle_left_type = "FREE"
-                p.handle_right_type ="FREE"
-                p.handle_left = splp[i][0]*mwi
-                p.co = splp[i][1]*mwi
-                p.handle_right=splp[i][2]*mwi
-                p.handle_left_type = splp[i][3]
-                p.handle_right_type =splp[i][4]
-        else:
-            #SPLIT CURVE
-            spl1 = []
-            spl2 = []
-            k=0 #changes to 1 when the first spline is processed
-            type = "ALIGNED"
-            for i, p in enumerate(points):
-                ph1 = p.handle_left*mw
-                pco = p.co*mw
-                ph2 = p.handle_right*mw
-                ph1type = p.handle_left_type
-                ph2type = p.handle_right_type
-                if k==0:
-                    spl1.append([ph1, pco, ph2, ph1type, ph2type])
-                else:
-                    spl2.append([ph1, pco, ph2, ph1type, ph2type])
-
-                if i==seg:
-                    spl1[-1][2]=h1
-                    spl1.append([h2, pos, h3, type, type])
-                    spl2.append([h2, pos, h3, type, type])
-                    k=1
-
-                if i==seg+1:
-                    spl2[-1][0]=h4
-                    spl2[-1][3]=type
-                    spl2[-1][4]=type
-
-            sp1 = obj.data.splines.new(type="BEZIER")
-            for i, p in enumerate(spl1):
-                if i>0: sp1.bezier_points.add()
-                sp1.bezier_points[i].handle_left_type = "FREE"
-                sp1.bezier_points[i].handle_right_type ="FREE"
-                sp1.bezier_points[i].handle_left = spl1[i][0]*mwi
-                sp1.bezier_points[i].co = spl1[i][1]*mwi
-                sp1.bezier_points[i].handle_right=spl1[i][2]*mwi
-                #i tried to preserve the handles here but
-                #didnt work well
-
-                sp1.bezier_points[i].handle_left_type = spl1[i][3]
-                sp1.bezier_points[i].handle_right_type =spl1[i][4]
-
-            sp2 = obj.data.splines.new(type="BEZIER")
-            for i, p in enumerate(spl2):
-                if i>0: sp2.bezier_points.add()
-                sp2.bezier_points[i].handle_left_type = "FREE"
-                sp2.bezier_points[i].handle_right_type = "FREE"
-                sp2.bezier_points[i].handle_left = spl2[i][0]*mwi
-                sp2.bezier_points[i].co = spl2[i][1]*mwi
-                sp2.bezier_points[i].handle_right=spl2[i][2]*mwi
-                sp2.bezier_points[i].handle_left_type = spl2[i][3]
-                sp2.bezier_points[i].handle_right_type =spl2[i][4]
-
-            obj.data.splines.remove(spline)
-
-class CutCurveOperator(bpy.types.Operator):
-    '''Subdivide / Split a bezier curve.'''
-    bl_idname = "curve.cut_operator"
-    bl_label = "Cut curve operator"
-
-    #cut or split
-    method = bpy.props.BoolProperty(default=False)
-    t = 0.0
-
-    @classmethod
-    def poll(self, context):
-        if context.active_object!=None:
-            return context.active_object.type=="CURVE"
-        else:
-            return False
-
-
-    def modal(self, context, event):
-
-        if event.type == 'MOUSEMOVE':
-            #full screen width
-            #not tested for multiple monitors
-            fullw = context.window_manager.windows[0].screen.areas[0].regions[0].width
-
-            self.t = event.mouse_x/fullw
-
-            #limit t to [0,...,1]
-            if self.t<0:
-                self.t=0.0
-            elif self.t>1.0:
-                self.t=1.0
-
-            obj = context.object
-            pos = calct(obj, self.t)
-
-            #if calct() detects a non bezier spline returns false
-            if pos==False:
-                return {'CANCELLED'}
-            cursor(pos)
-
-        elif event.type == 'LEFTMOUSE':
-            #print(self.method, self.t)
-            cutcurve(context.object, self.t, self.method)
-            return {'FINISHED'}
-
-        elif event.type in {'RIGHTMOUSE', 'ESC'}:
-            #print("Cancelled")
-
-            return {'CANCELLED'}
-
-        return {'RUNNING_MODAL'}
-
-    def invoke(self, context, event):
-
-        if context.object:
-
-            context.window_manager.modal_handler_add(self)
-            return {'RUNNING_MODAL'}
-        else:
-            self.report({'WARNING'}, "No active object, could not finish")
-            return {'CANCELLED'}
-
-### CURVE SNAP BLOCK
-
-class AllowCurveSnap(bpy.types.Operator):
-    bl_idname = "curve.allow_curve_snap"
-    bl_label = "Allow Curve Snap"
-
-    add = bpy.props.BoolProperty()
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object!=None
-
-    def execute(self, context):
-        add = self.add
-
-        scn = context.scene
-
-        if add==False:
-            for helper in context.scene.objects:
-                for key  in helper.keys():
-                    print(key)
-                    if key=="is_snap_helper" and helper[key]==1:
-                        scn.objects.unlink(helper)
-        else:
-            #objs = context.selected_objects
-            objs = context.scene.objects
-            for obj in objs:
-                if obj.type=="CURVE":
-
-                    res = obj.data.resolution_u
-
-                    obj.data.resolution_u = 100
-
-                    me = obj.to_mesh(scene=scn, apply_modifiers=True,settings = "PREVIEW" )
-                    obj.data.resolution_u = res
-                    newobj = bpy.data.objects.new(obj.name+"_snap", me)
-                    scn.objects.link(newobj)
-                    newobj.layers = obj.layers
-                    newobj.matrix_world = obj.matrix_world
-                    newobj["is_snap_helper"]=True
-                    newobj.hide_render=True
-                    newobj.hide_select = True
-                    cons = newobj.constraints.new(type="COPY_TRANSFORMS")
-                    cons.target =obj
-
-        return {'FINISHED'}
-
-def menu_func(self, context):
-    self.layout.operator("curve.allow_curve_snap").add=True
-    self.layout.operator("curve.allow_curve_snap", text = "Delete Snap Helpers").add=False
-
-### PANEL
-class CurvePanel(bpy.types.Panel):
-    bl_label = "Curve Tools"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    #bl_options = {'REGISTER', 'UNDO'}
-    #bl_context = "data"
-
-    steps = IntProperty(min=2, default = 12)
-
-    @classmethod
-    def poll(cls, context):
-        return (context.active_object != None) and (context.active_object.type=="CURVE")
-    def draw(self, context):
-        layout = self.layout
-
-        obj = context.object
-        scn = context.scene
-
-        align = True
-        row = layout.row(align=align)
-
-        row.prop(context.scene, "intype", text = "")
-        row.prop(context.scene, "dodriver", text = "Driven")
-        if scn.intype=='3': #Hermite interp
-            row = layout.row(align=align)
-            row.prop(scn, "tension")
-            row.prop(scn, "bias")
-
-        row = layout.row(align=align)
-        row.prop(context.scene, "steps")
-        row.prop(context.scene, "spans")
-        row = layout.row(align=align)
-        row.operator("mesh.loft_operator", text = "Loft")
-        row.operator("mesh.update_fix", text = "Update Fix")
-        row = layout.row(align=align)
-        row.operator("mesh.birail1_operator", text = "Birail 1")
-        row.prop(context.scene, "proportional", text = "Proportional")
-        row = layout.row(align=align)
-        row.operator("curve.arc_length_operator", text = "Calc Length")
-        row.prop(context.scene, "clen", text = "")
-        row = layout.row(align=align)
-        row.operator("curve.merge_splines", text = "Merge")
-        row.prop(context.scene,"limit",  text = "Limit")
-        row = layout.row(align=align)
-        row.operator("curve.cut_operator", text="Subdivide").method=True
-        row.operator("curve.cut_operator", text="Split").method=False
-
-#       col1 = row.column()
-#       col1.prop(context.scene, "intype", text = "")
-#       col1.prop(context.scene, "dodriver", text = "Driven")
-#       row = layout.row(align=align)
-#       col2 = row.column(align=align)
-#       col2.prop(context.scene, "steps")
-#       col2.prop(context.scene, "spans")
-#       row = layout.row(align=align)
-#       row.operator("mesh.loft_operator", text = "Loft")
-#       row.operator("mesh.update_fix", text = "Update Fix")
-#       row = layout.row(align=align)
-#       row.operator("mesh.birail1_operator", text = "Birail 1")
-#       row.prop(context.scene, "proportional", text = "Proportional")
-#       row = layout.row(align=align)
-#       row.operator("curve.arc_length_operator", text = "Calc Length")
-#       row.prop(context.scene, "clen", text = "")
-#       row = layout.row(align=align)
-#       row.operator("curve.merge_splines", text = "Merge")
-#       row.prop(context.scene,"limit",  text = "Limit")
-#       row = layout.row(align=align)
-#       row.operator("curve.cut_operator", text="Subdivide").method=True
-#       row.operator("curve.cut_operator", text="Split").method=False
-
-classes = [AllowCurveSnap, Selection, LoftOperator, Birail1Operator,
-            ArcLengthOperator, UpdateFix, MergeSplinesOperator, CutCurveOperator, NurbsWeightsPanel, CurvePanel]
-
-bpy.app.driver_namespace['loftdriver'] = loftdriver
-bpy.app.driver_namespace['birail1driver'] = birail1driver
-
-def register():
-
-    domenu=1
-    for op in dir(bpy.types):
-        if op=="CURVE_OT_allow_curve_snap":
-            domenu=0
-            break
-    if domenu:
-        bpy.types.VIEW3D_MT_object_specials.append(menu_func)
-
-    for c in classes:
-        bpy.utils.register_class(c)
-
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-
-    bpy.types.VIEW3D_MT_object_specials.remove(menu_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/development_class_viewer.py b/release/scripts/addons_contrib/development_class_viewer.py
deleted file mode 100644
index efd822a..0000000
--- a/release/scripts/addons_contrib/development_class_viewer.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    'name': "Class Viewer",
-    'author': "Mackraken", "batFinger"
-    'version': (0, 1, 2),
-    'blender': (2, 5, 8),
-    'location': "Text Editor > Toolbar, Text Editor > Right Click",
-    'warning': "",
-    'description': "List text's classes and definitions",
-    'wiki_url': "https://sites.google.com/site/aleonserra/home/scripts/class-viewer",
-    'category': "Development"}
-
-import bpy
-
-#lists all defs, comment or classes
-#space = current text editor
-#sort = sort result
-#tipo = kind of struct to look for
-#escape = character right next to the class or def name 
-
-def getfunc(space, sort, tipo="def ", escape= ""):
-    defs = []
-    if space.type=="TEXT_EDITOR":
-        if space.text!=None:
-            txt = space.text
-            
-            for i, l in enumerate(txt.lines):
-                try:
-                    line = l.body
-                except:
-                    line=""
-                
-                if line[0:len(tipo)]==tipo:
-                    end = line.find(escape)
-                    if end==0:
-                        func = line[len(tipo)::]
-                    else:
-                        func = line[len(tipo):end]
-                    defs.append([func, i+1])
-            
-            if sort: defs.sort()
-    
-    return defs
-
-class TEXT_OT_Jumptoline(bpy.types.Operator):
-    bl_label = "Jump"
-    bl_idname = "text.jumptoline"
-    __doc__ = "Jump to line"
-    line = bpy.props.IntProperty(default=-1)
-    
-    @classmethod
-    def poll(cls, context):
-        if context.area.spaces[0].type!="TEXT_EDITOR":
-            return False
-        else: 
-            return context.area.spaces[0].text!=None
-    
-    def execute(self, context):
-        
-        scn = context.scene
-
-        if self.line!=-1:
-            bpy.ops.text.jump(line=self.line)
-
-        return {'FINISHED'}
-
-
-
-class CommentsMenu(bpy.types.Menu):
-    bl_idname = "OBJECT_MT_select_comments"
-    bl_label = "Select"
-    
-    
-    
-    @classmethod
-    def poll(cls, context):
-        if context.area.spaces[0].type!="TEXT_EDITOR":
-            return False
-        else: 
-            return context.area.spaces[0].text!=None
-        
-    def draw(self, context):
-    
-        layout = self.layout
-        space = context.area.spaces[0]
-        
-        items = getfunc(space, 1, "### ", "")
-        
-        for it in items:
-            layout.operator("text.jumptoline",text=it[0]).line = it[1]
-
-class DefsMenu(bpy.types.Menu):
-    bl_idname = "OBJECT_MT_select_defs"
-    bl_label = "Select"
-    
-    tipo = bpy.props.BoolProperty(default=False)
-    
-    @classmethod
-    def poll(cls, context):
-        if context.area.spaces[0].type!="TEXT_EDITOR":
-            return False
-        else: 
-            return context.area.spaces[0].text!=None
-        
-    def draw(self, context):
-        scn = context.scene
-        layout = self.layout
-        space = context.area.spaces[0]
-        tipo = self.tipo
-        
-        
-        items = getfunc(space, 1, "def ", "(")
-        
-        for it in items:
-            layout.operator("text.jumptoline",text=it[0]).line = it[1]
-                
-class ClassesMenu(bpy.types.Menu):
-    bl_idname = "OBJECT_MT_select_classes"
-    bl_label = "Select"
-    
-    
-    
-    @classmethod
-    def poll(cls, context):
-        if context.area.spaces[0].type!="TEXT_EDITOR":
-            return False
-        else: 
-            return context.area.spaces[0].text!=None
-        
-    def draw(self, context):
-    
-        layout = self.layout
-        space = context.area.spaces[0]
-    
-        
-        
-        items = getfunc(space, 1, "class ", "(")
-        
-        for it in items:
-            layout.operator("text.jumptoline",text=it[0]).line = it[1]
-
-
-            
-def GotoComments(self, context): 
-    self.layout.menu("OBJECT_MT_select_comments", text="Comments", icon='PLUGIN')
-    return False
-
-def GotoDefs(self, context): 
-    self.layout.menu("OBJECT_MT_select_defs", text="Defs", icon='PLUGIN')
-    return False
-
-def GotoClasses(self, context): 
-    self.layout.menu("OBJECT_MT_select_classes", text="Classes", icon='PLUGIN')
-    return False
-
-
-classes = [TEXT_OT_Jumptoline, ClassesMenu, DefsMenu, CommentsMenu]
-
-
-def register():
-    for c in classes:
-        bpy.utils.register_class(c)
-        
-    bpy.types.TEXT_MT_toolbox.append(GotoComments)
-    bpy.types.TEXT_MT_toolbox.append(GotoDefs)
-    bpy.types.TEXT_MT_toolbox.append(GotoClasses)
-
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-        
-        bpy.types.TEXT_MT_toolbox.remove(GotoComments)
-    bpy.types.TEXT_MT_toolbox.remove(GotoDefs)
-    bpy.types.TEXT_MT_toolbox.remove(GotoClasses)
-    
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py
deleted file mode 100644
index 9e0245f..0000000
--- a/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Marcus Jenkins (Blenderartists user name FunkyWyrm)
-#
-# 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 *****
-# --------------------------------------------------------------------------
-
-bl_info = {
-    "name": "BRIK - Blender Ragdoll Implementation Kit",
-    "author": "FunkyWyrm",
-    "version": (0,2),
-    "blender": (2, 5, 5),
-    "location": "View 3D > Tool Shelf > BRIK Panel",
-    "description": "Kit for creating ragdoll structures from armatures and implementing them in the game engine.",
-    "warning": "Preliminary release for testing purposes. Use with caution on important files.",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Game_Engine/BRIK_ragdolls",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=24946",
-    "category": "Game Engine"}
-
-
-if "bpy" in locals():
-    import imp
-    imp.reload(brik)
-else:
-    from . import brik
-
-import bpy
-
-################################################################################
-##### REGISTER #####
-def register():
-    bpy.utils.register_module(__name__)
-    pass
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    pass
-    
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik.py
deleted file mode 100644
index 3ada81a..0000000
--- a/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik.py
+++ /dev/null
@@ -1,1056 +0,0 @@
-#brik_0_2.py
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Marcus Jenkins (Blenderartists user name FunkyWyrm)
-#
-# 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 *****
-# --------------------------------------------------------------------------
-
-"""
-brik is the Blender Ragdoll Implementation Kit.
-
-It aims to provide a tool kit that enables the easy implementation of ragdolls in Blender.
-
-Acnowledgements:
-    This section comes first because I am grateful to Thomas Eldredge (teldredge on
-www.blenderartists.com). Without his great script to take apart, I would never have got
-around to this even though it's been in my todo list for a while. The link to his thread is
-http://blenderartists.org/forum/showthread.php?t=152150
-    
-Website:
-    Blenderartists script development thread is:
-    http://blenderartists.org/forum/showthread.php?t=199191
-
-Bugs:
-    
-    Editing a text file after hitting the create or destroy button and then
-    changing an option such as writing the hierarchy file will undo the edits
-    to the text. This is a known bug due to the lack of a text editor global
-    undo push. See the bug tracker:
-        https://projects.blender.org/tracker/index.php?func=detail&aid=21043&group_id=9&atid=498
-            
-    Creating rigid body structures based on multiple armatures in the scene that have similarly
-    named bones can cause some rigid body objects to be removed. This can probably be fixed by
-    testing for membership of a group. However, similarly named bones should be renamed to a
-    unique name since bone name and driver object name being similar is essential for correct
-    operation of both the brik script and the brik_Use_doll game engine script.
-    
-    Running Create multiple times on the same armature will recreate the rigid body joints
-    rather than editing existing ones.
-
-Notes:
-    
-    The mass of each object could be calculated using their volume. The
-    armature could be assigned a mass and the bones' mass could be calculated
-    from this using their volume.
-    
-    Non-deforming bones do not have rigid body objects created for them. 
-    Perhaps this would be better given as a toggle option.
-"""
-
-import bpy
-from bpy.props import *
-import mathutils
-from mathutils import Vector
-from game_engine_ragdolls_kit.brik_funcs import *
-
-class VIEW3D_PT_brik_panel(bpy.types.Panel):
-
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_context = 'objectmode'
-    bl_label = 'brik'
-    
-    #Draws the panel header in the tools pane
-    def draw_header(self, context):
-        layout = self.layout
-        layout.label(text='', icon='CONSTRAINT_BONE')
-    
-    #Draws the brik panel in the tools pane
-    def draw(self, context):
-        
-        ob = bpy.context.object
-
-        layout = self.layout
-
-        col = layout.column()
-        if ob:
-            col.prop(ob, 'name', text = 'Selected', icon = 'OUTLINER_OB_'+str(ob.type))
-    
-            layout.separator()
-    
-            box = layout.box()
-            box.label(text = 'Create or remove?')
-            
-            if ob.type == 'ARMATURE':
-                col = box.column(align=True)
-                col.operator('object.brik_create_structure', text = 'Create structure')
-                
-                row = col.row()
-                remove_structure_active = 'brik_structure_created' in ob.keys() and ob['brik_structure_created']
-                row.active = remove_structure_active
-                row.operator('object.brik_destroy_structure', text = 'Remove structure')
-                
-                col = box.column(align = True)
-                col.operator('object.brik_create_hit_boxes', text = 'Create hit boxes')
-                
-                row = col.row()
-                remove_hit_boxes_active = 'brik_hit_boxes_created' in ob.keys() and ob['brik_hit_boxes_created']
-                row.active = remove_hit_boxes_active
-                row.operator('object.brik_remove_hit_boxes', text = 'Remove hit boxes')
-            else:
-                box.label(text='Select armature')
-                
-            game_options_active = 'brik_structure_created' in ob.keys() and ob['brik_structure_created'] \
-                                    and 'brik_hit_boxes_created' in ob.keys() and ob['brik_hit_boxes_created']
-            col = box.column(align = True)
-            col.active = game_options_active
-            col.label(text='Game options:')
-            col.operator('object.brik_write_game_file', text = 'Write game file')
-            create_logic_active = 'brik_file_written' in ob.keys() and ob['brik_file_written']
-            row = col.row()
-            row.active = create_logic_active
-            row.operator('object.brik_create_game_logic', text = 'Create game logic')
-                
-        else:
-            col.label(text='Select an object')
-
-class brik_create_structure(bpy.types.Operator):
-    bl_label = 'brik create structure operator'
-    bl_idname = 'object.brik_create_structure'
-    bl_description = 'Create a rigid body structure based on an amature.'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    #Properties that can be changed by the user
-
-    prefix = StringProperty(name='Prefix', \
-                            description='Prefix to be appended to the bone name that defines the rigid body object.',\
-                            default='RB_')
-    
-    driver_length = FloatProperty(name='Driver length',\
-                              description='Length of rigid body driver objects as proportion of bone length.',\
-                              min=0.05,\
-                              max=1.0,\
-                              step=0.05,\
-                              default=0.8)
-    
-    driver_width = FloatProperty(name = 'Driver width',\
-                                  description='Width of rigid body driver objects as proportion of bone length',\
-                                  min=0.05,\
-                                  max=1.0,\
-                                  step=0.05,\
-                                  default=0.2)
-    
-    add_to_group = BoolProperty(name='Add to group',\
-                                description='Add all created objects to a group',\
-                                default=True)
-                                
-    box_type = EnumProperty(name="Box type",
-        description="Shape that rigid body objects are created from.",
-        items=[ \
-          ('BONE', "Bone",
-              "Plain bone dimensions are used."),
-          ('ENVELOPE', "Envelope",
-              "Bone envelope dimensions are used."),
-          ('BBONE', "BBone",
-              "BBone dimensions are used. "\
-              "(BBones can be scaled using Ctrl+Alt+S in armature edit mode.)"),
-          ],
-        default='BBONE')
-    
-    #Create the rigid body boxes
-    def create_boxes(self, armature):
-        bones_dict = armature.pose.bones      #Dictionary of posebones
-        bones = bones_dict.values()
-        armature = bpy.context.object
-        
-        RB_dict = {}            #Dictionary of rigid body objects
-        
-        armature['brik_bone_driver_dict'] = {}
-        armature['brik_armature_locator_name'] = ''
-        
-        #All deforming bones have boxes created for them
-        for bone in bones:
-            if bone.bone.use_deform:
-                #print(self.box_type)
-                box = None
-                volume = 0.0
-                #Create boxes that do not exist
-                if self.box_type == 'BONE':
-                    box, volume = create_box(self.prefix, self.driver_length, self.driver_width, armature, bone)
-                elif self.box_type == 'BBONE':
-                    box, volume = create_box_bbone(self.prefix, armature, bone)
-                elif self.box_type == 'ENVELOPE':
-                    box, volume = create_box_envelope(self.prefix, armature, bone)
-                #box = create_box(self.prefix, self.driver_length, self.driver_width, armature, bone)
-                RB_dict[box.name] = box
-                armature['brik_bone_driver_dict'][bone.name] = box.name
-            
-                #Orientate and position the box
-                self.position_box(armature, bone, box)
-                box['brik_bone_name'] = bone.name
-                
-                #### Contributed by Wraaah #########
-                box.game.physics_type = 'RIGID_BODY'
-                box.game.mass = volume * 1.5 #Density I used was 1.5
-                ##############################
-        return RB_dict
-    
-    def make_bone_constraints(self, armature, RB_dict):
-        bones_dict = armature.pose.bones
-        
-        for bone in bones_dict:
-            if not 'brik_copy_rot' in bone.constraints:
-                constraint = bone.constraints.new(type='COPY_ROTATION')
-                constraint.name = 'brik_copy_rot'
-                constraint.target = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
-            if not 'brik_copy_loc' in bone.constraints:
-                if not bone.parent:
-                    #print(bone.head, bone.tail)
-                    if armature['brik_armature_locator_name'] == '':
-                        bpy.ops.object.add(type='EMPTY')
-                        locator = bpy.context.object
-                        locator.name = 'brik_'+armature.name+'_loc'
-                        locator.location = (0.0,-bone.length/2,0.0)
-                        locator.parent = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
-                        armature['brik_armature_locator_name'] = locator.name
-                        bpy.ops.object.select_all(action='DESELECT')
-                        bpy.ops.object.select_name(name=armature.name, extend=False)
-                    else:
-                        locator = bpy.data.objects['brik_armature_locator_name']
-                        locator.location = (0.0,-bone.length/2,0.0)
-                        locator.parent = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
-                    constraint = bone.constraints.new(type='COPY_LOCATION')
-                    constraint.name = 'brik_copy_loc'
-                    constraint.target = locator
-    
-    def reshape_boxes(self, armature):
-        '''
-        Reshape an existing box based on parameter changes.
-        I introduced this as an attempt to improve responsiveness. This should
-        eliminate the overhead from creating completely new meshes or objects on
-        each refresh.
-        '''
-        objects = bpy.context.scene.objects
-        
-        for bone_name in armature['brik_bone_driver_dict']:
-            bone = armature.bones[bone_name]
-            box = objects[armature['brik_bone_driver_dict'][bone_name]]
-        
-            height = bone.length
-            #gap = height * self.hit_box_length      #The distance between two boxes
-            box_length = bone.length*self.driver_length
-            width = bone.length * self.driver_width
-            
-            x = width/2
-            y = box_length/2
-            z = width/2
-            
-            verts = [[-x,y,-z],[-x,y,z],[x,y,z],[x,y,-z],\
-                     [x,-y,-z],[-x,-y,-z],[-x,-y,z],[x,-y,z]]
-            
-            #This could be a problem if custom object shapes are used...
-            count = 0
-            for vert in box.data.vertices:
-                vert.co = Vector(verts[count])
-                count += 1
-    
-    #Orient the box to the bone and set the box object centre to the bone location
-    def position_box(self, armature, bone, box):
-        scene = bpy.context.scene
-        
-        #Set the box to the bone orientation and location
-        box.matrix_world = bone.matrix
-        box.location = armature.location+bone.bone.head_local+(bone.bone.tail_local-bone.bone.head_local)/2
-    
-    #Set up the objects for rigid body physics and create rigid body joints.
-    def make_RB_constraints(self, armature, RB_dict):
-        bones_dict = armature.pose.bones
-        
-        for box in RB_dict:
-            bone = bones_dict[RB_dict[box]['brik_bone_name']]
-            
-            boxObj = RB_dict[box]
-            
-            #Make the radius half the length of the longest axis of the box
-            radius_driver_length = (bone.length*self.driver_length)/2
-            radius_driver_width = (bone.length*self.driver_width)/2
-            radius = radius_driver_length
-            if radius_driver_width > radius:
-                radius = radius_driver_width
-            
-            
-            #Set up game physics attributes
-            boxObj.game.use_actor = True
-            boxObj.game.use_ghost = False
-            boxObj.game.physics_type = 'RIGID_BODY'
-            boxObj.game.use_collision_bounds = True
-            boxObj.game.collision_bounds_type = 'BOX'
-            boxObj.game.radius = radius
-                
-            #Make the rigid body joints
-            if bone.parent:
-                #print(bone, bone.parent)
-                boxObj['brik_joint_target'] = armature['brik_bone_driver_dict'][bone.parent.name]
-                RB_joint = boxObj.constraints.new('RIGID_BODY_JOINT')
-                RB_joint.pivot_y = -bone.length/2
-                RB_joint.target = RB_dict[boxObj['brik_joint_target']]
-                RB_joint.use_linked_collision = True
-                RB_joint.pivot_type = ("GENERIC_6_DOF")
-                RB_joint.limit_angle_max_x = bone.ik_max_x
-                RB_joint.limit_angle_max_y = bone.ik_max_y
-                RB_joint.limit_angle_max_z = bone.ik_max_z
-                RB_joint.limit_angle_min_x = bone.ik_min_x
-                RB_joint.limit_angle_min_y = bone.ik_min_y
-                RB_joint.limit_angle_min_z = bone.ik_min_z
-                RB_joint.use_limit_x = True
-                RB_joint.use_limit_y = True
-                RB_joint.use_limit_z = True
-                RB_joint.use_angular_limit_x = True
-                RB_joint.use_angular_limit_y = True
-                RB_joint.use_angular_limit_z = True
-            else:
-                boxObj['brik_joint_target'] = 'None'
-    
-    def add_boxes_to_group(self, armature, RB_dict):
-        #print("Adding boxes to group")
-        group_name = self.prefix+armature.name+"_Group"
-        if not group_name in bpy.data.groups:
-            group = bpy.data.groups.new(group_name)
-        else:
-            group = bpy.data.groups[group_name]
-        #print(group)
-        #print(RB_dict)
-        for box in RB_dict:
-            if not box in group.objects:
-                group.objects.link(bpy.context.scene.objects[box])
-        
-        return
-    
-    #Armature and mesh need to be set to either no collision or ghost. No collision
-    #is much faster.
-    def set_armature_physics(self, armature):
-        armature.game.physics_type = 'NO_COLLISION'
-        for child in armature.children:
-            if hasattr(armature, "['brik_hit_boxes_created']"):
-                if child.name in armature['brik_bone_hit_box_dict'].values():
-                    continue
-                else:
-                    child.game.physics_type = 'NO_COLLISION'
-            else:
-                child.game.physics_type = 'NO_COLLISION'
-                
-
-    #The ui of the create operator that appears when the operator is called
-    def draw(self, context):
-        layout = self.layout
-
-        box = layout.box()
-        box.prop(self.properties, 'prefix')
-        box.prop(self.properties, 'add_to_group')
-        box.prop(self.properties, 'box_type')
-        if self.box_type == 'BONE':
-            box.prop(self.properties, 'driver_length')
-            box.prop(self.properties, 'driver_width')
-            
-    #The main part of the create operator
-    def execute(self, context):
-        #print("\n##########\n")
-        #print("EXECUTING brik_create_structure\n")
-        
-        armature = context.object
-        
-        self.set_armature_physics(armature)
-        
-        
-        if 'brik_structure_created' in armature.keys()\
-                and armature['brik_structure_created'] == True\
-                and self.box_type == 'BONE':
-            
-            self.reshape_boxes(armature)
-            
-        else:
-            RB_dict = self.create_boxes(armature)
-            armature['brik_structure_created'] = True
-            armature['brik_prefix'] = self.prefix
-            
-            self.make_RB_constraints(armature, RB_dict)
-            self.make_bone_constraints(armature, RB_dict)
-            
-            if self.add_to_group:
-                self.add_boxes_to_group(armature, RB_dict)
-        
-        return{'FINISHED'}
-
-class brik_destroy_structure(bpy.types.Operator):
-    bl_label = 'brik destroy structure operator'
-    bl_idname = 'object.brik_destroy_structure'
-    bl_description = 'Destroy a rigid body structure created by this brik.'
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    '''
-    For some reason the remove operators give a "cyclic" warning in the console.
-    
-    I have no idea what this means and have not been able to find out what this means.
-    '''
-    
-    def execute(self, context):
-        print("\n##########\n")
-        print("EXECUTING brik_remove_structure")
-        armature = context.object
-        scene = context.scene
-        
-        #Clean up all created objects, their meshes and bone constraints
-        for bone_name in armature['brik_bone_driver_dict']:
-            driver = scene.objects[armature['brik_bone_driver_dict'][bone_name]]
-            #Unlink and remove the mesh
-            mesh = driver.data
-            driver.data = None
-            mesh.user_clear()
-            bpy.data.meshes.remove(mesh)
-            #Unlink and remove the object
-            scene.objects.unlink(driver)
-            driver.user_clear()
-            bpy.data.objects.remove(driver)
-            
-            #Remove bone constraints
-            bone = armature.pose.bones[bone_name]
-            if 'brik_copy_rot' in bone.constraints:
-                const = bone.constraints['brik_copy_rot']
-                bone.constraints.remove(const)
-            if 'brik_copy_loc' in bone.constraints:
-                const = bone.constraints['brik_copy_loc']
-                bone.constraints.remove(const)
-        
-        #Remove armature locator
-        locator = bpy.data.objects[armature['brik_armature_locator_name']]
-        scene.objects.unlink(locator)
-        locator.user_clear()
-        bpy.data.objects.remove(locator)
-        
-        #Remove driver group
-        group_name = armature['brik_prefix']+armature.name+'_Group'
-        if group_name in bpy.data.groups:
-            group = bpy.data.groups[group_name]
-            bpy.data.groups.remove(group)
-        
-        #Remove custom properties
-        del armature['brik_armature_locator_name']
-        del armature['brik_structure_created']
-        del armature['brik_bone_driver_dict']
-        del armature['brik_prefix']
-    
-        return{'FINISHED'}
-        
-class brik_create_game_logic(bpy.types.Operator):
-    bl_label = 'brik create game logic operator'
-    bl_idname = 'object.brik_create_game_logic'
-    bl_description = 'Create the game logic for the created objects.'
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    template_path = bpy.utils.script_paths()[0]+'\\addons\\game_engine_ragdolls_kit\\templates\\'
-    
-    game_script_list = ['brik_load.py', \
-                        'brik_init_ragdoll.py', \
-                        'brik_spawn.py']
-                            
-    
-    def set_up_armature_logic(self, armature):
-        
-        if not 'brik_use_ragdoll' in armature.game.properties:
-            
-            bpy.ops.object.game_property_new()
-            prop = armature.game.properties[-1]
-            prop.name = 'brik_use_ragdoll'
-            prop.type = 'BOOL'
-            prop.value = False
-            
-            bpy.ops.object.game_property_new()
-            prop = armature.game.properties[-1]
-            prop.name = 'brik_init_ragdoll'
-            prop.type = 'BOOL'
-            prop.value = True
-            
-            #Logic to spawn the rigid body boxes
-            bpy.ops.logic.sensor_add(type='PROPERTY', name='brik_use_changed_sens', object=armature.name)
-            sens = armature.game.sensors[-1]
-            sens.property = 'brik_use_ragdoll'
-            sens.evaluation_type = 'PROPCHANGED'
-            
-            bpy.ops.logic.controller_add(type='PYTHON', name='brik_init_ragdoll_cont', object=armature.name)
-            cont = armature.game.controllers[-1]
-            cont.mode = 'MODULE'
-            cont.module = 'brik_init_ragdoll.main'
-            
-            bpy.ops.logic.actuator_add(type='EDIT_OBJECT', name='brik_spawn_boxes_act', object=armature.name)
-            act = armature.game.actuators[-1]
-            act.mode = 'ADDOBJECT'
-            
-            cont.link(sens, act)
-            
-            #Logic to change the value of brik_use_ragdoll property
-            bpy.ops.logic.sensor_add(type='KEYBOARD', name='brik_set_use_ragdoll_sens', object=armature.name)
-            sens = armature.game.sensors[-1]
-            sens.key = 'SPACE'
-            
-            bpy.ops.logic.controller_add(type='LOGIC_AND', name='brik_set_use_ragdoll_cont', object=armature.name)
-            cont = armature.game.controllers[-1]
-            
-            bpy.ops.logic.actuator_add(type='PROPERTY', name='brik_set_use_ragdoll_act', object=armature.name)
-            act = armature.game.actuators[-1]
-            act.mode = 'ASSIGN'
-            act.property = 'brik_use_ragdoll'
-            act.value = "True"
-            
-            cont.link(sens, act)
-            
-            #Logic to use the ragdoll.
-            bpy.ops.logic.sensor_add(type='PROPERTY', name='brik_use_sens', object=armature.name)
-            sens = armature.game.sensors[-1]
-            sens.property = 'brik_use_ragdoll'
-            sens.value = 'True'
-            sens.use_pulse_true_level = True
-            
-            bpy.ops.logic.controller_add(type='LOGIC_AND', name='brik_use_cont', object=armature.name)
-            cont = armature.game.controllers[-1]
-            
-            bpy.ops.logic.actuator_add(type='ARMATURE', name='brik_use_act', object=armature.name)
-            act = armature.game.actuators[-1]
-            act.mode = 'RUN'
-            
-            cont.link(sens, act)
-    
-    def set_up_spawn_logic(self, armature):
-        print('SETTING UP SPAWN LOGIC')
-        scene = bpy.context.scene
-        
-        #Need to use data to avoid naming conflicts
-        if not 'brik_spawn_location' in bpy.data.objects:
-            bpy.ops.object.add()
-            spawn_object = bpy.context.object
-            spawn_object.name = 'brik_spawn_location'
-        else:
-            spawn_object = bpy.data.objects['brik_spawn_location']
-        
-        bpy.ops.object.select_all(action='DESELECT')
-        bpy.ops.object.select_name(name=armature.name, extend=False)
-        
-        spawn_object.game.show_state_panel = False
-        
-        #Quick and dirty check to see if the spawn logic is already set up.
-        if not 'brik_spawn_cont' in spawn_object.game.controllers:
-            #The logic to spawn the mob
-            bpy.ops.logic.sensor_add(type='KEYBOARD', name='brik_Tab_sens', object=spawn_object.name)
-            sens = spawn_object.game.sensors[-1]
-            sens.key = 'TAB'
-            
-            bpy.ops.logic.controller_add(type='PYTHON', name='brik_spawn_cont', object=spawn_object.name)
-            cont = spawn_object.game.controllers[-1]
-            cont.mode = 'MODULE'
-            cont.module = 'brik_spawn.main'
-            
-            bpy.ops.logic.actuator_add(type='EDIT_OBJECT', name='brik_spawn_act', object=spawn_object.name)
-            act = spawn_object.game.actuators[-1]
-            
-            cont.link(sens, act)
-            
-            #Logic to load structure information
-            bpy.ops.logic.sensor_add(type='ALWAYS', name='brik_load_sens', object=spawn_object.name)
-            sens = spawn_object.game.sensors[-1]
-            
-            bpy.ops.logic.controller_add(type='PYTHON', name='brik_load_cont', object=spawn_object.name)
-            cont = spawn_object.game.controllers[-1]
-            cont.text = bpy.data.texts['brik_load.py']
-            
-            sens.link(cont)
-            
-            #Logic to initialise the spawn point with object to add, added object list and added object count.
-            bpy.ops.logic.controller_add(type='PYTHON', name='brik_spawn_init_cont', object=spawn_object.name)
-            cont = spawn_object.game.controllers[-1]
-            cont.mode = 'MODULE'
-            cont.module = 'brik_spawn.initialize'
-            
-            sens.link(cont)
-        
-        #Properties and text files to define the mobs that can be spawned.
-        for text in bpy.data.texts:
-            
-            print('CONSIDERING TEXT '+text.name)
-            prefix = armature['brik_prefix']
-            print(text.name[len(prefix):-4])
-            
-            
-            #If there is an armature and text pair.
-            if text.name[len(prefix):-4] == armature.name:
-                #If no mobs have been accounted for yet.
-                if not 'brik_mob_count' in spawn_object.game.properties:
-                    print('CREATING PROPERTY brik_mob_count')
-                    bpy.ops.object.select_all(action='DESELECT')
-                    spawn_object.select = True
-                    scene.objects.active = spawn_object
-                    
-                    bpy.ops.object.game_property_new()
-                    count_prop = spawn_object.game.properties[-1]
-                    count_prop.name = 'brik_mob_count'
-                    count_prop.type = 'INT'
-                    count_prop.value = -1   #Initialised to -1 meaning no data controllers yet created.
-        
-                    bpy.ops.object.select_all(action='DESELECT')
-                    bpy.ops.object.select_name(name=armature.name, extend=False)
-                else:
-                    count_prop = spawn_object.game.properties['brik_mob_count']
-                
-                #Find a list of armature texts currently accounted for in logic.
-                current_texts = []
-                for cont in spawn_object.game.controllers:
-                    if cont.name[:-1] == 'brik_ragdoll_data_':
-                        current_texts.append(cont.text)
-                
-                #Create a new data controller for any text not considered.
-                if not text in current_texts:
-                    count_prop.value += 1
-                    #Controller to store structure information.
-                    print('CREATING DATA CONTROLLER')
-                    bpy.ops.logic.controller_add(type='PYTHON', name='brik_ragdoll_data_'+str(int(count_prop.value)), object=spawn_object.name)
-                    cont = spawn_object.game.controllers[-1]
-                    cont.text = text
-        
-    
-    def set_up_hit_box_logic(self, armature, bone_name):
-        hit_box = bpy.data.objects[armature['brik_bone_hit_box_dict'][bone_name]]
-        scene = bpy.context.scene
-        
-        #Simply create a property for the ray cast to look for.
-        if not 'brik_can_hit' in hit_box.game.properties:
-            hit_box.select = True
-            scene.objects.active = hit_box
-            bpy.ops.object.game_property_new()
-            print(*hit_box.game.properties)
-            prop = hit_box.game.properties[-1]
-            prop.name = 'brik_can_hit'
-            prop.type = 'BOOL'
-            prop.value = True
-            scene.objects.active = armature
-            hit_box.select = False
-            
-        return
-    
-    def load_game_scripts(self):
-        
-        for script_name in self.game_script_list:
-            if not script_name in bpy.data.texts:
-                bpy.data.texts.load(self.template_path+script_name)
-                
-        return
-            
-    
-    def execute(self, context):
-        self.load_game_scripts()
-        
-        armature = context.object
-        
-        self.set_up_armature_logic(armature)
-        
-        for bone_name in armature['brik_optimal_order']:
-            self.set_up_hit_box_logic(armature, bone_name)
-        
-        self.set_up_spawn_logic(armature)
-        
-        
-        return{'FINISHED'}
-
-class brik_write_game_file(bpy.types.Operator):
-    bl_label = 'brik write game file operator'
-    bl_idname = 'object.brik_write_game_file'
-    bl_description = 'Write a file containing a description of the rigid body structure'
-    bl_options = {'REGISTER', 'UNDO'} 
-    
-    #Find the most efficient order to calculate bone rotations in the game engine
-    def calculate_structure(self, armature):
-        boneDict = armature.pose.bones
-        
-        boneChainsDict = {}
-        maxLength = 0       #This is the length of the longest chain of bones
-        
-        #Find the chains of bone parentage in the armature
-        for poseBone in boneDict:
-            bone = poseBone.bone
-            boneChain = []
-            while True:
-                boneChain.append(bone.name)
-                if bone.parent:
-                    bone = bone.parent
-                else:
-                    boneChainsDict[boneChain[0]] = boneChain
-                    if len(boneChain) > maxLength:
-                        maxLength = len(boneChain)
-                    break
-        
-        #Sort the bone chains to find which bone rotations to calculate first
-        optimalBoneOrder = self.find_optimal_bone_order(boneChainsDict, maxLength)
-        
-        return optimalBoneOrder, boneChainsDict
-        
-    def find_optimal_bone_order(self, boneChainsDict, maxLength):
-        tempBoneChainsOrder = []
-        
-        #Reorder the bone chains so that shorter bone chains are at the start of the list
-        for n in range(1,maxLength+1):
-            for chain in boneChainsDict:
-                if len(boneChainsDict[chain]) == n:
-                    tempBoneChainsOrder.append(boneChainsDict[chain])
-        
-        #Create a final list of bones so that the bones that need to be calculated first are
-        #at the start
-        finalBoneOrder = []
-        for chain in tempBoneChainsOrder:
-            finalBoneOrder.append(chain[0])     
-        return finalBoneOrder
-    
-    '''
-    I've found a method of reading from an internal text file in the game
-    engine... Place the text file in a python script controller set to 'script'
-    and it can be accessed as a string through cont.script. To avoid  throwing
-    a script compilation error on startup, all text must be enclosed within
-    triple quotation marks as a block comment.
-    There is no need to mess with different file systems and platforms... It can
-    all be done internally. =D
-    '''
-    
-    def save_structure_data(self, armature, optimalBoneOrder, boneChainsDict):
-        
-        prefix = armature['brik_prefix']
-        #Create or clear the text file for this armature
-        texts = bpy.data.texts
-        if prefix+armature.name+".txt" not in texts:
-            dataFile = texts.new(prefix+armature.name+".txt")
-        else:
-            dataFile = texts[prefix+armature.name+".txt"]
-            dataFile.clear()
-        
-        #Write to the text file
-        dataFile.write("'''\n")
-        
-        dataFile.write(armature.name+"\n")
-        
-        #Write bone data to the file
-        for bone_name in optimalBoneOrder:
-            #Write bone name and rigid body box for this bone
-            #If the bone is part of a chain (not the root bone)
-            dataFile.write(bone_name+"\n")
-            
-            box_name = armature['brik_bone_driver_dict'][bone_name]
-            dataFile.write(box_name+"\n")
-            
-            if len(boneChainsDict[bone_name])>1:
-                parent_bone_name = boneChainsDict[bone_name][1]
-                joint_target_name = armature['brik_bone_driver_dict'][parent_bone_name]
-                dataFile.write(joint_target_name+"\n")
-            else:
-                dataFile.write("None\n")
-            
-            #Write hit box name for this bone
-            if 'brik_bone_hit_box_dict' in armature.keys():
-                hit_box_name = armature['brik_bone_hit_box_dict'][bone_name]
-                dataFile.write(hit_box_name+"\n")
-            else:
-                dataFile.write('None\n')
-            
-            obj = bpy.data.objects[armature['brik_bone_driver_dict'][bone_name]]
-            
-            if not obj['brik_joint_target'] == 'None':
-                #Write rigid body joint position to file
-                pos_x = obj['joint_position_x']
-                pos_y = obj['joint_position_y']
-                pos_z = obj['joint_position_z']
-                itemString = str(pos_x)+"\n"+str(pos_y)+"\n"+str(pos_z)+"\n"
-                dataFile.write(itemString)
-                #############################################
-                #Should no longer need to do this.
-				
-                #Write rigid body joint limits to the file
-                max_x = obj['rot_max_x']
-                max_y = obj['rot_max_y']
-                max_z = obj['rot_max_z']
-                itemString = str(max_x)+"\n"+str(max_y)+"\n"+str(max_z)+"\n"
-                dataFile.write(itemString)
-                min_x = obj['rot_min_x']
-                min_y = obj['rot_min_y']
-                min_z = obj['rot_min_z']
-                itemString = str(min_x)+"\n"+str(min_y)+"\n"+str(min_z)+"\n"
-                dataFile.write(itemString)
-                
-            
-        dataFile.write("'''")
-        
-        return
-    
-    def store_joint_data(self, armature):
-        '''
-        Joint data is stored on the rigid body objects themselves. This will not be
-        necessary when the convertor is properly transferring these values from Blender
-        to the game engine.
-        '''
-        for bone_name in armature['brik_optimal_order']:
-            box = bpy.data.objects[armature['brik_bone_driver_dict'][bone_name]]
-            if not box['brik_joint_target'] == 'None':
-                RB_joint = box.constraints[0]
-                bone = armature.pose.bones[box['brik_bone_name']]
-                
-                ###############################
-                #Required for dynamic creation of joint in game
-                box['joint_position_x'] = RB_joint.pivot_x
-                box['joint_position_y'] = RB_joint.pivot_y
-                box['joint_position_z'] = RB_joint.pivot_z
-            
-            
-                '''
-                It would be nice to use IK limits to define rigid body joint limits,
-                but the limit arrays have not yet been wrapped in RNA apparently...
-                properties_object_constraint.py in ui directory, line 554 says:
-                Missing: Limit arrays (not wrapped in RNA yet)
-                
-                It is necessary to create the joint when spawning ragdolls anyway.
-                Joints can still be created in the game.
-                '''
-            
-                box['rot_max_x'] = bone.ik_max_x
-                box['rot_max_y'] = bone.ik_max_y
-                box['rot_max_z'] = bone.ik_max_z
-                box['rot_min_x'] = bone.ik_min_x
-                box['rot_min_y'] = bone.ik_min_y
-                box['rot_min_z'] = bone.ik_min_z
-    
-    def execute(self, context):
-        armature = context.object
-        
-        optimalBoneOrder, boneChainsDict = self.calculate_structure(armature)
-        
-        armature['brik_optimal_order'] = optimalBoneOrder
-        
-        self.store_joint_data(armature)
-        
-        self.save_structure_data(armature, optimalBoneOrder, boneChainsDict)
-        
-        armature['brik_file_written'] = True
-        
-        
-        return{'FINISHED'}
-
-class brik_create_hit_boxes(bpy.types.Operator):
-    bl_label = 'brik create hit boxes operator'
-    bl_idname = 'object.brik_create_hit_boxes'
-    bl_description = 'Create hit boxes for each bone in an armature and parent them to the bones.'
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    hit_box_prefix = StringProperty(name='Hit box prefix',\
-                            description='Prefix to be appended to the bone name that defines the hit box',\
-                            default='HIT')
-    
-    hit_box_length = FloatProperty(name='Hit box length',\
-                              description='Length of a hit box as a proportion of bone length.',\
-                              min=0.05,\
-                              max=1.0,\
-                              step=0.05,\
-                              default=0.8)
-    
-    hit_box_width = FloatProperty(name = 'Hit box width',\
-                                  description='Width of a hit box as a proportion of bone length.',\
-                                  min=0.05,\
-                                  max=1.0,\
-                                  step=0.05,\
-                                  default=0.2)
-    
-    add_to_group = BoolProperty(name='Add to group',\
-                                description='Add hit boxes to a group',\
-                                default=True)
-    
-    #Create the hit boxes
-    def create_hit_boxes(self, hit_box_prefix):
-        bones_dict = bpy.context.object.pose.bones      #Dictionary of posebones
-        bones = bones_dict.values()
-        armature = bpy.context.object
-        scene = bpy.context.scene
-        
-        hit_box_dict = {}
-        
-        #I hate this next line. Eugh. :S
-        if 'brik_hit_boxes_created' in armature.keys() and armature['brik_hit_boxes_created'] == True:
-            #Modify boxes that exist
-            for bone_name in armature['brik_bone_hit_box_dict']:
-                bone = bones_dict[bone_name]
-                hit_box = self.reshape_hit_box(armature, bone)
-                
-                #Orientate and position the box
-                #self.position_hit_box(armature, bone, hit_box)
-                hit_box['brik_bone_name'] = bone.name
-                
-                self.parent_to_bone(armature, hit_box, bone_name)
-                
-                hit_box.game.physics_type = 'STATIC'
-                hit_box.game.use_ghost = True
-                    
-                hit_box_dict[hit_box.name] = hit_box
-        
-        else:
-        
-            armature['brik_bone_hit_box_dict'] = {}
-                
-            #All bones have hit boxes created for them
-            for bone in bones:
-                if bone.bone.use_deform:
-                    #Create boxes that do not exist
-                    hit_box,volume = create_box_envelope(self.hit_box_prefix, armature, bone)
-                    #hit_box = create_box(self.hit_box_prefix, self.hit_box_length, self.hit_box_width, armature, bone)
-                    armature['brik_bone_hit_box_dict'][bone.name] = hit_box.name
-                
-                    #Orientate and position the box
-                    #self.position_hit_box(armature, bone, hit_box)
-                    hit_box['brik_bone_name'] = bone.name
-                    
-                    self.parent_to_bone(armature, hit_box, bone.name)
-                
-                    hit_box.game.physics_type = 'STATIC'
-                    hit_box.game.use_ghost = True
-                    
-                    hit_box_dict[hit_box.name] = hit_box
-        
-        return hit_box_dict
-        
-    #Reshape an existing box based on parameter changes.
-    #I introduced this as an attempt to improve responsiveness. This should
-    #eliminate the overhead from creating completely new meshes or objects on
-    #each refresh.
-    def reshape_hit_box(self, armature, bone):
-        #print('RESHAPING BOX')
-        armature_object = bpy.context.object
-        scene = bpy.context.scene
-        hit_box = scene.objects[armature['brik_bone_hit_box_dict'][bone.name]]
-        
-        height = bone.length
-        box_length = bone.length*self.hit_box_length
-        width = bone.length * self.hit_box_width
-        
-        x = width/2
-        y = box_length/2
-        z = width/2
-        
-        verts = [[-x,y,-z],[-x,y,z],[x,y,z],[x,y,-z],\
-                 [x,-y,-z],[-x,-y,-z],[-x,-y,z],[x,-y,z]]
-        
-        #This could be a problem if custom object shapes are used...
-        count = 0
-        for vert in hit_box.data.vertices:
-            vert.co = Vector(verts[count])
-            count += 1
-        
-        return(hit_box)
-
-    def add_hit_boxes_to_group(self, armature):
-        #print("Adding hit boxes to group")
-        group_name = self.hit_box_prefix+armature.name+"_Group"
-        if not group_name in bpy.data.groups:
-            group = bpy.data.groups.new(group_name)
-        else:
-            group = bpy.data.groups[group_name]
-        for bone_name in armature['brik_bone_hit_box_dict']:
-            hit_box_name = armature['brik_bone_hit_box_dict'][bone_name]
-            if not hit_box_name in group.objects:
-                group.objects.link(bpy.data.objects[hit_box_name])
-        
-        return
-        
-    def parent_to_bone(self, armature, hit_box, bone_name):
-        #Thanks Uncle Entity. :)
-        hit_box.parent = armature
-        hit_box.parent_bone = bone_name
-        hit_box.parent_type = 'BONE'
-        
-        return
-    
-    #The ui of the create operator that appears when the operator is called
-    def draw(self, context):
-        layout = self.layout
-
-        box = layout.box()
-        box.prop(self.properties, 'hit_box_prefix')
-        box.prop(self.properties, 'hit_box_length')
-        box.prop(self.properties, 'hit_box_width')
-        box.prop(self.properties, 'add_to_group')
-    
-    #The main part of the create operator
-    def execute(self, context):
-        #print("\n##########\n")
-        #print("EXECUTING brik_create_structure\n")
-        
-        armature = context.object
-        
-        hit_box_dict = self.create_hit_boxes(self.hit_box_prefix)
-        
-        if self.add_to_group:
-            self.add_hit_boxes_to_group(armature)
-        
-        armature['brik_hit_box_prefix'] = self.hit_box_prefix
-        armature['brik_hit_boxes_created'] = True
-        
-        return{'FINISHED'}
-
-class brik_remove_hit_boxes(bpy.types.Operator):
-    bl_label = 'brik remove hit boxes operator'
-    bl_idname = 'object.brik_remove_hit_boxes'
-    bl_description = 'Remove hit boxes crested by this addon.'
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    '''
-    For some reason the remove operators give a "cyclic" warning in the console.
-    
-    I have no idea what this means and have not been able to find out what this means.
-    '''
-    
-    def remove_hit_box(self, scene, bone_name, armature):
-        hit_box = scene.objects[armature['brik_bone_hit_box_dict'][bone_name]]
-        #Unlink and remove the mesh
-        mesh = hit_box.data
-        hit_box.data = None
-        mesh.user_clear()
-        bpy.data.meshes.remove(mesh)
-        #Unlink and remove the object
-        scene.objects.unlink(hit_box)
-        hit_box.user_clear()
-        bpy.data.objects.remove(hit_box)
-    
-    def draw(self, context):
-        pass
-    
-    def execute(self, context):
-        armature = context.object
-        scene = context.scene
-        for bone_name in armature['brik_bone_hit_box_dict']:
-            self.remove_hit_box(scene, bone_name, armature)
-        
-        group_name = armature['brik_hit_box_prefix']+armature.name+"_Group"
-        if group_name in bpy.data.groups:
-            group = bpy.data.groups[group_name]
-            bpy.data.groups.remove(group)
-        
-        del armature['brik_bone_hit_box_dict']
-        del armature['brik_hit_boxes_created']
-        del armature['brik_hit_box_prefix']
-        return{'FINISHED'}
-    
-  
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik_funcs.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik_funcs.py
deleted file mode 100644
index 986cd79..0000000
--- a/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik_funcs.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#brik_funcs.py
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Marcus Jenkins (Blenderartists user name FunkyWyrm)
-#
-# 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 *****
-# --------------------------------------------------------------------------
-
-'''
-This will be a collection of useful functions that can be reused across the different operators.
-
-'''
-
-import bpy
-
-#Create a box based on envelope size (easier matching of box to model proportions)
-def create_box_bbone(prefix, armature, poseBone):
-    #Thanks to Wraaah for this function
-    
-    ########################
-    #INSERT SHAPE CODE HERE#
-    
-    #Strange looking code as I am referencing the editbone data from the posebone.
-    h = poseBone.bone.bbone_x
-    w = poseBone.bone.bbone_z
-    l = poseBone.bone.length/2.0
-    #The bone points along it's y axis so head is -y and tail is +y
-    verts = [[h,-l, w],[h,-l,-w],[-h,-l,-w],[-h,-l,w],\
-            [h,l,w],[h,l,-w],[-h,l,-w],[-h,l,w]]
-    edges = [[0,1],[1,2],[2,3],[3,0],\
-            [4,5],[5,6],[6,7],[7,4],\
-            [0,4],[1,5],[2,6],[3,7]]
-    faces = [[3,2,1,0],[4,5,6,7],[0,4,7,3],[1,5,4,0],[2,6,5,1],[3,7,6,2]]
-    
-    ########################
-    
-    #Create the mesh
-    mesh = bpy.data.meshes.new(prefix + poseBone.name)
-    mesh.from_pydata(verts, edges, faces)
-    
-    #Create an object for the mesh and link it to the scene
-    box = bpy.data.objects.new(prefix + poseBone.name, mesh)
-    bpy.context.scene.objects.link(box)
-    
-    #Move the hit box so that when parented the object centre is at the bone centre
-    box.location.y = -poseBone.length/2
-    volume = h * l * w * 8.0 
-    return(box, volume)
-    
-#Create a box based on envelope size (easier matching of box to model proportions)
-def create_box_envelope(prefix, armature, poseBone):
-    ########################
-    #INSERT SHAPE CODE HERE#
-    
-    #Strange looking code as I am referencing the editbone data from the posebone.
-    l = poseBone.bone.length/2
-    h = poseBone.bone.head_radius
-    t = poseBone.bone.tail_radius
-    #The bone points along it's y axis so head is -y and tail is +y
-    verts = [[h,-l, h],[h,-l,-h],[-h,-l,-h],[-h,-l,h],\
-            [t,l,t],[t,l,-t],[-t,l,-t],[-t,l,t]]
-    edges = [[0,1],[1,2],[2,3],[3,0],\
-            [4,5],[5,6],[6,7],[7,4],\
-            [0,4],[1,5],[2,6],[3,7]]
-    faces = [[3,2,1,0],[4,5,6,7],[0,4,7,3],[1,5,4,0],[2,6,5,1],[3,7,6,2]]
-    
-    ########################
-    
-    #Create the mesh
-    mesh = bpy.data.meshes.new(prefix + poseBone.name)
-    mesh.from_pydata(verts, edges, faces)
-    
-    #Create an object for the mesh and link it to the scene
-    box = bpy.data.objects.new(prefix + poseBone.name, mesh)
-    bpy.context.scene.objects.link(box)
-    
-    #Move the hit box so that when parented the object centre is at the bone centre
-    box.location.y = -poseBone.length/2
-    volume = (((2*h)**2 + (2*t)**2)/2) * (2*l)
-    return(box, volume)
-    
-#Create a box based on bone size (manual resizing of bones)
-def create_box(prefix, length, width, armature, bone):
-    scene = bpy.context.scene
-    
-    height = bone.length
-    #gap = height * self.hit_box_length      #The distance between two boxes
-    box_length = bone.length * length
-    box_width = bone.length * width
-    
-    x = box_width/2
-    y = box_length/2
-    z = box_width/2
-    
-    verts = [[x,-y,z],[x,-y,-z],[-x,-y,-z],[-x,-y,z],\
-             [x,y,z],[x,y,-z],[-x,y,-z],[-x,y,z]]
-    edges = [[0,1],[1,2],[2,3],[3,0],\
-            [4,5],[5,6],[6,7],[7,4],\
-            [0,4],[1,5],[2,6],[3,7]]
-    faces = [[3,2,1,0],[4,5,6,7],[0,4,7,3],[1,5,4,0],[2,6,5,1],[3,7,6,2]]
-    
-    #Create the mesh
-    mesh = bpy.data.meshes.new(prefix + bone.name)
-    mesh.from_pydata(verts, edges, faces)
-    
-    #Create an object for the mesh and link it to the scene
-    obj = bpy.data.objects.new(prefix + bone.name, mesh)
-    scene.objects.link(obj)
-    
-    volume = x*y*z
-    
-    return(obj, volume)
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_init_ragdoll.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_init_ragdoll.py
deleted file mode 100644
index 51ebdbb..0000000
--- a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_init_ragdoll.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#brik_init_ragdoll.py
-
-# ***** BEGIN MIT LICENSE BLOCK *****
-#
-#Script Copyright (c) 2010 Marcus P. Jenkins (Blenderartists user name FunkyWyrm)
-#
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-#
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-#
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-#
-# ***** END MIT LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-'''
-This script spawns rigid body objects when ragdoll physics is activated.
-
-It spawns the rigid body objects, turns off the mob collision object's dynamics
-and makes the mob collision object 'Ghost'.
-
-    Objects cannot have 'Ghost' toggled from within the game. :(
-        
-    Mobs can probably be static, ghost anyway. If a mob needs to be dynamic
-    then it can be parented to a physics mesh and then the physics mesh can be
-    removed from the scene by this script to avoid collision conflicts with
-    the rigid bodies.
-
-It then sets the orientation and position to that of the hit boxes and links
-the rigid body objects together with rigid body joints.
-
-Rest orientations can be taken from the rigid body objects that remain on the
-hidden layer. I thought this would be a problem to set. It's so nice when
-something turns out easier than expected for a change. :)
-'''
-debug = False
-
-import bge
-
-scene = bge.logic.getCurrentScene()
-
-objects = scene.objects
-hidden_objects = scene.objectsInactive
-
-'''
-NOTE:
-    If a collision box is used then this will be the main added object
-    that is added and so will have the spawn_point and spawn_id
-    properties.
-    The collision box would need to be removed here.
-    In this case, the spawn_id and spawn_point would need to be copied
-    to the armature in order to properly identify which object is to be
-    ultimately removed from the scene.
-'''
-
-def main():
-
-    '''
-    Sensor disabled. Using brik_use_ragdoll 'changed' sensor
-    '''
-    #sens = spawn_boxes_cont.sensors['brik_spawn_boxes_sens']
-    #if sens.getKeyStatus(sens.key) == 1:
-    
-    init_ragdoll_controller = bge.logic.getCurrentController()
-    spawn_boxes_act = init_ragdoll_controller.actuators['brik_spawn_boxes_act']
-    
-    armature = init_ragdoll_controller.owner
-    
-    
-    #########################
-    hidden_armature = hidden_objects[armature.name]
-    #########################
-    
-    
-    spawn_point = armature['spawn_point']
-    spawn_id = armature['spawn_id']
-    
-    if armature['brik_use_ragdoll'] and armature['brik_init_ragdoll']:
-
-        print('#########################')
-        print('SPAWNING RIGID BODY OBJECTS')
-        
-        for bone_name in armature['optimal_order']:
-            box_name = armature['bone_box_dict'][bone_name]
-            print('ADDING '+box_name)
-            spawn_boxes_act.object = box_name
-            spawn_boxes_act.instantAddObject()
-            box = spawn_boxes_act.objectLastCreated
-            
-            hidden_box = hidden_objects[box_name]
-            
-            #Since the boxes are added to the armature, it is probably not necessary to store spawn info...
-            box['spawn_point'] = spawn_point
-            box['spawn_id'] = spawn_id
-            
-            #Add the box to a dictionary on the armature so it can be located in brik_use_doll_0_3.py
-            armature['driver_dict'][box_name] = box
-            
-            #Set the  drivers to the location and orientation of the hit boxes
-            hit_box_name = armature['bone_hit_box_dict'][bone_name]
-            hit_box = armature.children[hit_box_name]
-            box.worldPosition = hit_box.worldPosition
-            box.worldOrientation = hit_box.worldOrientation
-            
-            '''
-            I have absolutely NO idea why these next two lines are necessary...
-            Without these lines, object rotation appears to be set to the identity.
-            Damned weird stuff. =S
-            Update... these lines screw things up in version 35733 but leaving them for now
-            '''
-            #box.suspendDynamics()
-            #box.restoreDynamics()
-            
-            #Set up the rigid body joints for the newly spawned objects.
-            if not box['joint_target'] == 'None':
-                #Set up the rigid body joints for the newly spawned objects.
-                joint_target = armature['driver_dict'][box['joint_target']]
-                box_id = box.getPhysicsId()
-                joint_target_id = joint_target.getPhysicsId()
-                constraint_type = 12 #6DoF joint
-                flag = 128 #No collision with joined object.
-                pos = box['joint_position']
-                joint_rotation = [0.0, 0.0, 0.0]
-                joint = bge.constraints.createConstraint(box_id, joint_target_id, constraint_type, pos[0], pos[1], pos[2], 0.0, 0.0, 0.0, flag)
-                #Parameters 3 = limit x rotation, 4 = limit y rotation, 5 = limit z rotation
-                joint.setParam(3, *box['limit_rotation_x'])
-                joint.setParam(4, *box['limit_rotation_y'])
-                joint.setParam(5, *box['limit_rotation_z'])
-                
-                #Set up the copy rotation bone constraint for this driver
-                print('######################')
-                print('SETTING UP ROT BONE CONSTRAINTS FOR '+box.name)
-                print('BONE NAME '+box['bone_name'])
-                constraint_rot = armature.constraints[box['bone_name']+':brik_copy_rot']
-                constraint_rot.target = box
-            else:
-                print('######################')
-                print('SETTING UP LOC/ROT BONE CONSTRAINTS FOR '+box.name)
-                print('BONE NAME '+box['bone_name'])
-                #Set up the copy rotation constraint for this driver
-                constraint_rot = armature.constraints[box['bone_name']+':brik_copy_rot']
-                constraint_rot.target = box
-                print(constraint_rot)
-                
-                #Set up the copy location constraint for the empty parented to this driver
-                copy_loc_target = box.children['brik_'+armature.name+'_loc']
-                constraint_loc = armature.constraints[box['bone_name']+':brik_copy_loc']
-                constraint_loc.target = copy_loc_target
-                print(constraint_loc)
-            
-            box.worldLinearVelocity = hit_box.worldLinearVelocity
-            box.worldAngularVelocity = hit_box.worldAngularVelocity
-            
-            hit_box.endObject()
-            
-        for act in armature.actuators:
-            #There appears to be no direct way of checking that an actuator is an action actuator.
-            #act.type would be nice.
-            if hasattr(act, 'action'):
-                if not act.name == 'brik_use_act':
-                    init_ragdoll_controller.deactivate(act)
-                
-        #Needed to prevent brik_use_changed_sens second pulse from re-triggering the script.
-        armature['brik_init_ragdoll'] = False
-            
-        if debug == True:
-            for bone_name in armature['optimal_order']:
-                box_name = armature['bone_box_dict'][bone_name]
-                driver = armature['driver_dict'][box_name]
-                print(driver.name, driver['spawn_point'], driver['spawn_id'])
-    
-if __name__ == '__main__':
-    main()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_load.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_load.py
deleted file mode 100644
index d4f25c2..0000000
--- a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_load.py
+++ /dev/null
@@ -1,232 +0,0 @@
-#brik_load_0_1.py
-
-# ***** BEGIN MIT LICENSE BLOCK *****
-#
-#Script Copyright (c) 2010 Marcus P. Jenkins (Blenderartists user name FunkyWyrm)
-#
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-#
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-#
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-#
-# ***** END MIT LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-'''
-This script loads the necessary data from a text file and stores it in the
-appropriate locations.
-
-It should run once at the very start of the game/level to avoid issues with
-frame rate later on.
-
-This is a load better than my first attempt at parsing a text file, but could
-probably still be optimised more.
-
-FOR MULTIPLE RAGDOLLS IN THE SAME SCENE:
-
-The correct armature data fileS need to be loaded at the start of the game.
-To do this, the name of the text file in the brik_ragdoll_data controller needs
-to be changed so it corresponds with the correct armature.
-
-This needs to be done when brik creates the logic.
-A separate spawn point should be created for each new ragdoll structure that is
-added to the scene. Each spawn point would load the data for it's corresponding
-ragdoll.
-    Alternatively, the brik_load.py script should iterate through all ragdoll
-    structures and load them in turn.
-    
-    The spawn point would need a new property that is a list of all ragdoll armatures
-    in the scene.
-    
-    For each ragdoll:
-        Set the data controller to use the correct data file.
-        Load the data.
-    
-    This would allow for a single spawn point to load all structure data.
-'''
-print('###########################')
-print('RUNNING brik_load_0_1.py')
-
-import bge
-import mathutils
-from mathutils import Vector, Quaternion
-
-class Data:
-    ARMATURE            = 0
-    BASE                = 1
-    BONE                = 2
-
-class Arm:
-    NAME                = 0
-
-class Base:
-    BONE_NAME           = 0
-    BOX_NAME            = 1
-    JOINT_TARGET_NAME   = 2
-    HIT_BOX_NAME        = 3
-
-class Box:
-    BONE_NAME           = 0
-    BOX_NAME            = 1
-    JOINT_TARGET_NAME   = 2
-    HIT_BOX_NAME        = 3
-    JOINT_POSITION_X    = 4
-    JOINT_POSITION_Y    = 5
-    JOINT_POSITION_Z    = 6
-    ###################################################
-    #should no longer need to do this.
-    JOINT_LIMIT_MAX_X   = 7
-    JOINT_LIMIT_MAX_Y   = 8
-    JOINT_LIMIT_MAX_Z   = 9
-    JOINT_LIMIT_MIN_X   = 10
-    JOINT_LIMIT_MIN_Y   = 11
-    JOINT_LIMIT_MIN_Z   = 12
-    
-
-scene = bge.logic.getCurrentScene()
-cont = bge.logic.getCurrentController()
-
-objects = scene.objectsInactive
-
-spawn_point = cont.owner
-
-def load_data(data_cont):
-
-    data_file = data_cont.script
-    #print(data_file)
-    bone_dict = {}
-    optimal_order = []
-    armature_data = []
-    bone_data = []
-    bone_name = ''
-    
-    line = ''
-    data_count = 0
-    item_count = 0
-    for char in data_file:
-        if not char == '\n':
-            line += char
-        else:
-            if line == "'''":   #Ignore the first and last lines with the triple quote.
-                line = ''
-            else:
-                #Store armature data for later assignment to the armature.
-                if data_count == Data.ARMATURE:
-                    if not item_count == Arm.NAME:
-                        armature_data.append(line)
-                        line = ''
-                        item_count += 1
-                    elif item_count == Arm.NAME:    #The last item for the armature.
-                        armature_data.append(line)
-                        line = ''
-                        item_count = 0
-                        data_count += 1
-                #Store data for objects associated with the base bone. This is unique
-                #since it does not need to deal with a parent.
-                elif data_count == Data.BASE:
-                    if item_count == Base.BONE_NAME:
-                        bone_name = line
-                        bone_data.append(line)
-                        optimal_order.append(line)
-                        line = ''
-                        item_count += 1
-                    elif not item_count == Base.HIT_BOX_NAME:
-                        bone_data.append(line)
-                        line = ''
-                        item_count += 1
-                    elif item_count == Base.HIT_BOX_NAME: #The last item for the base bone.
-                        bone_data.append(line)
-                        bone_dict[bone_name] = bone_data
-                        line = ''
-                        bone_name = ''
-                        bone_data = []
-                        item_count = 0
-                        data_count +=1
-                #Store data for objects associated with all other bones in turn.
-                elif data_count == Data.BONE:
-                    if item_count == Box.BONE_NAME:
-                        bone_name = line
-                        optimal_order.append(line)
-                        bone_data.append(line)
-                        line = ''
-                        item_count += 1
-                    elif not item_count == Box.JOINT_LIMIT_MIN_Z:
-                        bone_data.append(line)
-                        line = ''
-                        item_count += 1
-                    elif item_count == Box.JOINT_LIMIT_MIN_Z:   #The last item for this bone.
-                        bone_data.append(line)
-                        bone_dict[bone_name] = bone_data
-                        line = ''
-                        bone_name = ''
-                        bone_data = []
-                        item_count = 0
-    #Armature data assignment
-    armature = objects[armature_data[Arm.NAME]]
-    
-    armature['optimal_order'] = optimal_order
-    armature['bone_box_dict'] = {}
-    armature['bone_hit_box_dict'] = {}
-    
-    #Assignment of bone data and associated objects.
-    for key in optimal_order:
-        data = bone_dict[key]
-        if len(data) == 4:      #The number of data items in the Base class
-            box = objects[data[Base.BOX_NAME]]
-            box['joint_target'] = data[Base.JOINT_TARGET_NAME]
-            box['bone_name'] = data[Base.BONE_NAME]
-            box['hit_box_name'] = data[Base.HIT_BOX_NAME]
-            hit_box = objects[data[Base.HIT_BOX_NAME]]
-            hit_box['bone_name'] = data[Base.BONE_NAME]
-            armature['bone_box_dict'][box['bone_name']] = box.name
-            armature['bone_hit_box_dict'][box['bone_name']] = hit_box.name
-        else:
-            box = objects[data[Box.BOX_NAME]]
-            box['joint_target'] = data[Box.JOINT_TARGET_NAME]
-            box['bone_name'] = data[Box.BONE_NAME]
-            box['hit_box_name'] = data[Box.HIT_BOX_NAME]
-            box['joint_position'] = [float(data[Box.JOINT_POSITION_X]),\
-                                     float(data[Box.JOINT_POSITION_Y]),\
-                                     float(data[Box.JOINT_POSITION_Z])]
-            #############################################
-            #should no longer need to do this
-            box['limit_rotation_x'] = [float(data[Box.JOINT_LIMIT_MIN_X]),\
-                                       float(data[Box.JOINT_LIMIT_MAX_X])]
-            box['limit_rotation_y'] = [float(data[Box.JOINT_LIMIT_MIN_Y]),\
-                                       float(data[Box.JOINT_LIMIT_MAX_Y])]
-            box['limit_rotation_z'] = [float(data[Box.JOINT_LIMIT_MIN_Z]),\
-                                       float(data[Box.JOINT_LIMIT_MAX_Z])]
-            
-            hit_box = objects[data[Box.HIT_BOX_NAME]]
-            hit_box['bone_name'] = data[Box.BONE_NAME]
-            armature['bone_box_dict'][box['bone_name']] = box.name
-            armature['bone_hit_box_dict'][box['bone_name']] = hit_box.name
-        
-    #Set the spawn point to spawn this armature.
-    spawn_point['mob_object'] = armature.name
-    
-def main():
-    mob_total = spawn_point['brik_mob_count']
-            
-    for count in range(0, mob_total+1):
-    
-        for cont in spawn_point.controllers:
-            if cont.name[:-8] == 'brik_ragdoll_data_'+str(count):
-                data_cont = cont
-                
-        load_data(data_cont)
-
-if __name__ == '__main__':
-    main()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_spawn.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_spawn.py
deleted file mode 100644
index d9e1805..0000000
--- a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_spawn.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#brik_spawn_init.py
-
-# ***** BEGIN MIT LICENSE BLOCK *****
-#
-#Script Copyright (c) 2010 Marcus P. Jenkins (Blenderartists user name FunkyWyrm)
-#
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-#
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-#
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-#
-# ***** END MIT LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-import bge
-
-def initialize():
-    spawn_point = bge.logic.getCurrentController().owner
-    
-    #This is a list of all objects added by this spawn point.
-    spawn_point['added_objects'] = []
-    
-    #This is the total number of objects added by this spawn point.
-    #It is used to supply a unique Id to each added object.
-    spawn_point['add_count'] = 0
-    
-def main():
-
-    cont = bge.logic.getCurrentController()
-    sens = cont.sensors['brik_Tab_sens']
-    
-    if sens.getKeyStatus(sens.key) == 1:
-        print('#########################')
-        print('SPAWNING MOB AND HIT BOXES')
-        
-        spawn_act = cont.actuators['brik_spawn_act']
-        
-        scene = bge.logic.getCurrentScene()
-        objects = scene.objects
-        hidden_objects = scene.objectsInactive
-        
-        spawn_empty = cont.owner
-        
-        mob_object = hidden_objects[spawn_empty['mob_object']]
-        #mob_object = hidden_objects['Armature.001']
-        
-        spawn_act.object = mob_object.name
-        spawn_act.instantAddObject()
-        last_spawned = spawn_act.objectLastCreated
-        #print(dir(last_spawned))
-        spawn_empty['added_objects'].append(last_spawned)
-        spawn_empty['add_count'] += 1
-        
-        #This is used to identify which spawn point the spawned object was added by.
-        last_spawned['spawn_point'] = spawn_empty.name
-        #This is a unique Id used to identify the added object.
-        last_spawned['spawn_id'] = spawn_empty['add_count']
-        #This is the dictionary of drivers that are unique to the added object.
-        '''
-        Originally this dictionary was defined in the brik_load.py script, but since
-        dictionaries are stored as a reference, and the added objects are copies of the
-        hidden object, the added objects had a copy of the reference to the dictionary
-        and all used the same dictionary.
-        Defining the dictionary after the objects are added to the scene ensures that
-        they each have a unique dictionary.
-        '''
-        last_spawned['driver_dict'] = {}
diff --git a/release/scripts/addons_contrib/geodesic_domes/__init__.py b/release/scripts/addons_contrib/geodesic_domes/__init__.py
deleted file mode 100644
index 97422ba..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/__init__.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Geodesic Domes",
-    "author": "PKHG , Meta Androcto, Kilon original for 2.49 from Andy Houston",
-    "version": (0,2,3),
-    "blender": (2, 6, 1),
-    "location": "View3D > UI > Geodesic...",
-    "description": "Choice for objects",
-    "warning": "not yet finished",
-    "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.5/Py/Scripts/Modeling/Geodesic_Domes",
-    "tracker_url": "",
-    "category": "Mesh"}
-
-"""
-Added save and load of parameters 14-12-2011 PKHG
-Added one possible *.bak for GD_0.GD (one time) 17-12-2011
-"""
-if "bpy" in locals():
-    import imp
-    imp.reload(third_domes_panel)
-    
-else:
-    from geodesic_domes import third_domes_panel
-   
-import bpy
-from bpy.props import *
-
-def register():
-    bpy.utils.register_module(__name__)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-if __name__ == "__main__":
-    register()
-
-
-
diff --git a/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py b/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py
deleted file mode 100644
index 324ef94..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import bpy
-import mathutils
-
-def reset_transform(ob):
-    m = mathutils.Matrix()
-    ob.matrix_local = m     
-
-def func_add_corrective_pose_shape_fast(source, target):
-    result = ""
-    reset_transform(target)
-    # If target object doesn't have Basis shape key, create it.
-    try:
-        num_keys = len( target.data.shape_keys.key_blocks )
-    except:
-        basis = target.shape_key_add()
-        basis.name = "Basis"
-        target.data.update()
-    key_index = target.active_shape_key_index
-    if key_index == 0:
-        # Insert new shape key
-        new_shapekey = target.shape_key_add()
-        new_shapekey.name = "Shape_" + source.name
-        new_shapekey_name = new_shapekey.name
-        key_index = len(target.data.shape_keys.key_blocks)-1
-        target.active_shape_key_index = key_index
-    # else, the active shape will be used (updated)
-    target.show_only_shape_key = True
-    shape_key_verts = target.data.shape_keys.key_blocks[ key_index ].data
-    try:
-        vgroup = target.active_shape_key.vertex_group
-        target.active_shape_key.vertex_group = ''
-    except:
-        print("blub")
-        result = "***ERROR*** blub"
-        pass
-    # copy the local vertex positions to the new shape
-    verts = source.data.vertices
-    try:
-        for n in range( len(verts)):
-            shape_key_verts[n].co = verts[n].co
-    # go to all armature modifies and unpose the shape
-    except:
-        message = "***ERROR***, meshes have different number of vertices"
-        result =  message
-    for n in target.modifiers:
-        if n.type == 'ARMATURE' and n.show_viewport:
-            #~ print("got one")
-            n.use_bone_envelopes = False
-            n.use_deform_preserve_volume = False
-            n.use_vertex_groups = True
-            armature = n.object
-            unposeMesh( shape_key_verts, target, armature)
-            break
-    
-    # set the new shape key value to 1.0, so we see the result instantly
-    target.data.shape_keys.key_blocks[ target.active_shape_key_index].value = 1.0
-    try:
-        target.active_shape_key.vertex_group = vgroup
-    except:
-        print("bluba")
-        result  = result + "bluba"
-        pass
-    target.show_only_shape_key = False
-    target.data.update()
-    return result
-    
-class add_corrective_pose_shape_fast(bpy.types.Operator):   
-    '''Adds 1st object as shape to 2nd object as pose shape (only 1 armature)'''
-    bl_idname = "object.add_corrective_pose_shape_fast"
-    bl_label = "Add object as corrective shape faster"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-    
-        if len(context.selected_objects) > 2:
-            print("Select source and target objects please")
-            return {'FINISHED'}
-
-        selection = context.selected_objects
-        target = context.active_object
-        if context.active_object == selection[0]:
-            source = selection[1]
-        else:
-            source = selection[0]
-        print(source)
-        print(target)
-        func_add_corrective_pose_shape_fast( source, target)
-        return {'FINISHED'}
-
-def register():
-    bpy.utils.register_module(__name__)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/geodesic_domes/forms_259.py b/release/scripts/addons_contrib/geodesic_domes/forms_259.py
deleted file mode 100644
index 4e451a5..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/forms_259.py
+++ /dev/null
@@ -1,222 +0,0 @@
-import math
-from math import pi,sin,cos,atan,tan,fabs
-from geodesic_domes.vefm_259 import *
-class form(mesh):
-    def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
-        mesh.__init__(self)
-        #PKHG alredey in vefm259 mesh: self.a360 = pi * 2.0
-        self.PKHG_parameters = [uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform]
-        self.ures = uresolution
-        self.vres = vresolution
-        
-        self.uscale = uscale
-        self.vscale = vscale
-        self.upart = upart
-        self.vpart = vpart
-        self.uphase = uphase * self.a360
-        self.vphase = vphase * self.a360
-        self.utwist = utwist
-        self.vtwist = vtwist
-        
-        self.xscale = xscale
-        self.yscale = yscale
-        self.sform = sform
-                
-        if self.upart != 1.0:    ## there is a gap in the major radius
-            self.uflag = 1
-        else:
-            self.uflag = 0
-        if self.vpart != 1.0:    ## there is a gap in the minor radius
-            self.vflag = 1
-        else:
-            self.vflag = 0
-        if self.uflag:
-            self.ufinish = self.ures + 1
-        else:
-            self.ufinish = self.ures
-        if self.vflag:
-            self.vfinish = self.vres + 1
-        else:
-            self.vfinish = self.vres
-        self.ustep = (self.a360 / self.ures) * self.upart
-        self.vstep = (self.a360 / self.vres) * self.vpart
-        if self.xscale != 1.0:
-            self.xscaleflag = 1
-        else:            
-            self.xscaleflag = 0        
-        if self.yscale != 1.0:            
-            self.yscaleflag = 1            
-        else:            
-            self.yscaleflag = 0                            
-        self.rowlist=[]
-
-    def generatepoints(self):
-        for i in range(self.ufinish):
-            row=[]
-            for j in range(self.vfinish):
-                u = self.ustep * i + self.uphase
-                v = self.vstep * j + self.vphase
-            #    if self.xscaleflag:
-            #        u = self.ellipsecomp(self.xscale,u) 
-            #    if self.yscaleflag:
-            #        v = self.ellipsecomp(self.yscale,v)            
-                if self.sform[12]:
-                    r1 = self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14] + u,self.sform[4],self.sform[5],self.sform[16] * v)
-                else:
-                    r1 = 1.0
-                if self.sform[13]:
-                    r2 = self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15] + v,self.sform[10],self.sform[11],self.sform[17] * v)
-                else:
-                    r2 = 1.0
-                x,y,z = self.formula(u,v,r1,r2)
-                point = vertex((x,y,z))
-                row.append(point)
-                self.verts.append(point)
-            self.rowlist.append(row)
-        if self.vflag:
-            pass
-        else:
-            for i in range(len(self.rowlist)):
-                self.rowlist[i].append(self.rowlist[i][0])
-        if  self.uflag:
-            pass
-        else:
-            self.rowlist.append(self.rowlist[0])
-
-#    def formula(self,u,v,r1,r2):
-#        pass
-
-    def generatefaces(self):
-        ufin = len(self.rowlist) - 1
-        vfin = len(self.rowlist[0]) - 1
-        for i in range(ufin):
-            for j in range(vfin):
-                top = i
-                bottom = i + 1
-                left = j
-                right = j + 1
-                a = self.rowlist[top][left]
-                b = self.rowlist[top][right]
-                c = self.rowlist[bottom][right]
-                d = self.rowlist[bottom][left]
-                face1 = face([a,b,c,d])
-                self.faces.append(face1)
-                edge1 = edge(a,b)
-                edge2 = edge(a,d)
-                self.edges.append(edge1)
-                self.edges.append(edge2)
-                if i + 1 == ufin:
-                    edge3 = edge(d,c)
-                    self.edges.append(edge3)
-                if j + 1 == vfin:
-                    edge4 = edge(b,c)
-                    self.edges.append(edge4)
-    
-class grid(form):
-    def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
-        form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
-        unit = 1.0 / self.a360
-        if self.ures == 1 :            
-            print("\n***ERRORin forms_259.grid L121***, ures is  1, changed into 2\n\n")
-            self.ures = 2
-        if self.vres == 1 :            
-            print("\n***ERROR in grid forms_259.grid L124***, vres is 1, changed into 2\n\n")
-            self.vres = 2            
-        self.ustep = self.a360 / (self.ures - 1)
-        self.vstep = self.a360 / (self.vres - 1)
-        
-        self.uflag = 1
-        self.vflag = 1
-            
-        self.xscaleflag = 0        
-        self.yscaleflag = 0
-        self.uexpand = unit * self.uscale
-        self.vexpand = unit * self.vscale
-        self.ushift = self.uscale * 0.5
-        self.vshift = self.vscale * 0.5
-        
-        self.generatepoints()
-        self.generatefaces()
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        self.connectivity()
-                
-    def formula(self,u,v,r1,r2):     
-        x = u * self.uexpand - self.ushift
-        y = v * self.vexpand - self.vshift
-        z = r1 * r2 - 1.0         
-        return x,y,z
-    
-    
-class cylinder(form):
-    def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
-        form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
-        unit = 1.0 / self.a360
-        self.vshift = self.vscale * 0.5
-        self.vexpand = unit * self.vscale
-        self.vflag = 1    
-        self.generatepoints()
-        self.generatefaces()
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        self.connectivity()    
-
-    def formula(self,u,v,r1,r2):
-        x = sin(u) * self.uscale * r1 * r2 * self.xscale
-        y = cos(u) * self.uscale * r1 * r2
-        z = v * self.vexpand - self.vshift
-        return x,y,z
-
-class parabola(form):
-    def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
-        form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
-        unit = 1.0 / self.a360
-        self.vshift = self.vscale * 0.5
-        self.vexpand = unit * self.vscale
-        self.vflag = 1
-        self.generatepoints()
-        self.generatefaces()
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        self.connectivity()        
-    
-    def formula(self,u,v,r1,r2):
-        factor = sqrt(v) + 0.001
-        x = sin(u) * factor * self.uscale * r1 * r2 * self.xscale
-        y = cos(u) * factor * self.uscale * r1 * r2
-        z = - v * self.vexpand + self.vshift
-        return x,y,z
-        
-class torus(form):    
-    def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
-        form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
-        self.generatepoints()
-        self.generatefaces()
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        self.connectivity()        
-                    
-    def formula(self,u,v,r1,r2):
-        z = sin(v) * self.uscale * r2 * self.yscale
-        y = (self.vscale + self.uscale * cos(v)) * cos(u) * r1 * r2
-        x = (self.vscale + self.uscale * cos(v)) * sin(u) * r1 * r2 * self.xscale
-        return x,y,z
-
-class sphere(form):
-    
-    def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
-        form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
-        self.vstep = (self.a360 / (self.vres - 1)) * self.vpart
-        self.vflag = 1
-        self.generatepoints()
-        self.generatefaces()
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        self.connectivity()        
-        
-    def formula(self,u,v,r1,r2):
-        v = (v * 0.5) - (self.a360 * 0.25)
-        x = r1 * cos(u) * r2 * cos(v) * self.uscale * self.xscale
-        y = r1 * sin(u) * r2 * cos(v) * self.uscale
-        z = r2 * sin(v) * self.uscale * self.yscale
-        return x,y,z
diff --git a/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py b/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py
deleted file mode 100644
index 15378ce..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py
+++ /dev/null
@@ -1,754 +0,0 @@
-#werkt from geodesic_domes.vefm_259 import *
-from geodesic_domes.vefm_259 import mesh, vertex, edge, face
-
-import math
-from math import pi,acos,sin,cos,atan,tan,fabs, sqrt
-
-def check_contains(cl,name , print_value = False):
-    dir_class = dir(cl)
-    for el in dir_class:
-        if el.startswith("_"):
-            pass
-        else:
-            if print_value:
-                tmp = getattr(cl,el)
-                print(name , " contains ==>",el," value = ", tmp)
-            else:
-                print(name , " contains ==>",el)
-    print("\ncheck_contains finished\n\n")
-
-class geodesic(mesh):
-    def __init__(self):
-        mesh.__init__(self)
-        self.PKHG_parameters = None
-#        print("\n------ geodesic L11 PKHG_parameters",PKHG_parameters)
-        self.panels = []
-        self.vertsdone = []
-        self.skeleton = []                ## List of verts in the full skeleton edges.
-        self.vertskeleton = [] # config needs this member
-        self.edgeskeleton = [] # config needs this member
-        self.sphericalverts = []
-        self.a45 = pi * 0.25
-        self.a90 = pi * 0.5
-        self.a180 = pi
-        self.a270 = pi * 1.5
-        self.a360 = pi * 2
-        #define members here
-        #setparams  needs:
-        self.frequency = None
-        self.eccentricity = None
-        self.squish = None
-        self.radius = None
-        self.square = None
-        self.squarez = None
-        self.cart = None
-        self.shape = None
-        self.baselevel = None
-        self.faceshape = None
-        self.dualflag = None
-        self.rotxy = None
-        self.rotz = None
-        self.klass = None
-        self.sform = None
-        self.super = None
-        self.odd = None
-        #config needs
-        self.panelpoints = None
-        self.paneledges = None
-        self.reversepanel = None
-        self.edgelength = None
-        self.vertsdone = None
-        self.panels = []
-    
-#PKHG because of unittest approach for a while the following three lines commentd
-#PKHG do not understand the problems with the next three lines
-#no does not work        self.setparameters()
-#        self.makegeodesic()
-#        self.connectivity()
-
-    def setparameters(self,params):
-        parameters = self.PKHG_parameters = params
-        self.frequency = parameters[0]    ## How many subdivisions - up to 20.
-        self.eccentricity = parameters[1]    ## Elliptical if >1.0.
-        self.squish = parameters[2]        ## Flattened if < 1.0.
-        self.radius = parameters[3]        ## Exactly what it says.
-        self.square = parameters[4]        ## Controls amount of superellipse in X/Y plane.
-        self.squarez = parameters[5]        ## Controls amount of superellipse in Z dimension.
-        self.cart = parameters[6]            ## Cuts out sphericalisation step.
-        self.shape = parameters[7]        ## Full sphere, dome, flatbase.
-        self.baselevel = parameters[8]        ## Where the base is cut on a flatbase dome.
-        self.faceshape = parameters[9]    ## Triangular, hexagonal, tri-hex.
-        self.dualflag = parameters[10]
-        self.rotxy = parameters[11]
-        self.rotz = parameters[12]
-        self.klass = parameters[13]
-        self.sform = parameters[14]
-        self.super = 0                    ## Toggles superellipse.
-        if self.square != 2.0 or self.squarez != 2.0:
-            self.super = 1
-        self.odd = 0                    ## Is the frequency odd. It matters for dome building.
-        if self.frequency % 2 != 0:
-            self.odd = 1
-
-    def makegeodesic(self):
-        self.vertedgefacedata() #PKHG only a pass 13okt11
-        self.config()                    ## Generate all the configuration information.
-        if self.klass:            
-            self.class2()
-        if self.faceshape == 1:
-            self.hexify()                ## Hexagonal faces
-        elif self.faceshape == 2:
-            self.starify()                ## Hex and Triangle faces
-        if self.dualflag:
-            self.dual()
-        if not self.cart:
-            self.sphericalize()    ##   Convert x,y,z positions into spherical u,v.
-        self.sphere2cartesian()    ##   Convert spherical uv back into cartesian x,y,z for final shape.
-        for i in range(len( self.verts)):
-            self.verts[i].index = i
-        for edg in self.edges:
-            edg.findvect()
-
-    def vertedgefacedata(self):
-        pass
-
-#PKHG 23.1    def config(self, frequency = 1): #???PKHG frequency problem  20 oct.
-    def config(self): #???PKHG frequency problem  20 oct.
-#PKHG_OK        print("\n20-11 >>>>>>>>>DBG geodesic_classes_259 config L117 called")
-        for i in range(len(self.vertskeleton)):
-            self.vertskeleton[i].index = i
-        for edges in self.edgeskeleton:
-#???PKHG TODO            s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic
-            s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic
-            self.skeleton.append(s)
-        for i in range(len( self.verts)):
-            self.verts[i].index = i
-        for i in range(len(self.panelpoints)):
-            a = self.vertsdone[self.panelpoints[i][0]][1]
-            b = self.vertsdone[self.panelpoints[i][1]][1]
-            c = self.vertsdone[self.panelpoints[i][2]][1]
-            panpoints = [    self.verts[a],
-                        self.verts[b],
-                        self.verts[c]]
-            panedges = [    self.skeleton[self.paneledges[i][0]],
-                        self.skeleton[self.paneledges[i][1]],
-                        self.skeleton[self.paneledges[i][2]]    ]
-            reverseflag = 0
-            for flag in self.reversepanel:
-                if flag == i:
-                    reverseflag = 1                     
-            p = panel(panpoints, panedges, reverseflag, self)
-#PKHG_panels not used?!            self.panels.append(p)
-        
-    def sphericalize(self):
-        if self.shape == 2:
-            self.cutbasecomp()
-        for vert in(self.verts):
-#PKHG test 20111030        
-#            x = vert.x
-#            y = vert.y
-#            z = vert.z
-            x = vert.vector.x
-            y = vert.vector.y
-            z = vert.vector.z
-
-            u = self.usphericalise(x,y,z)
-            v = self.vsphericalise(x,y,z)
-            self.sphericalverts.append([u,v])
-
-    def sphere2cartesian(self):
-#PKHG_TODOnot_now        check_contains(self,"sphereto self",True)
-        for i in range(len(self.verts)):
-            if self.cart:
-#PKHG test 20111030                        
-#                x = self.verts[i].x * self.radius * self.eccentricity
-#                y = self.verts[i].y * self.radius
-#                z = self.verts[i].z * self.radius * self.squish
-                x = self.verts[i].vector.x * self.radius * self.eccentricity
-                y = self.verts[i].vector.y * self.radius
-                z = self.verts[i].vector.z * self.radius * self.squish
-            else:
-                u = self.sphericalverts[i][0]
-                v = self.sphericalverts[i][1]
-                if self.squish != 1.0 or self.eccentricity>1.0:
-                    scalez = 1 / self.squish
-                    v = self.ellipsecomp(scalez,v)
-                    u = self.ellipsecomp(self.eccentricity,u)
-                if self.super:
-                    r1 = self.superell(self.square,u,self.rotxy)
-                    r2 = self.superell(self.squarez,v,self.rotz)
-                else:
-                    r1 = 1.0
-                    r2 = 1.0
-                
-            #    print "sform",self.sform,"  u",u,"  v",v
-                if self.sform[12]:
-                    
-                    r1 = r1 * self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14] + u,self.sform[4],self.sform[5],self.sform[16] * v)
-                if self.sform[13]:
-                
-                    r2 = r2 * self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15] + v,self.sform[10],self.sform[11],self.sform[17] * v)
-                x,y,z = self.cartesian(u,v,r1,r2)
-#PKHG test 20111030                        
-#            self.verts[i].x = x
-#            self.verts[i].y = y
-#            self.verts[i].z = z
-            self.verts[i] = vertex((x,y,z))
-        
-    def usphericalise(self,x,y,z):
-        if y == 0.0:
-            if x>0:
-                theta = 0.0
-            else:
-                theta = self.a180
-        elif x == 0.0:
-            if y>0:
-                theta = self.a90
-            else:
-                theta = self.a270
-                
-        else:
-            theta = atan(y / x)
-        if x < 0.0 and y < 0.0:
-            theta = theta + self.a180
-        elif x < 0.0 and y>0.0:
-            theta = theta + self.a180
-        u = theta
-        return u
-    
-    def vsphericalise(self,x,y,z) :
-        if z == 0.0:
-            phi = self.a90
-        else:
-            rho = sqrt(x ** 2 + y**2 + z**2)
-            phi = acos(z / rho)
-        v = phi
-        return v
-    def ellipsecomp(self,efactor,theta):
-        if theta == self.a90:
-            result = self.a90
-        elif theta == self.a270:
-            result = self.a270
-        else:
-            result = atan(tan(theta) / efactor**0.5)
-            if result>=0.0:
-                x = result
-                y = self.a180 + result
-                if fabs(x - theta) <= fabs(y - theta):
-                    result = x
-                else:
-                    result = y
-            else:
-                x = self.a180 + result
-                y = result
-            
-                if fabs(x - theta) <= fabs(y - theta):
-                    result = x
-                else:
-                    result = y
-        return result
-    def cutbasecomp(self):
-        pass
-
-    def cartesian(self,u,v,r1,r2):
-        x = r1 * cos(u) * r2 * sin(v) * self.radius * self.eccentricity
-        y = r1 * sin(u) * r2 * sin(v) * self.radius
-        z = r2 * cos(v) * self.radius * self.squish
-        return x,y,z
-#     def connectivity(self):
-# 
-#         self.dovertedge()
-#         self.dovertface()
-#         self.dofaceedge()
-
-class edgerow:
-    def __init__(self, count, anchor, leftindex, rightindex, stepvector, endflag, parentgeo):
-        self.points = []
-        self.edges = []
-        ## Make a row of evenly spaced points.
-        for i in range(count + 1):
-            if i == 0:
-                self.points.append(leftindex)
-            elif i == count and not endflag:
-                self.points.append(rightindex)
-            else: #PKHG Vectors added!
-                newpoint = anchor + (stepvector * i)
-                vertcount = len(parentgeo.verts)
-                self.points.append(vertcount)
-                newpoint.index = vertcount
-                parentgeo.verts.append(newpoint)
-        for i in range(count):
-            a = parentgeo.verts[self.points[i]]
-            b = parentgeo.verts[self.points[i + 1]]
-            line = edge(a,b)
-            self.edges.append(len(parentgeo.edges))
-            parentgeo.edges.append(line)
-
-class skeletonrow:
-    def __init__(self, count, skeletonedge, shortflag, parentgeo):
-        self.points = []
-        self.edges = []
-        self.vect = skeletonedge.vect
-        self.step = skeletonedge.vect / float(count)
-        ## Make a row of evenly spaced points.
-        for i in range(count + 1):
-            vert1 = skeletonedge.a
-            vert2 = skeletonedge.b
-            if i == 0:
-                if parentgeo.vertsdone[vert1.index][0]:
-                    self.points.append(parentgeo.vertsdone[vert1.index][1])
-                else:
-#PKHG test 20111030
-#                    newpoint = vertex((vert1.x, vert1.y, vert1.z))
-                    newpoint = vertex(vert1.vector)
-                    vertcount = len(parentgeo.verts)
-                    self.points.append(vertcount)
-                    newpoint.index = vertcount
-                    parentgeo.vertsdone[vert1.index] = [1,vertcount]
-                    parentgeo.verts.append(newpoint)                    
-                    
-            elif i == count:
-                if parentgeo.vertsdone[vert2.index][0]:
-                    self.points.append(parentgeo.vertsdone[vert2.index][1])
-                else:
-#PKHG test 20111030                    
-#                    newpoint = vertex((vert2.x, vert2.y, vert2.z))
-                    newpoint = vertex(vert2.vector)
-                    vertcount = len(parentgeo.verts)
-                    self.points.append(vertcount)
-                    newpoint.index = vertcount
-                    parentgeo.vertsdone[vert2.index] = [1,vertcount]
-                    parentgeo.verts.append(newpoint)                    
-            else:
-                newpoint = vertex(vert1.vector + (self.step * i)) #must be a vertex!
-                vertcount = len(parentgeo.verts)
-                self.points.append(vertcount)
-                newpoint.index = vertcount
-                parentgeo.verts.append(newpoint)
-        for i in range(count):
-            a = parentgeo.verts[self.points[i]]
-            b = parentgeo.verts[self.points[i + 1]]
-            line = edge(a,b)
-            self.edges.append(len(parentgeo.edges))
-            parentgeo.edges.append(line)
-
-class facefill:
-    def __init__(self, upper, lower, reverseflag, parentgeo, finish):
-        for i in range(finish):
-            a,b,c = upper.points[i],lower.points[i + 1],lower.points[i]
-            if reverseflag:
-                upface = face([parentgeo.verts[a],parentgeo.verts[c],parentgeo.verts[b]])
-            else:
-                upface = face([parentgeo.verts[a],parentgeo.verts[b],parentgeo.verts[c]])
-            parentgeo.faces.append(upface)
-            if i == finish - 1:
-                pass
-            else:
-                d = upper.points[i + 1]
-                if reverseflag:
-                    downface = face([parentgeo.verts[b],parentgeo.verts[d],parentgeo.verts[a]])
-                else:
-                    downface = face([parentgeo.verts[b],parentgeo.verts[a],parentgeo.verts[d]])
-                line = edge(parentgeo.verts[a],parentgeo.verts[b])
-                line2 = edge(parentgeo.verts[d],parentgeo.verts[b])
-                parentgeo.faces.append(downface)
-                parentgeo.edges.append(line)
-                parentgeo.edges.append(line2)
-class panel:
-    def __init__(self, points, edges, reverseflag, parentgeo):
-        self.cardinal = points[0]
-        self.leftv = points[1]
-        self.rightv = points[2]
-        self.leftedge = edges[0]
-        self.rightedge = edges[1]
-        self.baseedge = edges[2]
-        self.rows=[]
-        self.orient(parentgeo,edges)
-        self.createrows(parentgeo)
-        self.createfaces(parentgeo,reverseflag)
-
-    def orient(self,parentgeo,edges):
-        if self.leftedge.points[0] != self.cardinal.index:
-            self.leftedge.points.reverse()
-            self.leftedge.vect.negative()
-        
-        if self.rightedge.points[0] != self.cardinal.index:
-            self.rightedge.points.reverse()
-            self.rightedge.vect.negative()
-        
-        if self.baseedge.points[0] != self.leftv.index:
-        
-            self.baseedge.points.reverse()
-            self.baseedge.vect.negative()
-
-    def createrows(self, parentgeo):
-        for i in range(len(self.leftedge.points)):
-            if i == parentgeo.frequency:
-                newrow = self.baseedge
-            else:
-                newrow = edgerow(i, parentgeo.verts[self.leftedge.points[i]], self.leftedge.points[i], self.rightedge.points[i], self.baseedge.step, 0, parentgeo )
-            self.rows.append(newrow)
-    def createfaces(self, parentgeo,reverseflag):
-        for i in range(len(self.leftedge.points) - 1):
-            facefill(self.rows[i], self.rows[i + 1], reverseflag, parentgeo, len(self.rows[i].points))
-#############################
-#############################
-
-#for point on top?  YES!          
-class tetrahedron(geodesic,mesh):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-        
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( 0.0 , 0.0 , 1.73205080757 )),
-                            vertex(( 0.0 , -1.63299316185 , -0.577350269185 )),
-                            vertex(( 1.41421356237 , 0.816496580927 , -0.57735026919 )),
-                            vertex(( -1.41421356237 , 0.816496580927 , -0.57735026919 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[0],self.vertskeleton[2]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[2]),
-                            edge(self.vertskeleton[2],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[3])    ]
-        
-### probably to be removed, other gui! : "#??? delete PKHG"
-        self.panelpoints=[[0,1,2],[0,2,3],[0,1,3],[1,2,3]]
-        self.paneledges=[[0,1,3],[1,2,4],[0,2,5],[3,5,4]]
-        self.reversepanel=[2,3]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-
-#for edge on top? YES
-class tetraedge(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( 0.0 , -1.41421356237 , 1.0 )),
-                            vertex(( 0.0 , 1.41421356237 , 1.0 )),
-                            vertex(( 1.41421356237 , 0.0 , -1.0 )),
-                            vertex(( -1.41421356237 , 0.0 , -1.0 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[0],self.vertskeleton[2]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[2]),
-                            edge(self.vertskeleton[2],self.vertskeleton[3])    ]
-        for i in range(len(self.vertskeleton)):
-            self.vertskeleton[i].index = i
-        self.panelpoints=[[0,1,2],[1,2,3],[0,1,3],[0,2,3]]
-        self.paneledges=[[0,1,4],[4,3,5],[0,2,3],[1,2,5]]
-        self.reversepanel=[0,3]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-
-#for face on top? YES
-class tetraface(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( -1.41421356237 , -0.816496580927 , 0.57735026919 )),
-                            vertex(( 1.41421356237 , -0.816496580927 , 0.57735026919 )),
-                            vertex(( 0.0 , 1.63299316185 , 0.577350269185 )),
-                            vertex(( 0.0 , 0.0 , -1.73205080757 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[2],self.vertskeleton[1]),
-                            edge(self.vertskeleton[2],self.vertskeleton[0]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[3]),
-                            edge(self.vertskeleton[2],self.vertskeleton[3])    ]
-        self.panelpoints=[[2,0,1],[0,1,3],[2,1,3],[2,0,3]]
-        self.paneledges=[[2,1,0],[0,3,4],[1,5,4],[2,5,3]]
-        self.reversepanel=[1,3]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-
-class octahedron(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex((0.0,0.0,1.0)),
-                            vertex((0.0,1.0,0.0)),
-                            vertex((-1.0,0.0,0.0)),
-                            vertex((0.0,-1.0,0.0)),
-                            vertex((1.0,0.0,0.0)),
-                            vertex((0.0,0.0,-1.0))    ]
-        for i in range(len(self.vertskeleton)):
-            self.vertskeleton[i].index = i
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[0],self.vertskeleton[2]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[0],self.vertskeleton[4]),
-                            edge(self.vertskeleton[1],self.vertskeleton[2]),
-                            edge(self.vertskeleton[2],self.vertskeleton[3]),
-                            edge(self.vertskeleton[3],self.vertskeleton[4]),
-                            edge(self.vertskeleton[4],self.vertskeleton[1]),
-                            edge(self.vertskeleton[1],self.vertskeleton[5]),
-                            edge(self.vertskeleton[2],self.vertskeleton[5]),
-                            edge(self.vertskeleton[3],self.vertskeleton[5]),
-                            edge(self.vertskeleton[4],self.vertskeleton[5])    ]
-        self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]]
-        self.paneledges=[[0,1,4],[1,2,5],[2,3,6],[3,0,7],[4,8,9],[5,9,10],[6,10,11],[7,11,8]]
-        self.reversepanel=[4,5,6,7]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-class octaedge(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( 0.0 , -0.707106781187 , 0.707106781187 )),
-                            vertex(( 0.0 , 0.707106781187 , 0.707106781187 )),
-                            vertex(( 1.0 , 0.0 , 0.0 )),
-                            vertex(( -1.0 , 0.0 , 0.0 )),
-                            vertex(( 0.0 , -0.707106781187 , -0.707106781187 )),
-                            vertex(( 0.0 , 0.707106781187 , -0.707106781187 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[0],self.vertskeleton[4]),
-                            edge(self.vertskeleton[0],self.vertskeleton[2]),
-                            edge(self.vertskeleton[1],self.vertskeleton[2]),
-                               edge(self.vertskeleton[1],self.vertskeleton[5]),
-                            edge(self.vertskeleton[1],self.vertskeleton[3]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[2],self.vertskeleton[4]),
-                               edge(self.vertskeleton[2],self.vertskeleton[5]),
-                            edge(self.vertskeleton[3],self.vertskeleton[5]),
-                            edge(self.vertskeleton[3],self.vertskeleton[4]),
-                            edge(self.vertskeleton[4],self.vertskeleton[5])    ]
-        self.panelpoints=[[0,1,2],[0,1,3],[0,2,4],[1,2,5],[1,3,5],[0,3,4],[2,4,5],[3,4,5]]
-        self.paneledges=[[0,2,3],[0,6,5],[2,1,7],[3,4,8],[5,4,9],[6,1,10],[7,8,11],[10,9,11]]
-        self.reversepanel=[0,2,4,7]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-class octaface(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( 0.408248458663 , -0.707106781187 , 0.577350150255 )),
-                            vertex(( 0.408248458663 , 0.707106781187 , 0.577350150255 )),
-                            vertex(( -0.816496412728 , 0.0 , 0.577350507059 )),
-                            vertex(( -0.408248458663 , -0.707106781187 , -0.577350150255 )),
-                            vertex(( 0.816496412728 , 0.0 , -0.577350507059 )),
-                            vertex(( -0.408248458663 , 0.707106781187 , -0.577350150255 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[2],self.vertskeleton[1]),
-                            edge(self.vertskeleton[2],self.vertskeleton[0]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                             edge(self.vertskeleton[0],self.vertskeleton[4]),
-                            edge(self.vertskeleton[1],self.vertskeleton[4]),
-                            edge(self.vertskeleton[1],self.vertskeleton[5]),
-                            edge(self.vertskeleton[2],self.vertskeleton[5]),
-                            edge(self.vertskeleton[2],self.vertskeleton[3]),
-                            edge(self.vertskeleton[3],self.vertskeleton[4]),
-                            edge(self.vertskeleton[4],self.vertskeleton[5]),
-                            edge(self.vertskeleton[3],self.vertskeleton[5])    ]
-        self.panelpoints=[[2,0,1],[0,3,4],[0,1,4],[1,4,5],[2,1,5],[2,3,5],[2,0,3],[3,4,5]]
-        self.paneledges=[[2,1,0],[3,4,9],[0,4,5],[5,6,10],[1,7,6],[8,7,11],[2,8,3],[9,11,10]]
-        self.reversepanel=[2,5,6,7]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-class icosahedron(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( 0.0 , 0.0 , 0.587785252292 )),
-                            vertex(( 0.0 , -0.525731096637 , 0.262865587024 )),
-                            vertex(( 0.5 , -0.162459832634 , 0.262865565628 )),
-                            vertex(( 0.309016994375 , 0.425325419658 , 0.262865531009 )),
-                            vertex(( -0.309016994375 , 0.425325419658 , 0.262865531009 )),
-                            vertex(( -0.5 , -0.162459832634 , 0.262865565628 )),
-                            vertex(( 0.309016994375 , -0.425325419658 , -0.262865531009 )),
-                            vertex(( 0.5 , 0.162459832634 , -0.262865565628 )),
-                            vertex(( 0.0 , 0.525731096637 , -0.262865587024 )),
-                            vertex(( -0.5 , 0.162459832634 , -0.262865565628 )),
-                            vertex(( -0.309016994375 , -0.425325419658 , -0.262865531009 )),
-                            vertex(( 0.0 , 0.0 , -0.587785252292 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[0],self.vertskeleton[2]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[0],self.vertskeleton[4]),
-                            edge(self.vertskeleton[0],self.vertskeleton[5]),
-                            edge(self.vertskeleton[1],self.vertskeleton[2]),
-                            edge(self.vertskeleton[2],self.vertskeleton[3]),
-                            edge(self.vertskeleton[3],self.vertskeleton[4]),
-                            edge(self.vertskeleton[4],self.vertskeleton[5]),
-                            edge(self.vertskeleton[5],self.vertskeleton[1]),
-                            edge(self.vertskeleton[1],self.vertskeleton[6]),
-                            edge(self.vertskeleton[2],self.vertskeleton[6]),
-                            edge(self.vertskeleton[2],self.vertskeleton[7]),
-                            edge(self.vertskeleton[3],self.vertskeleton[7]),
-                            edge(self.vertskeleton[3],self.vertskeleton[8]),
-                            edge(self.vertskeleton[4],self.vertskeleton[8]),
-                            edge(self.vertskeleton[4],self.vertskeleton[9]),
-                            edge(self.vertskeleton[5],self.vertskeleton[9]),
-                            edge(self.vertskeleton[5],self.vertskeleton[10]),
-                            edge(self.vertskeleton[1],self.vertskeleton[10]),
-                            edge(self.vertskeleton[6],self.vertskeleton[7]),
-                            edge(self.vertskeleton[7],self.vertskeleton[8]),
-                            edge(self.vertskeleton[8],self.vertskeleton[9]),
-                            edge(self.vertskeleton[9],self.vertskeleton[10]),
-                            edge(self.vertskeleton[10],self.vertskeleton[6]),
-                            edge(self.vertskeleton[6],self.vertskeleton[11]),
-                            edge(self.vertskeleton[7],self.vertskeleton[11]),
-                            edge(self.vertskeleton[8],self.vertskeleton[11]),
-                            edge(self.vertskeleton[9],self.vertskeleton[11]),
-                            edge(self.vertskeleton[10],self.vertskeleton[11])    ]
-        self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],[2,6,7],[2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],[5,9,10],[5,1,10],[1,10,6],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11]]
-        self.paneledges=[[0,1,5],[1,2,6],[2,3,7],[3,4,8],[4,0,9],[5,10,11],[11,12,20],[6,12,13],[13,14,21],[7,14,15],[15,16,22],[8,16,17],[17,18,23],[9,18,19],[19,10,24],[20,25,26],[21,26,27],[22,27,28],[23,28,29],[24,29,25]]
-        self.reversepanel=[5,7,9,11,13,15,16,17,18,19]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-class icoedge(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( 0 , 0.309016994375 , 0.5 )),
-                            vertex(( 0 , -0.309016994375 , 0.5 )),
-                            vertex(( -0.5 , 0 , 0.309016994375 )),
-                            vertex(( 0.5 , 0 , 0.309016994375 )),
-                            vertex(( -0.309016994375 , -0.5 , 0 )),
-                            vertex(( 0.309016994375 , -0.5 , 0 )),
-                            vertex(( 0.309016994375 , 0.5 , 0 )),
-                            vertex(( -0.309016994375 , 0.5 , 0 )),
-                            vertex(( -0.5 , 0 , -0.309016994375 )),
-                            vertex(( 0.5 , 0 , -0.309016994375 )),
-                            vertex(( 0 , 0.309016994375 , -0.5 )),
-                            vertex(( 0 , -0.309016994375 , -0.5 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[0],self.vertskeleton[7]),
-                            edge(self.vertskeleton[0],self.vertskeleton[2]),
-                            edge(self.vertskeleton[1],self.vertskeleton[2]),
-                            edge(self.vertskeleton[1],self.vertskeleton[4]),
-                            edge(self.vertskeleton[1],self.vertskeleton[5]),
-                            edge(self.vertskeleton[1],self.vertskeleton[3]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[0],self.vertskeleton[6]),
-                            edge(self.vertskeleton[2],self.vertskeleton[7]),
-                            edge(self.vertskeleton[2],self.vertskeleton[8]),
-                            edge(self.vertskeleton[2],self.vertskeleton[4]),
-                            edge(self.vertskeleton[4],self.vertskeleton[5]),
-                            edge(self.vertskeleton[3],self.vertskeleton[5]),
-                            edge(self.vertskeleton[3],self.vertskeleton[9]),
-                            edge(self.vertskeleton[3],self.vertskeleton[6]),
-                            edge(self.vertskeleton[6],self.vertskeleton[7]),
-                            edge(self.vertskeleton[7],self.vertskeleton[10]),
-                            edge(self.vertskeleton[7],self.vertskeleton[8]),
-                            edge(self.vertskeleton[4],self.vertskeleton[8]),
-                            edge(self.vertskeleton[4],self.vertskeleton[11]),
-                            edge(self.vertskeleton[5],self.vertskeleton[11]),
-                            edge(self.vertskeleton[5],self.vertskeleton[9]),
-                            edge(self.vertskeleton[6],self.vertskeleton[9]),
-                            edge(self.vertskeleton[6],self.vertskeleton[10]),
-                            edge(self.vertskeleton[8],self.vertskeleton[10]),
-                            edge(self.vertskeleton[8],self.vertskeleton[11]),
-                            edge(self.vertskeleton[9],self.vertskeleton[11]),
-                            edge(self.vertskeleton[9],self.vertskeleton[10]),
-                            edge(self.vertskeleton[10],self.vertskeleton[11])    ]
-        self.panelpoints=[    [0,1,2],[0,1,3],[0,2,7],[1,2,4],[1,4,5],[1,3,5],[0,3,6],[0,6,7],[2,7,8],[2,4,8],
-                        [3,5,9],[3,6,9],[7,8,10],[4,8,11],[4,5,11],[5,9,11],[6,9,10],[6,7,10],[8,10,11],[9,10,11]]
-        self.paneledges=[[0,2,3],[0,7,6],[2,1,9],[3,4,11],[4,5,12],[6,5,13],[7,8,15],[8,1,16],[9,10,18],[11,10,19],
-                    [13,14,22],[15,14,23],[18,17,25],[19,20,26],[12,20,21],[22,21,27],[23,24,28],[16,24,17],[25,26,29],[28,27,29]]
-        self.reversepanel=[0,2,5,9,11,12,14,15,17,19]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-class icoface(geodesic):
-    def __init__(self,parameter):
-        geodesic.__init__(mesh)
-        geodesic.setparameters(self,parameter)
-        self.set_vert_edge_skeleons()
-    def set_vert_edge_skeleons(self):
-        self.vertskeleton=[        vertex(( -0.17841104489 , 0.309016994375 , 0.46708617948 )),
-                            vertex(( -0.17841104489 , -0.309016994375 , 0.46708617948 )),
-                            vertex(( 0.35682208977 , 0.0 , 0.467086179484 )),
-                            vertex(( -0.57735026919 , 0.0 , 0.110264089705 )),
-                            vertex(( -0.288675134594 , -0.5 , -0.11026408971 )),
-                            vertex(( 0.288675134594 , -0.5 , 0.11026408971 )),
-                            vertex(( 0.57735026919 , 0.0 , -0.110264089705 )),
-                            vertex(( 0.288675134594 , 0.5 , 0.11026408971 )),
-                            vertex(( -0.288675134594 , 0.5 , -0.11026408971 )),
-                            vertex(( -0.35682208977 , 0.0 , -0.467086179484 )),
-                            vertex(( 0.17841104489 , -0.309016994375 , -0.46708617948 )),
-                            vertex(( 0.17841104489 , 0.309016994375 , -0.46708617948 ))    ]
-        self.edgeskeleton=[    edge(self.vertskeleton[0],self.vertskeleton[1]),
-                            edge(self.vertskeleton[2],self.vertskeleton[1]),
-                            edge(self.vertskeleton[2],self.vertskeleton[0]),
-                            edge(self.vertskeleton[0],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[3]),
-                            edge(self.vertskeleton[1],self.vertskeleton[4]),
-                            edge(self.vertskeleton[1],self.vertskeleton[5]),
-                            edge(self.vertskeleton[2],self.vertskeleton[5]),
-                            edge(self.vertskeleton[2],self.vertskeleton[6]),
-                            edge(self.vertskeleton[2],self.vertskeleton[7]),
-                            edge(self.vertskeleton[0],self.vertskeleton[7]),
-                            edge(self.vertskeleton[0],self.vertskeleton[8]),
-                            edge(self.vertskeleton[3],self.vertskeleton[9]),
-                            edge(self.vertskeleton[3],self.vertskeleton[4]),
-                            edge(self.vertskeleton[5],self.vertskeleton[4]),
-                            edge(self.vertskeleton[5],self.vertskeleton[10]),
-                            edge(self.vertskeleton[5],self.vertskeleton[6]),
-                            edge(self.vertskeleton[7],self.vertskeleton[6]),
-                            edge(self.vertskeleton[7],self.vertskeleton[11]),
-                            edge(self.vertskeleton[7],self.vertskeleton[8]),
-                            edge(self.vertskeleton[3],self.vertskeleton[8]),
-                            edge(self.vertskeleton[4],self.vertskeleton[9]),
-                            edge(self.vertskeleton[4],self.vertskeleton[10]),
-                            edge(self.vertskeleton[6],self.vertskeleton[10]),
-                            edge(self.vertskeleton[6],self.vertskeleton[11]),
-                            edge(self.vertskeleton[8],self.vertskeleton[11]),
-                            edge(self.vertskeleton[8],self.vertskeleton[9]),
-                            edge(self.vertskeleton[9],self.vertskeleton[10]),
-                            edge(self.vertskeleton[11],self.vertskeleton[10]),
-                            edge(self.vertskeleton[11],self.vertskeleton[9])    ]
-        self.panelpoints=[[2,0,1],[0,1,3],[2,1,5],[2,0,7],[1,3,4],[1,5,4],[2,5,6],[2,7,6],[0,7,8],[0,3,8],[3,4,9],[5,4,10],[5,6,10],[7,6,11],[7,8,11],[3,8,9],[4,9,10],[6,11,10],[8,11,9],[11,9,10]]
-        self.paneledges=[[2,1,0],[0,3,4],[1,7,6],[2,9,10],[4,5,13],[6,5,14],[7,8,16],[9,8,17],[10,11,19],[3,11,20],
-                    [13,12,21],[14,15,22],[16,15,23],[17,18,24],[19,18,25],[20,12,26],[21,22,27],[24,23,28],[25,26,29],[29,28,27]]
-        self.reversepanel=[1,3,5,7,9,10,12,14,17,19]
-        self.edgelength=[]
-        self.vertsdone=[[0,0]] * len(self.vertskeleton)
-
-##???PKHG TODO this does not work yet ...
-def creategeo(geo,polytype,orientation,parameters):
-    
-    if polytype == 'Tetrahedron':
-        if orientation == 'PointUp':
-            #return
-            #geo(parameters)
-#            geo.setparameters()
-            my_tetrahedron = tetrahedron(geodesic)
-            my_tetrahedron.set_vert_edge_skeleons()
-            my_tetrahedron.config()            
-            check_contains(my_tetrahedron,"my_tetra",True)
-            vefm_add_object(geo)
-        elif orientation == 'EdgeUp':
-            geo = tetraedge(parameters)
-        else: # orientation==2:
-            geo=tetraface(parameters)
-    elif polytype == 'Octahedron':        # octahedron
-        if orientation == 'PointUp':
-            geo = octahedron(parameters)
-        elif orientation == 'EdgeUp':
-            geo = octaedge(parameters)
-        else: #if orientation==2:
-            geo = octaface(parameters)
-    elif polytype == 'Icosahedron':    # icosahedron
-        if orientation == 'PointUp':
-            geo = icosahedron(parameters)
-        elif orientation == 'EdgeUp':
-            geo = icoedge(parameters)
-        else: #if orientation==2:
-            geo = icoface(parameters)
-    return geo
diff --git a/release/scripts/addons_contrib/geodesic_domes/read_me.txt b/release/scripts/addons_contrib/geodesic_domes/read_me.txt
deleted file mode 100644
index ad20376..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/read_me.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Geodesic_Domes
-Based on a script by Andy Houston (serendipiti) for Blender 2.49
-Original Script Documentation:
-http://wiki.blender.org/index.php/Extensions:2.4/Py/Scripts/Wizards/Geodesic_dome
-Licence:
-GPL
-
-PKHG (did the conversion)
-BIG change after revision 2551 GUI adjusted ...
-You should download anew if older then 24-november-2011
-
-In principle all parts work:
-the *hedrons with superformparameters
-Grid ... Sphere with superformparameters
-Faces  **
-Hubs   **
-Struts **
-
-** means will be adjusted ... at the moment you  have to name objects and
-execute eventually again ;-( ...
-
-but PKHG is content with a this nearly 95% converted version.
-
-TODO, ranges of parameters could be chosen differently. Inform PKHG!
-
-Uplaod will be done today (25-11 at about 19.30... GMT -+1)
-
-_259 in the names is not important ... but let it be so (now) ;-)
diff --git a/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py b/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py
deleted file mode 100644
index 270f621..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py
+++ /dev/null
@@ -1,1061 +0,0 @@
-import bpy
-import os
-from geodesic_domes import vefm_259 
-from geodesic_domes import forms_259
-from geodesic_domes import geodesic_classes_259
-from geodesic_domes import add_shape_geodesic
-
-from bpy.props import EnumProperty, IntProperty, FloatProperty, StringProperty, BoolProperty
-import math
-from math import pi
-from mathutils import Vector #needed to check vertex.vector values
-try:
-    breakpoint = bpy.types.bp.bp
-except:
-    print("add breakpoint addon!")
-        
-
-########global######
-last_generated_object = None
-last_imported_mesh = None
-basegeodesic = None
-imported_hubmesh_to_use = None
-########global end######
-
-########EIND FOR SHAPEKEYS######
-### error messages?!
-bpy.types.Scene.error_message = StringProperty(name="actual error", default = "")    
-
-
-bpy.types.Scene.geodesic_not_yet_called = BoolProperty(name="geodesic_not_called",default = True)
-
-bpy.types.Scene.gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20)
-
-class Geodesic_Domes_Operator_Panel(bpy.types.Panel):
-    """start a GD object here"""
-    bl_label = "Geodesic Domes"
-    bl_region_type = "TOOLS" #UI possible too
-    bl_space_type = "VIEW_3D"
-
-    def draw(self,context):
-        sce = context.scene
-        layout = self.layout
-        col = layout.column()
-        col.label("To start an GD object: ")
-        col.operator(GenerateGeodesicDome.bl_idname,"execute me!")
-            
-class GenerateGeodesicDome(bpy.types.Operator):
-    bl_label = "Modify Geodesic Objects"
-    bl_idname = "mesh.generate_geodesic_dome"
-    bl_description = "Create object dependent on selection"
-    bl_options = {'REGISTER','UNDO'}
-
-#PKHG_NEW saving and loading parameters
-    save_parameters = BoolProperty(name = "save params",\
-           description = "activation save */tmp/GD_0.GD", default = False)
-    load_parameters  = BoolProperty(name = "load params",\
-           description = "read */tmp/GD_0.GD", default = False)
-
-    gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20)
-
-    
-    mainpages = EnumProperty(
-    name="Menu",
-    description="Create Faces, Struts & Hubs",
-    items=[("Main","Main","Geodesic objects"),
-           ("Faces","Faces","Generate Faces"),
-           ("Struts","Struts","Generate Struts"),
-           ("Hubs","Hubs","Generate Hubs"),
-           ("Help","Help","Not implemented"),
-          ],
-    default='Main')
-
-#for Faces!
-    facetype_menu = EnumProperty(
-    name="Faces",
-    description="choose a facetype",
-    items=[("0","strip","strip"),
-           ("1","open vertical","vertical"),
-           ("2","opwn slanted","slanted"),
-           ("3","closed point","closed point"),
-           ("4","pillow","pillow"),
-           ("5","closed vertical","closed vertical"),
-           ("6","stepped","stepped"),
-           ("7","spikes","spikes"),
-           ("8","boxed","boxed"),
-           ("9","diamond","diamond"),
-           ("10","bar","bar"),
-          ],
-    default='0')
-
-    facetoggle = BoolProperty(name="Activate: Face Object", description = "Activate Faces for Geodesic object", default = False )
-#    faceimporttoggle = BoolProperty(name="faceimporttoggle", default = False )
-    face_use_imported_object = BoolProperty(name="Use: Imported Object",\
-                description = "Activate faces on your Imported object",	default = False)
-    facewidth = FloatProperty(name="facewidth", min = -8,   max = 8, default = .50)
-    fwtog = BoolProperty(name="fwtog", default = False )
-    faceheight = FloatProperty(name="faceheight", min = -8, max = 8, default = 1 )
-    fhtog = BoolProperty(name="fhtog", default = False )
-    face_detach = BoolProperty(name="face_detach", default = False )
-    fmeshname = StringProperty(name="fmeshname", default = "defaultface")
-
-
-    geodesic_types = EnumProperty(
-    name="Objects",
-    description="Choose Geodesic, Grid, Cylinder,Parabola, Torus, Sphere, Import your mesh or Superparameters",
-    items=[("Geodesic","Geodesic","Generate Geodesic"),
-           ("Grid","Grid","Generate Grid"),
-           ("Cylinder","Cylinder","Generate Cylinder"),
-           ("Parabola","Parabola","Generate Parabola"),
-           ("Torus","Torus","Generate Torus"),
-           ("Sphere","Sphere","Generate Sphere"),
-           ("Import your mesh","Import your mesh","Import Your Mesh"),
-          ],
-    default='Geodesic')
-
-    import_mesh_name = StringProperty(name = "mesh to import",\
-            description = "the name has to be the name of a meshobject", default = "None") 
-
-    base_type = EnumProperty(
-    name="Hedron",
-    description="Choose between Tetrahedron, Octahedron, Icosahedron ",
-    items=[("Tetrahedron","Tetrahedron","Generate Tetrahedron"),
-           ("Octahedron","Octahedron","Generate Octahedron"),
-           ("Icosahedron","Icosahedron","Generate Icosahedron"),
-          ],
-    default='Tetrahedron')
-
-    orientation = EnumProperty(
-    name="Point^",
-    description="Point (Vert), Edge or Face pointing upwards",
-    items=[("PointUp","PointUp","Point up"),
-           ("EdgeUp","EdgeUp","Edge up"),
-           ("FaceUp","FaceUp","Face up"),
-           ],
-    default='PointUp')
-
-    geodesic_class = EnumProperty(
-    name="Class",
-    description="Subdivide Basic/Triacon",
-    items=[("Class 1","Class 1","class one"),
-           ("Class 2","Class 2","class two"),
-           ],
-    default='Class 1')
-
-    tri_hex_star = EnumProperty(
-    name="Shape",
-    description="Choose between tri hex star face types",
-    items=[("tri","tri","tri faces"),
-           ("hex","hex","hex faces(by tri)"),
-           ("star","star","star faces(by tri)"),
-              ],
-    default='tri')
-
-    spherical_flat = EnumProperty(
-    name="Round",
-    description="Choose between spherical or flat ",
-    items=[("spherical","spherical","Generate spherical"),
-           ("flat","flat","Generate flat"),
-              ],
-    default='spherical')
-
-    use_imported_mesh = BoolProperty(name="use import",\
-                    description = "Use an imported mesh", default = False)
-
-#Cylinder
-    cyxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\
-              description = "number of faces around x/y", default = 5 )
-    cyyres= IntProperty(name="Resolution z", min = 3, max = 32,\
-              description = "number of faces in z direction", default = 5 )
-    cyxsz= FloatProperty(name="Scale x/y", min = 0.01, max = 10,\
-	          description = "scale in x/y direction", default = 1 )
-    cyysz= FloatProperty(name="Scale z", min = 0.01, max = 10,\
-              description = "scale in z direction", default = 1 )    
-    cyxell= FloatProperty(name="Stretch x",  min = 0.001, max = 4,\
-              description = "stretch in x direction", default = 1 )
-    cygap= FloatProperty(name="Gap",  min = -2, max = 2, precision = 4,\
-              description = "shrink in % around radius", default = 1 )
-    cygphase= FloatProperty(name="Phase", min = -4, max = 4,\
-              description = "rotate around pivot x/y", default = 0 )
-#Parabola
-    paxres= IntProperty(name="Resolution x/y",  min = 3, max = 32,\
-           description = "number of faces around x/y", default = 5 )
-    payres= IntProperty(name="Resolution z",  min = 3, max = 32,\
-           description = "number of faces in z direction", default = 5 )
-    paxsz= FloatProperty(name="Scale x/y", min = 0.001, max = 10,\
-           description = "scale in x/y direction", default = 0.30)
-    paysz= FloatProperty(name="Scale z", min = 0.001, max = 10,\
-           description = "scale in z direction",	default = 1 )
-    paxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
-           description = "stretch in x direction",	default = 1 )
-    pagap= FloatProperty(name="Gap", min = -2, max = 2,\
-           description = "shrink in % around radius", precision = 4, default = 1 )
-    pagphase= FloatProperty(name="Phase", min = -4, max = 4,\
-           description = "rotate around pivot x/y",	default = 0 )
-#Torus            
-    ures= IntProperty(name="Resolution x/y",min = 3, max = 32,\
-           description = "number of faces around x/y", default = 8 )
-    vres= IntProperty(name="Resolution z", min = 3, max = 32,\
-            description = "number of faces in z direction", default = 8 )
-    urad= FloatProperty(name="Radius x/y", min = 0.001, max = 10,\
-            description = "radius in x/y plane",	default = 1 )
-    vrad= FloatProperty(name="Radius z", min = 0.001, max = 10,\
-            description = "radius in z plane",	default = 0.250)
-    uellipse= FloatProperty(name="Stretch x", min = 0.001, max = 10,\
-            description = "number of faces in z direction",	default = 1 )
-    vellipse= FloatProperty(name="Stretch z", min = 0.001, max = 10,\
-            description = "number of faces in z direction",	default = 1 )
-    upart= FloatProperty(name="Gap x/y", min = -4, max = 4, precision = 4,\
-            description = "shrink faces around x/y",	default = 1 )
-    vpart= FloatProperty(name="Gap z", min = -4, max = 4,  precision = 4,\
-            description = "shrink faces in z direction",	default = 1 )
-    ugap= FloatProperty(name="Phase x/y",  min = -4, max = 4, precision = 4,\
-           description = "rotate around pivot x/y", default = 0 )
-    vgap= FloatProperty(name="Phase z",  min = -4, max = 4, precision = 4,\
-           description = "rotate around pivot z", default = 0 )
-    uphase= FloatProperty(name="uphase", min = -4, max = 4,\
-            description = "number of faces in z direction",	default = 0 )
-    vphase= FloatProperty(name="vphase",  min = -4, max = 4,\
-            description = "number of faces in z direction",	default = 0 )
-    uexp= FloatProperty(name="uexp",  min = -4, max = 4,\
-            description = "number of faces in z direction",	default = 0 )
-    vexp= FloatProperty(name="vexp",  min = -4, max = 4,\
-            description = "number of faces in z direction",	default = 0 )
-    usuper= FloatProperty(name="usuper", min = -4, max = 4,\
-           description = "first set of superform parameters",  default = 2 )
-    vsuper= FloatProperty(name="vsuper",  min = -4, max = 4,\
-            description = "second set of superform parameters", default = 2 )
-    utwist= FloatProperty(name="Twist x/y", min = -4, max = 4,\
-            description = " use with superformular u",	default = 0 )
-    vtwist= FloatProperty(name="Twist z", min = -4, max = 4,\
-            description = "use with superformular v",	default = 0 )
-
-#Sphere 
-    bures= IntProperty(name="Resolution x/y", min = 3, max = 32,\
-            description = "number of faces around x/y",	default = 8 )
-    bvres= IntProperty(name="Resolution z", min = 3, max = 32,\
-            description = "number of faces in z direction",	default = 8 )
-    burad= FloatProperty(name="Radius",  min = -4, max = 4,\
-            description = "overall radius",	default = 1 )
-    bupart= FloatProperty(name="Gap x/y", min = -4, max = 4, precision = 4,\
-            description = "shrink faces around x/y",	default = 1 )
-    bvpart= FloatProperty(name="Gap z", min = -4, max = 4, precision = 4,\
-            description = "shrink faces in z direction",	default = 1 )
-    buphase= FloatProperty(name="Phase x/y",  min = -4, max = 4,
-            description = "rotate around pivot x/y",	default = 0 )
-    bvphase= FloatProperty(name="Phase z", min = -4, max = 4,\
-            description = "rotate around pivot z",	default = 0 )
-    buellipse= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
-            description = "stretch in the x direction",	default = 1 )
-    bvellipse= FloatProperty(name="Stretch z", min = 0.001, max = 4,\
-            description = "stretch in the z direction",	default = 1 )
-#Grid    
-    grxres = IntProperty(name="Resolution x", min = 2, soft_max = 10, max = 20,\
-                         description = "number of faces in x direction", default = 5 )
-    gryres = IntProperty(name="Resolution z",min = 2, soft_min = 2, soft_max=10, max = 20,\
-                         description = "number of faces in x direction", default = 2)
-    grxsz = FloatProperty(name = "X size", min = 1, soft_min=0.01, soft_max=5, max = 10,\
-                         description = "x size", default = 2.0)
-    grysz = FloatProperty(name="Y size",min = 1, soft_min=0.01, soft_max=5, max = 10,\
-                         description = "y size", default = 1.0)
-
-#PKHG_TODO_??? what means cart
-    cart = IntProperty(name = "cart",min = 0, max = 2,  default = 0)
-                         
-    frequency = IntProperty(name="Frequency", min = 1, max = 8,\
-                           description ="subdivide base triangles", default = 1 )
-    eccentricity = FloatProperty(name = "Eccentricity",  min = 0.01 , max = 4,\
-                 description = "scaling in x/y dimension", default = 1 )
-    squish = FloatProperty(name = "Squish",min = 0.01, soft_max = 4, max = 10,\
-                 description = "scaling in z dimension",  default = 1 )
-    radius = FloatProperty(name = "Radius",min = 0.01, soft_max = 4, max = 10,\
-                 description = "overall radius",  default = 1 )
-    squareness = FloatProperty(name="Square x/y", min = 0.1, max = 5,\
-                 description = "superelipse action in x/y", default = 2 )
-    squarez = FloatProperty(name="Square z", min = 0.1, soft_max = 5, max = 10,\
-                 description = "superelipse action in z", default = 2 )
-    baselevel = IntProperty(name="baselevel", default = 5 )
-    dual = BoolProperty(name="Dual", description = "faces become verts, verts become faces, edges flip", default = False)
-    rotxy = FloatProperty(name="Rotate x/y", min= -4, max = 4,\
-                 description = "rotate superelipse action in x/y", default = 0 )
-    rotz = FloatProperty(name="Rotate z",  min= -4, max = 4,\
-                 description = "rotate superelipse action in z", default = 0 )
-
-#for choice of superformula
-    uact = BoolProperty(name = 'superformula u (x/y)', description = "activate superformula u parameters", default = False)
-    vact = BoolProperty(name = 'superformula v (z)', description = "activate superformula v parameters", default = False)
-    um = FloatProperty(name = 'um', min = 0, soft_min=0.1, soft_max = 10, max = 20,\
-                 description = "to do",	default =  3)
-    un1 = FloatProperty(name = 'un1', min = 0, soft_min=0.1, soft_max = 10,max = 20,\
-                 description = "to do",	default =  1)
-    un2 = FloatProperty(name = 'un2', min = 0, soft_min=0.1, soft_max = 10,max = 20,\
-                 description = "to do",	default =  1)
-    un3 = FloatProperty(name = 'un3', min = 0,   soft_min=0.1, soft_max = 10, max = 20,\
-                 description = "to do",	default =  1)
-    ua = FloatProperty(name = 'ua', min = 0.01, soft_min=0.1, soft_max = 8, max = 16,\
-                 description = "semi-diameter (has both soft pars!)", default =  1.0)
-    ub = FloatProperty(name = 'ub', min = 0.01, soft_min = 0.1, soft_max = 8, max = 16,\
-                 description = "semi-diameter  (has both soft pars!)", default =  1.0)
-    vm = FloatProperty(name = 'vm', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  1)
-    vn1 = FloatProperty(name = 'vn1', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  1)
-    vn2 = FloatProperty(name = 'vn2', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  1)
-    vn3 = FloatProperty(name = 'vn3', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  1)
-    va = FloatProperty(name = 'va', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  1)
-    vb = FloatProperty(name = 'vb', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  1)
-
-    uturn = FloatProperty(name = 'uturn', min = -5, soft_min=0, soft_max=5,max = 10,\
-                 description = "to do",	default =  0)
-    vturn = FloatProperty(name = 'vturn', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  0)
-    utwist = FloatProperty(name = 'utwist', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  0)
-    vtwist = FloatProperty(name = 'vtwist', min = 0, soft_min=0.1, soft_max=5,max = 10,\
-                 description = "to do",	default =  0)
-
-#Strut
-    struttype= IntProperty(name="struttype", default= 0)
-    struttoggle = BoolProperty(name="struttoggle", default = False )
-    strutimporttoggle= BoolProperty(name="strutimporttoggle", default = False )
-    strutimpmesh= StringProperty(name="strutimpmesh", default = "None")
-    strutwidth= FloatProperty(name="strutwidth", min = -10, soft_min = 5, soft_max = 5, max = 10, default = 1 )
-    swtog= BoolProperty(name="swtog", default = False )
-    strutheight= FloatProperty(name="strutheight", min = -5, soft_min = -1, soft_max = 5, max = 10, default = 1 )
-    shtog= BoolProperty(name="shtog", default = False )
-    strutshrink= FloatProperty(name="strutshrink", min = 0.001, max = 4, default = 1 )
-    sstog= BoolProperty(name="sstog", default = False )
-    stretch= FloatProperty(name="stretch",  min= -4, max = 4, default = 1.0 )
-    lift= FloatProperty(name="lift", min = 0.001, max = 10, default = 0 )
-    smeshname= StringProperty(name="smeshname", default = "defaultstrut")
-
-#Hubs
-    hubtype = BoolProperty(name ="hubtype", description = "not used", default = True )
-    hubtoggle = BoolProperty(name ="hubtoggle", default = False )
-    hubimporttoggle = BoolProperty(name="new import", description = "import a mesh", default = False )
-    hubimpmesh = StringProperty(name="hubimpmesh",\
-                 description = "name of mesh to import",  default = "None")
-    hubwidth = FloatProperty(name="hubwidth", min = 0.01, max = 10,\
-                 default = 1 )
-    hwtog = BoolProperty(name="hwtog", default = False )
-    hubheight = FloatProperty(name="hubheight", min = 0.01, max = 10,\
-                 default = 1 )
-    hhtog = BoolProperty(name="hhtog", default = False )
-    hublength = FloatProperty(name ="hublength", min  = 0.1, max  = 10,\
-                 default  = 1 )
-    hstog= BoolProperty(name="hstog", default = False )
-    hmeshname= StringProperty(name="hmeshname", description = "Name of an existing mesh needed!", default = "None")
-
-    name_list = ['facetype_menu','facetoggle','face_use_imported_object',
-'facewidth','fwtog','faceheight','fhtog',
-'face_detach','fmeshname','geodesic_types','import_mesh_name',
-'base_type','orientation','geodesic_class','tri_hex_star',
-'spherical_flat','use_imported_mesh','cyxres','cyyres',
-'cyxsz','cyysz','cyxell','cygap',
-'cygphase','paxres','payres','paxsz',
-'paysz','paxell','pagap','pagphase',
-'ures','vres','urad','vrad',
-'uellipse','vellipse','upart','vpart',
-'ugap','vgap','uphase','vphase',
-'uexp','vexp','usuper','vsuper',
-'utwist','vtwist','bures','bvres',
-'burad','bupart','bvpart','buphase',
-'bvphase','buellipse','bvellipse','grxres',
-'gryres','grxsz','grysz',
-'cart','frequency','eccentricity','squish',
-'radius','squareness','squarez','baselevel',
-'dual','rotxy','rotz',
-'uact','vact','um','un1',
-'un2','un3','ua','ub',
-'vm','vn1','vn2','vn3',
-'va','vb','uturn','vturn',
-'utwist','vtwist','struttype','struttoggle',
-'strutimporttoggle','strutimpmesh','strutwidth','swtog',
-'strutheight','shtog','strutshrink','sstog',
-'stretch','lift','smeshname','hubtype',
-'hubtoggle','hubimporttoggle','hubimpmesh','hubwidth',
-'hwtog','hubheight','hhtog','hublength',
-'hstog','hmeshname']    
-
-    def write_params(self,filename):
-        file = open(filename, "w", encoding="utf8", newline="\n")
-        fw = file.write
-    #for Faces!
-        for el in self.name_list:
-            fw(el + ",")
-            fw(repr(getattr(self,el)))
-            fw(",\n")
-        file.close()
-
-    def read_file(self,filename):
-        file = open(filename, "r", newline="\n")
-        result = []
-        line = file.readline()
-        while(line):
-            tmp = line.split(",")
-            result.append(eval(tmp[1]))
-            line = file.readline()
-        return result
-    
-
-    def draw(self,context):
-        sce = context.scene
-        layout = self.layout
-        row = layout.row()
-        row.prop(self,"save_parameters")
-        row.prop(self,"load_parameters")
-        col = layout.column()
-        col.label(" ")
-        col.prop(self,"mainpages")
-        which_mainpages = self.mainpages
-        if which_mainpages == 'Main':
-            col = layout.column()
-            col.prop(self,"geodesic_types")
-            tmp = self.geodesic_types
-            if tmp == "Geodesic":
-                col.label(text="Geodesic Object Types:")
-                col.prop(self, "geodesic_class")                
-                col.prop(self, "base_type")
-                col.prop(self, "orientation")
-                col.prop(self, "tri_hex_star")
-                col.prop(self, "spherical_flat")
-                col.label("Geodesic Object Parameters:")
-                row = layout.row()
-                row.prop(self,"frequency")
-                row = layout.row()
-                row.prop(self,"radius")
-                row = layout.row()
-                row.prop(self,"eccentricity")
-                row = layout.row()
-                row.prop(self,"squish")
-                row = layout.row()
-                row.prop(self,"squareness")
-                row = layout.row()
-                row.prop(self,"squarez")
-                row = layout.row()
-                row.prop(self,"rotxy")
-                row = layout.row()
-                row.prop(self,"rotz")
-                row = layout.row()
-                row.prop(self,"dual")
-            elif tmp == 'Torus':
-                col.label("Torus Parameters")
-                row = layout.row()
-                row.prop(self, "ures")
-                row = layout.row()
-                row.prop(self, "vres")
-                row = layout.row()
-                row.prop(self, "urad")
-                row = layout.row()
-                row.prop(self, "vrad")
-                row = layout.row()
-                row.prop(self, "uellipse")
-                row = layout.row()
-                row.prop(self, "vellipse")
-                row = layout.row()
-                row.prop(self, "upart")
-                row = layout.row()
-                row.prop(self, "vpart")
-                row = layout.row()
-                row.prop(self, "ugap")
-                row.prop(self, "vgap")
-                row = layout.row()
-                row.prop(self, "uphase")
-                row.prop(self, "vphase")
-                row = layout.row()
-                row.prop(self, "uexp")
-                row.prop(self, "vexp")
-                row = layout.row()
-                row.prop(self, "usuper")
-                row.prop(self, "vsuper")
-                row = layout.row()
-                row.prop(self, "vgap")
-                row = layout.row()
-            elif tmp == 'Sphere':
-                col.label("Sphere Parameters")
-                row = layout.row()
-                row.prop(self,"bures")
-                row = layout.row()
-                row.prop(self,"bvres")
-                row = layout.row()
-                row.prop(self,"burad")
-                row = layout.row()                
-                row.prop(self,"bupart")
-                row = layout.row()
-                row.prop(self,"buphase")
-                row = layout.row()
-                row.prop(self,"bvpart")
-                row = layout.row()
-                row.prop(self,"bvphase")
-                row = layout.row()
-                row.prop(self,"buellipse")
-                row = layout.row()
-                row.prop(self,"bvellipse")
-            elif tmp == 'Parabola':
-                col.label("Parabola Parameters")
-                row = layout.row()
-                row.prop(self, "paxres")
-                row = layout.row()
-                row.prop(self, "payres")
-                row = layout.row()
-                row.prop(self, "paxsz")
-                row = layout.row()
-                row.prop(self, "paysz")
-                row = layout.row()
-                row.prop(self, "paxell")
-                row = layout.row()
-                row.prop(self, "pagap")
-                row = layout.row()
-                row.prop(self, "pagphase")
-            elif tmp == 'Cylinder':
-                col.label("Cylinder Parameters")
-                col.prop(self, "cyxres")
-                col.prop(self, "cyyres")
-                col.prop(self, "cyxsz")
-                col.prop(self, "cyysz")
-                col.prop(self, "cyxell")
-                col.prop(self, "cygap")
-                col.prop(self, "cygphase")
-            elif tmp == 'Grid':
-                col.label("Grid Parameters")
-                row = layout.row()
-                row.prop(self, "grxres")
-                row = layout.row()
-                row.prop(self, "gryres")
-                row = layout.row()
-                row.prop(self, "grxsz")
-                row = layout.row()
-                row.prop(self, "grysz")
-            elif tmp == 'Import your mesh':
-                col.prop(self,"use_imported_mesh")
-                col.prop(self, "import_mesh_name")
-#######superform parameters only where possible
-            row = layout.row()
-            row.prop(self,"uact")
-            row = layout.row()
-            row.prop(self,"vact")                
-            row = layout.row()
-            if not(tmp == 'Import your mesh'):
-                if (self.uact == False) and (self.vact == False):
-                    row.label("no checkbox active!")
-                else:
-                    row.label("Superform Parameters")
-                if self.uact:
-                    row = layout.row()
-                    row.prop(self,"um")
-                    row = layout.row()
-                    row.prop(self,"un1")
-                    row = layout.row()
-                    row.prop(self,"un2")
-                    row = layout.row()
-                    row.prop(self,"un3")
-                    row = layout.row()
-                    row.prop(self,"ua")
-                    row = layout.row()
-                    row.prop(self,"ub")
-                    row = layout.row()
-                    row.prop(self,"uturn")
-                    row = layout.row()
-                    row.prop(self,"utwist")
-                if self.vact:
-                    row = layout.row()
-                    row.prop(self,"vm")
-                    row = layout.row()
-                    row.prop(self,"vn1")
-                    row = layout.row()
-                    row.prop(self,"vn2")
-                    row = layout.row()
-                    row.prop(self,"vn3")
-                    row = layout.row()
-                    row.prop(self,"va")
-                    row = layout.row()
-                    row.prop(self,"vb")
-                    row = layout.row()
-                    row.prop(self,"vturn")
-                    row = layout.row()
-                    row.prop(self,"vtwist")                
-########einde superfo
-        elif  which_mainpages == "Hubs":
-            row = layout.row()
-            row.prop(self, "hubtoggle")
-#PKHG_NOT_USDED_YET_24-11            row.prop(self, "hubtype")
-            row = layout.row()            
-#25-11 not needed            row.prop(self, "hubimporttoggle")
-            row = layout.row()
-            if self.hubimpmesh == "None":
-                row = layout.row()
-                row.label("name of a hub to use")
-                row = layout.row()
-            row.prop(self, "hubimpmesh")
-            row = layout.row()
-            if self.hmeshname == "None":
-                row = layout.row()
-                row.label("name of mesh to be filled in!")
-                row = layout.row()
-            row.prop(self,"hmeshname")
-            row = layout.row()
-            row.prop(self, "hwtog")
-            if self.hwtog:
-                row.prop(self, "hubwidth")
-            row = layout.row()
-            row.prop(self, "hhtog")
-            if self.hhtog:
-                row.prop(self, "hubheight")
-            row = layout.row()
-            row.prop(self, "hublength")                
-        elif which_mainpages == "Struts":
-            row = layout.row()
-#            row.prop(self, "struttype")
-            row.prop(self, "struttoggle")
-#            row = layout.row()            
-#            row.prop(self, "strutimporttoggle")
-            row = layout.row()            
-            row.prop(self, "strutimpmesh")
-            row = layout.row()
-            row.prop(self, "swtog")
-            if self.swtog:
-                row.prop(self, "strutwidth")
-            row = layout.row()
-            row.prop(self, "shtog")
-            if self.shtog:
-                row.prop(self, "strutheight")
-            row = layout.row()
-            row.prop(self, "sstog")
-            if self.sstog:
-               row.prop(self, "strutshrink")
-            row = layout.row()               
-            row.prop(self, "stretch")
-            row = layout.row()            
-            row.prop(self, "lift")
-            row = layout.row()            
-            row.prop(self, "smeshname")
-        elif which_mainpages == "Faces":
-            row = layout.row()
-            row.prop(self,"facetoggle")
-            row = layout.row()
-            row.prop(self,"face_use_imported_object")
-            row = layout.row()
-            row.prop(self,"facetype_menu")
-            row = layout.row()
-            row.prop(self,"fwtog")
-            if self.fwtog:
-                row.prop(self,"facewidth")
-            row = layout.row()
-            row.prop(self,"fhtog")
-            if self.fhtog:
-                row.prop(self,"faceheight")
-            row = layout.row()
-            row.prop(self,"face_detach")
-            row = layout.row()
-            row.prop(self,"fmeshname")
-            row = layout.row()
-        
-        #help menu GUI
-        elif which_mainpages == "Help":
-            import textwrap
-
-            # a function that allows for multiple labels with text that wraps
-            # you can allow the user to set where the text wraps with the 
-            # text_width parameter
-            # other parameters are ui : here you usually pass layout
-            # text: is a list with each index representing a line of text
-            
-            def multi_label(text, ui,text_width=120):
-                for x in range(0,len(text)):
-                    el = textwrap.wrap(text[x], width = text_width )
-            
-                    for y in range(0,len(el)):
-                        ui.label(text=el[y])
-
-            box = layout.box() 
-            help_text = ["NEW! ", 
-                "New facility: save or load (nearly all) parameters ",
-                 "A file GD_0.GD will be used, living in: ",
-                 "geodesic_domes/tmp ",
-                 "and if possible two backups "
-                 "--------",
-                 "After loading you have to change a ",
-                 "parameter back and forth "
-                 "to see it"]
-            text_width = self.gd_help_text_width
-            box.prop(self,"gd_help_text_width",slider=True)
-            multi_label(help_text,box, text_width)
-
-    def execute(self, context):
-        global last_generated_object, last_imported_mesh, basegeodesic, imported_hubmesh_to_use 
-        #default superformparam = [3, 10, 10, 10, 1, 1, 4, 10, 10, 10, 1, 1, 0, 0, 0.0, 0.0, 0, 0]]
-        superformparam = [self.um, self.un1, self.un2, self.un3, self.ua,\
-                          self.ub, self.vm, self.vn1, self.vn2, self.vn3,\
-                          self.va, self.vb, self.uact, self.vact,\
-                          self.uturn*pi, self.vturn*pi, \
-                          self.utwist, self.vtwist]
-        context.scene.error_message = "" 
-        if self.mainpages == 'Main':
-            if self.geodesic_types == "Geodesic":
-                tmp_fs = self.tri_hex_star
-                faceshape = 0 # tri!
-                if tmp_fs == "hex":
-                    faceshape = 1
-                elif tmp_fs == "star":
-                    faceshape = 2
-                tmp_cl = self.geodesic_class
-                klass = 0
-                if tmp_cl == "Class 2":
-                    klass = 1
-                shape = 0 
-                parameters = [self.frequency, self.eccentricity, self.squish,\
-                          self.radius, self.squareness, self.squarez, 0,\
-                          shape, self.baselevel, faceshape, self.dual,\
-                          self.rotxy, self.rotz, klass, superformparam]               
-                basegeodesic =  creategeo(self.base_type,self.orientation,parameters)
-                basegeodesic.makegeodesic()
-                basegeodesic.connectivity()
-                mesh = vefm_259.mesh()                
-                vefm_259.finalfill(basegeodesic,mesh) #always! for hexifiy etc. necessarry!!!                     
-                vefm_259.vefm_add_object(mesh)
-                last_generated_object = context.active_object
-                last_generated_object.location  = (0,0,0)
-                context.scene.objects.active = last_generated_object            
-            elif self.geodesic_types == 'Grid':
-                basegeodesic = forms_259.grid(self.grxres,self.gryres,\
-                       self.grxsz,self.grysz,1.0,1.0,0,0,0,\
-                                      0,1.0,1.0,superformparam)
-                vefm_259.vefm_add_object(basegeodesic)
-                bpy.data.objects[-1].location = (0,0,0)
-            elif self.geodesic_types == "Cylinder":
-                basegeodesic = forms_259.cylinder(self.cyxres, self.cyyres, \
-                                   self.cyxsz, self.cyysz, self.cygap, \
-                                   1.0, self.cygphase, 0, 0, 0, self.cyxell,\
-                                   1.0, superformparam)
-                vefm_259.vefm_add_object(basegeodesic)
-                bpy.data.objects[-1].location = (0,0,0)                
-                
-            elif self.geodesic_types == "Parabola":
-                basegeodesic=forms_259.parabola(self.paxres, self.payres,\
-                    self.paxsz, self.paysz, self.pagap,1.0, self.pagphase,\
-                    0,0,0, self.paxell,1.0,superformparam)
-                vefm_259.vefm_add_object(basegeodesic)
-                bpy.data.objects[-1].location = (0,0,0)                
-            elif self.geodesic_types == "Torus":
-                basegeodesic = forms_259.torus(self.ures, self.vres,\
-                       self.vrad, self.urad, self.upart, self.vpart,\
-                       self.ugap, self.vgap,0,0, self.uellipse,\
-                       self.vellipse, superformparam)
-                vefm_259.vefm_add_object(basegeodesic)
-                bpy.data.objects[-1].location = (0,0,0)
-            elif self.geodesic_types == "Sphere":
-                basegeodesic=forms_259.sphere(self.bures, self.bvres,\
-                        self.burad,1.0, self.bupart, self.bvpart,\
-                        self.buphase, self.bvphase,0,0, self.buellipse,\
-                        self.bvellipse,superformparam)	
-
-                vefm_259.vefm_add_object(basegeodesic)
-                bpy.data.objects[-1].location = (0,0,0)                
-            elif self.geodesic_types == "Import your mesh":
-                obj_name = self.import_mesh_name
-                if obj_name == "None":
-                    message = "fill in a name \nof an existing mesh\nto be imported"
-                    context.scene.error_message = message
-                    self.report({"INFO"}, message)
-                    print("***INFO*** you have to fill in the name of an existing mesh")
-                else:
-#                    obj_in_scene = context.objects
-                    names = [el.name for el in context.scene.objects]
-                    if obj_name in names and context.scene.objects[obj_name].type == "MESH":
-                        obj = context.scene.objects[obj_name]
-#                        if obj.type == "MESH":                        
-                        your_obj = vefm_259.importmesh(obj.name,False)
-                        last_imported_mesh = your_obj
-                        vefm_259.vefm_add_object(your_obj)
-                        last_generated_object = bpy.context.active_object
-                        last_generated_object.name ="Imported mesh"
-                        bpy.context.active_object.location = (0,0,0)
-                    else:
-                        message = obj_name +" does not exist \nor is not a MESH"
-                        context.scene.error_message = message                
-                        bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
-                        self.report({'ERROR'}, message)
-                        print("***ERROR***" + obj_name +" does not exist or is not a MESH")
-        elif self.mainpages == "Hubs":
-            hubtype = self.hubtype
-            hubtoggle =  self.hubtoggle
-            hubimporttoggle = self.hubimporttoggle
-            hubimpmesh = self.hubimpmesh
-            hubwidth = self.hubwidth
-            hwtog = self.hwtog
-            hubheight = self.hubheight
-            hhtog = self.hhtog
-            hublength = self.hublength
-            hstog =  self.hstog
-            hmeshname=  self.hmeshname
-#PKHG_TODO_27-11 better info!??
-            if not (hmeshname == "None") and not (hubimpmesh == "None") and  hubtoggle:                
-                try:                    
-                    hub_obj = vefm_259.importmesh(hmeshname,0)
-                    hub = vefm_259.hub(hub_obj, True,\
-                            hubwidth, hubheight, hublength,\
-                              hwtog, hhtog, hstog, hubimpmesh)
-                    mesh = vefm_259.mesh("test")
-                    vefm_259.finalfill(hub,mesh)
-                    vefm_259.vefm_add_object(mesh)
-                    bpy.data.objects[-1].location = (0,0,0)
-                except:
-                    message = "***ERROR*** \neither no mesh for hub\nor " + hmeshname +  " available"                    
-                    context.scene.error_message = message
-                    bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
-                    print(message)                
-            else:
-                message = "***INFO***\nuse the hub toggle!"
-                context.scene.error_message = message
-                print("\n***INFO*** use the hub toggle!")
-        elif self.mainpages == "Struts":
-            struttype = self.struttype
-            struttoggle = self.struttoggle
-            strutimporttoggle = self.strutimporttoggle
-            strutimpmesh = self.strutimpmesh
-            strutwidth = self.strutwidth
-            swtog = self.swtog
-            strutheight = self.strutheight
-            shtog = self.shtog
-            strutshrink = self.strutshrink
-            sstog = self.sstog
-            stretch = self.stretch
-            lift = self.lift
-            smeshname = self.smeshname
-            if not (strutimpmesh == "None") and struttoggle:
-                names = [el.name for el in context.scene.objects]
-                if strutimpmesh in names and context.scene.objects[strutimpmesh].type == "MESH":
-                    strut = vefm_259.strut(basegeodesic, struttype,strutwidth,strutheight,stretch,swtog,shtog,swtog,strutimpmesh,sstog,lift)
-                    strutmesh = vefm_259.mesh()
-                    vefm_259.finalfill(strut,strutmesh)
-                    vefm_259.vefm_add_object(strutmesh)
-                    last_generated_object = context.active_object
-                    last_generated_object.name = smeshname
-                    last_generated_object.location  = (0,0,0)
-                else:
-                    message = "***ERROR***\n" + strutimpmesh + "\nis not a MESH"
-                    context.scene.error_message = message
-                    bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
-                    print("***ERROR*** strut obj is not a MESH")
-            else:
-                vefm_259.vefm_add_object(basegeodesic)
-        elif self.mainpages == "Faces":
-            if self.facetoggle:
-                faceparams=[[self.face_detach,0,[[0.5,0.0]]], #0 strip
-                            [self.face_detach,0,[[0.0,0.5]]], #1 vertical
-                            [self.face_detach,0,[[0.5,0.5]]], #2 slanted
-                            [self.face_detach,1,[[0.25,0.25],[0.5,0.5]]], #3 closed point
-                            [self.face_detach,1,[[0.1,0.03],[0.33,0.06],[0.0,0.1]]], #4 pillow
-                            [self.face_detach,2,[[0.0,0.5]]], #5 closed vertical
-                            [self.face_detach,2,[[0.0,0.25],[0.25,0.25],[0.25,0.5]]], #6 stepped
-                            [self.face_detach,1,[[0.2,0.1],[0.4,0.2],[0.0,1.0]]], #7 spikes
-                            [self.face_detach,3,[[0.25,0.0],[0.25,0.5],[0.0,0.5]]], #8 boxed 
-                            [self.face_detach,3,[[0.25,0.5],[0.5,0.0],[0.25,-0.5]]], #9 diamond
-                            [self.face_detach,4,[[0.5,0.0],[0.5,0.5],[0.0,0.5]]],] #10 bar
-                facedata = faceparams[int(self.facetype_menu)]
-                if not self.face_use_imported_object:
-                    faceobject = vefm_259.facetype(basegeodesic,facedata,self.facewidth,self.faceheight,self.fwtog)
-                else:
-                    if last_imported_mesh: 
-                        faceobject = vefm_259.facetype(last_imported_mesh, facedata,self.facewidth,self.faceheight,self.fwtog)
-                    else:
-                        message = "***ERROR***\nno imported message available\n" + "last geodesic used"
-                        self.face_use_imported_object = False
-                        context.scene.error_message = message
-                        bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
-                        print("\n***ERROR*** no imported mesh available")
-                        print("last geodesic used!")
-                        faceobject = vefm_259.facetype(basegeodesic,facedata,\
-                                     self.facewidth,self.faceheight,self.fwtog)
-                facemesh = vefm_259.mesh()
-                finalfill(faceobject,facemesh)
-
-                vefm_259.vefm_add_object(facemesh)
-                obj = bpy.data.objects[-1]
-                obj.name = self.fmeshname
-                obj.location = (0,0,0)
-#PKHG save or load (nearly) all parameters                
-        if self.save_parameters:
-            self.save_parameters = False
-            try:
-                print("DBG L884")
-                message = ""
-                scriptpath = bpy.utils.script_paths()[0]
-                sep = os.path.sep
-                tmpdir = os.path.join(scriptpath,"addons", "geodesic_domes" , "tmp")
-#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp"
-                print("tmpdirL890 = ",tmpdir)
-                if not os.path.isdir(tmpdir):
-                    message += "***ERROR***\n" + tmpdir + "\nnot (yet) available\n"
-                    print(message)
-                else:
-                    filename = tmpdir + sep + "GD_0.GD"
-                    filename_ren = tmpdir + sep + "GD_0.GD.bak"
-                    filename_ren2 = tmpdir + sep + "GD_0.GD.2bak"
-                    if os.path.isfile(filename_ren2):
-                        try:
-                            os.remove(filename_ren2)
-                            message = "***Info***\nGD_0.GD.2bak removed\n"
-                        except:
-                            message = "***ERROR***\n,GD_0.GD.2bak could not be removed\n"
-                        print(message)
-                    if os.path.isfile(filename_ren):
-                        try:
-                            os.rename(filename_ren,filename_ren2)
-                            message += "***INFO***\nGD_0.GD.bak renamed into GD_0.GD.2bak\n"
-                        except:
-                            message += "***Info***\nrenaming GD_0.GD.bak not possible\n"
-                    if os.path.isfile(filename):
-                        try:
-                            os.rename(filename,filename_ren)
-                            message += "***INFO***\nGD_0.GD renamed into GD_0.GD.bak\n"
-                        except:
-                            message += "***ERROR***\ncreation of GD_0.GD.bak not possible\n"
-                    try:
-                        print("DBG L921")
-                        self.write_params(filename)
-                        message += "***OK***\nparameters saved in\n" + filename
-                        print(message)
-                    except:
-                        message = "***ERRROR***\n" + "writing " + filename + "\nnot possible"
-                        print(message)                 
-            except:
-                
-                message += "***ERROR***\n Contakt PKHG, something wrong happened"
-                print(message)
-                
-            context.scene.error_message = message
-            bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
-
-        if self.load_parameters:
-            self.load_parameters = False
-            try:
-                scriptpath = bpy.utils.script_paths()[0]
-                sep = os.path.sep
-                tmpdir = os.path.join(scriptpath,"addons", "geodesic_domes" , "tmp")
-#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp"                              
-                if not os.path.isdir(tmpdir):
-                    message = "***ERROR***\n" + tmpdir + "\nnot available"  
-                    print(message)
-                filename = tmpdir + sep + "GD_0.GD"
-#        self.read_file(filename)
-                try:
-                    res = self.read_file(filename)
-                    for i,el in enumerate(self.name_list):
-                        setattr(self,el,res[i])
-                        
-                    message = "***OK***\nparameters read from\n" + filename
-                    print(message)
-                    
-                except:
-                    message = "***ERRROR***\n" + "writing " + filename + "\nnot possible"
-                #bpy.context.scene.instant_filenames = filenames
-                
-            except:
-                message = "***ERROR***\n Contakt PKHG,\nsomething went wrong reading params happened"
-            context.scene.error_message = message
-            bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
-        return {'FINISHED'}
-    
-    def invoke(self, context, event):
-        global basegeodesic
-        bpy.ops.view3d.snap_cursor_to_center()
-        tmp = context.scene.geodesic_not_yet_called
-        if tmp:            
-            context.scene.geodesic_not_yet_called = False
-        self.execute(context)
-        return {'FINISHED'}
-
-def creategeo(polytype,orientation,parameters):
-    geo = None
-    if polytype == "Tetrahedron":
-        if orientation == "PointUp":
-            geo = geodesic_classes_259.tetrahedron(parameters)
-        elif orientation == "EdgeUp":
-            geo=geodesic_classes_259.tetraedge(parameters)
-        elif orientation == "FaceUp":
-            geo=geodesic_classes_259.tetraface(parameters)
-    elif polytype == "Octahedron": 
-        if orientation == "PointUp":
-            geo=geodesic_classes_259.octahedron(parameters)
-        elif orientation == "EdgeUp":
-            geo=geodesic_classes_259.octaedge(parameters)
-        elif orientation == "FaceUp":
-            geo=geodesic_classes_259.octaface(parameters)
-    elif polytype == "Icosahedron":
-        if orientation == "PointUp":
-            geo=geodesic_classes_259.icosahedron(parameters)
-        elif orientation == "EdgeUp":
-            geo=geodesic_classes_259.icoedge(parameters)
-        elif orientation == "FaceUp":
-            geo=geodesic_classes_259.icoface(parameters)
-    return geo
-    
-basegeodesic,fmeshname,smeshname,hmeshname,outputmeshname,strutimpmesh,hubimpmesh = [None]*7
-
-def finalfill(source,target):
-    count=0
-    for point in source.verts:
-        newvert = vefm_259.vertex(point.vector)
-        target.verts.append(newvert)
-        point.index = count
-        count  += 1 
-    for facey in source.faces:
-        row=len(facey.vertices)
-        if row >= 5:
-            newvert = vefm_259.average(facey.vertices).centroid()
-            centre = vefm_259.vertex(newvert.vector)
-            target.verts.append(centre)
-            for i in range(row):
-                if i == row - 1:
-                    a = target.verts[facey.vertices[-1].index]
-                    b = target.verts[facey.vertices[0].index]
-                else:
-                    a = target.verts[facey.vertices[i].index]
-                    b = target.verts[facey.vertices[i+1].index]
-                c = centre
-                f = [a,b,c]
-                target.faces.append(f)
-        else:
-            f = []
-            for j in range(len(facey.vertices)):
-
-                a = facey.vertices[j]
-                f.append(target.verts[a.index])
-            target.faces.append(f)
-        
-###for error messages         
-class DialogOperator(bpy.types.Operator):
-    bl_idname = "object.dialog_operator"
-    bl_label = "INFO"
-
-    def draw(self,context):
-        layout = self.layout
-        message = context.scene.error_message
-        col = layout.column()
-        tmp = message.split("\n")
-        for el in tmp:
-            col.label(el)
-        
-    def execute(self, context):
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        wm = context.window_manager
-        return wm.invoke_props_dialog(self)
-            
-
-######### register all
-def register():
-    bpy.utils.register_module(__name__)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-if __name__ == "__main__":
-    register()
-
diff --git a/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD b/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD
deleted file mode 100644
index cdf5422..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD
+++ /dev/null
@@ -1,115 +0,0 @@
-facetype_menu,'3',
-facetoggle,True,
-face_use_imported_object,False,
-facewidth,0.26006004214286804,
-fwtog,True,
-faceheight,1.0,
-fhtog,False,
-face_detach,False,
-fmeshname,'defaultface',
-geodesic_types,'Geodesic',
-import_mesh_name,'None',
-base_type,'Octahedron',
-orientation,'EdgeUp',
-geodesic_class,'Class 1',
-tri_hex_star,'tri',
-spherical_flat,'spherical',
-use_imported_mesh,False,
-cyxres,5,
-cyyres,5,
-cyxsz,1.0,
-cyysz,1.0,
-cyxell,1.0,
-cygap,1.0,
-cygphase,0.0,
-paxres,5,
-payres,5,
-paxsz,0.30000001192092896,
-paysz,1.0,
-paxell,1.0,
-pagap,1.0,
-pagphase,0.0,
-ures,8,
-vres,8,
-urad,1.0,
-vrad,0.25,
-uellipse,1.0,
-vellipse,1.0,
-upart,1.0,
-vpart,1.0,
-ugap,0.0,
-vgap,0.0,
-uphase,0.0,
-vphase,0.0,
-uexp,0.0,
-vexp,0.0,
-usuper,2.0,
-vsuper,2.0,
-utwist,0.0,
-vtwist,0.0,
-bures,8,
-bvres,8,
-burad,1.0,
-bupart,1.0,
-bvpart,1.0,
-buphase,0.0,
-bvphase,0.0,
-buellipse,1.0,
-bvellipse,1.0,
-grxres,5,
-gryres,2,
-grxsz,2.0,
-grysz,1.0,
-cart,0,
-frequency,2,
-eccentricity,1.0,
-squish,1.0,
-radius,2.8912599086761475,
-squareness,2.0,
-squarez,2.0,
-baselevel,5,
-dual,False,
-rotxy,0.0,
-rotz,0.0,
-uact,False,
-vact,False,
-um,3.0,
-un1,1.0,
-un2,1.0,
-un3,1.0,
-ua,1.0,
-ub,4.0,
-vm,1.0,
-vn1,1.0,
-vn2,1.0,
-vn3,1.0,
-va,1.0,
-vb,1.0,
-uturn,0.0,
-vturn,0.0,
-utwist,0.0,
-vtwist,0.0,
-struttype,0,
-struttoggle,True,
-strutimporttoggle,False,
-strutimpmesh,'GD_mesh',
-strutwidth,1.0,
-swtog,False,
-strutheight,1.0,
-shtog,False,
-strutshrink,1.0,
-sstog,False,
-stretch,1.0,
-lift,0.0010000000474974513,
-smeshname,'defaultstrut',
-hubtype,True,
-hubtoggle,False,
-hubimporttoggle,False,
-hubimpmesh,'None',
-hubwidth,1.0,
-hwtog,False,
-hubheight,1.0,
-hhtog,False,
-hublength,1.0,
-hstog,False,
-hmeshname,'None',
diff --git a/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD b/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD
deleted file mode 100644
index a75eafb..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD
+++ /dev/null
@@ -1,115 +0,0 @@
-facetype_menu,'0',
-facetoggle,False,
-face_use_imported_object,False,
-facewidth,0.5,
-fwtog,False,
-faceheight,1.0,
-fhtog,False,
-face_detach,False,
-fmeshname,'defaultface',
-geodesic_types,'Geodesic',
-import_mesh_name,'None',
-base_type,'Tetrahedron',
-orientation,'PointUp',
-geodesic_class,'Class 1',
-tri_hex_star,'tri',
-spherical_flat,'spherical',
-use_imported_mesh,False,
-cyxres,5,
-cyyres,5,
-cyxsz,1.0,
-cyysz,1.0,
-cyxell,1.0,
-cygap,1.0,
-cygphase,0.0,
-paxres,5,
-payres,5,
-paxsz,0.30000001192092896,
-paysz,1.0,
-paxell,1.0,
-pagap,1.0,
-pagphase,0.0,
-ures,8,
-vres,8,
-urad,1.0,
-vrad,0.25,
-uellipse,1.0,
-vellipse,1.0,
-upart,1.0,
-vpart,1.0,
-ugap,0.0,
-vgap,0.0,
-uphase,0.0,
-vphase,0.0,
-uexp,0.0,
-vexp,0.0,
-usuper,2.0,
-vsuper,2.0,
-utwist,0.0,
-vtwist,0.0,
-bures,8,
-bvres,8,
-burad,1.0,
-bupart,1.0,
-bvpart,1.0,
-buphase,0.0,
-bvphase,0.0,
-buellipse,1.0,
-bvellipse,1.0,
-grxres,5,
-gryres,2,
-grxsz,2.0,
-grysz,1.0,
-cart,0,
-frequency,1,
-eccentricity,1.0,
-squish,1.0,
-radius,1.0,
-squareness,2.0,
-squarez,2.0,
-baselevel,5,
-dual,False,
-rotxy,0.0,
-rotz,0.0,
-uact,False,
-vact,False,
-um,3.0,
-un1,1.0,
-un2,1.0,
-un3,1.0,
-ua,1.0,
-ub,4.0,
-vm,1.0,
-vn1,1.0,
-vn2,1.0,
-vn3,1.0,
-va,1.0,
-vb,1.0,
-uturn,0.0,
-vturn,0.0,
-utwist,0.0,
-vtwist,0.0,
-struttype,0,
-struttoggle,False,
-strutimporttoggle,False,
-strutimpmesh,'None',
-strutwidth,1.0,
-swtog,False,
-strutheight,1.0,
-shtog,False,
-strutshrink,1.0,
-sstog,False,
-stretch,1.0,
-lift,0.0,
-smeshname,'defaultstrut',
-hubtype,True,
-hubtoggle,False,
-hubimporttoggle,False,
-hubimpmesh,'None',
-hubwidth,1.0,
-hwtog,False,
-hubheight,1.0,
-hhtog,False,
-hublength,1.0,
-hstog,False,
-hmeshname,'None',
diff --git a/release/scripts/addons_contrib/geodesic_domes/vefm_259.py b/release/scripts/addons_contrib/geodesic_domes/vefm_259.py
deleted file mode 100644
index ab79070..0000000
--- a/release/scripts/addons_contrib/geodesic_domes/vefm_259.py
+++ /dev/null
@@ -1,1218 +0,0 @@
-# vert class and overloading experiments
-import bpy
-import math
-from math import sqrt,acos,pi,sin,cos,atan,tan,fabs
-from mathutils import Vector
-
-#dbg = True
-sgn = lambda x : (x>0) - (x<0) #missing signum functin in Python
-try:
-    breakpoint = bpy.types.bp.bp
-except:
-    pass    
-
-from bpy_extras.object_utils import AddObjectHelper, object_data_add
-
-from collections import Counter
-
-'''PKHG not needed?
-def find_twice_vert(l1,l2):
-    tmp = [el for el in l1]
-    tmp.extend(l2)
-    tt = Counter(tmp)
-    result = max(tt.keys(),key = lambda k:tt[k])
-    print("twice give", result)
-    return result
-'''
-
-def vefm_add_object(selfobj):
-    for i in range(len(selfobj.verts)):
-        selfobj.verts[i].index = i
-    v = [el.vector for el in selfobj.verts]    
-#    e = [[edge.a.index,edge.b.index] for edge in selfobj.edges]
-    e = []
-    if type(selfobj.faces[0]) == type([]):
-#    print("\n=========== selfobj.faces[0]", selfobj.faces[0],type(selfobj.faces[0]))
-#PKHG should be a list of vertices, which have an index
-        f =  [[v.index for v in  face] for face in selfobj.faces]
-    else:
-        f =  [[v.index for v in  face.vertices] for face in selfobj.faces]
-#PKHG_DBG_25-11    print("dbg 25-11 f list =",f)
-#PKHG_DBG_25-11    print("dgb 25-11 v list +",v)
-    m = bpy.data.meshes.new(name= selfobj.name)
-    m.from_pydata(v, e, f )
-    # useful for development when the mesh may be invalid.
-#PKHG not needed, as ideasman_42 says    m.validate(verbose = False)
-    object_data_add(bpy.context, m, operator = None)
-#???ERROR PKHG in AddSelf    setMaterial(bpy.context.active_object,pkhg_red_color)
-
-#extra test phase
-
-
-
-
-class vertex:
-
-    def __init__(self,vec=(0,0,0)): #default x = 0,y = 0,z = 0):        
-        self.vector  = Vector(vec)
-        self.length = self.vector.length
-        self.index = 0
-        self.normal = 0
-        self.edges = []
-        self.faces = []
-        self.boundary = 0
-
-    def findlength(self):
-         self.length = self.vector.length
-
-    def normalize(self):
-        self.findlength()
-        if self.length > 0:
-            tmp = 1.0/self.length
-            self.vector  =  tmp * self.vector 
-#            self.x = self.vector[0] #(1.0/self.length)
-#            self.y = self.vector[1] #(1.0/self.length)
-#            self.z = self.vector[2] #(1.0/self.length)
-            self.length = 1.0
-
-    def findnormal(self):
-        target = []
-        if self.faces[:] == []:
-            print("vefm vertex L81 pkhg:*****ERROR**** findnormal has no faces")
-            return
-        for currentface in self.faces:
-            target.append(currentface.normal)
-        self.normal = average(target).centroid()
-        self.normal.findlength()
-        if self.length == 0:
-            print("******ERROR*** lenght zero in findnormal, j = (0,1,0) replcaced")
-            self.normal = vertex((0,1,0))
-        self.normal.normalize()
-
-    def clockwise(self): #PKHG self is a vertex
-        if self.boundary:
-            start = self.boundarystart() #???PKHG TODO error
-        else:
-            start = self.faces[0]
-#PKHG TODO do understand 21-11 solves starify of a normal tetrahedron
-#        start = self.faces[0]     #PKHG TODO see error above!
-#        start.docorners() #PKHG???? 
-        self.tempedges = []
-        self.tempfaces = []
-        for i in range(len(self.edges)):
-            #print("\n----------------------voor breakpunt pkhg in clockwise")
-            #breakpoint(locals(), self.index == 0)
-            self.tempfaces.append(start)
-            for corner in start.corners:
-                if corner[0] is not self:
-                    pass
-                elif corner[0] is self:
-                    self.tempedges.append(corner[1])
-                    nextedge = corner[2]
-            for facey in nextedge.faces:
-                if facey is not start:
-                    start = facey
-                    break
-        self.edges = self.tempedges
-        self.faces = self.tempfaces
-
-    def boundarystart(self):
-        #PKHG not implemented, needed?
-        pass
-
-#???PKHG TODO why are add and sub different? Solved check the two cases used 
-    def __add__(self,other):
-        if "<class 'mathutils.Vector'>" == str(type(other)):
-            tmp = self.vector + other
-        else:
-            tmp = self.vector + other.vector
-        return vertex(tmp)
-
-    def __sub__(self,other):
-        if "<class 'mathutils.Vector'>" == str(type(other)):
-            tmp = self.vector -  other
-        else:
-            tmp = self.vector - other.vector
-#        tmp = self.vector - other.vector
-        return vertex(tmp)
-
-    def __mul__(self,other):
-        tmp = self.vector * other
-        return vertex(tmp)
-
-    def __truediv__(self,other):
-        denom = 1.0/other
-        tmp = self.vector * denom
-        return (tmp)
-
-    def negative(self):
-        return vertex(-self.vector)
-
-class crossp:
-    ##   Takes in two vertices(vectors), returns the cross product.
-    def __init__(self,v1,v2):
-        self.v1 = v1
-        self.v2 = v2
-#
-    def docrossproduct(self):
-        tmp = self.v1.vector.cross(self.v2.vector)
-        return vertex(tmp)
-
-class average:
-    ##   Takes a list of vertices and returns the average. If two verts are passed, returns midpoint.
-    def __init__(self,vertlist):
-        self.vertlist = vertlist
- 
-    def centroid(self):
-        tmp  =  Vector()
-#PKHG avoid emptylist problems        
-        divisor = 1.0
-        nr_vertices = len(self.vertlist)
-        if nr_vertices > 1:
-            divisor = 1.0 / len(self.vertlist)
-        elif nr_vertices == 0:
-            print("\n***WARNING*** empty list in vefm_259.centroid! L180")
-        for vert in self.vertlist:
-            tmp = tmp + vert.vector
-        tmp = tmp * divisor
-        return vertex(tmp)
-
-class edge:
-    def __init__(self,a = 0,b = 0):
-        self.a = a
-        self.b = b
-        self.index = 0
-        self.normal = 0
-        self.cross = 0
-        self.unit = 0
-        self.faces = []
-        self.vect = 0  #PKHG becomes  b - a
-        self.vectb = 0 #PKHG becomes  a - b
-#        self.length = 0
-        self.boundary = 0
-        self.findvect()
-#        print("vect len before",self.vect.length)
-        self.findlength()
-#        print("vect after",self.vect.length)
-
-    def findvect(self):
-        self.vect = self.b - self.a
-        self.vectb = self.a - self.b
-
-    def findlength(self):
-        self.vect.findlength()
-        self.vectb.length = self.vect.length
-
-    def findnormal(self):
-                
-        if self.boundary:
-            self.normal = self.faces[0].normal    #average([self.a,self.b]).centroid()
-        else:
-            self.normal = average([self.faces[0].normal,self.faces[1].normal]).centroid()
-        self.normal.normalize()
-#     def findother(self,vertindex):
-#
-#         if vertindex==self.a:
-#
-#             return self.b
-#
-#         else:
-#             return self.a
-##        different classes for 3,4,> sides??
-
-class face:
-    def __init__(self,vertices=[]):
-#PKHG ok good for tri's at least        print("\n ========= vefm L226======dbg face vertices = ",vertices)
-        self.vertices = vertices    ##   List of vertex instances.
-        self.edges=[]            ##   Will be filled with the sides of the face.
-        self.boundary = 0        ##   When set will have bool and id of edge concerned.
-        self.normal = 0            ##   Face normal found through cross product.
-        self.corners=[]
-        self.spokes=[]            ##   Vectors of the bisecting angles from each corner to the centre + dotproduct.
-        self.index = 0
- 
- #dotproduct is misleading name, it is the hook between two vectors!
-    def dotproduct(self,v1,v2):
-        v1.findlength()
-        v2.findlength()
-        if v1.length == 0 or v2.length == 0:
-            print("\nPKHG warning, =====vefm_259 dotproduct L245====== at least one zero vector 0 used")         
-            return 0 # pi * 0.25 #PKHT_TEST04nov pi * 0.25  #45 degrees??? #PKHG???TODO
-        dot = v1.vector.dot(v2.vector)
-        costheta = dot / (v1.length * v2.length)
-        tmp = acos(costheta)
-        return tmp
-    
-    def orderedges(self):
-        temp=[]
-        finish = len(self.vertices)
-        for i in range(finish):
-            current = self.vertices[i]
-            if i==finish-1:
-                next = self.vertices[0]
-            else:
-                next = self.vertices[i+1]
-            for edge in face.edges:
-                if edge.a==current and edge.b==next:
-                    face.clockw.append(edge.vect)
-                    face.aclockw.append(edge.vectb)
-                    temp.append(edge)
-                if edge.b==current and edge.a==next:
-                    face.clockw.append(edge.vectb)
-                    face.aclockw.append(edge.vect)
-                    temp.append(edge)
-            for edge in face.edges:
-                if edge.a==current and edge.b==next:
-                    face.clockw.append(edge.vect)
-                    face.aclockw.append(edge.vectb)
-                    temp.append(edge)
-                if edge.b==current and edge.a==next:
-                    face.clockw.append(edge.vectb)
-                    face.aclockw.append(edge.vect)
-                    temp.append(edge)
-            face.vertices = temp
-    
-    
-    def docorners(self):
-        ##   This function identifies and stores the vectors coming from each vertex
-        ##   allowing easier calculation of cross and dot products.
-        finish = len(self.vertices)
-        '''
-        which = None
-        occur1 = None
-        occur2 = None
-        if finish == 3 and len(self.edges) == 2 :    
-            print("\n***ERROR*** only two edges should be three")
-      #      return        
-            occur1 = [self.vertices.index(self.edges[0].a),self.vertices.index(self.edges[0].b)]
-            occur2 = [self.vertices.index(self.edges[1].a),self.vertices.index(self.edges[1].b)]
-            #occur2 = [self.edges[1].a.index, self.edges[1].b.index]
-            twice = find_twice_vert(occur1,occur2)
-            occur1.remove(twice)
-            occur2.remove(twice)
-            #new_edge = edge(self.vertices[occur1[0]],self.vertices[occur2[0]])
-            #self.edges.append(new_edge)
-        '''
-        for i in range(finish):
-            current = self.vertices[i]
-            if i==finish-1:
-                next = self.vertices[0]
-            else:
-                next = self.vertices[i+1]
-            if i==0:
-                previous = self.vertices[-1]
-            else:
-                previous = self.vertices[i-1]
-            corner=[current] #PKHG new for each vertex = current
-            #corner = current
-            rightedge = None
-            leftedge = None
-            teller = -1
-            for edge in self.edges:
-        #        if finish == 3 and len(self.edges) == 2  and i == 2:
-        #            return    
-                teller += 1                                                        
-                currentinfo = (current, edge.a, edge.b, edge.a is current, edge.b is current)
-                #next and previous are vertex with respect to ith vertex
-                if edge.a is current or edge.b is current:    ##  does this edge contain our current vert
-                    if edge.a is current:
-                        if edge.b is next:
-                            rightedge = edge
-                            rightvect = edge.vect
-                        if edge.b is previous:
-                            leftedge = edge
-                            leftvect = edge.vect
-                    elif edge.b is current:
-                        if edge.a is next:
-                            rightedge = edge
-                            rightvect = edge.vectb
-                        if edge.a is previous:
-                            leftedge = edge
-                            leftvect = edge.vectb
-            corner.append(rightedge)
-            corner.append(leftedge)
-            if rightedge and leftedge:
-                '''
-                if rightedge:
-                    print("rightedge",rightedge.index)
-                if leftedge:
-                    print( "leftedge",leftedge.index)
-                print("corner",corner)
-                #'''
-                dotty = self.dotproduct(rightvect,leftvect)
-                corner.append(dotty)
-            self.corners.append(corner)
-     
-     
-    def findnormal(self):
-        one = self.corners[1][2]
-        two = self.corners[1][1]
-        if one.a is self.corners[1][0]:
-            one = one.vect
-        elif one.b is self.corners[1][0]:
-            one = one.vectb
-        if two.a is self.corners[1][0]:
-            two = two.vect
-        elif two.b is self.corners[1][0]:
-            two = two.vectb
-        self.normal = crossp(one,two).docrossproduct()
-        self.normal.findlength()
-        self.normal.normalize()
-
-    def dospokes(self):
-#PKHG_OK_24-11        print("\n============vefm L375==============dbg, dospokes called corners =", self.corners[:])
-        for corner in self.corners:
-            vert = corner[0]
-            right = corner[1]
-            left = corner[2]
-            if right.a is vert:
-                one = vertex(right.vect.vector)
-            elif right.b is vert:
-                one = vertex(right.vectb.vector)
-            if left.a is vert:
-                two = vertex(left.vect.vector)
-            elif left.b is vert:
-                two = vertex(left.vectb.vector)
-            
-            one.normalize()
-            two.normalize()
-            spoke = one+two
-            spoke.normalize()
-            self.spokes.append(spoke)
-
-    def artspokes(self):
-        centre = average(self.vertices).centroid()
-        for point in self.vertices:
-            newedge = edge(point,centre)
-            spokes.append(newedge)
-            
-class mesh:
-    def __init__(self , name="GD_mesh"):
-        self.name = name #pkhg test phase at least ;-)
-        self.verts=[]
-        self.edges=[]
-        self.faces=[]
-        self.edgeflag = 0
-        self.faceflag = 0
-        self.vertexflag = 0
-        self.vertedgeflag = 0
-        self.vertfaceflag = 0
-        self.faceedgeflag = 0
-        self.boundaryflag = 0
-        self.vertnormalflag = 0
-        self.edgenormalflag = 0
-        self.facenormalflag = 0
-        #found in geodesic.py ??? needed for test here!
-        self.a45 = pi * 0.25
-        self.a90 = pi * 0.5
-        self.a180 = pi
-        self.a270 = pi * 1.5
-        self.a360 = pi * 2        
-
-        
-    def power(self,a,b):         ## Returns a power, including negative numbers
-        result = sgn(a)*(abs(a)**b)
-        return result
-
-    def sign(self,d):    ## Works out the sign of a number.
-        return sgn(d)
-
-    def ellipsecomp(self,efactor,theta):
-        if theta==self.a90:
-            result = self.a90
-        elif theta==self.a180:
-            result = self.a180
-        elif theta==self.a270:
-            result = self.a270
-        elif theta==self.a360:
-            result = 0.0
-        else:                        
-            result = atan(tan(theta)/efactor**0.5)
-            if result<0.0:
-                if theta>self.a180:
-                    result = result+self.a180
-                elif theta<self.a180:
-                    result = result+self.a180
-    ##  Fishy - check this.
-            if result>0.0:
-                if theta>self.a180:
-                    result = result+self.a180
-                elif theta<self.a180:
-                    result = result
-        return result
-        
-    def connectivity(self):
-        self.dovertedge()
-        self.dovertface()
-        self.dofaceedge()
-        self.boundary()
-
-    def superell(self,n1,uv,turn):
-        t1 = sin(uv+turn)
-        t1 = abs(t1)
-        t1 = t1**n1
-        t2 = cos(uv+turn)
-        t2 = abs(t2)
-        t2 = t2**n1
-        r = self.power(1.0/(t1+t2),(1.0/n1))
-        return r
-
-#PKHG changed according to http://de.wikipedia.org/wiki/Superformel
-#a and b a semi-diameter
-    def superform(self,m,n1,n2,n3,uv,a,b,twist):
-        t1 = cos(m*(uv+twist)*.25) / a
-        t1 = abs(t1)
-        t1 = t1**n2
-        t2 = sin(m*(uv+twist)*.25) / b
-        t2 = abs(t2)
-        t2 = t2**n3
-        r = self.power(1.0/(t1+t2),n1)        
-        return r
-        
-    def dovertedge(self):
-        if not self.vertedgeflag:
-            for vert in self.verts:
-                vert.edges = []
-            for currentedge in self.edges:
-                currentedge.a.edges.append(currentedge)
-                currentedge.b.edges.append(currentedge)
-        self.vertedgeflag = 1
-        
-    def dovertface(self):
-        if not self.vertfaceflag:
-            for vert in self.verts:
-                vert.faces = []
-            for face in self.faces:
-                for vert in face.vertices:
-                    vert.faces.append(face)
-        self.vertfaceflag = 1
-        
-    def dofaceedge(self):
-        self.dovertedge()    ## just in case they haven't been done
-        self.dovertface()    ##
-        if not self.faceedgeflag:
-            for edge in self.edges:
-                edge.faces=[]
-            for face in self.faces:
-                face.edges = []
-            for face in self.faces:
-                finish = len(face.vertices)
-                for i in range(finish):
-                    current = face.vertices[i]
-                    if i == finish-1:
-                        next = face.vertices[0]
-                    else:
-                        next = face.vertices[i+1]
-                    for edge in current.edges:
-                        if edge.a is current or edge.b is current:
-                            if edge.b is next or edge.a is next:
-                                edge.faces.append(face)
-                                face.edges.append(edge)
-        self.faceedgeflag = 1
- 
-    def boundary(self):
-        if not self.boundaryflag:
-            for edge in self.edges:
-                if len(edge.faces) < 2:
-                    edge.boundary = 1
-                    edge.faces[0].boundary = 1
-                    edge.a.boundary = 1
-                    edge.b.boundary = 1
-                    
-##   The functions below turn the basic triangular faces into
-##   hexagonal faces, creating the buckyball effect.
-#PKHG seems to work only for meshes with tri's ;-) ??!!
-    def hexify(self):
-        self.hexverts=[]
-        self.hexedges=[]
-        self.hexfaces=[]
-        #PKHG renumbering the index of the verts
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        #PKHG renumbering the index of the edges
-        for i in range(len(self.edges)):
-            self.edges[i].index = i
-        #PKHG  self=> dovertedge, dovertface, dofaceedge, boundary()
-        self.connectivity()
-        hexvert_counter = 0
-        for edge in self.edges:
-#            print("21-11 >>>>>>>>>>>>>>dbg hexify L552")
-#            breakpoint(locals(),True)
-            self.hexshorten(edge,hexvert_counter)
-            hexvert_counter += 2 #PKHG two new vertices done
-#PKHG 21-11            print("21-11 <<<<<<<<<<<<<<< na hexshorten L557", hexvert_counter)
-#PKHG 21-11            breakpoint(locals(),True)
-
-        for face in self.faces:
-            self.makehexfaces(face)
-        
-        for vert in self.verts:
-            vert.clockwise()
-            self.hexvertface(vert)
-        self.verts = self.hexverts
-        self.edges = self.hexedges
-        self.faces = self.hexfaces
-        self.vertedgeflag = 0
-        self.vertfaceflag = 0
-        self.faceedgeflag = 0
-#PKHG_DBG        print("\n ==========================self hexified I hope")
-        #breakpoint(locals(),True)
- 
-    def hexshorten(self,currentedge, hexvert_counter):
-        third = vertex(currentedge.vect/3.0)
-        newvert1 = vertex(currentedge.a.vector)
-        newvert2 = vertex(currentedge.b.vector)
-        newvert1 = newvert1 + third
-        newvert1.index = hexvert_counter
-        newvert2 = newvert2 - third
-        newvert2.index = hexvert_counter + 1 #PKHG caller adjusts +=2 
-        newedge = edge(newvert1,newvert2)
-        newedge.index = currentedge.index
-        self.hexverts.append(newvert1)
-        self.hexverts.append(newvert2)
-        self.hexedges.append(newedge)
- 
-    def makehexfaces(self,currentface):
-        vertices=[]
-        currentface.docorners()
-        for corner in currentface.corners:
-            vert = corner[0]
-            rightedge = corner[1]
-            leftedge = corner[2]
-            lid = leftedge.index
-            rid = rightedge.index
-            
-            if leftedge.a is vert:
-                vertices.append(self.hexedges[lid].a)
-            elif leftedge.b is vert:
-                vertices.append(self.hexedges[lid].b)
-                
-            if rightedge.a is vert:
-                vertices.append(self.hexedges[rid].a)
-            elif rightedge.b is vert:
-                vertices.append(self.hexedges[rid].b)
-                
-        newface = face(vertices)
-        newedge1 = edge(vertices[0],vertices[1])
-        newedge2 = edge(vertices[2],vertices[3])
-        newedge3 = edge(vertices[4],vertices[5])
-        self.hexfaces.append(newface)
-        self.hexedges.append(newedge1)
-        self.hexedges.append(newedge2)
-        self.hexedges.append(newedge3)
-
-    def hexvertface(self,vert):
-        vertices=[]
-        for edge in vert.edges:
-            eid = edge.index
-            if edge.a is vert:
-                vertices.append(self.hexedges[eid].a)
-            elif edge.b is vert:
-                vertices.append(self.hexedges[eid].b)
-        newface = face(vertices)
-        self.hexfaces.append(newface)
- 
-    def starify(self):
-        self.starverts=[]
-        self.staredges=[]
-        self.starfaces=[]
-        for i in range(len(self.verts)):
-            self.verts[i].index = i
-        for i in range(len(self.edges)):
-            self.edges[i].index = i
-        self.connectivity()
-        star_vert_counter = 0
-        for currentedge in self.edges:
-            newvert = average([currentedge.a,currentedge.b]).centroid()
-            newvert.index = star_vert_counter
-            star_vert_counter += 1
-            self.starverts.append(newvert)
-        star_face_counter = 0
-        star_edge_counter = 0
-        for currentface in self.faces:
-            currentface.docorners()
-            vertices=[]
-            for corner in currentface.corners:
-                vert = self.starverts[corner[1].index]
-#                vert.index = star_vert_counter
-#                star_vert_counter += 1
-                vertices.append(vert)
-            newface = face(vertices)
-            newface.index = star_face_counter
-            star_face_counter += 1
-            newedge1 = edge(vertices[0],vertices[1])
-            newedge1.index = star_edge_counter
-            newedge2 = edge(vertices[1],vertices[2])
-            newedge2.index = star_edge_counter + 1
-            newedge3 = edge(vertices[2],vertices[0])
-            newedge3.index = star_edge_counter + 2
-            star_edge_counter += 3
-            self.starfaces.append(newface)
-            self.staredges.append(newedge1)
-            self.staredges.append(newedge2)
-            self.staredges.append(newedge3)
-        for vert in self.verts:
-            vertices=[]
-            vert.clockwise()
-            for currentedge in vert.edges:
-                eid = currentedge.index
-                vertices.append(self.starverts[eid])
-            newface = face(vertices)
-            newface.index = star_face_counter
-            star_face_counter += 1
-            self.starfaces.append(newface)
-        self.verts = self.starverts
-        self.edges = self.staredges
-        self.faces = self.starfaces
-        self.vertedgeflag = 0
-        self.vertfaceflag = 0
-        self.faceedgeflag = 0
-
-    def class2(self):
-        self.class2verts=[] #PKHG_??? used?
-        self.class2edges=[] #PKHG_??? used?
-        self.class2faces=[]
-        
-        newvertstart = len(self.verts)
-        newedgestart = len(self.edges)
-        counter_verts = len(self.verts) #PKHG
-#        for i in range(len(self.verts)):
-        for i in range(counter_verts):
-            self.verts[i].index = i
-        for i in range(len(self.edges)):
-            self.edges[i].index = i
-        for i in range(len(self.faces)):
-            self.faces[i].index = i
-        self.connectivity()
-        for currentface in self.faces:
-            currentface.docorners()
-            newvert = average(currentface.vertices).centroid()
-            newvert.index = counter_verts
-#PKHG_??? 20-11
-            counter_verts += 1
-            self.verts.append(newvert)
-            newedge1 = edge(currentface.vertices[0],newvert)
-            newedge2 = edge(currentface.vertices[1],newvert)
-            newedge3 = edge(currentface.vertices[2],newvert)
-            self.edges.append(newedge1)
-            self.edges.append(newedge2)
-            self.edges.append(newedge3)
-        for currentedge in range(newedgestart):
-            self.edges[currentedge].a = self.verts[self.edges[currentedge].faces[0].index+newvertstart]
-            self.edges[currentedge].b = self.verts[self.edges[currentedge].faces[1].index+newvertstart]
-            self.edges[currentedge].findvect()
-        #breakpoint(locals(),True)                
-        for currentvert in range(newvertstart):
-            vert = self.verts[currentvert]
-            vertices=[]
-            vert.clockwise()
-            for currentface in vert.faces:
-                eid = currentface.index
-#PKHG_OK                print(">>>>eid = ", eid,newvertstart + eid)
-                vertices.append(self.verts[newvertstart + eid])
-            #print("21-11 L710  currentvert is=", currentvert)
-            #breakpoint(locals(),True)    
-            for i in range(len(vertices)):
-                if i == len(vertices) - 1:
-                    next = vertices[0]
-                else:
-                    next = vertices[i+1]
-                #print("21-11 L710  i is=", i)
-                #breakpoint(locals(),True)    
-                newface = face([vert,vertices[i],next])
-                self.class2faces.append(newface)
-        #self.verts = self.class2verts
-        #self.edges = self.class2edges
-        self.faces = self.class2faces
-        self.vertedgeflag = 0
-        self.vertfaceflag = 0
-        self.faceedgeflag = 0    
-        
-    def dual(self):
-        self.dualverts=[]
-#        self.dualedges=[]
-        self.dualfaces=[]
-#PKHG 21-11 dual problem?!        
-        counter_verts = len(self.verts)
-        for i in range(counter_verts):
-            self.verts[i].index = i
-        for i in range(len(self.edges)):
-            self.edges[i].index = i
-        for i in range(len(self.faces)):
-            self.faces[i].index = i
-        self.connectivity()
-        counter_verts = 0
-        for currentface in self.faces:
-            currentface.docorners()
-            newvert = average(currentface.vertices).centroid()
-            newvert.index = counter_verts #PKHG needed in >= 2.59 
-            counter_verts += 1            
-            self.dualverts.append(newvert)
-        for vert in self.verts:
-            vertices=[]
-            vert.clockwise()
-            for currentface in vert.faces:
-                eid = currentface.index
-                vertices.append(self.dualverts[eid])
-            newface = face(vertices)
-            self.dualfaces.append(newface)
-        for currentedge in self.edges:
-            currentedge.a = self.dualverts[currentedge.faces[0].index]
-            currentedge.b = self.dualverts[currentedge.faces[1].index]
-        self.verts = self.dualverts
-#        self.edges = self.staredges
-        self.faces = self.dualfaces
-        self.vertedgeflag = 0
-        self.vertfaceflag = 0
-        self.faceedgeflag = 0
- 
-class facetype(mesh):
-    def __init__(self,basegeodesic,parameters,width,height,relative):
-        mesh.__init__(self)
-        self.detatch = parameters[0]
-        self.endtype = parameters[1]
-        self.coords = parameters[2]
-        self.base = basegeodesic
-        self.relative = relative
-        self.width = width
-    
-        if not self.relative:
-            newwidth = self.findrelative()
-            self.width = width*newwidth
-        self.height = height
-        self.base.connectivity()
-        for coord in self.coords:
-            coord[0]=coord[0]*self.width
-            coord[1]=coord[1]*self.height
-        if not self.base.facenormalflag:
-            for currentface in self.base.faces:
-            #    print("face normal ",currentface.normal)
-                currentface.docorners()
-                currentface.findnormal()
-            #    print("face normal ",currentface.normal.x,currentface.normal.y,currentface.normal.z)
-            self.base.facenormalflag = 1
-        if self.endtype==4 and not self.base.vertnormalflag:
-            for currentvert in self.base.verts:
-                currentvert.findnormal()
-            self.base.vertnormalflag = 1
-        self.createfaces()
- 
-    def findrelative(self):
-        centre = average(self.base.faces[0].vertices).centroid()
-        edgelist=[]
-        for point in self.base.faces[0].vertices:
-            newedge = edge(centre,point)
-            edgelist.append(newedge)
-        length = 0
-        for edg in edgelist:
-            extra = edg.vect.length
-            length = length+extra
-        #    print("length",length,"extra",extra)
-        length = length/len(edgelist)
-    #    print("find relative",length)
-        return length
- 
-    def createfaces(self):
-        if not self.detatch:
-            for point in self.base.verts:
-                self.verts.append(point)
-        if self.endtype==4:
-            self.createghostverts()
-        for currentface in self.base.faces:
-            self.doface(currentface)
-
-    def createghostverts(self):
-        self.ghoststart = len(self.verts)
-        for vert in self.base.verts:
-            newvert = vert + (vert.normal * self.coords[-1][1])
-            self.verts.append(newvert)
-        
-    def doface(self,candidate):
-        grid=[]
-        candidate.dospokes()
-    #    print("Candidate normal",candidate.normal.x,candidate.normal.y,candidate.normal.z)
-        if not self.detatch:
-            line=[]
-            for vert in candidate.vertices:
-                line.append(vert)
-            grid.append(line)
-        else:
-            line=[]
-            for point in candidate.vertices:
-                newvert = vertex(point.vector)
-                self.verts.append(newvert)
-                line.append(newvert)
-            grid.append(line)
-        finish = len(self.coords)
-        if self.endtype==1 or self.endtype==4:
-            finish = finish-1
-        for i in range(finish):
-            up = candidate.normal*self.coords[i][1]
-            line=[]
-            for j in range(len(candidate.vertices)):
-                dotfac = candidate.corners[j][3]*0.5
-                vec=(candidate.spokes[j]*(self.coords[i][0]/sin(dotfac)))        #self.coords[i][0])#(self.coords[i][0]/sin(dotfac)))#+up
-                newvert = candidate.vertices[j]+vec+up
-                line.append(newvert)
-                self.verts.append(newvert)
-            grid.append(line)
-        if self.endtype==4:
-            line=[]
-            for i in range(len(candidate.vertices)):
-                vert = self.verts[candidate.vertices[i].index+self.ghoststart]
-                line.append(vert)
-            #    self.verts.append(vert)
-            grid.append(line)
-        for line in grid:
-            line.append(line[0])
-        if self.endtype==3:
-            grid.append(grid[0])
-        for i in range(len(grid)-1):
-            for j in range(len(grid[i])-1):
-                one = grid[i][j]
-                two = grid[i][j+1]
-                three = grid[i+1][j+1]
-                four = grid[i+1][j]
-                newface = face([one, two, three, four])
-                self.faces.append(newface)
-        if self.endtype==2:
-            finalfaceverts = grid[-1]
-            newface = face(finalfaceverts[:-1])
-            self.faces.append(newface)
-        if self.endtype==1:
-            lastvert = average(candidate.vertices).centroid()
-            up = candidate.normal*self.coords[-1][1]
-            newvert = lastvert+up
-            self.verts.append(newvert)
-            ring = grid[-1]
-            for i in range(len(ring)-1):
-                newface = face([newvert,ring[i],ring[i+1]])
-                self.faces.append(newface)
-
-class importmesh(mesh):
-    def __init__(self,meshname,breakquadflag):    
-        mesh.__init__(self)
-#        print("mesh and breakquad",meshname,breakquadflag)
-#        impmesh = NMesh.GetRawFromObject(meshname)
-        impmesh = bpy.data.objects[meshname]
-        copied_mesh = None
-        if breakquadflag:
-            name = impmesh.name
-#PKHG???needed???NO 3-11-2011            impmesh.name = "Original_" + name
-            impmesh.name =  name
-#PKHG TODO use a copy?   no not necessary         bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0, 0,0}))
-#PKHG TODO use a copy?            copied_mesh = bpy.context.active_object
-            bpy.ops.object.mode_set(mode='EDIT')
-            bpy.ops.mesh.quads_convert_to_tris()
-            bpy.ops.object.mode_set(mode='OBJECT')
-
-        for v in impmesh.data.vertices:
-            vert = vertex(v.co)
-            vert.index = v.index
-            self.verts.append(vert)
-#PKHG verts is now a list of vertex, so to say a copy of the Vectors
-
-#PKHG edges
-        for e in impmesh.data.edges:
-            tmp = []
-            for vert in e.vertices:
-                a = self.verts[vert]
-                tmp.append(a)
-            newedge = edge(tmp[0],tmp[1])
-            newedge.index = e.index
-            self.edges.append(newedge)            
-#PKHG faces with out bmesh replace next line polygons by faces
-        for f in impmesh.data.polygons:
-            temp=[]
-            for vert in f.vertices:  #PKHG a list! of indices 
-                a = self.verts[vert] #PKHG verts contains already vertex objects
-                temp.append(a)
-            newface = face(temp)
-            newface.index = f.index #indexcount
-            self.faces.append(newface)
-        self.dovertedge()
-        self.dovertface()
-        self.temp=[]    
-
-        for i in range(len(self.verts)):
-            self.temp.append([])
-            self.verts[i].index = i
-        for i in range(len(self.verts)):
-            target = self.surroundingverts(self.verts[i])    
-            for j in range(len(target)):                ## go through those verts
-                temptarg = self.temp[target[j].index]        
-                flag = 0                    ## set a flag up
-        
-                for k in range(len(temptarg)):        ## go through temp list for each of those verts
-                    
-                    if temptarg[k]==i:            ## if we find a match to the current vert...
-                        flag = 1            ## raise the flag
-            
-                if flag==0:                ## if there is no flag after all that...
-                    self.temp[target[j].index].append(i)    ## add current vert to temp list of this surrounding vert
-                    self.temp[i].append(target[j].index)    ## add this surrounding vert to the current temp list
-                    newedge = edge(self.verts[i],self.verts[target[j].index])
-                    self.edges.append(newedge)    ## add the newly found edge to the edges list
-        
-        for edg in self.edges:
-            edg.findvect()
-        self.vertedgeflag = 0    
-        self.vertedgeflag = 0    
-        self.connectivity()
-#PKHG_DBG_OK        print("\n======= mesh imported")
-                                                    
-    def surroundingverts(self,vert):
-        ''' Find the verts surrounding vert'''        
-        surround=[]                    ## list to be filled and returned        
-        for faces in vert.faces:        ## loop through faces attached to vert
-            finish = len(faces.vertices)
-            for i in range(finish):            
-                if i==finish-1:
-                    next = faces.vertices[0]
-                else:
-                    next = faces.vertices[i+1]
-                if vert == faces.vertices[i]:
-                    surround.append(next)                                    
-        return surround
-
-    def breakquad(self,quad_face):
-        ''' turn quads into triangles'''
-        distance1 = quad_face.vertices[0]-quad_face.vertices[2]
-        distance2 = quad_face.vertices[1]-quad_face.vertices[3]        
-        distance1.findlength()
-        distance2.findlength()        
-        if abs(distance1.length)<abs(distance2.length):
-            self.faces[quad_face.index]=face([quad_face.vertices[0],quad_face.vertices[1],quad_face.vertices[2]])
-            self.faces.append(face([quad_face.vertices[0],quad_face.vertices[2],quad_face.vertices[3]]))
-        else:
-            self.faces[quad_face.index]=face([quad_face.vertices[0],quad_face.vertices[1],quad_face.vertices[3]])
-            self.faces.append(face([quad_face.vertices[1],quad_face.vertices[2],quad_face.vertices[3]]))            
-        
-                        
-class strut(mesh):
-    def __init__(self,base,struttype,width,height,length,widthtog,heighttog,lengthtog,meshname,stretchflag,lift):
-        mesh.__init__(self)
-        ## put in strut prep stuff here
-        if struttype==None:
-            return
-        total = 0
-        divvy = len(base.faces[0].edges)
-        for lengf in base.faces[0].edges:
-            lengf.vect.findlength()
-            total = total+lengf.vect.length
-        yardstick = total/divvy
-        if widthtog:
-            self.width = width
-        else:
-            self.width = width * yardstick
-        if heighttog:
-            self.height = height
-        else:
-            self.height = height*yardstick
-        if lengthtog:
-            self.shrink = length
-        else:
-            self.shrink = length * yardstick        
-        if not base.facenormalflag:
-            for currentface in base.faces:
-                currentface.docorners()
-                currentface.findnormal()
-            base.facenormalflag = 1
-        for edj in base.edges:
-            edj.findnormal()
-            side = edge(edj.a,edj.b)
-            edj.unit = side.vect
-            edj.unit.normalize()    
-            edj.cross = crossp(edj.normal,edj.unit).docrossproduct()
-        template = importmesh(meshname,0)
-        maxx = 0
-        minx = 0
-        for vert in template.verts:
-#            if vert.x>maxx:
-            if vert.vector.x > maxx:
-#                maxx = vert.x
-                maxx = vert.vector.x
-#            if vert.x<minx:
-            if vert.vector.x < minx:
-#                minx = vert.x
-                minx = vert.vector.x
-        for edj in base.edges:
-            start = len(self.verts)
-            centre = average([edj.a,edj.b]).centroid()
-            split = edj.vect.length/2
-            #PKHG no division by zero!!
-            tmp = 1.0
-            if maxx != minx:
-                tmp = 1.0/(maxx - minx)
-#            dubbl = edj.vect.length/(maxx-minx)
-            dubbl = edj.vect.length * tmp
-            #PKHG end no division by zero!!
-            diffplus = split-maxx
-            diffminus=-split-minx
-            for point in template.verts:
-#                ay=(edj.normal*point.z*self.height)+(edj.normal*lift)
-                ay=(edj.normal * point.vector.z * self.height) + (edj.normal * lift)
-#                ce = edj.cross * point.y * self.width
-                ce = edj.cross * point.vector.y * self.width
-                if stretchflag:
-#                    be = edj.unit*self.shrink*dubbl*point.x
-                    be = edj.unit * self.shrink * dubbl * point.vector.x
-                else:
-#                    if point.x > 0.0:
-                    if point.vector.x > 0.0:    
-#                        be = edj.unit * self.shrink * (point.x + diffplus)
-                        be = edj.unit * self.shrink * (point.vector.x + diffplus)
-#                    elif point.x < 0.0:
-                    elif point.vector.x < 0.0:    
-#                        be = edj.unit * self.shrink * (point.x + diffminus)
-                        be = edj.unit * self.shrink * (point.vector.x + diffminus)
-#                    elif point.x == 0.0:
-                    elif point.vector.x == 0.0:
-#                        be = edj.unit * self.shrink * point.x
-                        be = edj.unit * self.shrink * point.vector.x
-                de = ay + be + ce
-                newvert = centre + de
-                self.verts.append(newvert)
-            for edjy in template.edges:
-                one = edjy.a.index+start
-                two = edjy.b.index+start
-                newedge = edge(self.verts[one],self.verts[two])
-                self.edges.append(newedge)
-            for facey in template.faces:
-                faceverts=[]
-                for verty in facey.vertices:
-                    index = verty.index+start
-                    faceverts.append(self.verts[index])
-                newface = face(faceverts)
-                self.faces.append(newface)
-        self.vertedgeflag = 0    
-        self.vertedgeflag = 0                        
-        self.connectivity()    
-        
-class hub(mesh):
-    def __init__(self,base,hubtype,width,height,length,widthtog,heighttog,lengthtog,meshname):
-        mesh.__init__(self)
-        self.width = 1.0
-        self.height = 1.0
-        self.shrink = 1.0
-        ## put in strut prep stuff here
-        if hubtype==None:
-            return
-        total = 0
-        divvy = len(base.faces[0].edges)
-        for lengf in base.verts[0].edges:
-            lengf.vect.findlength()
-            total = total+lengf.vect.length
-        yardstick = total / divvy
-        if widthtog:
-            self.width = width
-        else:
-            self.width = width * yardstick
-        if heighttog:
-            self.height = height
-        else:
-            self.height = height * yardstick
-        if lengthtog:
-            self.shrink = length
-        else:
-            self.shrink = length * yardstick
-            
-        if not base.facenormalflag:
-            for currentface in base.faces:
-                currentface.docorners()
-                currentface.findnormal()
-            base.facenormalflag = 1
-#PKHG_2411        breakpoint(locals(),True) #PKHG_DBG 24-11 reason ERROR**** findnormal has no faces
-
-            
-        for apex in base.verts:
-            apex.findnormal()
-            side = edge(apex.edges[0].a,apex.edges[0].b)
-            apex.unit = side.vect #PKHG is Vector: b -a
-            apex.unit.normalize()    
-            apex.cross = crossp(apex.normal,apex.unit).docrossproduct()
-            apex.unit = crossp(apex.cross,apex.normal).docrossproduct()
-            
-        template = importmesh(meshname,0)
-        for apex in base.verts:
-            start = len(self.verts)
-            centre = apex    
-            for point in template.verts:
-                ay = apex.normal * point.vector.z * self.height
-                ce = apex.cross * point.vector.y * self.width
-                be = apex.unit * point.vector.x * self.shrink
-                de = ay+be+ce
-                newvert = centre+de
-                self.verts.append(newvert)
-            for edjy in template.edges:
-                one = edjy.a.index+start
-                two = edjy.b.index+start
-                newedge = edge(self.verts[one],self.verts[two])
-                self.edges.append(newedge)
-            for facey in template.faces:
-                faceverts=[]
-                for verty in facey.vertices:
-                    index = verty.index+start
-                    faceverts.append(self.verts[index])
-                newface = face(faceverts)
-                self.faces.append(newface)
-        self.vertedgeflag = 0    
-        self.vertedgeflag = 0                        
-        self.connectivity()
-
-#???PKHG TODO Nmesh used yet wrong!            
-def finalfill(source,target):
-    if source == target: #PKHG: otherewise >infinite< loop
-        print("\n***WARNING*** vefm_259.finalfill L1148 source == target empty mesh used")
-        target = mesh() #
-#PKHG_??? maybe renumverting and checkkin faces wiht >=4 5 vertices?        
-    count = 0
-#PKHG_OK    print("\n>>>>>>>>20-11 DBG vefm_259 in finalfill L1152, len(source.verts) =",len(source.verts))
-    for point in source.verts:
-#        newvert = NMesh.Vert(point.x,point.y,point.z)
-        newvert = vertex(point.vector)
-#PKHG_??? needed???
-        newvert.index = count 
-        target.verts.append(newvert)
-        point.index = count  #PKHG_INFO source renumbered too!
-#PKHG_OK        print("test gelijk",newvert.vector == point.vector)
-        count += 1 #count+1
-    
-    #PKHG indices of the vertex in faceyvertices are renumbered!
-#PKHG_OK    print("\n>>>>>>>>20-11 DBG vefm_259 in finalfill L1163, len(source.faces) =",len(source.faces))    
-    for facey in source.faces:
-        row = len(facey.vertices)
-        if row >= 5:
-#PKHG does not take the good vectors???            newvert = average(facey.vertices).centroid()
-            tmp = Vector()
-            for el in facey.vertices:
-                tmp = tmp +  target.verts[el.index].vector
-            tmp = tmp / row
-            centre = vertex(tmp) #does not work here!==>  average(facey.vertices).centroid()
-            centre.index = count #PKHG_??? give it a good index
-            count += 1
-#PKHG_DBG 21-11
-            #breakpoint(locals(),True)
-            
-            target.verts.append(centre)
-            for i in range(row):
-                if i == row - 1:
-                    a = target.verts[facey.vertices[-1].index]
-                    b = target.verts[facey.vertices[0].index]
-                else:
-                    a = target.verts[facey.vertices[i].index]
-                    b = target.verts[facey.vertices[i+1].index]
-                target.faces.append([a,b,centre])
-        else:
-            f = []
-#PKHG_DBG 21-11
-#            print("\n-----++++ L1217 dbg final dual", facey )
-#PKHG_DBG 21-11
-#            breakpoint(locals(),True)
-
-            for j in range(len(facey.vertices)):
-                a = facey.vertices[j]
-#PKHG_NOTNEEDED                tmp = a.index
-                f.append(target.verts[a.index])
-            target.faces.append(f)
-
diff --git a/release/scripts/addons_contrib/gpencil_retopo/__init__.py b/release/scripts/addons_contrib/gpencil_retopo/__init__.py
deleted file mode 100644
index 8de0dd8..0000000
--- a/release/scripts/addons_contrib/gpencil_retopo/__init__.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-
-bl_info = {
-    "name": "Grease Pencil Retopology",
-    "author": "Campbell Barton, Bart Crouch",
-    "version": (1, 0, 0),
-    "blender": (2, 5, 7),
-    "location": "View3D > Properties > Grease Pencil",
-    "warning": "",
-    "description": "Use Grease Pencil to retopologise a mesh.",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-
-
-# retopo operator
-class Retopo(bpy.types.Operator):
-    bl_idname = "mesh.gp_retopo"
-    bl_label = "Retopo"
-    bl_description = "Convert Grease Pencil drawings to a mesh"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    precision = bpy.props.IntProperty(name="Precision",
-        description="Lower values result in more removed doubles and "
-                    "smoother less precise results",
-        default=40,
-        min=2,
-        soft_max=100)
-
-    @classmethod
-    def poll(cls, context):
-        return context.object
-
-    def execute(self, context):
-        from . import retopo
-        scene, gp = retopo.initialise(context)
-        if not gp:
-            self.report('WARNING', "No grease pencil data found")
-            return {'CANCELLED'}
-
-        obj_new = retopo.calculate(gp, self.precision)
-
-        bpy.ops.object.select_all(action='DESELECT')
-        scene.objects.active = obj_new
-        obj_new.select = True
-
-        # nasty, recalc normals
-        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-        bpy.ops.mesh.normals_make_consistent(inside=False)
-        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-
-        return {'FINISHED'}
-
-
-# draw function for integration in panels
-def panel_func(self, context):
-    self.layout.operator("mesh.gp_retopo")
-
-
-# define classes and panels for registration
-classes = [Retopo]
-panels = [bpy.types.VIEW3D_PT_tools_objectmode,
-    bpy.types.VIEW3D_PT_tools_meshedit,
-    bpy.types.VIEW3D_PT_tools_curveedit,
-    bpy.types.VIEW3D_PT_tools_surfaceedit,
-    bpy.types.VIEW3D_PT_tools_armatureedit,
-    bpy.types.VIEW3D_PT_tools_mballedit,
-    bpy.types.VIEW3D_PT_tools_latticeedit,
-    bpy.types.VIEW3D_PT_tools_posemode]
-
-
-# registering and menu integration
-def register():
-    for c in classes:
-        bpy.utils.register_class(c)
-    for panel in panels:
-        panel.append(panel_func)
-
-
-# unregistering and removing menus
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-    for panel in panels:
-        panel.remove(panel_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/gpencil_retopo/retopo.py b/release/scripts/addons_contrib/gpencil_retopo/retopo.py
deleted file mode 100644
index b164bf4..0000000
--- a/release/scripts/addons_contrib/gpencil_retopo/retopo.py
+++ /dev/null
@@ -1,522 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-import bpy
-from math import radians
-from mathutils.geometry import intersect_point_line, intersect_line_line
-
-
-# gather initial data and prepare for retopologising
-def initialise(context):
-    scene = context.scene
-    obj = context.object
-
-    gp = None
-    if obj:
-        gp = obj.grease_pencil
-    if not gp:
-        gp = scene.grease_pencil
-
-    if gp:
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-    return(scene, gp)
-
-
-def get_hub(co, _hubs, EPS_SPLINE):
-
-    if 1:
-        for hub in _hubs.values():
-            if (hub.co - co).length < EPS_SPLINE:
-                return hub
-
-        key = co.to_tuple(3)
-        hub = _hubs[key] = Hub(co, key, len(_hubs))
-        return hub
-    else:
-        pass
-
-        '''
-        key = co.to_tuple(3)
-        try:
-            return _hubs[key]
-        except:
-            hub = _hubs[key] = Hub(co, key, len(_hubs))
-            return hub
-        '''
-
-
-class Hub(object):
-    __slots__ = "co", "key", "index", "links"
-
-    def __init__(self, co, key, index):
-        self.co = co.copy()
-        self.key = key
-        self.index = index
-        self.links = []
-
-    def get_weight(self):
-        f = 0.0
-
-        for hub_other in self.links:
-            f += (self.co - hub_other.co).length
-
-    def replace(self, other):
-        for hub in self.links:
-            try:
-                hub.links.remove(self)
-            except:
-                pass
-            if other not in hub.links:
-                hub.links.append(other)
-
-    def dist(self, other):
-        return (self.co - other.co).length
-
-    def calc_faces(self, hub_ls):
-        faces = []
-        # first tris
-        for l_a in self.links:
-            for l_b in l_a.links:
-                if l_b is not self and l_b in self.links:
-                    # will give duplicates
-                    faces.append((self.index, l_a.index, l_b.index))
-
-        # now quads, check which links share 2 different verts directly
-        def validate_quad(face):
-            if len(set(face)) != len(face):
-                return False
-            if hub_ls[face[0]] in hub_ls[face[2]].links:
-                return False
-            if hub_ls[face[2]] in hub_ls[face[0]].links:
-                return False
-
-            if hub_ls[face[1]] in hub_ls[face[3]].links:
-                return False
-            if hub_ls[face[3]] in hub_ls[face[1]].links:
-                return False
-
-            return True
-
-        for i, l_a in enumerate(self.links):
-            links_a = {l.index for l in l_a.links}
-            for j in range(i):
-                l_b = self.links[j]
-
-                links_b = {l.index for l in l_b.links}
-
-                isect = links_a.intersection(links_b)
-                if len(isect) == 2:
-                    isect = list(isect)
-
-                    # check there are no diagonal lines
-                    face = (isect[0], l_a.index, isect[1], l_b.index)
-                    if validate_quad(face):
-
-                        faces.append(face)
-
-        return faces
-
-
-class BBox(object):
-    __slots__ = "xmin", "ymin", "zmin", "xmax", "ymax", "zmax"
-
-    def __init__(self):
-        self.xmin = self.ymin = self.zmin = 100000000.0
-        self.xmax = self.ymax = self.zmax = -100000000.0
-
-    @property
-    def xdim(self):
-        return self.xmax - self.xmin
-
-    @property
-    def ydim(self):
-        return self.ymax - self.ymin
-
-    @property
-    def zdim(self):
-        return self.zmax - self.zmin
-
-    def calc(self, points):
-        xmin = ymin = zmin = 100000000.0
-        xmax = ymax = zmax = -100000000.0
-
-        for pt in points:
-            x, y, z = pt
-            if x < xmin:
-                xmin = x
-            if y < ymin:
-                ymin = y
-            if z < zmin:
-                zmin = z
-
-            if x > xmax:
-                xmax = x
-            if y > ymax:
-                ymax = y
-            if z > zmax:
-                zmax = z
-
-        self.xmin, self.ymin, self.zmin = xmin, ymin, zmin
-        self.xmax, self.ymax, self.zmax = xmax, ymax, zmax
-
-    def xsect(self, other, margin=0.0):
-        if margin == 0.0:
-            if self.xmax < other.xmin:
-                return False
-            if self.ymax < other.ymin:
-                return False
-            if self.zmax < other.zmin:
-                return False
-
-            if self.xmin > other.xmax:
-                return False
-            if self.ymin > other.ymax:
-                return False
-            if self.zmin > other.zmax:
-                return False
-
-        else:
-            xmargin = ((self.xdim + other.xdim) / 2.0) * margin
-            ymargin = ((self.ydim + other.ydim) / 2.0) * margin
-            zmargin = ((self.zdim + other.zdim) / 2.0) * margin
-
-            if self.xmax < other.xmin - xmargin:
-                return False
-            if self.ymax < other.ymin - ymargin:
-                return False
-            if self.zmax < other.zmin - zmargin:
-                return False
-
-            if self.xmin > other.xmax + xmargin:
-                return False
-            if self.ymin > other.ymax + ymargin:
-                return False
-            if self.zmin > other.zmax + zmargin:
-                return False
-        return True
-
-    def __iadd__(self, other):
-        self.xmin = min(self.xmin, other.xmin)
-        self.ymin = min(self.ymin, other.ymin)
-        self.zmin = min(self.zmin, other.zmin)
-
-        self.xmax = max(self.xmax, other.xmax)
-        self.ymax = max(self.ymax, other.ymax)
-        self.zmax = max(self.zmax, other.zmax)
-        return self
-
-
-class Spline(object):
-    __slots__ = "points", "hubs", "closed", "length", "bb"
-
-    def __init__(self, points, precision):
-        self.points = points
-        self.hubs = []
-        self.calc_length()
-        self.closed = self.calc_closed(precision)
-        self.bb = BBox()
-        self.bb.calc(points)
-
-    def calc_length(self):
-        # calc length
-        f = 0.0
-        co_prev = self.points[0]
-        for co in self.points[1:]:
-            f += (co - co_prev).length
-            co_prev = co
-        self.length = f
-
-    def calc_closed(self, precision):
-        return (self.points[0] - self.points[-1]).length < (self.length / precision)
-
-    def link(self):
-        if len(self.hubs) < 2:
-            return
-
-        edges = list(set([i for i, hub in self.hubs]))
-        edges.sort()
-
-        edges_order = {}
-        for i in edges:
-            edges_order[i] = []
-
-        # self.hubs.sort()
-        for i, hub in self.hubs:
-            edges_order[i].append(hub)
-
-        hubs_order = []
-        for i in edges:
-            ls = edges_order[i]
-            edge_start = self.points[i]
-            ls.sort(key=lambda hub: (hub.co - edge_start).length)
-            hubs_order.extend(ls)
-
-        # Now we have the order, connect the hubs
-        hub_prev = hubs_order[0]
-
-        for hub in hubs_order[1:]:
-            hub.links.append(hub_prev)
-            hub_prev.links.append(hub)
-            hub_prev = hub
-
-        if self.closed:
-            hubs_order[0].links.append(hubs_order[-1])
-            hubs_order[-1].links.append(hubs_order[0])
-
-
-def get_points(stroke):
-    return [point.co.copy() for point in stroke.points]
-
-
-def get_splines(gp, precision):
-    l = gp.layers.active
-    if l:
-        frame = l.active_frame
-        return [Spline(get_points(stroke), precision) for stroke in frame.strokes if len(stroke.points) > 1]
-    else:
-        return []
-
-
-def xsect_spline(sp_a, sp_b, _hubs, precision):
-    pt_a_prev = pt_b_prev = None
-    EPS_SPLINE = min(sp_a.length, sp_b.length) / precision
-    pt_a_prev = sp_a.points[0]
-    for a, pt_a in enumerate(sp_a.points[1:]):
-        pt_b_prev = sp_b.points[0]
-        for b, pt_b in enumerate(sp_b.points[1:]):
-
-            # Now we have 2 edges
-            # print(pt_a, pt_a_prev, pt_b, pt_b_prev)
-            xsect = intersect_line_line(pt_a, pt_a_prev, pt_b, pt_b_prev)
-            if xsect is not None:
-                if (xsect[0] - xsect[1]).length <= EPS_SPLINE:
-                    f = intersect_point_line(xsect[1], pt_a, pt_a_prev)[1]
-                    # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
-                        # for some reason doesnt work so well, same below
-                    if f >= 0.0 and f <= 1.0:
-                        f = intersect_point_line(xsect[0], pt_b, pt_b_prev)[1]
-                        # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
-                        if f >= 0.0 and f <= 1.0:
-                            # This wont happen often
-                            co = xsect[0].lerp(xsect[1], 0.5)
-                            hub = get_hub(co, _hubs, EPS_SPLINE)
-
-                            sp_a.hubs.append((a, hub))
-                            sp_b.hubs.append((b, hub))
-
-            pt_b_prev = pt_b
-
-        pt_a_prev = pt_a
-
-
-def connect_splines(splines, precision):
-    HASH_PREC = 8
-    ANG_LIMIT = radians(25.0)  # limit for joining splines into 1
-
-    def sort_pair(a, b):
-        if a < b:
-            return a, b
-        else:
-            return b, a
-
-    #def test_join(p1a, p1b, p2a, p2b, length_average):
-    def test_join(s1, s2, dir1, dir2, length_average):
-        if dir1 is False:
-            p1a = s1.points[0]
-            p1b = s1.points[1]
-        else:
-            p1a = s1.points[-1]
-            p1b = s1.points[-2]
-
-        if dir2 is False:
-            p2a = s2.points[0]
-            p2b = s2.points[1]
-        else:
-            p2a = s2.points[-1]
-            p2b = s2.points[-2]
-
-        v1 = p1a - p1b
-        v2 = p2b - p2a
-
-        if v1.angle(v2, ANG_LIMIT) >= ANG_LIMIT:
-            return False
-
-        # trim s2, allow overlapping line.
-        v2_test_1 = p2b - p2a
-        if dir2 is False:
-            i = 2
-            while (p2b - p1a).length < (p2a - p1a).length and i < len(s2.points):
-                p2a = p2b
-                p2b = s2.points[i]
-                i += 1
-        else:
-            i = -3
-            while (p2b - p1a).length < (p2a - p1a).length and -i <= len(s2.points):
-                p2a = p2b
-                p2b = s2.points[i]
-                i -= 1
-
-        # when trimming did we we turn a corner?
-        v2_test_2 = p2b - p2a
-        if v2_test_1.angle(v2_test_2, ANG_LIMIT) >= ANG_LIMIT:
-            return False
-        del v2_test_1
-        del v2_test_2
-        # end trimming
-
-        # compare length between tips
-        if (p1a - p2a).length > (length_average / precision):
-            return False
-
-        # print("joining!")
-        return True
-
-    # lazy, hash the points that have been compared.
-    comparisons = set()
-
-    do_join = True
-    while do_join:
-        do_join = False
-        for i, s1 in enumerate(splines):
-            key1a = s1.points[0].to_tuple(HASH_PREC)
-            key1b = s1.points[-1].to_tuple(HASH_PREC)
-
-            for j, s2 in enumerate(splines):
-                if s1 is s2:
-                    continue
-
-                length_average = min(s1.length, s2.length)
-
-                key2a = s2.points[0].to_tuple(HASH_PREC)
-                key2b = s2.points[-1].to_tuple(HASH_PREC)
-
-                # there are 4 ways this may be joined
-                key_pair = sort_pair(key1a, key2a)
-                if key_pair not in comparisons:
-                    comparisons.add(key_pair)
-                    if test_join(s1, s2, False, False, length_average):
-                        s1.points[:0] = reversed(s2.points)
-                        s1.bb += s2.bb
-                        s1.calc_length()
-                        del splines[j]
-                        do_join = True
-                        break
-
-                key_pair = sort_pair(key1a, key2b)
-                if key_pair not in comparisons:
-                    comparisons.add(key_pair)
-                    if test_join(s1, s2, False, True, length_average):
-                        s1.points[:0] = s2.points
-                        s1.bb += s2.bb
-                        s1.calc_length()
-                        del splines[j]
-                        do_join = True
-                        break
-
-                key_pair = sort_pair(key1b, key2b)
-                if key_pair not in comparisons:
-                    comparisons.add(key_pair)
-                    if test_join(s1, s2, True, True, length_average):
-                        s1.points += list(reversed(s2.points))
-                        s1.bb += s2.bb
-                        s1.calc_length()
-                        del splines[j]
-                        do_join = True
-                        break
-
-                key_pair = sort_pair(key1b, key2a)
-                if key_pair not in comparisons:
-                    comparisons.add(key_pair)
-                    if test_join(s1, s2, True, False, length_average):
-                        s1.points += s2.points
-                        s1.bb += s2.bb
-                        s1.calc_length()
-                        del splines[j]
-                        do_join = True
-                        break
-
-            if do_join:
-                break
-
-
-def calculate(gp, precision):
-    # note, this precision is for closed lines, it could be a different arg.
-    splines = get_splines(gp, precision)
-
-    # spline endpoints may be co-linear, join these into single splines
-    connect_splines(splines, precision)
-
-    _hubs = {}
-
-    for i, sp in enumerate(splines):
-        for j, sp_other in enumerate(splines):
-            if j <= i:
-                continue
-
-            if sp.bb.xsect(sp_other.bb, margin=0.1):
-                xsect_spline(sp, sp_other, _hubs, precision)
-
-    for sp in splines:
-        sp.link()
-
-    # remove these
-    hubs_ls = [hub for hub in _hubs.values() if hub.index != -1]
-
-    _hubs.clear()
-    _hubs = None
-
-    for i, hub in enumerate(hubs_ls):
-        hub.index = i
-
-    # Now we have connected hubs, write all edges!
-    def order(i1, i2):
-        if i1 > i2:
-            return i2, i1
-        return i1, i2
-
-    edges = {}
-
-    for hub in hubs_ls:
-        i1 = hub.index
-        for hub_other in hub.links:
-            i2 = hub_other.index
-            edges[order(i1, i2)] = None
-
-    verts = []
-    edges = edges.keys()
-    faces = []
-
-    for hub in hubs_ls:
-        verts.append(hub.co)
-        faces.extend(hub.calc_faces(hubs_ls))
-
-    # remove double faces
-    faces = dict([(tuple(sorted(f)), f) for f in faces]).values()
-
-    mesh = bpy.data.meshes.new("Retopo")
-    mesh.from_pydata(verts, [], faces)
-
-    scene = bpy.context.scene
-    mesh.update()
-    obj_new = bpy.data.objects.new(name="Retopo", object_data=mesh)
-    scene.objects.link(obj_new)
-
-    return obj_new
diff --git a/release/scripts/addons_contrib/gyes/__init__.py b/release/scripts/addons_contrib/gyes/__init__.py
deleted file mode 100644
index af5673b..0000000
--- a/release/scripts/addons_contrib/gyes/__init__.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-""" Copyright  Kilon 2011 GPL licence applies"""
-
-bl_info = {
-    "name": "Gyes (Random Materials and Textures Generator)",
-    "description": "GYES is an addon that can produce Random Materials and Textures . The randomization is controlled by the user and so the user can set what is randomized and how much .",
-    "author": "Kilon",
-    "version": (1, 0, 0),
-    "blender": (2, 6, 0),
-    "location": "View3D > Left panel ",
-    "warning": '',  # used for warning icon and text in addons panel
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/System/Gyes",
-    "tracker_url": "https://github.com/kilon/Gyes",
-    "category": "Material"}
-
-if "bpy" in locals():
-    import imp
-    imp.reload(random_material_generator)
-    imp.reload(random_texture_generator)
-    #imp.reload(random_landscape_generator)
-else:
-    from gyes import random_material_generator
-    from gyes import random_texture_generator
-    #from gyes import random_landscape_generator
-import bpy
-from bpy.props import *
-
-
-# Choose the tool you want to use
-bpy.types.Scene.tool = EnumProperty(attr='tool', name='Tool', items=(
-('RMG', 'RMG', 'Random Material Generator'),
-('RTG', 'RTG', 'Random Texture Generator')), default='RMG')
-
-rm = random_material_generator.rm
-rt = random_texture_generator.rt
-
-
-# this the main panel
-class gyes_panel(bpy.types.Panel):
-    bl_label = "Gyes"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-   
-    def draw(self, context):
-        layout = self.layout
-        row = layout.row()
-        row.prop(context.scene , "tool" )
-        
-        # check which tool the user has selected (RGM is the default one) and display the appropriate gui
-        
-        if context.scene.tool == 'RMG':
-            rm.draw_gui(context,self)
-        
-        if context.scene.tool == 'RTG':
-            rt.draw_gui(context,self,rm)
- 
-        r = layout.row()
-        if context.scene.tool == 'RLG':
-            r.label(text="WIP not finished yet")
-        if context.scene.tool == 'TARTARA':
-            r.label(text="WIP not finished yet")
-
-def register():
-    bpy.utils.register_module(__name__)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
- 
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/gyes/random_material_generator.py b/release/scripts/addons_contrib/gyes/random_material_generator.py
deleted file mode 100644
index a6647a6..0000000
--- a/release/scripts/addons_contrib/gyes/random_material_generator.py
+++ /dev/null
@@ -1,734 +0,0 @@
-# -*- coding: UTF-8 -*-
-# first we import all the required modules
-
-import bpy ,random , copy 
-from bpy.props import *
-import textwrap
-
-def h_names(self,contex):
-    h_list=list(rm.rm_history)
-    h_list.sort()
-    names=[]
-    for x in h_list:
-        names=names+[(x,x,x)]
-    return names 
-
-class random_material_class:
-    """ this class contains all fuctions and variables concerning generation of random material """
-    
-    def __init__(self):
-        """ several fuctions can be found here . All options for random generation . The History dictionary and several others."""
-                   
-        # various gui modes (simple, template etc)
-        bpy.types.Scene.gui_mode = EnumProperty(attr='mode', name='Mode', items=(
-('enable', 'Enable', 'Enable Disable material parameters for randomisation'),
-('percentage', 'Percentage' , 'here you define the percentage randomisation for each parameter'),
-('help', 'Help', 'Help documentation')), default='enable')
-
-        # Here I define the selective areas that the user can enable or disable for randomisation in simple mode               
-                     
-        bpy.types.Scene.rdiffuse_shader = BoolProperty(name= "Diffuse Shader" ,description = "Enable/Disable Randomisation for the  Diffuse Shader " , default = True)
-        bpy.types.Scene.rdiffuse_color = BoolProperty(name= "Diffuse Color" ,description = "Enable/Disable Randomisation for the Diffuse Color", default = True  )
-        bpy.types.Scene.rdiffuse_intensity = BoolProperty(name= "Diffuse Intensity" ,description = "Enable/Disable Randomisation for the Diffuse Intensity" , default = True )    
-        bpy.types.Scene.rspecular_color = BoolProperty(name= "Specular Color" ,description = "Enable/Disable Randomisation for the Specular Color" , default = True)
-        bpy.types.Scene.rspecular_shader = BoolProperty(name= "Specular Shader" ,description = "Enable/Disable Randomisation for the Specular Shader" , default = True)
-        bpy.types.Scene.rspecular_intensity = BoolProperty(name= "Specular Intensity" ,description = "Enable/Disable Randomisation for the Specular Intensity" , default = True)
-        bpy.types.Scene.rspecular_hardness = BoolProperty(name= "Specular Hardness" ,description = "Enable/Disable Randomisation for the Specular Hardness" , default = True)
-        bpy.types.Scene.rtransparency = BoolProperty(name= "Transparency" ,description = "Use and Randomise Transparency" , default = True)
-        bpy.types.Scene.rtexture = BoolProperty(name= "Texture" ,description = "Use and Randomise Textures" , default = True)
-        
-        # Percentage randomisation
-        bpy.types.Scene.general_percentage = IntProperty(name="General percentage", description = " General percentage of randomisation" , min = 0 , max = 100 , default = 100, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rdiffuse_shader_percentage =  IntProperty(name="Diffuse shader", description = " Diffuse shader percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rdiffuse_color_percentage =  IntProperty(name="Diffuse Color", description = " Diffuse Color percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rdiffuse_intensity_percentage =  IntProperty(name="Diffuse Intensity", description = " Diffuse Intensity percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rspecular_color_percentage =  IntProperty(name="Specular Color", description = " Specular Color percentage of randomisation" , min = 0 , max = 100 , default = 0 , subtype = 'PERCENTAGE')
-        bpy.types.Scene.rspecular_shader_percentage =  IntProperty(name="Specular Shader", description = " Specular Shader percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rspecular_intensity_percentage =  IntProperty(name="Specular Intensity", description = " Specular Intensity percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rspecular_hardness_percentage =  IntProperty(name="Specular Hardness", description = " Specular Hardness percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtransparency_percentage =  IntProperty(name="Transparency", description = " Transparency percentage of randomisation" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        
-        # this is the dictionary that stores history
-        bpy.types.Scene.history_index = IntProperty(name= "History Index" ,description = "The Number of Random Material Assigned to the Active MAterial of the Selected Object from the history" , default = 1, min = 1 )
-        bpy.types.Scene.filter = StringProperty(name="Filter", description ="Filter text , only if the text matches even partially with the material name will be stored")
-        self.rm_history={"slot 01":{1:{}} , "slot 02":{1:{}} , "slot 03":{1:{}} ,"slot 04":{1:{}} ,"slot 05":{1:{}} ,"slot 06":{1:{}} ,
-                         "slot 07":{1:{}} ,"slot 08":{1:{}} , "slot 09":{1:{}} , "slot 10":{1:{}} ,"slot 11":{1:{}} ,"slot 12":{1:{}} }
-        self.delete_start_index=1
-        bpy.types.Scene.h_selected = EnumProperty(attr='name', name='Name :', items=h_names)
-        
-        
-        # the prop that controls the text wrap in help menu
-        bpy.types.Scene.text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 20 , max = 180 , min = 1)
-        
-        # here is where history dictionary is saved with the blend file
-        # if the backup is already saved with the blend file it is used 
-        # to restory the history dictionary , if not it is created
-        
-        if hasattr(bpy.context.scene , "historybak")==False:
-            bpy.types.Scene.historybak = StringProperty()
-            print("Gyes log : created history backup")
-            
-         # non read only material properties where keyframes can be inserted or removed
-        self.animated_properties=["alpha",
-        "ambient",
-        "darkness",
-        "diffuse_color",
-        "diffuse_fresnel",
-        "diffuse_fresnel_factor",
-        "diffuse_intensity",
-        "diffuse_ramp_blend",
-        "diffuse_ramp_factor",
-        "diffuse_ramp_input",
-        "diffuse_shader",
-        "diffuse_toon_size",
-        "diffuse_toon_smooth",
-        "emit",
-        "invert_z",
-        "mirror_color",
-        "offset_z",
-        "preview_render_type",
-        "roughness",
-        "shadow_buffer_bias",
-        "shadow_cast_alpha",
-        "shadow_only_type",
-        "shadow_ray_bias",
-        "specular_alpha",
-        "specular_color",
-        "specular_hardness",
-        "specular_intensity",
-        "specular_ior",
-        "specular_ramp_blend",
-        "specular_ramp_factor",
-        "specular_ramp_input",
-        "specular_shader",
-        "specular_slope",
-        "specular_toon_size",
-        "specular_toon_smooth",
-        "translucency",
-        "transparency_method",
-        "type",
-        "use_cast_approximate",
-        "use_cast_buffer_shadows",
-        "use_cast_shadows_only",
-        "use_cubic",
-        "use_diffuse_ramp",
-        "use_face_texture",
-        "use_face_texture_alpha",
-        "use_full_oversampling",
-        "use_light_group_exclusive",
-        "use_mist",
-        "use_nodes",
-        "use_object_color",
-        "use_only_shadow",
-        "use_ray_shadow_bias",
-        "use_raytrace",
-        "use_shadeless",
-        "use_shadows",
-        "use_sky",
-        "use_specular_ramp",
-        "use_tangent_shading",
-        "use_textures",
-        "use_transparency",
-        "use_transparent_shadows",
-        "use_vertex_color_paint"]
-            
-    
-       
-    # compute randomisation based on the general or specific percentage chosen
-    # if the specific percentage is zero then the general percentage is used
-    def compute_percentage(self,min,max,value,percentage):
-        range = max-min
-        general_percentage = bpy.context.scene.general_percentage
-        
-        if percentage == 0:
-            percentage_random = ( value -((range*(general_percentage/100))/2) )+ (range * (general_percentage / 100) * random.random())
-        else:
-            percentage_random = ( value - ((range*(percentage/100))/2)) + (range * (percentage / 100) * random.random())
-             
-        if percentage_random > max:
-            percentage_random = max
-        if percentage_random < min:
-            percentage_random = min
-        
-        return percentage_random 
-    
-    #deletes from history an index but without leaving empty spaces, everythings is pushed back    
-    def delete_from_history(self):
-        h_name = bpy.context.scene.h_selected
-        length = len(self.rm_history[h_name])
-        index = bpy.context.scene.history_index
-        for x in range(index , length):
-            if index != length :
-                self.rm_history[h_name][x]= self.rm_history[h_name][x+1] 
-        del self.rm_history[h_name][length]
-        length = len(self.rm_history[h_name]) 
-        if index <= length:
-            self.activate()
-            
-        bpy.context.scene.historybak = str(self.rm_history)
-    
-    # the fuction that randomises the material 
-    def random_material(self,active_material,name):
-        mat = active_material
-        scn = bpy.context.scene
-             
-        #checks that the user has allowed the randomisation of that specific parameter            
-        if scn.rdiffuse_color:
-            rand_perc = scn.rdiffuse_color_percentage
-            mat.diffuse_color = (self.compute_percentage(0,1,mat.diffuse_color[0],rand_perc),
-            self.compute_percentage(0,1,mat.diffuse_color[1],rand_perc),
-            self.compute_percentage(0,1,mat.diffuse_color[2],rand_perc))
-            
- 
-        if scn.rdiffuse_shader:
-            mat.diffuse_shader = random.choice(['LAMBERT','FRESNEL','TOON','MINNAERT'])
-    
-        if scn.rdiffuse_intensity:
-            mat.diffuse_intensity = self.compute_percentage(0,1, mat.diffuse_intensity , scn.rdiffuse_intensity_percentage) 
-    
-        if scn.rspecular_color:
-            rand_perc = scn.rspecular_color_percentage
-            mat.specular_color = (self.compute_percentage(0,1,mat.specular_color[0],rand_perc),
-            self.compute_percentage(0,1,mat.specular_color[1],rand_perc),
-            self.compute_percentage(0,1,mat.specular_color[2],rand_perc))
-    
-        if scn.rspecular_shader:
-            mat.specular_shader = random.choice(['COOKTORR','WARDISO','TOON','BLINN','PHONG'])
-    
-        if scn.rspecular_intensity:
-            mat.specular_intensity =  self.compute_percentage(0,1, mat.specular_intensity , scn.rspecular_intensity_percentage)
-    
-        if scn.rspecular_hardness:
-            mat.specular_hardness =  round(self.compute_percentage(1,511, mat.specular_hardness, scn.rspecular_shader_percentage))
-            
-        mat.use_transparency = scn.rtransparency 
-        
-        if mat.use_transparency == True :
-            mat.transparency_method == random.choice(['MASK', 'Z_TRANSPARENCY', 'RAYTRACE'])
-            mat.alpha = self.compute_percentage(0,1, mat.alpha, scn.rtransparency_percentage)
-  
-            if mat.transparency_method == 'MASK' :
-                bing =0     # dummy code
-                
-            if mat.transparency_method == 'Z_TRANSPARENCY' :
-                bing =0     # dummy code
-                mat.specular_alpha= random.random()
-        
-        if scn.rtexture :
-            bpy.ops.gyes.random_texture()
-            
-        mat.ambient = self.compute_percentage(0,1, mat.ambient, scn.general_percentage)
-        
-        # after you finishes randomisation store the random material to history
-        self.store_to_history(mat)
-          
-        return mat
-
-   
-    #store active material to history
-    def store_to_history(self, mat):
-        scn = bpy.context.scene
-        history_index = scn.history_index
-        h_name = scn.h_selected
-        self.rm_history[h_name][history_index]={"name" : mat.name}
-        print("Gyes log : mat stored : "+self.rm_history[h_name][history_index]["name"]+" in history name : "+h_name+" in index : "+str(history_index))
-        mat.use_fake_user = True
-                 
-        bpy.context.scene.historybak = str(self.rm_history)
-        
-    # Activate. Make active material the particular history index the user has chosen
-    def activate(self, random_assign = False):
-        h_name = bpy.context.scene.h_selected
-        for i in bpy.context.selected_objects :
-            
-            if random_assign == False and ( bpy.context.scene.history_index in rm.rm_history[h_name] ) and rm.rm_history[h_name][bpy.context.scene.history_index] and rm.rm_history[h_name][bpy.context.scene.history_index]["name"]:                
-                scn = bpy.context.scene
-                mat = i.active_material
-                index = scn.history_index
-                
-                if len(i.material_slots) == 0:
-                    print("Gyes log : no slot found creating a new one")
-                    i.active_material= bpy.data.materials[self.rm_history[h_name][index]["name"]]
-                else:
-                    print("Gyes log : found slot assigning material")
-                    i.material_slots[i.active_material_index].material= bpy.data.materials[self.rm_history[h_name][index]["name"]]
-                
-            if random_assign == True and ( bpy.context.scene.history_index in rm.rm_history[h_name] ) and rm.rm_history[h_name][bpy.context.scene.history_index] and rm.rm_history[h_name][bpy.context.scene.history_index]["name"]:
-            
-                index = round(len(self.rm_history) * random.random())
-                
-                if index == 0 :
-                    index = 1
-                    
-                scn = bpy.context.scene
-                mat = i.active_material
-                scn.history_index=index
-                
-                if len(i.material_slots) == 0:
-                    print("Gyes log : no slot found creating a new one")
-                    i.active_material= bpy.data.materials[self.rm_history[h_name][index]["name"]]
-                else:
-                    print("Gyes log : found slot assigning material")
-                    i.material_slots[i.active_material_index].material= bpy.data.materials[self.rm_history[h_name][index]["name"]]
-              
-            
-            
-                   
-    # a nice multi label                        
-    def multi_label(self, text, ui,text_width):
-        
-        for x in range(0,len(text)):
-            el = textwrap.wrap(text[x], width = text_width)
-            
-            for y in range(0,len(el)):
-                ui.label(text=el[y])
-                
-    def draw_gui(self ,context,panel):
-        layout = panel.layout
-        row = layout.row()
-        
-        row.prop(context.scene , "gui_mode" )
-        
-        # check which Gui mode the user has selected (Simple is the default one and display the appropriate gui
-        
-        if context.scene.gui_mode == 'enable' :
-            
-            box = layout.box()
-            
-            box.prop(context.scene,"rdiffuse_shader", toggle = True)
-            box.prop(context.scene,"rdiffuse_color", toggle = True)
-            box.prop(context.scene,"rdiffuse_intensity", toggle = True)
-            box.prop(context.scene,"rspecular_shader", toggle = True)
-            box.prop(context.scene,"rspecular_color", toggle = True)
-            box.prop(context.scene,"rspecular_intensity", toggle = True)
-            box.prop(context.scene,"rspecular_hardness", toggle = True)
-            box.prop(context.scene,"rtransparency", toggle = True)
-            box.prop(context.scene,"rtexture", toggle = True)
-            
-            box.prop(context.scene,"general_percentage", slider = True)           
-            layout.operator("gyes.random_material")
-            
-        if context.scene.gui_mode == 'percentage' :
-            box = layout.box()
-            
-            if context.scene.rdiffuse_shader :
-                box.prop(context.scene,"rdiffuse_shader_percentage", slider = True)
-            else:
-                box.label(text="Diffuse Shader is disabled ")
-                
-            if context.scene.rdiffuse_color :
-                box.prop(context.scene,"rdiffuse_color_percentage", slider = True)
-            else:
-                box.label(text="Diffuse Color is disabled ")
-                
-            if context.scene.rdiffuse_intensity :
-                box.prop(context.scene,"rdiffuse_intensity_percentage", slider = True)
-            else:
-                box.label(text="Diffuse Intensity is disabled ")
-                
-            if context.scene.rspecular_shader :
-                box.prop(context.scene,"rspecular_shader_percentage", slider = True)
-            else:
-                box.label(text="Specular Shader is disabled ")
-                
-            if context.scene.rspecular_color :
-                box.prop(context.scene,"rspecular_color_percentage", slider = True)
-            else:
-                box.label(text="Specular Color is disabled ")
-                
-            if context.scene.rspecular_intensity :
-                box.prop(context.scene,"rspecular_intensity_percentage", slider = True)
-            else:
-                box.label(text="Specular Intensity is disabled ")
-                
-            if context.scene.rspecular_hardness :
-                box.prop(context.scene,"rspecular_hardness_percentage", slider = True)
-            else:
-                box.label(text="Specular Hardness is disabled ")
-            
-            if context.scene.rtransparency :
-                box.prop(context.scene,"rtransparency_percentage", slider = True)
-            else:
-                box.label(text="Transparency is disabled ")
-                
-            box.prop(context.scene,"general_percentage", slider = True)
-            layout.operator("gyes.random_material")
-        
-                           
-        if context.scene.gui_mode== 'help' :
-            box = layout.box()
-            help_text=["","Copyright 2011 Kilon  ",
-            "GYES - RGM",    
-            "Random Material  Generator",
-            "A tool that generates random materials.",
-            "",
-            "Simple Mode",
-            "--------------------------",
-            "In this mode you can do basic randomisation. Choose parameters you want to randomise by turning them on or off with clicking on them. Hit the random button when you are ready. Each time you hit the button the new random material is stored in a history index",
-            "",
-            "History",
-            "--------------------------",
-            "History index -> choose index",
-            "( < ) -> Previous index (activate)",
-            "( > ) -> Next index (activate)",
-            "( |< ) -> First history index",
-            "( >| ) -> Last history index",
-            "Activate -> use this index as active material",
-            "Animate -> Insert a keyframe in the current frame for every singly non read only material property",
-            "X -> Remove a keyframe in the current frame for every singly non read only material property",
-            "R -> works just like activate but instead of using the current selected index use a randomly selected one",
-            "Delete -> delete this index",
-            "Del start -> start deletion from here",
-            "Del end -> end deletion here",
-            "Restore -> restores history from the saved blend file",
-            "",
-            "Percentage",
-            "--------------------------",
-            "Percentage randomisation means that the parameter is randomised inside a range of percentage of the full range of the value. When a specific percentage is zero, the general percentage is used instead for that area. When a specific percentage is not zero then general percentage is ignored and specific percentage is used instead. If you dont want to randomise that area at all, in Simple Mode use the corresponding button to completely disable that area , the percentage slider will also be disable in the percentage mode. Randomisation takes always the current value as starting point so the next randomisation will use the current randomised value. Randomisation is always 50% of the specific percentage bellow the current value and 50% above . If the percentage exceeed minimum and maximum values of the full range, then it will default to minimum and maximum accordingly. "]
-            w=bpy.context.scene.text_width
-            box.prop(context.scene,"text_width", slider =True)
-            self.multi_label(help_text,box,w) 
-                                
-        # Display the History Gui for all modes
-        h_name=bpy.context.scene.h_selected
-        layout.label(text="History (RMG + RTG)")
-        history_box= layout.box()
-        history_box.prop(context.scene, "h_selected")
-        history_box.prop(context.scene, "history_index")
-        row = history_box.row()
-        row.operator("gyes.first")
-        row.operator("gyes.previous")
-        row.operator("gyes.next")
-        row.operator("gyes.last")
-        rm_index = context.scene.history_index
-        
-        if rm_index in self.rm_history[h_name] and self.rm_history[h_name][rm_index] :
-            row = history_box.row()
-            a = row.split(percentage = 0.3, align = True)
-            a.operator("gyes.activate")
-            a.operator("gyes.animate")
-            b=a.split(percentage = 0.3, align = True)
-            b.operator("gyes.x")
-            b.operator("gyes.random_activate")                       
-        else:
-            
-            row = history_box.row()
-            a = row.split(percentage = 0.3, align = True)
-            a.label(text= "Empty Index ! ")
-            a.operator("gyes.animate")
-            b=a.split(percentage = 0.3, align = True)
-            b.operator("gyes.x")
-            b.operator("gyes.random_activate")  
-        
-        if context.scene.history_index < len(self.rm_history[h_name])+2:
-            history_box.operator("gyes.store")
-        else:
-            history_box.label(text= "Not the first Empty Index")
-            
-        if rm_index in self.rm_history[h_name] and self.rm_history[h_name][rm_index] :
-            history_box.operator("gyes.delete")
-            row2 = history_box.row()
-            row2.operator("gyes.delete_start")
-            row2.operator("gyes.delete_end")
-            
-        if hasattr(bpy.context.scene,"historybak") and bpy.context.scene.historybak!='':
-            history_box.operator("gyes.restore")
-        else:
-            history_box.label(text="Backup not Found")
-        history_box.prop(context.scene,"filter")
-        history_box.operator("gyes.import_materials")                            
-# create the instance class for randomisation   
-rm =random_material_class()
-
-            
-        
-# Generate the random material button
-class gyes_random_material(bpy.types.Operator):
-    
-    bl_idname = "gyes.random_material"
-    bl_label = "Random Material"
-    label = bpy.props.StringProperty()
-    bl_description = "Generate the random material"
-    
-    def execute(self, context):
-        for i in context.selected_objects :
-            if not i.material_slots:
-                print("Gyes log : no material_slot found , creating new with material")
-                new_random = bpy.data.materials.new("Random")
-                i.active_material=new_random
-                rm.random_material(i.active_material,'Random')
-
-
-            if i.material_slots[0].material:
-                print("Gyes log : found an existing material, using this one ")
-                rm.random_material(i.active_material,'Random')
-
-            if not i.material_slots[0].material:
-                print("Gyes log : no material found , creating new")
-                new_random = bpy.data.materials.new("Random")
-                i.active_material=new_random
-                rm.random_material(i.active_material,'Random')
-
-        return{'FINISHED'}
-
-# Move to the first history index and activate it
-class history_first(bpy.types.Operator):
-    
-    bl_label = "|<"
-    bl_idname = "gyes.first"
-    bl_description = "Move to the first history index and activate it"
-    
-    def execute(self, context):
-        context.scene.history_index = 1 
-        rm.activate()
-        
-        return{'FINISHED'}
-
-# Move to the previous hisory index and activate it
-class history_previous(bpy.types.Operator):
-    
-    bl_label = "<"
-    bl_idname = "gyes.previous"
-    bl_description = "Move to the previous history index and activate it"
-    
-    def execute(self, context):
-        if context.scene.history_index > 1 :
-            context.scene.history_index = context.scene.history_index -1
-            rm_index = context.scene.history_index
-            h_name = bpy.context.scene.h_selected
-            if rm_index in rm.rm_history[h_name] and rm.rm_history[h_name][rm_index]:
-                rm.activate()
-        
-        return{'FINISHED'}
-
-# Move to the next hisory index and activate it
-class history_next(bpy.types.Operator):
-    
-    bl_label = ">"
-    bl_idname = "gyes.next"
-    bl_description = "Move to the next history index and activate it"
-    
-    def execute(self, context):
-        if context.scene.history_index > 0 :
-            context.scene.history_index = context.scene.history_index +1
-            rm_index = context.scene.history_index
-            h_name = bpy.context.scene.h_selected
-            if rm_index in rm.rm_history[h_name] and rm.rm_history[h_name][rm_index]:
-                rm.activate()
-        
-        return{'FINISHED'}
-    
-
-# Move to the last hisory index and activate it
-class history_last(bpy.types.Operator):
-    
-    bl_label = ">|"
-    bl_idname = "gyes.last"
-    bl_description = "Move to the last history index and activate it"
-    
-    def execute(self, context):
-        h_name= bpy.context.scene.h_selected
-        index = rm.rm_history[h_name] 
-        context.scene.history_index = len(index) 
-        rm.activate()
-        
-        return{'FINISHED'}
-
-# The current history index becomes the active material 
-class history_activate(bpy.types.Operator):
-    
-    bl_label = "Activate"
-    bl_idname = "gyes.activate"
-    bl_description = "The current history index becomes the active material"
-    
-    def execute(self, context):
-        rm_index = context.scene.history_index
-        h_name = bpy.context.scene.h_selected
-        if rm.rm_history[h_name][rm_index] != {}:
-            rm.activate()
-        
-        return{'FINISHED'}
-
-# A random history index becomes the active material 
-class history_random_activate(bpy.types.Operator):
-    
-    bl_label = "R"
-    bl_idname = "gyes.random_activate"
-    bl_description = "A random history index becomes the active material"
-    
-    def execute(self, context):
-        rm_index = context.scene.history_index
-        h_name = bpy.context.scene.h_selected
-        if rm.rm_history[h_name][rm_index] != {}:
-            rm.activate(random_assign = True)
-        
-        return{'FINISHED'}
-
-
-# It stores current active material to the selected history index
-class store_to_history(bpy.types.Operator):
-    
-    bl_label = "Store"
-    bl_idname = "gyes.store"
-    bl_description = " It stores current active material to the selected history index"
-    
-    def execute(self, context):
-        mat = context.selected_objects[0].active_material
-        rm.store_to_history(mat)
-                 
-        return{'FINISHED'}
-
-# Delete selected history index from history
-class delete_from_history(bpy.types.Operator):
-    
-    bl_label = "Delete"
-    bl_idname = "gyes.delete"
-    bl_description = "Delete selected history index from history"
-    
-    def execute(self, context):
-        rm.delete_from_history()
-        
-        return{'FINISHED'}
-               
-# Start deletion from this index
-class delete_from_history_start(bpy.types.Operator):
-    
-    bl_label = "Del Start"
-    bl_idname = "gyes.delete_start"
-    bl_description = "Start deletion from this index"
-    
-    def execute(self, context):
-        rm_index = context.scene.history_index
-        rm.delete_start_index = rm_index
-        
-        return{'FINISHED'}   
-
-# End deletion here and delete all selected indices
-class delete_from_history_end(bpy.types.Operator):
-    
-    bl_label = "Del End"
-    bl_idname = "gyes.delete_end"
-    bl_description = "End deletion here and delete all selected indices"
-    
-    def execute(self, context):
-        delete_end_index = context.scene.history_index
-        context.scene.history_index = rm.delete_start_index
-        for x in range ( rm.delete_start_index , delete_end_index):
-            rm.delete_from_history()
-        
-        return{'FINISHED'} 
-    
-# End deletion here and delete all selected indices
-class restore_history(bpy.types.Operator):
-    
-    bl_label = "Restore"
-    bl_idname = "gyes.restore"
-    bl_description = "Restore history"
-    
-    def execute(self, context):
-        
-        s=""
-        s = bpy.context.scene.historybak
-       
-        rm.rm_history=eval(s)
-        
-        print("Gyes log : restored history dictionary") 
-        
-        return{'FINISHED'} 
-    
-# Animate inserts a keyframe for every randomised material parameter except nodes
-class animate(bpy.types.Operator):
-    
-    bl_label = "Animate"
-    bl_idname = "gyes.animate"
-    bl_description = "Animate inserts a keyframe for every non read only material parameter"
-    
-    def execute(self, context):
-        framen = bpy.context.scene.frame_current
-        for i in range(0,len(bpy.context.selected_objects)):
-            mat = bpy.context.selected_objects[i].active_material
-                        
-            for y in range(0,len(rm.animated_properties)):
-                mat.keyframe_insert(data_path = rm.animated_properties[y], frame = framen)
-        
-        return{'FINISHED'}
- 
-# Remove Animation
-class x(bpy.types.Operator):
-    
-    bl_label = "X"
-    bl_idname = "gyes.x"
-    bl_description = "Reverse Animate by deleting every keyframe inserted by animate for every non read only material parameter"
-    
-    def execute(self, context):
-        framen = bpy.context.scene.frame_current
-        for i in range(0,len(bpy.context.selected_objects)):
-            mat = bpy.context.selected_objects[i].active_material
-            
-            for y in range(0,len(rm.animated_properties)):
-                mat.keyframe_delete(data_path = rm.animated_properties[y], frame = framen)
-        
-        return{'FINISHED'}
-
-# Move to the first history index and activate it
-class import_materials(bpy.types.Operator):
-    
-    bl_label = "Import"
-    bl_idname = "gyes.import_materials"
-    bl_description = "Import all materials matching filter in the active history"
-    
-    def execute(self, context):
-        filter = bpy.context.scene.filter
-        h_name = bpy.context.scene.h_selected
-        bpy.context.scene.history_index = len(rm.rm_history[h_name])+1
-        for mat in bpy.data.materials:
-            if filter in mat.name:
-                rm.store_to_history(mat)
-                bpy.context.scene.history_index = bpy.context.scene.history_index+1
-                    
-                
-                
-        
-        return{'FINISHED'}
-
-
-
-
-
-#registration is necessary for the script to appear in the GUI
-def register():
-    bpy.utils.register_class(gyes_panel)
-    bpy.utils.register_class(gyes_random_material)
-    bpy.utils.register_class(history_previous)
-    bpy.utils.register_class(history_next)
-    bpy.utils.register_class(history_activate)
-    bpy.utils.register_class(history_random_activate)
-    bpy.utils.register_class(store_to_history)
-    bpy.utils.register_class(delete_from_history)
-    bpy.utils.register_class(delete_from_history_start)
-    bpy.utils.register_class(delete_from_history_end)
-    bpy.utils.register_class(history_first)
-    bpy.utils.register_class(history_last)
-    bpy.utils.register_class(restore_history)
-    bpy.utils.register_class(animate)
-    bpy.utils.register_class(x)
-    bpy.utils.register_class(import_materials)
-def unregister():
-    bpy.utils.unregister_class(gyes_panel)
-    bpy.utils.unregister_class(gyes_random_material)
-    bpy.utils.unregister_class(history_previous)
-    bpy.utils.unregister_class(history_next)
-    bpy.utils.unregister_class(history_activate)
-    bpy.utils.unregister_class(history_random_activate)
-    bpy.utils.unregister_class(store_to_history)
-    bpy.utils.unregister_class(delete_from_history)
-    bpy.utils.unregister_class(delete_from_history_start)
-    bpy.utils.unregister_class(delete_from_history_end)
-    bpy.utils.unregister_class(history_first)
-    bpy.utils.unregister_class(history_last)
-    bpy.utils.unregister_class(restore_history)
-    bpy.utils.unregister_class(animate)
-    bpy.utils.unregister_class(x)
-    bpy.utils.unregister_class(import_materials)
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/gyes/random_texture_generator.py b/release/scripts/addons_contrib/gyes/random_texture_generator.py
deleted file mode 100644
index 5acf238..0000000
--- a/release/scripts/addons_contrib/gyes/random_texture_generator.py
+++ /dev/null
@@ -1,791 +0,0 @@
-# -*- coding: UTF-8 -*-
-# first we import all the required modules
-
-import bpy ,random , copy 
-from bpy.props import *
-import textwrap
-
-class random_texture_class:
-    """ this class contains all fuctions and variables concerning generation of random material """
-    
-    def __init__(self):
-        """ several fuctions can be found here . All options for random generation . The History dictionary and several others."""
-                   
-        # various gui modes (simple, template etc)
-        bpy.types.Scene.rtexture_gui_mode = EnumProperty(attr='mode', name='Mode', items=(
-('enable', 'Enable', 'Enable Disable texture parameters for randomisation'),
-('percentage', 'Percentage' , 'here you define percentage of randomisation for each texture parameters'),
-('help', 'Help', 'Help documentation')), default='enable')
-
-        # Here I define the selective areas that the user can enable or disable for randomisation in simple mode               
-        bpy.types.Scene.rtexture_type = EnumProperty(attr='type', name='type', items=(
-('RANDOM','RANDOM','RANDOM'),
-('BLEND','BLEND','BLEND'),
-('CLOUDS','CLOUDS','CLOUDS'),
-('DISTORTED_NOISE','DISTORTED_NOISE','DISTORTED_NOISE'),
-#('ENVIRONMENT_MAP','ENVIRONMENT_MAP','ENVIRONMENT_MAP'),
-#('IMAGE','IMAGE','IMAGE'),
-('MAGIC','MAGIC','MAGIC'),
-('MARBLE','MARBLE','MARBLE'),
-('MUSGRAVE','MUSGRAVE','MUSGRAVE'),
-('NOISE','NOISE','NOISE'),
-#('POINT_DENSITY','POINT_DENSITY','POINT_DENSITY'),
-('STUCCI','STUCCI','STUCCI'),
-('VORONOI','VORONOI','VORONOI'),
-('WOOD','WOOD','WOOD')), default='RANDOM')
-#('VOXEL_DATA','VOXEL_DATA','VOXEL_DATA') 
-
-        bpy.types.Scene.rtexture_color = BoolProperty(name= "Color Factor" ,description = "Color factor of the texture" , default = True)    
-        bpy.types.Scene.rtexture_intensity = BoolProperty(name= "Intensity" ,description = "Intensity of the texture" , default = True)
-        bpy.types.Scene.rtexture_contrast = BoolProperty(name= "Contrast" ,description = "Contrast of the texture" , default = True)
-        bpy.types.Scene.rtexture_saturation = BoolProperty(name= "Saturation" ,description = "Saturation of the texture" , default = True)
-        bpy.types.Scene.rtexture_progression = BoolProperty(name= "Progression" ,description = "Progression of the texture" , default = True)
-        bpy.types.Scene.rtexture_axis = BoolProperty(name= "Progr. Axis" ,description = "Progression of the texture" , default = True)
-        bpy.types.Scene.rtexture_cloud_type = BoolProperty(name= "Cloud Type" ,description = "Cloud Type of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_type = BoolProperty(name= "Noise Type" ,description = "Noise Type of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_basis = BoolProperty(name= "Noise Basis" ,description = "Noise Basis of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_scale = BoolProperty(name= "Noise Scale" ,description = "Noise Scale of the texture" , default = True)
-        bpy.types.Scene.rtexture_nabla = BoolProperty(name= "Nabla" ,description = "Nabla of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_depth = BoolProperty(name= "Noise Depth" ,description = "Noise Depth of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_distortion = BoolProperty(name= "Noise Distortion" ,description = "Noise Distortion of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_intensity = BoolProperty(name= "Noise Intensity" ,description = "Noise Intensity of the texture" , default = True)
-        bpy.types.Scene.rtexture_distortion = BoolProperty(name= "Distortion" ,description = "Distortion of the texture" , default = True)
-        bpy.types.Scene.rtexture_turbulence = BoolProperty(name= "Turbulence" ,description = "Turbulence of the texture" , default = True)
-        bpy.types.Scene.rtexture_marble_type = BoolProperty(name= "Marble Type" ,description = "Marble type of the texture" , default = True)
-        bpy.types.Scene.rtexture_noise_basis_2 = BoolProperty(name= "Noise Basis" ,description = "Noise Basis of the texture" , default = True)
-        bpy.types.Scene.rtexture_musgrave_type = BoolProperty(name= "Musgrave Type" ,description = "Musgrave Type of the texture" , default = True)
-        bpy.types.Scene.rtexture_lacunarity = BoolProperty(name= "Dimension Max" ,description = "Dimension Max of the texture" , default = True)
-        bpy.types.Scene.rtexture_octaves = BoolProperty(name= "Dimension Max" ,description = "Dimension Max of the texture" , default = True)
-        bpy.types.Scene.rtexture_dimension_max = BoolProperty(name= "Dimension Max" ,description = "Dimension Max of the texture" , default = True)
-        bpy.types.Scene.rtexture_offset = BoolProperty(name= "Offset" ,description = "Offset of the texture" , default = True)
-        bpy.types.Scene.rtexture_gain = BoolProperty(name= "Gain" ,description = "Gain of the texture" , default = True)
-        bpy.types.Scene.rtexture_stucci_type = BoolProperty(name= "Type" ,description = "Stucci type of the texture" , default = True)
-        bpy.types.Scene.rtexture_dist_metric = BoolProperty(name= "Metric" ,description = "Distance Metric of the texture" , default = True)
-        bpy.types.Scene.rtexture_exponent = BoolProperty(name= "Exponent" ,description = "Minkovsky Exponent of the texture" , default = True)
-        bpy.types.Scene.rtexture_color_mode = BoolProperty(name= "Color Mode" ,description = "Color Mode of the texture" , default = True)
-        bpy.types.Scene.rtexture_weight_1 = BoolProperty(name= "Weight 1" ,description = "Weight 1 of the texture" , default = True)
-        bpy.types.Scene.rtexture_weight_2 = BoolProperty(name= "Weight 2" ,description = "Weight 2 of the texture" , default = True)
-        bpy.types.Scene.rtexture_weight_3 = BoolProperty(name= "Weight 3" ,description = "Weight 3 of the texture" , default = True)
-        bpy.types.Scene.rtexture_weight_4 = BoolProperty(name= "Weight 4" ,description = "Weight 4 of the texture" , default = True)
-        bpy.types.Scene.rtexture_wood_type = BoolProperty(name= "Wood Type" ,description = "Wood Type of the texture" , default = True)
-        
-        # Percentage randomisation
-        bpy.types.Scene.rtexture_general_percentage = IntProperty(name="General percentage", description = " General percentage of randomisation" , min = 0 , max = 100 , default = 100, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_color_percentage = IntProperty(name="Color Factor", description = " Color factor percentage of randomisation" , min = 0 , max = 100 , default = 100, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_intensity_percentage = IntProperty(name="Intensity", description = " Intensity of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_contrast_percentage = IntProperty(name="Contrast", description = " Contrast of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_saturation_percentage = IntProperty(name="Saturation", description = " Saturation of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_noise_scale_percentage = IntProperty(name="Noise Scale", description = " Noise Scale of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_nabla_percentage = IntProperty(name="Nabla", description = " Nabla of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_noise_depth_percentage = IntProperty(name="Noise Depth", description = " Noise Depth of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_noise_int_percentage = IntProperty(name="Noise Intensity", description = " Noise Intensity of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_distortion_percentage = IntProperty(name="Distortion", description = "Distortion of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_turbulence_percentage = IntProperty(name="Turbulence", description = "Turbulence of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_dimension_percentage = IntProperty(name="Dimension", description = "Dimension of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_lacunarity_percentage = IntProperty(name="Lacunarity", description = "Lacunarity of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_octaves_percentage = IntProperty(name="Octaves", description = "Octaves of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_offset_percentage = IntProperty(name="Offset", description = "Offset of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_gain_percentage = IntProperty(name="Gain", description = "Gain of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_exponent_percentage = IntProperty(name="Exponent", description = "Exponent of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_weight_1_percentage = IntProperty(name="Weight 1", description = "Weight 1 of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_weight_2_percentage = IntProperty(name="Weight 2", description = "Weight 2 of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_weight_3_percentage = IntProperty(name="Weight 3", description = "Weight 3 of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-        bpy.types.Scene.rtexture_weight_4_percentage = IntProperty(name="Weight 4", description = "Weight 4 of the texture" , min = 0 , max = 100 , default = 0, subtype = 'PERCENTAGE')
-       
-        
-        
-        # the prop that controls the text wrap in help menu
-        bpy.types.Scene.text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 20 , max = 180 , min = 1)
-        
-        
-            
-         # non read only material properties where keyframes can be inserted or removed
-        self.animated_properties=["alpha",
-        "use_vertex_color_paint"]
-            
-        
-    # compute randomisation based on the general or specific percentage chosen
-    # if the specific percentage is zero then the general percentage is used
-    def compute_percentage(self,min,max,value,percentage):
-        range = max-min
-        general_percentage = bpy.context.scene.rtexture_general_percentage
-        
-        if percentage == 0:
-            percentage_random = ( value -((range*(general_percentage/100))/2) )+ (range * (general_percentage / 100) * random.random())
-        else:
-            percentage_random = ( value - ((range*(percentage/100))/2)) + (range * (percentage / 100) * random.random())
-             
-        if percentage_random > max:
-            percentage_random = max
-        if percentage_random < min:
-            percentage_random = min
-        
-        return percentage_random 
-    
-    #deletes from history an index but without leaving empty spaces, everythings is pushed back    
-    def delete_from_history(self):
-        
-        length = len(self.history)
-        index = bpy.context.scene.texture_history_index
-        for x in range(index , length):
-            if index != length :
-                self.history[x]= self.history[x+1] 
-        del self.history[length]
-        length = len(self.history) 
-        if index <= length:
-            self.activate()
-            
-        bpy.context.scene.texture_historybak = str(self.rm_history)
-    
-    # the fuction that randomises the material 
-    
-    def random_texture_color(self,texture):
-        scn = bpy.context.scene
-        if scn.rtexture_color:
-            texture.factor_red = self.compute_percentage(0,2,texture.factor_red,scn.rtexture_color_percentage)
-            texture.factor_green = self.compute_percentage(0,2,texture.factor_green,scn.rtexture_color_percentage)
-            texture.factor_blue = self.compute_percentage(0,2,texture.factor_blue,scn.rtexture_color_percentage)
-        if scn.rtexture_intensity:
-            texture.intensity = self.compute_percentage(0,2,texture.intensity,scn.rtexture_intensity_percentage)
-        if scn.rtexture_contrast:
-            texture.contrast = self.compute_percentage(0,5,texture.contrast,scn.rtexture_contrast_percentage)
-        if scn.rtexture_saturation:
-            texture.saturation = self.compute_percentage(0,2,texture.saturation,scn.rtexture_saturation_percentage)        
-    
-    def random_texture(self,material):
-        scn = bpy.context.scene
-        
-        # if the texture exists use that for randomisation if not then create a new one
-        if material.texture_slots[material.active_texture_index] and material.texture_slots[material.active_texture_index].texture:
-            texture = material.texture_slots[material.active_texture_index].texture
-            if not scn.rtexture_type=='RANDOM':
-               texture.type = scn.rtexture_type
-            else:
-               texture.type = random.choice(['BLEND','CLOUDS','DISTORTED_NOISE','MAGIC','MARBLE','MUSGRAVE','NOISE','STUCCI','VORONOI','WOOD'])
-            material.texture_slots[material.active_texture_index].texture = texture 
-        else:
-            material.texture_slots.create(material.active_texture_index)           
-            if not scn.rtexture_type=='RANDOM':
-                texture = bpy.data.textures.new('Rand_tex_',scn.rtexture_type)
-            else:
-                texture = bpy.data.textures.new('Rand_tex_','NOISE')
-            material.texture_slots[material.active_texture_index].texture = texture
-        
-        # randomise parameters depending on the type of the texture
-        
-        if scn.rtexture_type == 'BLEND':
-            
-            self.random_texture_color(texture)
-            
-            if scn.rtexture_progression:
-                texture.progression = random.choice(['LINEAR', 'QUADRATIC', 'EASING', 'DIAGONAL', 'SPHERICAL', 'QUADRATIC_SPHERE', 'RADIAL'])
-            if scn.rtexture_axis and not (texture.progression=='DIAGONAL' or texture.progression=='SPHERICAL' or texture.progression=='QUADRATIC_SPHERE'):
-                texture.use_flip_axis = random.choice(['HORIZONTAL', 'VERTICAL'])
-        
-        if scn.rtexture_type == 'CLOUDS':
-            
-            self.random_texture_color(texture)
-            
-            if scn.rtexture_cloud_type:
-                texture.cloud_type = random.choice(['GREYSCALE', 'COLOR'])
-            if scn.rtexture_noise_type:
-                texture.noise_type = random.choice(['SOFT_NOISE', 'HARD_NOISE'])
-            if scn.rtexture_noise_basis:
-                texture.noise_basis = random.choice(['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN', 'IMPROVED_PERLIN', 'VORONOI_F1', 'VORONOI_F2', 'VORONOI_F3',    'VORONOI_F4', 'VORONOI_F2_F1', 'BLENDER_ORIGINAL', 'VORONOI_CRACKLE', 'CELL_NOISE'])
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-            if scn.rtexture_nabla:
-                texture.nabla = self.compute_percentage(0,0.10,texture.nabla,scn.rtexture_nabla_percentage)
-            if scn.rtexture_noise_depth:
-                texture.noise_depth = int(self.compute_percentage(0,24,texture.noise_depth,scn.rtexture_noise_depth_percentage))
-        
-        if scn.rtexture_type == 'DISTORTED_NOISE':
-            
-            self.random_texture_color(texture)
-            if scn.rtexture_noise_distortion:
-                texture.noise_distortion = random.choice(['BLENDER_ORIGINAL','ORIGINAL_PERLIN', 'IMPROVED_PERLIN', 'VORONOI_F1', 'VORONOI_F2','VORONOI_F3','VORONOI_F4', 'VORONOI_F2_F1', 'BLENDER_ORIGINAL','VORONOI_CRACKLE','CELL_NOISE'])
-            if scn.rtexture_noise_basis:
-                texture.noise_basis = random.choice(['BLENDER_ORIGINAL','ORIGINAL_PERLIN','IMPROVED_PERLIN','VORONOI_F1', 'VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1','BLENDER_ORIGINAL','VORONOI_CRACKLE','CELL_NOISE'])
-            if scn.rtexture_distortion:
-                texture.distortion = self.compute_percentage(0,10,texture.distortion,scn.rtexture_distortion_percentage)
-            if scn.rtexture_nabla:
-                texture.nabla = self.compute_percentage(0,0.10,texture.nabla,scn.rtexture_nabla_percentage)
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-        
-        if scn.rtexture_type == 'MAGIC':
-            
-            self.random_texture_color(texture)
-            
-            if scn.rtexture_noise_depth:
-                texture.noise_depth = int(self.compute_percentage(0,24,texture.noise_depth,scn.rtexture_noise_depth_percentage))
-            if scn.rtexture_turbulence:
-                texture.turbulence = int(self.compute_percentage(0,1000,texture.turbulence,scn.rtexture_turbulence_percentage))    
-            
-        if scn.rtexture_type == 'MARBLE':
-            
-            self.random_texture_color(texture)
-            if scn.rtexture_marble_type:
-                texture.marble_type = random.choice(['SOFT', 'SHARP', 'SHARPER'])
-            if scn.rtexture_noise_basis_2:
-                texture.noise_basis_2 = random.choice(['SIN', 'SAW', 'TRI'])
-            if scn.rtexture_noise_type:
-                texture.noise_type = random.choice(['SOFT_NOISE', 'HARD_NOISE'])
-            if scn.rtexture_noise_basis:
-                texture.noise_basis = random.choice(['BLENDER_ORIGINAL','ORIGINAL_PERLIN','IMPROVED_PERLIN','VORONOI_F1', 'VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1','BLENDER_ORIGINAL','VORONOI_CRACKLE','CELL_NOISE'])
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-            if scn.rtexture_turbulence:
-                texture.turbulence = int(self.compute_percentage(0,1000,texture.turbulence,scn.rtexture_turbulence_percentage))    
-            if scn.rtexture_noise_depth:
-                texture.noise_depth = int(self.compute_percentage(0,24,texture.noise_depth,scn.rtexture_noise_depth_percentage))
-            if scn.rtexture_nabla:
-                texture.nabla = self.compute_percentage(0,0.10,texture.nabla,scn.rtexture_nabla_percentage)
-            
-        if scn.rtexture_type == 'MUSGRAVE':
-            
-            self.random_texture_color(texture)
-            if scn.rtexture_musgrave_type:
-                texture.musgrave_type = random.choice(['MULTIFRACTAL','RIDGED_MULTIFRACTAL','HYBRID_MULTIFRACTAL','FBM','HETERO_TERRAIN'])
-            if scn.rtexture_dimension_max:
-                texture.dimension_max = self.compute_percentage(0,2,texture.dimension_max,scn.rtexture_dimension_percentage)
-            if scn.rtexture_noise_intensity:
-                texture.noise_intensity = self.compute_percentage(0,10,texture.noise_intensity,scn.rtexture_noise_int_percentage)
-            if scn.rtexture_lacunarity:
-                texture.lacunarity= self.compute_percentage(0,6,texture.lacunarity,scn.rtexture_lacunarity_percentage)
-            if scn.rtexture_noise_basis:
-                texture.noise_basis = random.choice(['BLENDER_ORIGINAL','ORIGINAL_PERLIN','IMPROVED_PERLIN','VORONOI_F1', 'VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1','BLENDER_ORIGINAL','VORONOI_CRACKLE','CELL_NOISE'])
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-            if scn.rtexture_nabla:
-                texture.nabla = self.compute_percentage(0,0.10,texture.nabla,scn.rtexture_nabla_percentage)
-            if scn.rtexture_offset:
-                texture.offset = self.compute_percentage(0,6,texture.offset,scn.rtexture_offset_percentage)
-            if scn.rtexture_gain:
-                texture.offset = self.compute_percentage(0,6,texture.gain,scn.rtexture_gain_percentage)
-            if scn.rtexture_octaves:
-                texture.octaves = self.compute_percentage(0,8,texture.octaves,scn.rtexture_octaves_percentage)      
-        
-        if scn.rtexture_type == 'STUCCI':
-            
-            self.random_texture_color(texture)
-            if scn.rtexture_stucci_type:
-                texture.stucci_type = random.choice(['PLASTIC', 'WALL_IN', 'WALL_OUT'])
-            if scn.rtexture_noise_type:
-                texture.noise_type = random.choice(['SOFT_NOISE', 'HARD_NOISE'])
-            if scn.rtexture_noise_basis:
-                texture.noise_basis = random.choice(['BLENDER_ORIGINAL','ORIGINAL_PERLIN','IMPROVED_PERLIN','VORONOI_F1', 'VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1','BLENDER_ORIGINAL','VORONOI_CRACKLE','CELL_NOISE'])
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-            if scn.rtexture_turbulence:
-                texture.turbulence = int(self.compute_percentage(0,1000,texture.turbulence,scn.rtexture_turbulence_percentage))    
-        
-        
-        if scn.rtexture_type == 'VORONOI':
-            
-            self.random_texture_color(texture)
-            if scn.rtexture_dist_metric:
-                texture.distance_metric = random.choice(['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', 'CHEBYCHEV', 'MINKOVSKY_HALF', 'MINKOVSKY_FOUR', 'MINKOVSKY'])
-            if scn.rtexture_noise_type:
-                texture.color_mode = random.choice(['INTENSITY', 'POSITION', 'POSITION_OUTLINE', 'POSITION_OUTLINE_INTENSITY'])
-            if scn.rtexture_exponent:
-                texture.minkovsky_exponent = self.compute_percentage(0,2,texture.minkovsky_exponent ,scn.rtexture_exponent_percentage)
-            if scn.rtexture_noise_intensity:
-                texture.noise_intensity = self.compute_percentage(0,10,texture.noise_intensity,scn.rtexture_noise_int_percentage)
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-            if scn.rtexture_nabla:
-                texture.nabla = self.compute_percentage(0,0.10,texture.nabla,scn.rtexture_nabla_percentage)
-            if scn.rtexture_weight_1:
-                texture.weight_1 = self.compute_percentage(-2,2,texture.weight_1,scn.rtexture_weight_1_percentage)
-            if scn.rtexture_weight_2:
-                texture.weight_2 = self.compute_percentage(-2,2,texture.weight_2,scn.rtexture_weight_2_percentage)
-            if scn.rtexture_weight_3:
-                texture.weight_3 = self.compute_percentage(-2,2,texture.weight_3,scn.rtexture_weight_3_percentage)
-            if scn.rtexture_weight_4:
-                texture.weight_4 = self.compute_percentage(-2,2,texture.weight_4,scn.rtexture_weight_4_percentage) 
-        
-        if scn.rtexture_type == 'WOOD':
-            
-            self.random_texture_color(texture)
-            if scn.rtexture_wood_type:
-                texture.wood_type = random.choice(['BANDS', 'RINGS', 'BANDNOISE', 'RINGNOISE'])
-            if scn.rtexture_noise_basis_2:
-                texture.noise_basis_2 = random.choice(['SIN', 'SAW', 'TRI'])
-            if scn.rtexture_noise_type:
-                texture.noise_type = random.choice(['SOFT_NOISE', 'HARD_NOISE'])
-            if scn.rtexture_noise_basis:
-                texture.noise_basis = random.choice(['BLENDER_ORIGINAL','ORIGINAL_PERLIN','IMPROVED_PERLIN','VORONOI_F1', 'VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1','BLENDER_ORIGINAL','VORONOI_CRACKLE','CELL_NOISE'])
-            if scn.rtexture_noise_scale:
-                texture.noise_scale = self.compute_percentage(0,2,texture.noise_scale,scn.rtexture_noise_scale_percentage)
-            if scn.rtexture_turbulence:
-                texture.turbulence = int(self.compute_percentage(0,1000,texture.turbulence,scn.rtexture_turbulence_percentage))    
-            if scn.rtexture_nabla:
-                texture.nabla = self.compute_percentage(0,0.10,texture.nabla,scn.rtexture_nabla_percentage)
-                   
-        if scn.rtexture_type == 'NOISE':
-            
-            self.random_texture_color(texture)
-          
-        #self.store_to_history(texture)
-          
-        return texture
-
-    
-    # a nice multi label                        
-    def multi_label(self, text, ui,text_width):
-        
-        for x in range(0,len(text)):
-            el = textwrap.wrap(text[x], width = text_width)
-            
-            for y in range(0,len(el)):
-                ui.label(text=el[y])
-    
-    def draw_gui_simple_texture_color(self,context,box):
-        box.prop(context.scene,"rtexture_color", toggle = True)
-        box.prop(context.scene,"rtexture_intensity", toggle = True)
-        box.prop(context.scene,"rtexture_contrast", toggle = True)
-        box.prop(context.scene,"rtexture_saturation", toggle = True)
-       
-    def draw_gui_percentage_texture_color(self,context,box):
-        if context.scene.rtexture_color:
-            box.prop(context.scene,"rtexture_color_percentage", slider = True)
-        else:
-            box.label(text="Texture Intensity disabled ")
-                    
-        if context.scene.rtexture_intensity:
-            box.prop(context.scene,"rtexture_intensity_percentage", slider = True)
-        else:
-            box.label(text="Texture Intensity disabled ")
-                
-        if context.scene.rtexture_intensity: 
-            box.prop(context.scene,"rtexture_contrast_percentage", slider = True)
-        else:
-            box.label(text="Texture Contrast disabled ")
-                
-        if context.scene.rtexture_saturation: 
-            box.prop(context.scene,"rtexture_saturation_percentage", slider = True)
-        else:
-            box.label(text="Texture Saturation disabled ")
-    
-        
-            
-    def draw_gui(self ,context,panel,rm):
-        layout = panel.layout
-        row = layout.row()
-        row.prop(context.scene , "rtexture_gui_mode" )
-        
-        # check which Gui mode the user has selected (Simple is the default one and display the appropriate gui
-        
-        if context.scene.rtexture_gui_mode == 'enable' :
-            box = layout.box()
-            box.prop(context.scene,"rtexture_type")
-            
-            if context.scene.rtexture_type=='BLEND':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_progression", toggle = True)
-                box.prop(context.scene,"rtexture_axis", toggle = True)
-            
-            if context.scene.rtexture_type=='CLOUDS':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_noise_type", toggle = True)
-                box.prop(context.scene,"rtexture_cloud_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)
-                box.prop(context.scene,"rtexture_nabla", toggle = True)
-                box.prop(context.scene,"rtexture_noise_depth", toggle = True)
-            
-            if context.scene.rtexture_type=='DISTORTED_NOISE':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_noise_distortion", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis", toggle = True)
-                box.prop(context.scene,"rtexture_distortion", toggle = True)
-                box.prop(context.scene,"rtexture_nabla", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)   
-            
-            if context.scene.rtexture_type=='MAGIC':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_turbulence", toggle = True)
-                box.prop(context.scene,"rtexture_noise_depth", toggle = True)
-            
-            if context.scene.rtexture_type=='MARBLE':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_marble_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis_2", toggle = True)
-                box.prop(context.scene,"rtexture_noise_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)
-                box.prop(context.scene,"rtexture_turbulence", toggle = True)
-                box.prop(context.scene,"rtexture_noise_depth", toggle = True)
-                box.prop(context.scene,"rtexture_nabla", toggle = True)
-               
-            if context.scene.rtexture_type=='MUSGRAVE':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_musgrave_type", toggle = True)
-                box.prop(context.scene,"rtexture_dimension_max", toggle = True)
-                box.prop(context.scene,"rtexture_noise_intensity", toggle = True)
-                box.prop(context.scene,"rtexture_lacunarity", toggle = True)
-                box.prop(context.scene,"rtexture_octaves", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)
-                box.prop(context.scene,"rtexture_offset", toggle = True)
-                box.prop(context.scene,"rtexture_gain", toggle = True)
-            
-            if context.scene.rtexture_type=='STUCCI':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_stucci_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)
-                box.prop(context.scene,"rtexture_turbulence", toggle = True)
-            
-            if context.scene.rtexture_type=='VORONOI':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_metric", toggle = True)
-                box.prop(context.scene,"rtexture_exponent", toggle = True)
-                box.prop(context.scene,"rtexture_noise_intensity", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)
-                box.prop(context.scene,"rtexture_nablae", toggle = True)
-                box.prop(context.scene,"rtexture_weight_1", toggle = True)
-                box.prop(context.scene,"rtexture_weight_2", toggle = True)
-                box.prop(context.scene,"rtexture_weight_3", toggle = True)
-                box.prop(context.scene,"rtexture_weight_4", toggle = True)
-            
-            if context.scene.rtexture_type=='WOOD':
-                self.draw_gui_simple_texture_color(context,box)
-                box.prop(context.scene,"rtexture_wood_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis_2", toggle = True)
-                box.prop(context.scene,"rtexture_noise_type", toggle = True)
-                box.prop(context.scene,"rtexture_noise_basis", toggle = True)
-                box.prop(context.scene,"rtexture_noise_scale", toggle = True)
-                box.prop(context.scene,"rtexture_turbulence", toggle = True)
-                box.prop(context.scene,"rtexture_nabla", toggle = True)
-            
-            if context.scene.rtexture_type=='NOISE':
-                self.draw_gui_simple_texture_color(context,box)
-               
-                           
-            box.prop(context.scene,"rtexture_general_percentage", slider = True)
-            layout.operator("gyes.random_texture")
-            
-        if context.scene.rtexture_gui_mode == 'percentage' :
-            box = layout.box()
-            
-            if context.scene.rtexture_type=='BLEND':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                            
-            if context.scene.rtexture_type=='CLOUDS':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-                
-                if context.scene.rtexture_nabla: 
-                    box.prop(context.scene,"rtexture_nabla_percentage", slider = True)
-                else:
-                    box.label(text="Texture Nabla disabled ")
-                    
-                if context.scene.rtexture_noise_depth: 
-                    box.prop(context.scene,"rtexture_noise_depth_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Depth disabled ")
-            
-            if context.scene.rtexture_type=='DISTORTED NOISE':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                    
-                if context.scene.rtexture_distortion: 
-                    box.prop(context.scene,"rtexture_distortion_percentage", slider = True)
-                else:
-                    box.label(text="Texture Distortion disabled ")
-                
-                if context.scene.rtexture_nabla: 
-                    box.prop(context.scene,"rtexture_nabla_percentage", slider = True)
-                else:
-                    box.label(text="Texture Nabla disabled ")
-                    
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-            
-            if context.scene.rtexture_type=='MAGIC':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_turbulence: 
-                    box.prop(context.scene,"rtexture_turbulence_percentage", slider = True)
-                else:
-                    box.label(text="Texture Turbulence disabled ")
-                    
-                if context.scene.rtexture_noise_depth: 
-                    box.prop(context.scene,"rtexture_noise_depth_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Depth disabled ")
-            
-            if context.scene.rtexture_type=='MARBLE':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-                
-                if context.scene.rtexture_turbulence: 
-                    box.prop(context.scene,"rtexture_turbulence_percentage", slider = True)
-                else:
-                    box.label(text="Texture Turbulence disabled ")
-                
-                if context.scene.rtexture_noise_depth: 
-                    box.prop(context.scene,"rtexture_noise_depth_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Depth disabled ")
-                
-                if context.scene.rtexture_nabla: 
-                    box.prop(context.scene,"rtexture_nabla_percentage", slider = True)
-                else:
-                    box.label(text="Texture Nabla disabled ")
-                    
-               
-            if context.scene.rtexture_type=='MUSGRAVE':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_dimension_max: 
-                    box.prop(context.scene,"rtexture_dimension_percentage", slider = True)
-                else:
-                    box.label(text="Texture Dimension Max disabled ")
-                
-                if context.scene.rtexture_noise_intensity: 
-                    box.prop(context.scene,"rtexture_noise_int_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Intensity disabled ")
-                
-                if context.scene.rtexture_lacunarity: 
-                    box.prop(context.scene,"rtexture_lacunarity_percentage", slider = True)
-                else:
-                    box.label(text="Texture Lacunarity disabled ")
-                    
-                if context.scene.rtexture_octaves: 
-                    box.prop(context.scene,"rtexture_octaves_percentage", slider = True)
-                else:
-                    box.label(text="Texture Lacunarity disabled ")
-                        
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-                
-                if context.scene.rtexture_nabla: 
-                    box.prop(context.scene,"rtexture_nabla_percentage", slider = True)
-                else:
-                    box.label(text="Texture Nabla disabled ")
-                    
-                if context.scene.rtexture_offset: 
-                    box.prop(context.scene,"rtexture_offset_percentage", slider = True)
-                else:
-                    box.label(text="Texture Offset disabled ")
-                    
-                if context.scene.rtexture_gain: 
-                    box.prop(context.scene,"rtexture_gain_percentage", slider = True)
-                else:
-                    box.label(text="Texture Gain disabled ")
-            
-            if context.scene.rtexture_type=='STUCCI':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-                
-                if context.scene.rtexture_turbulence: 
-                    box.prop(context.scene,"rtexture_turbulence_percentage", slider = True)
-                else:
-                    box.label(text="Texture Turbulence disabled ")
-                    
-            if context.scene.rtexture_type=='VORONOI':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_exponent: 
-                    box.prop(context.scene,"rtexture_exponent_percentage", slider = True)
-                else:
-                    box.label(text="Texture Exponent disabled ")
-                
-                if context.scene.rtexture_noise_intensity: 
-                    box.prop(context.scene,"rtexture_noise_int_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Intensity disabled ")
-                    
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-                
-                if context.scene.rtexture_nabla: 
-                    box.prop(context.scene,"rtexture_nabla_percentage", slider = True)
-                else:
-                    box.label(text="Texture Weight 1 disabled ")
-                    
-                if context.scene.rtexture_weight_1: 
-                    box.prop(context.scene,"rtexture_weight_1_percentage", slider = True)
-                else:
-                    box.label(text="Texture Weight 1 disabled ")
-                    
-                if context.scene.rtexture_weight_2: 
-                    box.prop(context.scene,"rtexture_weight_2_percentage", slider = True)
-                else:
-                    box.label(text="Texture Weight 2 disabled ")
-                
-                if context.scene.rtexture_weight_3: 
-                    box.prop(context.scene,"rtexture_weight_3_percentage", slider = True)
-                else:
-                    box.label(text="Texture Weight 3 disabled ")
-                
-                if context.scene.rtexture_weight_4: 
-                    box.prop(context.scene,"rtexture_weight_4_percentage", slider = True)
-                else:
-                    box.label(text="Texture Weight 4 disabled ")
-            
-            if context.scene.rtexture_type=='WOOD':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-                
-                if context.scene.rtexture_noise_scale: 
-                    box.prop(context.scene,"rtexture_noise_scale_percentage", slider = True)
-                else:
-                    box.label(text="Texture Noise Scale disabled ")
-                
-                if context.scene.rtexture_turbulence: 
-                    box.prop(context.scene,"rtexture_turbulence_percentage", slider = True)
-                else:
-                    box.label(text="Texture Turbulence disabled ")
-                
-                if context.scene.rtexture_nabla: 
-                    box.prop(context.scene,"rtexture_nabla_percentage", slider = True)
-                else:
-                    box.label(text="Texture Nabla disabled ")
-            
-            if context.scene.rtexture_type=='NOISE':
-            
-                self.draw_gui_percentage_texture_color(context,box)
-               
-            box.prop(context.scene,"rtexture_general_percentage", slider = True)
-            layout.operator("gyes.random_texture")
-        
-        if context.scene.rtexture_gui_mode== 'templates' : 
-            box = layout.box()
-            box.label(text="Not yet implemented")
-                    
-        if context.scene.rtexture_gui_mode== 'help' :
-            box = layout.box()
-            help_text=["","Copyright 2011 Kilon  ",
-            "GYES - RTG",    
-            "Random Material  Generator",
-            "A tool that generates random materials.",
-            "",
-            "Simple Mode",
-            "--------------------------",
-            "In this mode you can do basic randomisation. Choose parameters you want to randomise by turning them on or off with clicking on them. Hit the random button when you are ready. Each time you hit the button a new random texture is generated using existing texture or if there is not one it creates a new one",
-            "",
-            "History",
-            "--------------------------",
-            "History index -> choose index",
-            "( < ) -> Previous index (activate)",
-            "( > ) -> Next index (activate)",
-            "( |< ) -> First history index",
-            "( >| ) -> Last history index",
-            "Activate -> use this index as active material",
-            "Animate -> Insert a keyframe in the current frame for every singly non read only material property",
-            "X -> Remove a keyframe in the current frame for every singly non read only material property",
-            "R -> works just like activate but instead of using the current selected index use a randomly selected one",
-            "Delete -> delete this index",
-            "Del start -> start deletion from here",
-            "Del end -> end deletion here",
-            "Restore -> restores history from the saved blend file",
-            "Filter -> Text that used to filter material selection for import",
-            "Import -> import materials that match the filter even partially and store them one by one in history "
-            "Percentage",
-            "--------------------------",
-            "Percentage randomisation means that the parameter is randomised inside a range of percentage of the full range of the value. When a specific percentage is zero, the general percentage is used instead for that area. When a specific percentage is not zero then general percentage is ignored and specific percentage is used instead. If you don't want to randomise that parameter at all, in Simple Mode use the corresponding button to completely disable that parameter , the percentage slider will also be disabled in the percentage mode. Randomization takes always the current value as starting point so the next randomization will use the current randomized value. Randomization is always 50% of the specific percentage bellow the current value and 50% above . If the percentage exceeds minimum and maximum values of the full range, then it will default to minimum and maximum accordingly. "]
-            w=bpy.context.scene.text_width
-            box.prop(context.scene,"text_width", slider =True)
-            self.multi_label(help_text,box,w) 
-        
-        # Display the History Gui for all modes
-        
-        layout.label(text="History (RMG + RTG)")
-        history_box= layout.box()
-        history_box.prop(context.scene, "history_index")
-        row = history_box.row()
-        row.operator("gyes.first")
-        row.operator("gyes.previous")
-        row.operator("gyes.next")
-        row.operator("gyes.last")
-        rm_index = context.scene.history_index
-        
-        if rm_index in rm.rm_history and rm.rm_history[rm_index] :
-            row = history_box.row()
-            a = row.split(percentage = 0.3, align = True)
-            a.operator("gyes.activate")
-            a.operator("gyes.animate")
-            b=a.split(percentage = 0.3, align = True)
-            b.operator("gyes.x")
-            b.operator("gyes.random_activate")                       
-        else: 
-            row = history_box.row()
-            a = row.split(percentage = 0.3, align = True)
-            a.label(text= "Empty Index ! ")
-            a.operator("gyes.animate")
-            b=a.split(percentage = 0.3, align = True)
-            b.operator("gyes.x")
-            b.operator("gyes.random_activate")  
-        
-        if context.scene.history_index < len(rm.rm_history)+2:
-            history_box.operator("gyes.store")
-        else:
-            history_box.label(text= "Not the first Empty Index")
-            
-        if rm_index in rm.rm_history and rm.rm_history[rm_index] :
-            history_box.operator("gyes.delete")
-            row2 = history_box.row()
-            row2.operator("gyes.delete_start")
-            row2.operator("gyes.delete_end")
-            
-        if hasattr(bpy.context.scene,"historybak") and bpy.context.scene.historybak!='':
-            history_box.operator("gyes.restore")
-        else:
-            history_box.label(text="Backup not Found")
-                                
-rt =random_texture_class()
-
-            
-        
-# Generate the random material button
-class gyes_random_texture(bpy.types.Operator):
-    
-    bl_idname = "gyes.random_texture"
-    bl_label = "Random Texture"
-    label = bpy.props.StringProperty()
-    bl_description = "Generate the random texture"
-    
-    def execute(self, context):
-        for i in context.selected_objects :
-            rt.random_texture(i.active_material)
-
-        return{'FINISHED'}
-
-#registration is necessary for the script to appear in the GUI
-def register():
-    bpy.utils.register_class(gyes_random_texture)
-def unregister():
-    bpy.utils.unregister_class(gyes_random_texture)
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/io_directx_bel/README b/release/scripts/addons_contrib/io_directx_bel/README
deleted file mode 100644
index c147ac9..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/README
+++ /dev/null
@@ -1,262 +0,0 @@
-a DirectX importer addon for Blender 2.6
-
-first goals :
-
-. to import anything from an .x file.
-  obviously verts, faces but uv, armatures, weights, normals...
-. import .x in binary format too
-
-horizon :
-. export to .x or mod/co-maintain the existing x exporter.
-. this project is also a prototype for a 'Blender Exchange Layer' project.
-  BEL would be a common layer logically located between an importer/exporter
-  addon and the blender data format, that would allow :
-    . to provide a common set of methods to retrieve/inject objects in Blender
-    . to provide a common set of transformation and selection tools between an
-      import/export script and Blender datas (rotate, rescale, filters...)
-    . to provide a common set of parsing helpers for new io addons
-
-PLY won't be used unfortunately (it's way too slow as far as I tested)
-
-
-TO TEST THE SCRIPT :
-  . copy the 'io_directx_bel' in /scripts/addons or addons_contrib
-  . start blender
-  . enable then addon in  user prefs > addons
-  . run the script with file > import > directX
-
-25/01/12 0.17
-  . faster, 60% faster in some case : various loops improvements, infile templates parsing disabled by default
-    saw another bottleneck about data chunks as string but will wait for binary support for better point of view.
-  . interface cosmetics
-    
-23/01/12 rc 0.16
-. committed to svn (and littleneo git as usual)
-. corrected a bug about referenced token parenting
-. corrected a bug about non parented meshes
-. armatures/empties importation enabled by default
-. last run importer options are saved in a 'last_run' preset,
-  so it can be replayed or saved under another name once a
-  particular .x profile has been defined
-. tagged script for 2.6.1
-
-12/01/12 rc 0.15 :)
-. name conversion changed from 5 to 4 digits
-. matname, imagename and texturename fixes :
-. a path test is made at image import time with any existing data images, 
-  so a same file cant be loaded twice wathever the naming method, / or \, rel or abs etc 
-  (bel.material.new() and after line 835)
-. image and texture names should be ok now (tested with : incrediblylongname.x)
-. materials are replaced accordingly in existing objs when using the 'replace' naming method
-. fyi, the Dx exporter has the following inconveniences :
-    . split linked faces into individual faces
-    . inversed uvmapping (y axis) ?
-    -> see testfiles/blender_x_export/incrediblylongname.x
-   
-29 and 31/12/11
-. Cosmetics, code cleaning and optimizations
-. bpy.ops.object.select_name methods replaced with
-    ob.select = True
-    bpy.context.scene.objects.active = ob
-. corrected a big bug about tokens info appending in dXtree()
-. new bpyname() method in bel module. removed bel.common
-
-26/12/11
-. armature import and bone max. length option
-
-23/11/11
-. contrib candidate :)
-. solved some naming cases, added bel methods.
-. added experimental option about parenting (no armature yet just empties, when needed)
-. a bit faster
-. added some test files (empty parenting, armature etc)
-
-22/11/11
-campbell feedback (cont):
-. added naming methods as options (default is blender name inc. if name exists)
-  me and ob remove() should be ok with special cases (empties, mesh with multi-users)
-. improved ui
-
-
-21/11/11
-campbell feedback :
-. converted immutables to tuples : templates_x.py and some other vars.
-  http://stackoverflow.com/questions/3340539/why-tuple-is-faster-than-list
-. dprint() (console debug) removed, replaced by a inloop tests (a bit faster)
-  I'd like to keep it for now for easier debug (eg user feedbacks with 'processing' option)
-  
-19/11/11
-. object parenting support. parsing the x tree from roots using import_dxtree()
-  actually faster than before
-  
-16/11/11
-. weight group import
-. improved ui a bit and console logs
-. x matrices to blender ones conversion
-
-14/11/11
-. global matrix options
-. added messy code about binary (not working)
-
-11/11/11
-. import materials and textures (basics) : uv and image mapped (multitex mode)
-  and material created with tex slot if any. alpha should be ok.. ?
-. added a smooth options
-. better tolerance with faulty .x (upper/lower case of template names)
-. token names length from x to blender conversion should be ok also (long name cases)
-. corrected a parser pointer error after one array parsing case.
-. added more templates (for mat and tex support)
-. removed texture files from repo in testfile (tex does not match meshes )
-  added some other x files for further tests in binary and compressed format
-  ( http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/test/models/X/ )
-  
-08/11/11
-. turned into an addon (fork from obj import so unused functions atm)
-  enable it in addon, then file > import > directx
-. splitted directx parser (io_directx_bel folder) and bel draft 
-  the bel folder is intended to be located in /scripts/modules (shared components)
-  but it's ok in scripts/addons too (tbd)
-  bel folder (will) includes anything related to blender data helper (read/write)
-. corrected duplicated quotes for x string type
-
-07/11/11
-. uv import
-. generic directx token parser. templates items are used to read datas of any token type
-  a bit slower but cool since it should support non strict standard directx files
-  virtually it can retrieve everything from now supposing the template is know
-  by default or given in the file. calls are now like :
-		nbslots, mats = readToken('MeshMaterialList001') or
-		uv = readToken('uv001') or
-		nVerts, verts, nFaces, faces = readToken('Hydralisk_backbone1') etc
-. removed the specific mesh parser the 'rigid' file is the last before mutation to
-  generic parser. a bit faster but harder to make evolve or adapt. keep it as a faster
-  strict 'branch'
-. added some default templates
-  goals / wip :
-  . to compare template declaration in file and default one.
-    so either use the default one (strict) or the .x one (could differ)
-  . use by the generic data parser to avoid a parser for each kind of token
-. cleaner code (grouping methods, function names, docs etc) 
-  functions separated from calls
-  renamed token dict as tokens etc
-. added tweaks at the beginning of the file :
-	chunksize = 1024     # size of file streams red in a row
-	quickmode = False    # this to only find meshes (no parenting, no other tokens than Mesh ones)
-	showtree = False     # display the entire token tree in the console
-	showtemplate = True  # display template datas found in file
-. added a patch for malformed datas of vertices (meshFaces) :
-	# patch for malformed datas not completely clear yet ( I guess
-	# there's bunch of us when looking at meshface syntax in .x files) :
-	# when array members are like 3;v0,v1,v2;,
-	# and not like 3;v0;v1;v2;, depending on template declarations.
-	# http://paulbourke.net/dataformats/directx/#xfilefrm_Use_of_commas
-. the script now generates linked faces (was not my fault !)
-  > it seems Dx always separate each face :
-  so it defines (vert * linked faces) verts for one needed vert
-  the readvertices loop now remove duplicates at source
-  it uses a verts lookup list to redirect vert id defined in faces
-
-06/11/11
-. vertices and faces imported from each test files
-. added some info to test yourself in README 
-. switched to binary for .x as text to retrieve eol (pointer bugs). should be ok whatever it's win, mac or unix text format,
-  also works with mixed eol.
-  it seems python 3.1 can't return a 'line' when data.realine() when read mode is 'rb' (U default and universal ? really ? ;) ) 
-  when file has mac eol (\r)
-  -> read(1024) in binary, decode, and replace any \r with \n. yes, it doubles lines for windows and lines value is wrong for now
-  -> but the used pointer value is always ok now whatever the file format and still way faster than a data.tell()
-  see CRCF folder to compare output wispwind.x by format.
-. files are still splitted into chunks (1024 B) and readable as lines
-. references : added 'user' fields when token is used. users store a reference with their childs but with a '*' tag at chr0.
-  the tree reflects the changes
-. now read anything and add it to the 'tree'. this includes unknow tokens.
-. references are recognized. by reference I mean fields like { cube0 } rather than an inline frame cube0 {
-  declaration.
-  I don't know if one item can be referenced several time or referenced before declaration
-  should be.. waiting for a case. for now only one 'parent' token, messages will show up
-  multi references to one token if cases arise. 
-. more permissive syntax : 'frame spam{', 'frame     spam   egg{', 'frame spam egg  {'..
-. comments are recognized (inlines ones not done yet, since still no useful data red :) )
-. header is red
-. found other .x test files here :
-  http://www.xbdev.net/3dformats/x/xfileformat.php
-  created from 3ds max
-. added .x files in repo. line 70 and following to switch.
-. some token comes with no names, add a noname<00000> to them
-. console gives line number (more useful than char position I guess)
-
-
-05/11/11	day 0 :
-
-. made some disapointing test with ply (from a speed point of view, else it looks really cool)
-. made my own parser
-. nothing imported for now, it's more about self-eduction to .x and concept
-. but it reads the .x structure and can gather some info
-
-resource gathered :
-
-http://paulbourke.net/dataformats/directx/
-http://www.informikon.com/various/the-simplest-skeletal-animation-possible.html
-http://msdn.microsoft.com/en-us/library/windows/desktop/bb173011%28v=VS.85%29.aspx
-http://www.toymaker.info/Games/index.html
-
-
-
-step 1 : read main structure :
-
-    read main token names (any 'template', any 'frame', any 'mesh')
-    stores names in a token directory :
-        token['template'] for templates :
-            token['template'][templatename]
-            token['template'][templatename]['pointer']          (int) chr position in .x file (tell() like*)
-            token['template'][templatename]['line']             (int) line number in .x file
-        token['frame'] for frame and mesh type :
-            token['template'][frame or mesh name]
-            token['template'][frame or mesh name]['pointer']    (int) chr position in .x file (tell() like*)
-            token['template'][frame or mesh name]['line']       (int) line number in .x file
-            token['template'][frame or mesh name]['type']       (str) 'ob/bone' or 'mesh'
-            token['template'][frame or mesh name]['parent']     (str) frame parent of current item
-            token['template'][frame or mesh name]['childs']     (str list) list of child frame or mesh names
-            token['template'][frame or mesh name]['matrix']     (int) for now chr position of FrameTransformMatrix
-
-at the end of step 1 the script prints a tree of these datas
-
-step 2 : read template definitions :
-
-    for each template in dict, populate definitions in it.
-    it creates new fields in each token['template'][templatename]
-    according to values found in .x :
-        token['template'][templatename]['uuid']                 (str) <universally unique identifier>
-        token['template'][templatename]['members']['name']      (str) member name
-        token['template'][templatename]['members']['type']      (str) DWORD,FLOAT etc keywords or template name
-        token['template'][templatename]['restriction']          (str) 'open' , 'closed' , or the specidied (restricted) value
-
-that's all for now.
-
-idea would be to allow 2 steps importation and random access to file :
-
-    . first the file is quickly parsed. we only retrieve main info, nothing about verts, faces etc
-    info like number of mats, textures, objects/mesh/bone trees
-    for now : 150000 lines in 5 secs for step 1
-    . then user select what to import
-    . then the script retrieve selected datas according to selection, using the 'pointer' value
-      to seek() to the needed data, then grab/parse/translate in something usable.
-    . template are used at this point to know how to parse a specific part (adaptive parser)
-	  
-    so far this looks fast.
-	
-tested on windows. can be important because of eol and the code I wrote to compute pointer value.
-(data.tell() is slow)
-only one .x file tested, header is : xof 0303txt 0032 (windows \r\n eol)
-
-don't know a lot about .x format :
-
-uuid : 
-  are the member/restriction always the same for a same uuid/template ?
-  template name can vary for a same uuid ?
-syntax :
-  blank lines IN a stream of a {} section, after ; ?
-  comments // and # IN a stream of data ?
-  '{' and '<something>' and '}' on the same line or '{' '}' are always unique ?
-  
- 
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/__init__.py b/release/scripts/addons_contrib/io_directx_bel/__init__.py
deleted file mode 100644
index df1cd05..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/__init__.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# Blender directX importer
-bl_info = {
-    "name": "DirectX Importer",
-    "description": "Import directX Model Format (.x)",
-    "author": "Littleneo (Jerome Mahieux)",
-    "version": (0, 17),
-    "blender": (2, 6, 1),
-    "location": "File > Import > DirectX (.x)",
-    "warning": "",
-    "wiki_url": "https://github.com/littleneo/directX_blender/wiki",
-    "tracker_url": "https://github.com/littleneo/directX_blender/issues",
-    "category": "Import-Export",
-    "dependencies": ""
-}
-
-if "bpy" in locals():
-    import imp
-    if "import_x" in locals():
-        imp.reload(import_x)
-    #if "export_x" in locals():
-    #    imp.reload(export_x)
-
-
-import bpy
-from bpy.props import (BoolProperty,
-                       FloatProperty,
-                       StringProperty,
-                       EnumProperty,
-                       )
-from bpy_extras.io_utils import (ExportHelper,
-                                 ImportHelper,
-                                 path_reference_mode,
-                                 axis_conversion,
-                                 )
-
-'''
-class DisplayTree(bpy.types.Operator) :
-    bl_idname = 'city.selector'
-    bl_label = 'preview'
-
-    def execute(self,context) :
-'''
-
-def hide_templates(self,context) :
-    if self.use_templates == False : self.show_templates = False
-
-def not_parented(self,context) :
-    self.parented = False
-    self.use_templates = False
-
-class ImportX(bpy.types.Operator, ImportHelper):
-    '''Load a Direct x File'''
-    bl_idname = "import_scene.x"
-    bl_label = "Import X"
-    bl_options = {'PRESET', 'UNDO'}
-
-    filename_ext = ".x"
-    filter_glob = StringProperty(
-            default="*.x",
-            options={'HIDDEN'},
-            )
-    show_tree = BoolProperty(
-            name="Show x tokens tree",
-            description="display relationships between x items in the console",
-            default=False,
-            )
-    show_templates = BoolProperty(
-            name="Show x templates",
-            description="display any token structure definition found in the .x file",
-            default=False,
-            )
-    show_geninfo = BoolProperty(
-            name="Show processing",
-            description="display details for each imported thing",
-            default=False,
-            )
-    
-    quickmode = BoolProperty(
-            name="Quick mode",
-            description="only retrieve mesh basics",
-            default=False,
-            update=not_parented
-            )
-    
-    parented = BoolProperty(
-            name="Object Relationships",
-            description="import armatures, empties, rebuild parent-childs relations",
-            default=True,
-            )
-
-    use_templates = BoolProperty(
-            name="Use infile x templates",
-            description="parse any token structure definition found in the .x file, use it prior to standard ones",
-            default=False,
-            update=hide_templates
-            )
-    
-    bone_maxlength = FloatProperty(
-            name="Bone length",
-            description="Bones max length",
-            min=0.1, max=10.0,
-            soft_min=0.1, soft_max=10.0,
-            default=1.0,
-            )
-    
-    chunksize = EnumProperty(
-            name="Chunksize",
-            items=(('0', "all", ""),
-                   ('16384', "16KB", ""),
-                   ('8192', "8KB", ""),
-                   ('4096', "4KB", ""),
-                   ('2048', "2KB", ""),
-                   ('1024', "1KB", ""),
-                   ),
-            default='2048',
-            description="number of bytes red in a row",
-            )
-    naming_method = EnumProperty(
-            name="Naming method",
-            items=(('0', "increment name if exists", "blender default"),
-                   ('1', "use existing", "this only append new elements"),
-                   ('2', "rename existing", "names are forced"),
-                   ('3', "replace existing", ""),
-                   ),
-            default='0',
-            description="behaviour when a name already exists in Blender Data",
-            )
-    use_ngons = BoolProperty(
-            name="NGons",
-            description="Import faces with more then 4 verts as fgons",
-            default=True,
-            )
-    use_edges = BoolProperty(
-            name="Lines",
-            description="Import lines and faces with 2 verts as edge",
-            default=True,
-            )
-    use_smooth_groups = BoolProperty(
-            name="Smooth Groups",
-            description="Surround smooth groups by sharp edges",
-            default=True,
-            )
-
-    use_split_objects = BoolProperty(
-            name="Object",
-            description="Import OBJ Objects into Blender Objects",
-            default=True,
-            )
-    use_split_groups = BoolProperty(
-            name="Group",
-            description="Import OBJ Groups into Blender Objects",
-            default=True,
-            )
-
-    use_groups_as_vgroups = BoolProperty(
-            name="Poly Groups",
-            description="Import OBJ groups as vertex groups",
-            default=False,
-            )
-
-    use_image_search = BoolProperty(
-            name="Image Search",
-            description="Search subdirs for any assosiated images " \
-                        "(Warning, may be slow)",
-            default=True,
-            )
-
-    split_mode = EnumProperty(
-            name="Split",
-            items=(('ON', "Split", "Split geometry, omits unused verts"),
-                   ('OFF', "Keep Vert Order", "Keep vertex order from file"),
-                   ),
-            )
-
-    global_clamp_size = FloatProperty(
-            name="Clamp Scale",
-            description="Clamp the size to this maximum (Zero to Disable)",
-            min=0.0, max=1000.0,
-            soft_min=0.0, soft_max=1000.0,
-            default=0.0,
-            )
-    
-    axis_forward = EnumProperty(
-            name="Forward",
-            items=(('X', "Left (x)", ""),
-                   ('Y', "Same (y)", ""),
-                   ('Z', "Bottom (z)", ""),
-                   ('-X', "Right (-x)", ""),
-                   ('-Y', "Back (-y)", ""),
-                   ('-Z', "Up (-z)", ""),
-                   ),
-            default='-Z',
-            )
-
-    axis_up = EnumProperty(
-            name="Up",
-            items=(('X', "Right (x)", ""),
-                   ('Y', "Back (y)", ""),
-                   ('Z', "Same (z)", ""),
-                   ('-X', "Left (-x)", ""),
-                   ('-Y', "Front (-y)", ""),
-                   ('-Z', "Bottom (-z)", ""),
-                   ),
-            default='Y',
-            )
-
-    def execute(self, context):
-        from . import bel
-        from . import import_x
-        if self.split_mode == 'OFF':
-            self.use_split_objects = False
-            self.use_split_groups = False
-        else:
-            self.use_groups_as_vgroups = False
-            
-        keywords = self.as_keywords(ignore=("axis_forward",
-                                            "axis_up",
-                                            "filter_glob",
-                                            "split_mode",
-                                            ))
-
-        keywords["naming_method"] = int(self.naming_method)
-        
-        global_matrix = axis_conversion(from_forward=self.axis_forward,
-                                        from_up=self.axis_up,
-                                        ).to_4x4()
-        keywords["global_matrix"] = global_matrix
-
-    
-        bel.fs.saveOptions('import_scene.x', self.as_keywords(ignore=(
-                                            "filter_glob",
-                                            "filepath",
-                                            )))
-        return import_x.load(self, context, **keywords)
-
-    def draw(self, context):
-        layout = self.layout
-        
-        # import box
-        box = layout.box()
-        col = box.column(align=True)
-        col.label('Import Options :')  
-        col.prop(self, "chunksize")
-        col.prop(self, "use_smooth_groups")      
-        col.prop(self, "quickmode")
-        row = col.row()
-        row.enabled = not(self.quickmode)
-        row.prop(self, "parented")
-        #if self.parented :
-        row = col.row()
-        row.enabled = self.parented
-        row.prop(self, "bone_maxlength")
-        
-        # source orientation box
-        box = layout.box()
-        col = box.column(align=True)
-        col.label('Source Orientation :')      
-        col.prop(self, "axis_forward")
-        col.prop(self, "axis_up")
-
-        # naming methods box
-        box = layout.box()
-        col = box.column(align=True)
-        col.label('Naming Method :')
-        col.props_enum(self,"naming_method")
-
-        # info/debug box
-        box = layout.box()
-        col = box.column(align=True)
-        col.label('Info / Debug :')
-        col.prop(self, "show_tree")
-        col.prop(self, "show_geninfo")
-        col.prop(self, "use_templates")
-        row = col.row()
-        row.enabled = self.use_templates
-        row.prop(self, "show_templates")  
-        
-        #row = layout.row(align=True)
-        #row.prop(self, "use_ngons")
-        #row.prop(self, "use_edges")
-        
-        '''
-        box = layout.box()
-        row = box.row()
-        row.prop(self, "split_mode", expand=True)
-
-        row = box.row()
-        if self.split_mode == 'ON':
-            row.label(text="Split by:")
-            row.prop(self, "use_split_objects")
-            row.prop(self, "use_split_groups")
-        else:
-            row.prop(self, "use_groups_as_vgroups")
-
-        row = layout.split(percentage=0.67)
-        row.prop(self, "global_clamp_size")
-
-        layout.prop(self, "use_image_search")
-        '''
-
-def menu_func_import(self, context):
-    self.layout.operator(ImportX.bl_idname, text="DirectX (.x)")
-
-#def menu_func_export(self, context):
-#    self.layout.operator(ExportX.bl_idname, text="DirectX (.x)")
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_file_import.append(menu_func_import)
-    #bpy.types.INFO_MT_file_export.append(menu_func_export)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_file_import.remove(menu_func_import)
-    #bpy.types.INFO_MT_file_export.remove(menu_func_export)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py b/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py
deleted file mode 100644
index ab9cc89..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# set a given name to a unique
-# blender data name in its collection
-def bpyname(name,collection,suffix=4) :
-    name = name[:20-suffix]
-    tpl = '%s.%.'+str(suffix)+'d'
-    bname = name
-    id = 0
-    while bname in collection :
-        id += 1
-        bname = tpl%(name,id)
-    return bname
-
-## check if there's nested lists in a list. used by functions that need
-# list(s) of vertices/faces/edges etc as input
-# @param lst a list of vector or a list of list of vectors
-# @returns always nested list(s)
-# a boolean True if was nested, False if was not
-def nested(lst) :
-    try :
-        t = lst[0][0][0]
-        return lst, True
-    except :
-        return [lst], False
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/fs.py b/release/scripts/addons_contrib/io_directx_bel/bel/fs.py
deleted file mode 100644
index c9398fb..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/fs.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# v0.1
-import bpy
-from os import path as os_path, listdir as os_listdir
-from bpy import path as bpy_path
-
-# cross platform paths (since ms conform to / path ;) )
-# maybe add utf8 replace to old ascii blender builtin
-# // can be omitted for relative
-def clean(path) :
-    path = path.strip().replace('\\','/')
-    if ('/') not in path : path = '//'+path
-    return path
-    
-## test for existence of a file or a dir
-def exist(path) :
-    if isfile(path) or isdir(path) : return True
-    return False
-
-## test for existence of a file
-def isfile(path) :
-    if os_path.isfile(path) : return True
-    # could be blender relative
-    path = bpy_path.abspath(path)
-    if os_path.isfile(path) : return True
-    return False
-
-## test for existence of a dir
-def isdir(path) :
-    if os_path.isdir(path) : return True
-    # could be blender relative
-    path = bpy_path.abspath(path)
-    if os_path.isdir(path) : return True
-    return False
-
-## returns a list of every absolute filepath
-# to each file within the 'ext' extensions
-# from a folder and its subfolders
-def scanDir(path,ext='all') :
-    files = []
-    fields = os_listdir(path)
-    if ext != 'all' and type(ext) != list : ext = [ext]
-    for item in fields :
-        if os_path.isfile(path + '/' + item) and (ext == 'all' or item.split('.')[-1] in ext) :
-            #print('  file %s'%item)
-            files.append(path + '/' + item)
-        elif os_path.isdir(path + '/' + item) :
-            print('folder %s/%s :'%(path,item))
-            files.extend(scanDir(path + '/' + item))
-    return files
-
-def saveOptions(operator_name, tokens, filename='last_run'):
-    target_path = os_path.join("operator", operator_name)
-    target_path = os_path.join("presets", target_path)
-    target_path = bpy.utils.user_resource('SCRIPTS',target_path,create=True)
-    if target_path:
-        filepath = os_path.join(target_path, filename) + ".py"
-        file_preset = open(filepath, 'w')
-        file_preset.write("import bpy\nop = bpy.context.active_operator\n\n")
-        properties_blacklist = bpy.types.Operator.bl_rna.properties.keys()
-        for key, value in tokens.items() :
-            if key not in properties_blacklist :
-                # convert thin wrapped sequences to simple lists to repr()
-                try:
-                    value = value[:]
-                except:
-                    pass
-    
-                file_preset.write("op.%s = %r\n" % (key, value))
-
-        file_preset.close()
-    
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/image.py b/release/scripts/addons_contrib/io_directx_bel/bel/image.py
deleted file mode 100644
index cc6400a..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/image.py
+++ /dev/null
@@ -1,264 +0,0 @@
-import bpy
-import bpy.path
-import io_directx_bel.bel.fs
-from io_directx_bel import bel
-
-debuglevel = 0
-
-def dprint(str,l=2) :
-    if l <= debuglevel :
-        print(str)
-
-# create or retrieve a bdata image
-# given its path 
-def new(path, name=False, relative = True, premul = True) :
-    path = bel.fs.clean(path)
-    # check file
-    if bel.fs.isfile(path) == False :
-        dprint('Texture image not found')
-        return False
-
-    if relative :
-        try :
-            path = bpy.path.relpath(path)
-            path = bel.fs.clean(path)
-        except : 
-            print('cant turn path into relative one (.blend and img path drive letters ?) ')
-        
-    # retrieve paths to image file from existing image slot
-    # returns img if paths match
-    for img in bpy.data.images :
-        if img.filepath != '' :
-            if bpy.path.abspath(path) == bpy.path.abspath(bel.fs.clean(img.filepath)) :
-                return img
-
-    # create a unique name in image slot
-    if name == False : 
-        name = bpy.path.basename(path)
-    name = bel.bpyname(name,bpy.data.images.keys())
-
-    # finally :
-    img = bpy.data.images.load(filepath=path)
-    img.name = name
-    img.use_premultiply = premul
-    return img
-
-
-def applyShader(mat,config) :
-
-    # matslot.link = 'DATA'
-    #mat = bpy.data.materials['Female_Body']
-
-    texslot = mat.texture_slots[0]
-    tex = texslot.texture
-    img = tex.image
-    
-    #config = shaders[shadername]
-    alpha = True if 'alpha' in config else False
-
-    ## MAT
-
-    mat.type = 'SURFACE'
-    # diffuse
-    mat.diffuse_color = Color((0.6, 0.6, 0.6))
-    mat.diffuse_intensity = 0.8
-    mat.diffuse_shader = 'LAMBERT'
-    mat.use_diffuse_ramp = False
-
-    # specular
-    mat.specular_color = Color((1.0, 1.0, 1.0))
-    mat.specular_intensity = 0.25
-    mat.specular_shader = 'COOKTORR'
-    mat.use_specular_ramp = False
-    mat.specular_hardness = 1.0
-
-    # shading
-    mat.emit = 0.0
-    mat.ambient = 0.5
-    mat.translucency = 0.0
-    mat.use_shadeless = False
-    mat.use_tangent_shading = False
-    mat.use_cubic = False
-
-    # transparency
-    mat.use_transparency = alpha
-    mat.transparency_method = 'Z_TRANSPARENCY'
-    mat.alpha = not(alpha)
-    mat.specular_alpha = not(alpha)
-    mat.raytrace_transparency.fresnel = 0.0
-    mat.raytrace_transparency.fresnel_factor = 1.25
-
-    # mirror
-    mat.raytrace_mirror.use = False
-
-    # subsurface_scattering
-    mat.subsurface_scattering.use
-
-    # strand
-    # options
-    # shadow
-    mat.use_shadows = True
-    mat.use_transparent_shadows = True
-    mat.use_cast_shadows_only = False
-    mat.shadow_cast_alpha = 1.0
-    mat.use_only_shadow = False
-    mat.shadow_only_type = 'SHADOW_ONLY_OLD'
-    mat.use_cast_buffer_shadows = True
-    mat.shadow_buffer_bias = 0.0
-    mat.use_ray_shadow_bias = True
-    mat.shadow_ray_bias = 0.0
-    mat.use_cast_approximate = True
-
-    # TEXTURE SLOT 0
-
-    # diffuse
-    texslot.diffuse_factor = 1.0
-    texslot.use_map_diffuse = True
-    texslot.diffuse_color_factor = 1.0
-    texslot.use_map_color_diffuse = True
-    texslot.alpha_factor = 1.0
-    texslot.use_map_alpha = alpha
-    texslot.translucency_factor = 0.0
-    texslot.use_map_translucency = False
-
-    # specular
-    texslot.specular_factor = 0.3
-    texslot.use_map_specular = True
-    texslot.specular_color_factor = 1.0
-    texslot.use_map_color_spec = True
-    texslot.hardness_factor = 0.1
-    texslot.use_map_hardness = True
-
-    # shading
-    texslot.ambient_factor = 0.0
-    texslot.use_map_ambient = False
-    texslot.emit_factor = 0.1
-    texslot.use_map_emit = True
-    texslot.mirror_factor = 0.0
-    texslot.use_map_mirror = False
-    texslot.raymir_factor = 0.0
-    texslot.use_map_raymir = False
-
-    # geometry
-    texslot.normal_factor = 0.0
-    texslot.use_map_normal = False
-    texslot.warp_factor = 0.1
-    texslot.use_map_warp = False
-    texslot.displacement_factor = 0.0
-    texslot.use_map_displacement = False
-
-    texslot.blend_type = 'MIX'
-    texslot.invert = False
-    texslot.use_rgb_to_intensity = False
-    texslot.color = Color((1.0, 0.0, 1.0)) # default
-    texslot.use_stencil = False
-    texslot.default_value = 1.0
-
-    # TEXTURE
-    tex.use_alpha = alpha
-    tex.use_preview_alpha = alpha
-
-    # IMAGE
-    if type(img) != type(None) :
-        img.use_premultiply = True
-
-def BSshader(nodes,pointer) :
-    tkm = bpy.context.scene.tkm
-    typ, nodename = pointer.split(' ')
-    RenderShader = nodes[typ][nodename]
-    name = BSname(nodename,RenderShader['Object.Name'])
-    if name in bpy.data.materials :
-        mat = bpy.data.materials[name]
-    else :
-        mat = bpy.data.materials.new(name=name)
-        # Unused
-        DepthWriteEnable = RenderShader['DepthWriteEnable'] if 'DepthWriteEnable' in RenderShader else False # an integer
-        ShaderTransparency = RenderShader['MultiDrawLayer'] if 'MultiDrawLayer' in RenderShader else False # an integer
-        LightEnable = RenderShader['LightEnable'] if 'LightEnable' in RenderShader else False # an integer
-
-        ShaderPhong = BSnode(nodes,RenderShader['Surface'])
-        #print('mat : %s'%ShaderPhong['Material'])
-        RenderMaterial = BSnode(nodes,ShaderPhong['Material'])
-        DiffuseColor = RenderMaterial['DiffuseColor'] if 'DiffuseColor' in RenderMaterial else False
-        SpecularColor = RenderMaterial['SpecularColor'] if 'SpecularColor' in RenderMaterial else False
-        AmbientColor = RenderMaterial['AmbientColor'] if 'AmbientColor' in RenderMaterial else False
-        EmissionColor = RenderMaterial['Shininess'] if 'EmissionColor' in RenderMaterial else False
-        Shininess = RenderMaterial['Shininess'] if 'Shininess' in RenderMaterial else False
-        Transparency = RenderMaterial['Transparency'] if 'Transparency' in RenderMaterial else False
-        for key in RenderMaterial.keys() :
-            if key not in ['DiffuseColor','SpecularColor','AmbientColor','EmissionColor','Shininess','Transparency'] :
-                print('NEW RENDERMATERIAL PROP ! : %s'%key)
-        
-        #print(AmbientColor)
-        if DiffuseColor : mat.diffuse_color = Color(DiffuseColor) #[0][0],DiffuseColor[0][1],DiffuseColor[0][2])
-        if SpecularColor : mat.specular_color = Color(SpecularColor)#[0][0],SpecularColor[0][1],SpecularColor[0][2])
-        if AmbientColor : mat.ambient = AmbientColor[0] # source value is a vector3f with x=y=z 
-        if EmissionColor : mat.emit = EmissionColor[0] # source value is a vector3f with x=y=z 
-        #if Shininess : mat.
-        #alpha is a boolean, whereas Transparency is a float or False
-        if Transparency :
-            mat.use_transparency = True
-            mat.transparency_method = 'Z_TRANSPARENCY'
-            mat.alpha = Transparency
-            mat.specular_alpha = 0
-            alpha = True
-        else : alpha = False
-        texinfluence = False
-        if 'Color' in ShaderPhong :
-            ShaderTexture = BSnode(nodes,ShaderPhong['Color'])
-            texinfluence = 'Color'
-        if 'Reflection' in ShaderPhong :
-            ShaderTexture = BSnode(nodes,ShaderPhong['Reflection'])
-            texinfluence = 'Reflection'
-        if texinfluence == False :
-            print('neither color nor refl. in ShaderPhong %s'%RenderShader['Surface'])
-            print('other props are : %s'%ShaderPhong.keys())
-            return mat
-
-        ShaderTextureName = ShaderTexture['Object.Name']
-
-        Texture2D = BSnode(nodes,ShaderTexture['Texture'])
-        Texture2DName = Texture2D['Object.Name']
-
-        FileObject = BSnode(nodes,Texture2D['Texture.FileObject'])
-        imgpath = FileObject['FileName']
-        imgname = imgpath.split('/')[-1]
-        imgpath = tkm.path_archives+'/Images/Q=Tex032M/'+imgpath
-
-        if imgname not in bpy.data.images :        
-            if os.path.isfile(imgpath+'.png') : ext = '.png'
-            elif os.path.isfile(imgpath+'.jp2') : ext = '.jp2'
-            else :
-                print('Texture image not found ! %s'%Texture2D['Texture.FileObject'])
-                print('path : %s.png or .jp2 '%imgpath)
-                return mat
-            img = bpy.data.images.load(filepath=imgpath+ext)
-            img.name = imgname
-            img.use_premultiply = True
-        else : img = bpy.data.images[imgname]
-        
-        '''
-        texslot = mat.texture_slots[0]
-        mat.texture_slots[0]
-        tex = texslot.texture
-        tex.type = 'IMAGE'
-        img = tex.image        
-        img.name
-        '''
-        #img = bpy.data.images.new(name='imgname',width=640, height=512)
-
-        if ShaderTextureName not in bpy.data.textures :
-            tex = bpy.data.textures.new(name=ShaderTextureName,type='IMAGE')
-            tex.image = img
-            tex.use_alpha = alpha
-            tex.use_preview_alpha = alpha
-        else : tex = bpy.data.textures[ShaderTextureName]
-
-        texslot = mat.texture_slots.create(index=0)
-        texslot.texture = tex
-        texslot.texture_coords = 'UV'
-        texslot.uv_layer = 'UV0'
-        texslot.use_map_alpha = alpha
-        texslot.alpha_factor = 1.0
-
-    return mat
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/material.py b/release/scripts/addons_contrib/io_directx_bel/bel/material.py
deleted file mode 100644
index d39f32c..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/material.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import bpy
-
-'''
-given name < 21
-if material name exists :
-naming_method = 0   blender default (increment name)
-naming_method = 1   do nothing, abort creation and use existing
-naming_method = 2   create new, rename existing, 
-naming_method = 3   create new, replace existing
-'''
-
-def new(name, naming_method=0) :
-    if name not in bpy.data.materials or naming_method == 0:
-        return bpy.data.materials.new(name=name)
-    
-    elif naming_method == 1 :
-        return bpy.data.materials[name]
-    
-    mat = bpy.data.materials.new(name=name)
-    
-    if naming_method == 2 :
-        mat.name = name
-        return mat
-    
-    # naming_method = 3 : replace 
-    prevmat = bpy.data.materials[name]
-    for ob in bpy.data.objects :
-        for matslot in ob.material_slots :
-            if matslot.material == prevmat :
-                matslot.material = mat
-    bpy.data.materials.remove(prevmat)
-    return mat
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py b/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py
deleted file mode 100644
index c779905..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py
+++ /dev/null
@@ -1,209 +0,0 @@
-##\file
-# raw extract quick cleaning from blended cities2.6 project. thanks to myself for cooperation, but what a messy code we have here.
-import bpy
-import mathutils
-from mathutils import *
-
-import io_directx_bel.bel.uv
-import io_directx_bel.bel.ob
-from io_directx_bel import bel
-
-debuglevel = 0
-'''
-wip.. naming behaviour previous to any data
-name exist ?
-no : create
-yes :
-    naming_method = 0   blender default (increment name)
-    naming_method = 1   do nothing, abort creation and use existing
-    naming_method = 2   create new, rename existing, 
-    naming_method = 3   create new, remove existing
-    
-for now, and mesh data, 0 2 or 3
-'''
-
-## material MUST exist before creation of material slots
-## map only uvmap 0 to its image defined in mat  for now (multitex view)
-def write(obname,name, 
-          verts=[], edges=[], faces=[], 
-          matslots=[], mats=[], uvs=[], 
-          groupnames=[], vindices=[], vweights=[],
-          smooth=False,
-          naming_method = 0,
-          ) :
-
-    
-    obj = bpy.data.objects[obname] if obname in bpy.data.objects else False
-    me = bpy.data.meshes[name] if name in bpy.data.meshes else False
-
-    #print(naming_method,type(obj),type(me))
-    #print(obj,me)
-    #print()
-    if naming_method == 1 and me and obj and obj.data == me :
-        #print('%s and %s exist, reuse'%(obj.name,me.name))
-        return obj
-       
-    if naming_method == 3 :
-        if obj : 
-            #print('remove ob %s'%obj.name)
-            bel.ob.remove(obj,False)
-        if me :
-            #print('remove me %s'%me.name)
-            bel.ob.removeData(me)
-    
-
-    me = bpy.data.meshes.new(name)
-    if naming_method == 2 : me.name = name
-    
-    me.from_pydata(verts, edges, faces)
-    me.update()
-
-    if smooth : shadesmooth(me)
-    
-    # material slots
-    matimage=[]
-    if len(matslots) > 0 :
-        for matname in matslots :
-            '''
-            if matname not in bpy.data.materials :
-                mat = bpy.data.materials.new(name=matname)
-                mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
-                mat.use_fake_user = True
-                warn.append('Created missing material : %s'%matname)
-            else :
-            '''
-            mat = bpy.data.materials[matname]
-            me.materials.append(mat)
-            texslot_nb = len(mat.texture_slots)
-            if texslot_nb :
-                texslot = mat.texture_slots[0]
-                if type(texslot) != type(None) :
-                    tex = texslot.texture
-                    if tex.type == 'IMAGE' :
-                        img = tex.image
-                        if type(img) != type(None) :
-                            matimage.append(img)
-                            continue
-            matimage.append(False)
-
-    # map a material to each face
-    if len(mats) > 0 :
-        for fi,f in enumerate(me.faces) :
-            f.material_index = mats[fi]
-
-    # uvs
-    if len(uvs) > 0 :
-        bel.uv.write(me, uvs, matimage)
-
-
-    obj = bpy.data.objects.new(name=obname, object_data=me)
-    if naming_method != 0 :
-        obj.name = obname
-            
-    '''
-    else :
-        ob = bpy.data.objects[name]
-        ob.data = me
-        if naming_method == 2 : ob.name = 
-        ob.parent = None
-        ob.matrix_local = Matrix()
-        print('  reuse object %s'%ob.name)
-    '''
-            
-    # vertexgroups
-    if len(groupnames) > 0 :
-        for gpi, groupname in enumerate(groupnames) :
-            weightsadd(obj, groupname, vindices[gpi], vweights[gpi])
-    
-    # scene link check
-    if obj.name not in bpy.context.scene.objects.keys() :
-        bpy.context.scene.objects.link(obj)
-        
-    return obj
-
-def shadesmooth(me,lst=True) :
-    if type(lst) == list :
-        for fi in lst :
-            me.faces[fi].use_smooth = True
-    else :
-        for fi,face in enumerate(me.faces) :
-            face.use_smooth = True
- 
-def shadeflat(me,lst=True) :
-    if type(lst) == list :
-        for fi in lst :
-            me.faces[fi].use_smooth = False
-    else :
-        for fi,face in enumerate(me.faces) :
-            face.use_smooth = False
-
-def weightsadd(ob, groupname, vindices, vweights=False) :
-    if vweights == False : vweights = [1.0 for i in range(len(vindices))]
-    elif type(vweights) == float : vweights = [vweights for i in range(len(vindices))]
-    group = ob.vertex_groups.new(groupname)
-    for vi,v in enumerate(vindices) :
-        group.add([v], vweights[vi], 'REPLACE')
-
-def matToString(mat) :
-    #print('*** %s %s'%(mat,type(mat)))
-    return str(mat).replace('\n       ','')[6:]
-
-def stringToMat(string) :
-    return Matrix(eval(string))
-
-
-def objectBuild(elm, verts, edges=[], faces=[], matslots=[], mats=[], uvs=[] ) :
-    #print('build element %s (%s)'%(elm,elm.className()))
-    dprint('object build',2)
-    city = bpy.context.scene.city
-    # apply current scale
-    verts = metersToBu(verts)
-    
-    if type(elm) != str :
-        obname = elm.objectName()
-        if obname == 'not built' :
-            obname = elm.name
-    else : obname= elm
-
-    obnew = createMeshObject(obname, True, verts, edges, faces, matslots, mats, uvs)
-    #elm.asElement().pointer = str(ob.as_pointer())
-    if type(elm) != str :
-        if elm.className() == 'outlines' :
-            obnew.lock_scale[2] = True
-            if elm.parent :
-                obnew.parent = elm.Parent().object()
-        else :
-            #otl = elm.asOutline()
-            #ob.parent = otl.object()
-            objectLock(obnew,True)
-        #ob.matrix_local = Matrix() # not used
-        #ob.matrix_world = Matrix() # world
-    return obnew
-
-def dprint(str,l=2) :
-    if l <= debuglevel :
-        print(str)
-
-
-def materialsCheck(bld) :
-    if hasattr(bld,'materialslots') == False :
-        #print(bld.__class__.__name__)
-        builderclass = eval('bpy.types.%s'%(bld.__class__.__name__))
-        builderclass.materialslots=[bld.className()]
-
-    matslots = bld.materialslots
-    if len(matslots) > 0 :
-        for matname in matslots :
-            if matname not in bpy.data.materials :
-                mat = bpy.data.materials.new(name=matname)
-                mat.use_fake_user = True
-                if hasattr(bld,'mat_%s'%(matname)) :
-                    method = 'defined by builder'
-                    matdef = eval('bld.mat_%s'%(matname))
-                    mat.diffuse_color = matdef['diffuse_color']
-                else :
-                    method = 'random'
-                    mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
-                dprint('Created missing material %s (%s)'%(matname,method),2)
-
-
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/ob.py b/release/scripts/addons_contrib/io_directx_bel/bel/ob.py
deleted file mode 100644
index b875fb8..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/ob.py
+++ /dev/null
@@ -1,116 +0,0 @@
-import bpy
-from bpy.types import Mesh, PointLamp, SpotLamp, HemiLamp, AreaLamp, SunLamp, Camera, TextCurve, MetaBall, Lattice, Armature
-
-
-def new(name,datatype,naming_method):
-    if name in bpy.data.objects and naming_method :
-        ob = bpy.data.objects[name]
-        if naming_method == 1 :
-            ob.parent = None
-            ob.user_clear()
-        elif naming_method == 2 :
-            ob = bpy.data.objects.new(name,datatype)
-            ob.name = name
-        elif naming_method == 3 :
-            bpy.context.scene.objects.unlink(ob)
-            ob.user_clear()
-            bpy.data.objects.remove(ob)
-            ob = bpy.data.objects.new(name,datatype)
-    else :
-        ob = bpy.data.objects.new(name,datatype)
-    if ob.name not in bpy.context.scene.objects.keys() :
-        bpy.context.scene.objects.link(ob)
-    return ob
-
-## returns an object or a list of objects
-# @param ob 'all', 'active', 'selected', <object>, 'objectname'
-# @return a list of objects or an empty list
-def get(ob) :
-    if type(ob) == str :
-        if ob == 'all' : return bpy.context.scene.objects
-        elif ob == 'active' : return [bpy.context.active_object] if bpy.context.active_object != None else []
-        elif ob == 'selected' : return bpy.context.selected_objects
-        else :
-            try : return [bpy.data.objects[ob]]
-            except : return []
-    return [ob]
-
-
-## remove an object from blender internal
-def remove(ob,with_data=True) :
-    objs = get(ob)
-    #if objs :
-    #    if type(objs) == bpy.types.Object : objs = [objs]
-    for ob in objs :
-            data = ob.data
-            #and_data=False
-            # never wipe data before unlink the ex-user object of the scene else crash (2.58 3 770 2)
-            # if there's more than one user for this data, never wipeOutData. will be done with the last user
-            # if in the list
-            and_data = with_data
-            try :
-                if data.users > 1 :
-                    and_data=False
-            except :
-                and_data=False # empties
-                
-            # odd (pre 2.60) :
-            # ob=bpy.data.objects[ob.name]
-            # if the ob (board) argument comes from bpy.data.groups['aGroup'].objects,
-            #  bpy.data.groups['board'].objects['board'].users_scene
-            ob.name = '_dead'
-            for sc in ob.users_scene :
-                sc.objects.unlink(ob)
-
-            #try :
-                #print('  removing object %s...'%(ob.name)),
-            bpy.data.objects.remove(ob)
-                #print('  done.')
-            #except :
-            #    print('removing failed, but renamed %s and unlinked'%ob.name)
-
-            # never wipe data before unlink the ex-user object of the scene else crash (2.58 3 770 2)
-            if and_data :
-                wipeOutData(data)
-
-
-## remove an object data from blender internal
-## or rename it _dead if there's still users
-def removeData(data) :
-    #print('%s has %s user(s) !'%(data.name,data.users))
-    
-    if data.users <= 0 :
-
-            #data.user_clear()
-            data_type = type(data)
-            
-            # mesh
-            if data_type == Mesh :
-                bpy.data.meshes.remove(data)
-            # lamp
-            elif data_type in [ PointLamp, SpotLamp, HemiLamp, AreaLamp, SunLamp ] :
-                bpy.data.lamps.remove(data)
-            # camera
-            elif data_type == Camera :
-                bpy.data.cameras.remove(data)
-            # Text, Curve
-            elif data_type in [ Curve, TextCurve ] :
-                bpy.data.curves.remove(data)
-            # metaball
-            elif data_type == MetaBall :
-                bpy.data.metaballs.remove(data)
-            # lattice
-            elif data_type == Lattice :
-                bpy.data.lattices.remove(data)
-            # armature
-            elif data_type == Armature :
-                bpy.data.armatures.remove(data)
-            else :
-                print('  data still here : forgot %s type'%type(data))
-        #except :
-            # empty, field
-        #    print('%s has no user_clear attribute ? (%s).'%(data.name,type(data)))
-    else :
-        #print('  not done, %s has %s user'%(data.name,data.users))
-        data.name = '_dead'
-        
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/uv.py b/release/scripts/addons_contrib/io_directx_bel/bel/uv.py
deleted file mode 100644
index ef85b76..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/bel/uv.py
+++ /dev/null
@@ -1,81 +0,0 @@
-from mathutils import Vector
-from .. import bel
-
-def write(me, uvs, matimage = False) :
-    uvs, nest = bel.nested(uvs)
-    newuvs = []
-    append = newuvs.append
-    for uvi, uvlist in enumerate(uvs) :
-
-        uv = me.uv_textures.new()
-        uv.name = 'UV%s'%uvi
-        
-        for uvfi, uvface in enumerate(uvlist) :
-            #uv.data[uvfi].use_twoside = True # 2.60 changes mat ways
-            mslotid = me.faces[uvfi].material_index
-            #mat = mesh.materials[mslotid]
-            if matimage :
-                if matimage[mslotid] :
-                    img = matimage[mslotid]
-                    uv.data[uvfi].image=img
-                    #uv.data[uvfi].use_image = True
-            
-            uv.data[uvfi].uv1 = Vector((uvface[0],uvface[1]))
-            uv.data[uvfi].uv2 = Vector((uvface[2],uvface[3]))
-            uv.data[uvfi].uv3 = Vector((uvface[4],uvface[5]))
-            if len(uvface) == 8 :
-                uv.data[uvfi].uv4 = Vector((uvface[6],uvface[7]))
-        append(uv)
-    if nest : return newuvs
-    else : return newuvs[0]
-
-
-# face are squared or rectangular, 
-# any orientation
-# vert order width then height 01 and 23 = x 12 and 03 = y
-# normal default when face has been built
-def row(vertices,faces,normals=True) :
-    uvs = []
-    append = uvs.append
-    for face in faces :
-        v0 = vertices[face[0]]
-        v1 = vertices[face[1]]
-        v2 = vertices[face[-1]]
-        #print(v0,v1)
-        lx = (v1 - v0).length
-        ly = (v2 - v0).length
-        # init uv
-        if len(uvs) == 0 :
-            x = 0
-            y = 0
-        elif normals :
-            x = uvs[-1][2]
-            y = uvs[-1][3]
-        else :
-            x = uvs[-1][0]
-            y = uvs[-1][1]
-        if normals : append([x,y,x+lx,y,x+lx,y+ly,x,y+ly])
-        else : append([x+lx,y,x,y,x,y+ly,x+lx,y+ly])
-    return uvs
-
-## convert UV given as verts location to blender format
-# eg : [ [v0x,v0y] , [vnx , vny] ... ] -> [ [ v1x,v1y,v0x,v0y,v4x,v4y] ... ]
-# this format is found in directx files
-'''
-def asVertsLocation(verts2d, faces) :
-    uv = []
-    for f in faces :
-        uvface = []
-        for vi in f :
-            uvface.extend(verts2d[vi])
-        uv.append(uvface)
-    return uv
-'''
-def asVertsLocation(verts2d, idFaces) :
-    coFaces = []
-    uvBlender = []
-    conv0 = coFaces.extend
-    conv1 = uvBlender.extend
-    for f in idFaces : conv0([verts2d[vi] for vi in f])
-    for f in coFaces : conv1(f)
-    return uvBlender
diff --git a/release/scripts/addons_contrib/io_directx_bel/import_x.py b/release/scripts/addons_contrib/io_directx_bel/import_x.py
deleted file mode 100644
index 00e8a72..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/import_x.py
+++ /dev/null
@@ -1,976 +0,0 @@
-# Blender directX importer
-# version baby
-
-# litterature explaining the parser directions :
-
-# I don't want to load the whole file as it can be huge : go chunks
-# also I want random access to 3d datas to import pieces, not always everything
-# so step1 is a whole file fast parsing, retrieving tokens name and building the internal dict
-# with no 3d datas inside.
-# step 2 is to call any token by their names and retrieve the 3d datas thanks to a pointer stored in dicts
-# between stp1 and step 2 a script ui should be provided to select, transform etc before import.
-# > I need to know the pointer position of tokens but data.tell() is slow
-# a += pointer computed from line length is way faster. so I need eol -> rb mode
-# and readline() is ok in binary mode 'rb' with \r\n (win) \n (unix) but not \r mac..
-# 2chrs for windows, 1 for mac and lunix > win eol \r\n becomes \n\n (add a line)
-# mac eol \r becomes \n so win lines info are wrong
-# this also allows support for wrong files format (mixed \r and \r\n)
-# for now it only works for text format, but the used methods will be independant of the container type.
-
-# TEST FILES
-# http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/test/models/X/
-
-
-import os
-import re
-import struct, binascii
-import time
-
-import bpy
-from mathutils import Vector, Matrix
-
-
-import io_directx_bel.bel.mesh
-import io_directx_bel.bel.image
-import io_directx_bel.bel.uv
-import io_directx_bel.bel.material
-import io_directx_bel.bel.ob
-import io_directx_bel.bel.fs
-from io_directx_bel import bel
-
-# XXX, should use explicit names
-from .templates_x import *
-
-'''
-# just a temp hack to reload bel everytime
-import imp
-imp.reload(bel)
-imp.reload(bel.fs)
-imp.reload(bel.image)
-imp.reload(bel.material)
-imp.reload(bel.mesh)
-imp.reload(bel.ob)
-imp.reload(bel.uv)
-'''
-
-###################################################
-
-def load(operator, context, filepath,
-         global_clamp_size=0.0,
-         show_tree=False,
-         show_templates=False,
-         show_geninfo=False,
-         quickmode=False,
-         parented=False,
-         use_templates=False,
-         bone_maxlength=1.0,
-         chunksize=2048,
-         naming_method=0,
-         use_ngons=True,
-         use_edges=True,
-         use_smooth_groups=True,
-         use_split_objects=True,
-         use_split_groups=True,
-         use_groups_as_vgroups=False,
-         use_image_search=True,
-         global_matrix=None,
-         ):
-    
-    
-    if quickmode :
-        parented = False
-    
-    bone_minlength = bone_maxlength / 100.0
-    
-    #global templates, tokens
-    rootTokens = []
-    namelookup = {}
-    imgnamelookup = {}
-    chunksize = int(chunksize)
-    reserved_type = (
-        'dword',
-        'float',
-        'string'
-    )
-
-    '''
-        'array',
-        'Matrix4x4',
-        'Vector',
-    '''
-    '''
-    with * : defined in dXdata
-    
-    WORD     16 bits
-    * DWORD     32 bits
-    * FLOAT     IEEE float
-    DOUBLE     64 bits
-    CHAR     8 bits
-    UCHAR     8 bits
-    BYTE     8 bits
-    * STRING     NULL-terminated string
-    CSTRING     Formatted C-string (currently unsupported)
-    UNICODE     UNICODE string (currently unsupported)
-
-BINARY FORMAT
-# TOKENS in little-endian WORDs
-#define TOKEN_NAME         1
-#define TOKEN_STRING       2
-#define TOKEN_INTEGER      3
-#define TOKEN_GUID         5
-#define TOKEN_INTEGER_LIST 6
-#define TOKEN_FLOAT_LIST   7
-#define TOKEN_OBRACE      10
-#define TOKEN_CBRACE      11
-#define TOKEN_OPAREN      12
-#define TOKEN_CPAREN      13
-#define TOKEN_OBRACKET    14
-#define TOKEN_CBRACKET    15
-#define TOKEN_OANGLE      16
-#define TOKEN_CANGLE      17
-#define TOKEN_DOT         18
-#define TOKEN_COMMA       19
-#define TOKEN_SEMICOLON   20
-#define TOKEN_TEMPLATE    31
-#define TOKEN_WORD        40
-#define TOKEN_DWORD       41
-#define TOKEN_FLOAT       42
-#define TOKEN_DOUBLE      43
-#define TOKEN_CHAR        44
-#define TOKEN_UCHAR       45
-#define TOKEN_SWORD       46
-#define TOKEN_SDWORD      47
-#define TOKEN_VOID        48
-#define TOKEN_LPSTR       49
-#define TOKEN_UNICODE     50
-#define TOKEN_CSTRING     51
-#define TOKEN_ARRAY       52
-    
-    '''
-    
-    # COMMON REGEX
-    space = '[\ \t]{1,}' # at least one space / tab
-    space0 = '[\ \t]{0,}' # zero or more space / tab
-    
-    # DIRECTX REGEX TOKENS
-    r_template = r'template' + space + '[\w]*' + space0 + '\{'
-    if quickmode :
-        r_sectionname = r'Mesh' + space + '[\W-]*'
-    else :
-        r_sectionname = r'[\w]*' + space + '[\w-]*' + space0 + '\{'
-    r_refsectionname = r'\{' + space0 + '[\w-]*' + space0 + '\}'
-    r_endsection = r'\{|\}'
-    
-    # dX comments
-    r_ignore = r'#|//'
-    
-    #r_frame = r'Frame' + space + '[\w]*'
-    #r_matrix = r'FrameTransformMatrix' + space + '\{[\s\d.,-]*'
-    #r_mesh = r'Mesh' + space + '[\W]*'
-
-    ###################
-    ## STEP 1 FUNCTIONS
-    ###################
-    
-    ## HEADER
-    # returns header values or False if directx reco tag is missing
-    # assuming there's never comment header and that xof if the 1st
-    # string of the file
-    '''
-     they look like xof 0303txt 0032
-     4       Magic Number (required) "xof "
-     2       Minor Version 03
-     2       Major Version 02
-     4       Format Type (required) 
-        "txt " Text File
-        "bin " Binary File  
-        "tzip" MSZip Compressed Text File
-        "bzip" MSZip Compressed Binary File
-     4       Float Accuracy "0032" 32 bit or "0064" 64 bit
-    '''
-    def dXheader(data) :
-        l = data.read(4)
-        if l != b'xof ' :
-            print ('no header found !')
-            data.seek(0)
-            return False
-        minor = data.read(2).decode()
-        major = data.read(2).decode()
-        format = data.read(4).decode().strip()
-        accuracy = int(data.read(4).decode())
-        data.seek(0)
-        return ( minor, major, format, accuracy )
-        
-    
-    ##
-    def dXtree(data,quickmode = False) :
-        tokens = {}
-        templates = {}
-        tokentypes = {}
-        c = 0
-        lvl = 0
-        tree = ['']
-        ptr = 0
-        eol = 0
-        trunkated = False
-        previouslvl = False
-        while True :
-            lines, trunkated = nextFileChunk(data,trunkated)
-            if lines == None : break
-            for l in lines :
-                
-                # compute pointer position
-                ptr += eol
-                c += 1
-                eol = len(l) + 1
-                #print(c,data.tell(),ptr+eol)
-                #if l != '' : print('***',l)
-                #if l == ''  : break
-                l = l.strip()
-                
-                # remove blank and comment lines
-                if l == '' or re.match(r_ignore,l) :
-                    continue
-                
-                # one line token cases level switch
-                if previouslvl :
-                    lvl -= 1
-                    previouslvl = False
-                
-                #print('%s lines in %.2f\''%(c,time.clock()-t),end='\r')
-                #print(c,len(l)+1,ptr,data.tell())
-                if '{' in l :
-                    lvl += 1
-                    if '}' in l : previouslvl = True #; print('got one line token : \n%s'%l)
-                elif '}' in l :
-                    lvl -= 1
-                #print(c,lvl,tree)
-                
-                if quickmode == False :
-                    ## look for templates
-                    if use_templates and re.match(r_template,l) :
-                        tname = l.split(' ')[1]
-                        templates[tname] = {'pointer' : ptr, 'line' : c}
-                        continue
-    
-                    ## look for {references}
-                    if re.match(r_refsectionname,l) :
-                        refname = namelookup[ l[1:-1].strip() ]
-                        #print('FOUND reference to %s in %s at line %s (level %s)'%(refname,tree[lvl-1],c,lvl))
-                        #tree = tree[0:lvl]
-                        parent = tree[lvl-1]
-                        # tag it as a reference, since it's not exactly a child.
-                        # put it in childs since order can matter in sub tokens declaration
-                        tokens[parent]['childs'].append('*'+refname)
-                        if refname not in tokens :
-                            print('reference to %s done before its declaration (line %s)\ncreated dummy'%(refname,c))
-                            tokens[refname] = {}
-                        if 'user' not in tokens[refname] : tokens[refname]['users'] = [parent]
-                        else : tokens[refname]['users'].append(parent)
-                        continue
-    
-                ## look for any token or only Mesh token in quickmode
-                if re.match(r_sectionname,l) :
-                    tokenname = getName(l,tokens)
-                    #print('FOUND %s %s %s %s'%(tokenname,c,lvl,tree))
-                    #print('pointer %s %s'%(data.tell(),ptr))
-                    if lvl == 1 : rootTokens.append(tokenname)
-                    typ = l.split(' ')[0].strip().lower()
-                    tree = tree[0:lvl]
-                    if typ not in tokentypes : tokentypes[typ] = [tokenname]
-                    else : tokentypes[typ].append(tokenname)
-                    parent = tree[-1]
-                    if tokenname in tokens :
-                        tokens[tokenname]['pointer'] = ptr
-                        tokens[tokenname]['line'] = c
-                        tokens[tokenname]['parent'] = parent
-                        tokens[tokenname]['childs'] = []
-                        tokens[tokenname]['type'] = typ
-                        
-                    else : tokens[tokenname] = {'pointer': ptr,
-                                                'line'   : c,
-                                                'parent' : parent,
-                                                'childs' : [],
-                                                'users'  : [],
-                                                'type'   : typ
-                                                }
-                    tree.append(tokenname)
-                    if lvl > 1 and quickmode == False :
-                        tokens[parent]['childs'].append(tokenname)
-                    
-        return tokens, templates, tokentypes
-        
-    ## returns file binary chunks
-    def nextFileChunk(data,trunkated=False,chunksize=1024) :
-        if chunksize == 0 : chunk = data.read()
-        else : chunk = data.read(chunksize)
-        if format == 'txt' :
-            lines = chunk.decode('utf-8', errors='ignore')
-            #if stream : return lines.replace('\r','').replace('\n','')
-            #lines = [ l + '\n' for l in lines.replace('\r','\n').split('\n') ]
-            lines = lines.replace('\r','\n').split('\n')
-            if trunkated : lines[0] = trunkated + lines[0]
-            if len(lines) == 1 : 
-                if lines[0] == '' : return None, None
-                return lines, False
-            return lines, lines.pop()
-        # wip, todo for binaries
-        else :
-            print(chunk)
-            for word in range(0,len(chunk)) :
-                w = chunk[word:word+4]
-                print(word,w,struct.unpack("<l", w),binascii.unhexlify(w))
-
-    
-    # name unnamed tokens, watchout for x duplicate
-    # for blender, referenced token in x should be named and unique..
-    def getName(l,tokens) :
-        xnam = l.split(' ')[1].strip()
-        
-        #if xnam[0] == '{' : xnam = ''
-        if xnam and xnam[-1] == '{' : xnam = xnam[:-1]
-        
-        name = xnam
-        if len(name) == 0 : name = l.split(' ')[0].strip()
-        
-        namelookup[xnam] = bel.bpyname(name,tokens,4)
-
-        return namelookup[xnam]
-    
-    
-    ###################
-    ## STEP 2 FUNCTIONS
-    ###################
-    # once the internal dict is populated the functions below can be used
-    
-    ## from a list of tokens, displays every child, users and references
-    '''
-      walk_dxtree( [ 'Mesh01', 'Mesh02' ] ) # for particular pieces
-      walk_dxtree(tokens.keys()) for the whole tree
-    '''
-    def walk_dXtree(field,lvl=0,tab='') :
-        for fi, tokenname in enumerate(field) :
-            if lvl > 0 or tokens[tokenname]['parent'] == '' :
-                if tokenname not in tokens :
-                    tokenname = tokenname[1:]
-                    ref = 'ref: '
-                else : ref = False
-                
-                frame_type = tokens[tokenname]['type']
-                line = ('{:7}'.format(tokens[tokenname]['line']))
-                log = ' %s%s (%s)'%( ref if ref else '', tokenname, frame_type )
-                print('%s.%s%s'%(line, tab, log))
-                if fi == len(field) - 1 : tab = tab[:-3] + '   '
-    
-                if ref == False :
-                    for user in tokens[tokenname]['users'] :
-                         print('%s.%s |__ user: %s'%(line, tab.replace('_',' '), user))
-                    walk_dXtree(tokens[tokenname]['childs'],lvl+1,tab.replace('_',' ')+' |__')
-                
-                if fi == len(field) - 1 and len(tokens[tokenname]['childs']) == 0 :
-                    print('%s.%s'%(line,tab))
-    
-    ## remove eol, comments, spaces from a raw block of datas
-    def cleanBlock(block) :
-        while '//' in block :
-            s = block.index('//')
-            e = block.index('\n',s+1)
-            block = block[0:s] + block[e:]
-        while '#' in block :
-            s = block.index('#')
-            e = block.index('\n',s+1)
-            block = block[0:s] + block[e:]
-        block = block.replace('\n','').replace(' ','').replace('\t ','')
-        return block
-        
-    def readToken(tokenname) :
-        token = tokens[tokenname]
-        datatype = token['type'].lower()
-        if datatype in templates : tpl = templates[datatype]
-        elif datatype in defaultTemplates : tpl = defaultTemplates[datatype]
-        else :
-            print("can't find any template to read %s (type : %s)"%(tokenname,datatype))
-            return False
-        #print('> use template %s'%datatype)
-        block = readBlock(data,token)
-        ptr = 0
-        #return dXtemplateData(tpl,block)
-        fields, ptr = dXtemplateData(tpl,block)
-        if datatype in templatesConvert :
-            fields = eval( templatesConvert[datatype] )
-        return fields
-    
-    def dXtemplateData(tpl,block,ptr=0) :
-        #print('dxTPL',block[ptr])
-        pack = []
-        append = pack.append
-        namespace = locals()
-        for member in tpl['members'] :
-            #print(member)
-            datatype = member[0].lower()
-            dataname = member[-1]
-            if datatype ==  'array' :
-                datatype = member[1].lower()
-                s = dataname.index('[') + 1
-                e = dataname.index(']')
-                #print(dataname[s:e])
-                length = eval(dataname[s:e])
-                #print("array %s type %s length defined by '%s' : %s"%(dataname[:s-1],datatype,dataname[s:e],length))
-                dataname = dataname[:s-1]
-                datavalue, ptr = dXarray(block, datatype, length, ptr)
-                #print('back to %s'%(dataname))
-            else :
-                length = 1
-                datavalue, ptr = dXdata(block, datatype, length, ptr)
-    
-            #if len(str(datavalue)) > 50 : dispvalue = str(datavalue[0:25]) + ' [...] ' + str(datavalue[-25:])
-            #else : dispvalue = str(datavalue)
-            #print('%s :  %s %s'%(dataname,dispvalue,type(datavalue)))
-            #exec('%s = datavalue'%(dataname))
-            namespace[dataname] = datavalue
-            append( datavalue )
-        return pack, ptr + 1
-    
-    def dXdata(block,datatype,length,s=0,eof=';') :
-        #print('dxDTA',block[s])
-        # at last, the data we need
-        # should be a ';' but one meet ',' often, like in meshface
-        if datatype == 'dword' :
-            e = block.index(';',s+1)
-            try : field = int(block[s:e])
-            except :
-                e = block.index(',',s+1)
-                field = int(block[s:e])
-            return field, e+1
-        elif datatype == 'float' :
-            e = block.index(eof,s+1)
-            return float(block[s:e]), e+1
-        elif datatype == 'string' :
-            e = block.index(eof,s+1)
-            return str(block[s+1:e-1]) , e+1
-        else :
-            if datatype in templates : tpl = templates[datatype]
-            elif datatype in defaultTemplates : tpl = defaultTemplates[datatype]
-            else :
-                print("can't find any template for type : %s"%(datatype))
-                return False
-            #print('> use template %s'%datatype)
-            fields, ptr = dXtemplateData(tpl,block,s)
-            if datatype in templatesConvert :
-                fields = eval( templatesConvert[datatype] )
-            return fields, ptr
-    
-    def dXarray(block, datatype, length, s=0) :
-        #print('dxARR',block[s])
-        lst = []
-        append = lst.append
-        if datatype in reserved_type :
-            eoi=','
-            for i in range(length) :
-                if i+1 == length : eoi = ';'
-                datavalue, s = dXdata(block,datatype,1,s,eoi)
-                append( datavalue )
-        
-        else :
-            eoi = ';,'
-            for i in range(length) :
-                if i+1 == length : eoi = ';;'
-                #print(eoi)
-                e = block.index(eoi,s)
-                #except : print(block,s) ; popo()
-                datavalue, na = dXdata(block[s:e+1],datatype,1)
-                append( datavalue )
-                s = e + 2
-        return lst, s
-    
-    ###################################################
-
-    ## populate a template with its datas
-    # this make them available in the internal dict. should be used in step 2 for unknown data type at least
-    def readTemplate(data,tpl_name,display=False) :
-        ptr = templates[tpl_name]['pointer']
-        line = templates[tpl_name]['line']
-        #print('> %s at line %s (chr %s)'%(tpl_name,line,ptr))
-        data.seek(ptr)
-        lines = []
-        append = lines.append
-        trunkated = False
-        go = True
-        while go :
-            rawlines, trunkated = nextFileChunk(data,trunkated,chunksize) # stream ?
-            if rawlines == None : break
-            for l in rawlines :
-                append(l.strip())
-                if '}' in l :
-                    go = False
-                    break
-        block = ''.join(lines)
-        uuid = re.search(r'<.+>',block).group()
-        templates[tpl_name]['uuid'] = uuid.lower()
-        templates[tpl_name]['members'] = []
-        templates[tpl_name]['restriction'] = 'closed'
-        
-        members = re.search(r'>.+',block).group()[1:-1].split(';')
-        for member in members :
-            if member == '' : continue
-            if member[0] == '[' :
-                templates[tpl_name]['restriction'] = member
-                continue  
-            templates[tpl_name]['members'].append( member.split(' ') )
-    
-        if display : 
-            print('\ntemplate %s :'%tpl_name)
-            for k,v in templates[tpl_name].items() :
-                if k != 'members' :
-                    print('  %s : %s'%(k,v))
-                else :
-                    for member in v :
-                        print('  %s'%str(member)[1:-1].replace(',',' ').replace("'",''))
-                
-            if tpl_name in defaultTemplates :
-                defaultTemplates[tpl_name]['line'] = templates[tpl_name]['line']
-                defaultTemplates[tpl_name]['pointer'] = templates[tpl_name]['pointer']
-                if defaultTemplates[tpl_name] != templates[tpl_name] :
-                    print('! DIFFERS FROM BUILTIN TEMPLATE :')
-                    print('raw template %s :'%tpl_name)
-                    print(templates[tpl_name])
-                    print('raw default template %s :'%tpl_name)
-                    print(defaultTemplates[tpl_name])
-                    #for k,v in defaultTemplates[tpl_name].items() :
-                    #    if k != 'members' :
-                    #        print('  %s : %s'%(k,v))
-                    #    else :
-                    #        for member in v :
-                    #            print('  %s'%str(member)[1:-1].replace(',',' ').replace("'",''))
-                else :
-                    print('MATCHES BUILTIN TEMPLATE')
-
-    ##  read any kind of token data block
-    # by default the block is cleaned from inline comment space etc to allow data parsing
-    # useclean = False (retrieve all bytes) if you need to compute a file byte pointer
-    # to mimic the file.tell() function and use it with file.seek() later
-    def readBlock(data,token, clean=True) :
-        data.seek(token['pointer'])
-        lines = []
-        append = lines.append
-        strip = str.strip
-        go = True
-        init = True
-        
-        def cleanLine(l):
-            if '//' in l : l = l[0:l.index('//')]
-            if '#' in l : l = l[0:l.index('#')]
-            return l.strip().replace(' ','').replace('\t','')
-            
-        while go :
-            chunk = data.read(512).decode('utf-8', errors='ignore')
-            chunk = chunk.replace('\r','\n').split('\n')
-            for l in map(cleanLine, chunk) :
-                if l == '' : continue
-                if init :
-                    l = l[l.index('{')+1:]
-                    init = False
-                if '}' in l :
-                    append(l[0:l.index('}')])
-                    go = False
-                    break
-                append(l)
-        
-        block = ''.join(lines)
-        return block
-
-
-    def getChilds(tokenname) :
-        childs = []
-        # '*' in childname means it's a reference. always perform this test
-        # when using the childs field
-        for childname in tokens[tokenname]['childs'] :
-            if childname[0] == '*' : childname = childname[1:]
-            childs.append( childname )
-        return childs
-    
-	# the input nested list of [bonename, matrix, [child0,child1..]] is given by import_dXtree()
-    def buildArm(armdata, child,lvl=0,parent_matrix=False) :
-        
-        bonename, bonemat, bonechilds = child
-        
-        if lvl == 0 :
-            armname = armdata
-            armdata = bpy.data.armatures.new(name=armname)
-            arm = bpy.data.objects.new(armname,armdata)
-            bpy.context.scene.objects.link(arm)
-            arm.select = True
-            bpy.context.scene.objects.active = arm
-            bpy.ops.object.mode_set(mode='EDIT')
-            parent_matrix = Matrix()
-        
-        bone = armdata.edit_bones.new(name=bonename)
-        bonematW = parent_matrix * bonemat
-        bone.head = bonematW.to_translation()
-        #bone.roll.. ?
-        bone_length = bone_maxlength
-        for bonechild in bonechilds :
-            bonechild = buildArm(armdata,bonechild,lvl+1,bonematW)
-            bonechild.parent = bone
-            bone_length = min((bonechild.head - bone.head).length, bone_length)
-        bone.tail = bonematW * Vector((0,bone_length,0))
-        if lvl == 0 :
-            bpy.ops.object.mode_set(mode='OBJECT')
-            return arm
-        return bone
-    
-    def import_dXtree(field,lvl=0) :
-        tab = ' '*lvl*2
-        if field == [] : 
-            if show_geninfo : print('%s>> no childs, return False'%(tab))
-            return False
-        ob = False
-        mat = False
-        is_root = False
-        frames = []
-        obs = []
-        
-        parentname = tokens[field[0]]['parent']
-        if show_geninfo : print('%s>>childs in frame %s :'%(tab,parentname))
-        
-        for tokenname in field :
-
-            tokentype = tokens[tokenname]['type']
-            
-            # frames can contain more than one mesh
-            if tokentype  == 'mesh' :
-                # object and mesh naming :
-                # if parent frame has several meshes : obname = meshname = mesh token name,
-                # if parent frame has only one mesh  : obname = parent frame name, meshname =  mesh token name.
-                if parentname :
-                    meshcount = 0
-                    for child in getChilds(parentname) :
-                        if tokens[child]['type'] == 'mesh' : 
-                            meshcount += 1
-                            if meshcount == 2 :
-                                parentname = tokenname
-                                break
-                else : parentname = tokenname
-                
-                ob = getMesh(parentname,tokenname)
-                obs.append(ob)
-
-                if show_geninfo : print('%smesh : %s'%(tab,tokenname))
-            
-            # frames contain one matrix (empty or bone)
-            elif tokentype  == 'frametransformmatrix' :
-                [mat] = readToken(tokenname)
-                if show_geninfo : print('%smatrix : %s'%(tab,tokenname))
-            
-            # frames can contain 0 or more frames
-            elif tokentype  == 'frame' :
-                frames.append(tokenname)
-                if show_geninfo : print('%sframe : %s'%(tab,tokenname))
-        
-        # matrix is used for mesh transform if some mesh(es) exist(s)      
-        if ob :
-            is_root = True
-            if mat == False :
-                mat = Matrix()
-                if show_geninfo : print('%smesh token without matrix, set it to default\n%splease report in bug tracker if you read this !'%(tab,tab))
-            if parentname == '' : 
-                mat = mat * global_matrix
-            if len(obs) == 1 :
-                ob.matrix_world = mat
-            else :
-                ob = bel.ob.new(parentname, None, naming_method)
-                ob.matrix_world = mat
-                for child in obs :
-                    child.parent = ob
-        
-        # matrix only, store it as a list as we don't know if
-        # it's a bone or an empty yet
-        elif mat :
-            ob = [parentname, mat,[]]
-
-        # nothing case ?
-        else :
-            ob = [parentname, Matrix() * global_matrix,[]]
-            if show_geninfo : print('%snothing here'%(tab))
-
-        childs = []
-        
-        for tokenname in frames :
-            if show_geninfo : print('%s<Begin %s :'%(tab,tokenname))
-            
-            # child is either False, empty, object, or a list or undefined name matrices hierarchy
-            child = import_dXtree(getChilds(tokenname),lvl+1)
-            if child and type(child) != list :
-                is_root = True
-            childs.append( [tokenname, child] )
-            if show_geninfo : print('%sEnd %s>'%(tab,tokenname))
-        
-        if is_root and parentname != '' :
-            
-            if show_geninfo : print('%send of tree a this point'%(tab))
-            if type(ob) == list :
-                mat = ob[1]
-                ob = bel.ob.new(parentname, None, naming_method)
-            ob.matrix_world = mat
-            
-        for tokenname, child in childs :
-            if show_geninfo : print('%sbegin2 %s>'%(tab,tokenname))
-            # returned a list of object(s) or matrice(s)
-            if child :
-
-                # current frame is an object or an empty, we parent this frame to it
-                #if eot or (ob and ( type(ob.data) == type(None) or type(ob.data) == bpy.types.Mesh ) ) :
-                if is_root :
-                    # this branch is an armature, convert it
-                    if type(child) == list :
-                        if show_geninfo : print('%sconvert to armature %s'%(tab,tokenname))
-                        child = buildArm(tokenname, child)
-                        
-                    # parent the obj/empty/arm to current
-                    # or apply the global user defined matrix to the object root
-                    if parentname != '' :
-                        child.parent = ob
-                    else :
-                        child.matrix_world = global_matrix
-                        
-                # returned a list of parented matrices. append it in childs list
-                elif type(child[0]) == str :
-                    ob[2].append(child)
-
-                # child is an empty or a mesh, so current frame is an empty, not an armature
-                elif ob and ( type(child.data) == type(None) or type(child.data) == bpy.types.Mesh ) :
-                    #print('  child data type: %s'%type(child.data))
-                    child.parent = ob
-                    #print('%s parented to %s'%(child.name,ob.name))
-                
-            # returned False
-            else :
-                 if show_geninfo : print('%sreturned %s, nothing'%(tab,child))
-
-        #print('>> %s return %s'%(field,ob))
-        return ob# if ob else False
-
-    # build from mesh token type
-    def getMesh(obname,tokenname,debug = False):
-    
-        if debug : print('\nmesh name : %s'%tokenname)
-        
-        verts = []
-        edges = []
-        faces = []
-        matslots = []
-        facemats = []
-        uvs = []
-        groupnames = []
-        groupindices = []
-        groupweights = []
-
-        nVerts, verts, nFaces, faces = readToken(tokenname) 
-
-        if debug :
-            print('verts    : %s %s\nfaces    : %s %s'%(nVerts, len(verts),nFaces, len(faces)))
-        
-        #for childname in token['childs'] :
-        for childname in getChilds(tokenname) :
-            
-            tokentype = tokens[childname]['type']
-            
-            # UV
-            if tokentype == 'meshtexturecoords' :
-                uv = readToken(childname)
-                uv = bel.uv.asVertsLocation(uv, faces)
-                uvs.append(uv)
-                
-                if debug : print('uv       : %s'%(len(uv)))
-            
-            # MATERIALS
-            elif tokentype == 'meshmateriallist' :
-                nbslots, facemats = readToken(childname)
-                
-                if debug : print('facemats : %s'%(len(facemats)))
-                
-                # mat can exist but with no datas so we prepare the mat slot
-                # with dummy ones
-                for slot in range(nbslots) :
-                    matslots.append('dXnoname%s'%slot )
-        
-                # length does not match (could be tuned more, need more cases)
-                if len(facemats) != len(faces) :
-                    facemats = [ facemats[0] for i in faces ]
-
-                # seek for materials then textures if any mapped in this mesh.
-                # no type test, only one option type in token meshmateriallist : 'Material'
-                for slotid, matname in enumerate(getChilds(childname)) :
-                    
-                    # rename dummy mats with the right name
-                    matslots[slotid] = matname
-
-                    # blender material creation (need tuning)
-                    mat = bel.material.new(matname,naming_method)
-                    matslots[slotid] = mat.name
-                    
-                    if naming_method != 1 :
-                        #print('matname : %s'%matname)
-                        (diffuse_color,alpha), power, specCol, emitCol = readToken(matname)
-                        #if debug : print(diffuse_color,alpha, power, specCol, emitCol)
-                        mat.diffuse_color = diffuse_color
-                        mat.diffuse_intensity = power
-                        mat.specular_color = specCol
-                        # dX emit don't use diffuse color but is a color itself
-                        # convert it to a kind of intensity 
-                        mat.emit = (emitCol[0] + emitCol[1] + emitCol[2] ) / 3
-                        
-                        if alpha != 1.0 :
-                            mat.use_transparency = True
-                            mat.transparency_method = 'Z_TRANSPARENCY'
-                            mat.alpha = alpha
-                            mat.specular_alpha = 0
-                            transp = True
-                        else : transp = False
-            
-                        # texture
-                        # only 'TextureFilename' can be here, no type test
-                        # textures have no name in .x so we build 
-                        # image and texture names from the image file name
-                        # bdata texture slot name = bdata image name
-                        btexnames = []
-                        for texname in getChilds(matname) :
-                            
-                            # create/rename/reuse etc corresponding data image
-                            # (returns False if not found)
-                            [filename] = readToken(texname)
-                            img = bel.image.new(path+'/'+filename)
-                            
-                            if img == False :
-                                imgname = 'not_found'
-                            else :
-                                imgname = img.name
-                                
-                            #print('texname : %s'%texname)
-                            #print('filename : %s'%filename)
-                            #print('btex/img name : %s'%imgname)
-                            
-                            # associated texture (no naming check.. maybe tune more)
-                            # tex and texslot are created even if img not found
-                            if imgname in bpy.data.textures and ( img == False or bpy.data.textures[imgname].image == img ) :
-                                tex = bpy.data.textures[imgname]
-                            else :
-                                tex = bpy.data.textures.new(name=imgname,type='IMAGE')
-                                if img : tex.image = img
-                                
-                            tex.use_alpha = transp
-                            tex.use_preview_alpha = transp
-                                
-                            # then create texture slot
-                            texslot = mat.texture_slots.create(index=0)
-                            texslot.texture = tex
-                            texslot.texture_coords = 'UV'
-                            texslot.uv_layer = 'UV0'
-                            texslot.use_map_alpha = transp
-                            texslot.alpha_factor = alpha
-
-                # create remaining dummy mat
-                for slotid, matname in enumerate(matslots) :
-                    if matname not in bpy.data.materials :
-                        mat = bel.material.new(matname,naming_method)
-                        matslots[slotid] = mat.name
-                        
-                if debug : print('matslots : %s'%matslots)
-                
-            # VERTICES GROUPS/WEIGHTS
-            elif tokentype == 'skinweights' :
-                groupname, nverts, vindices, vweights, mat = readToken(childname)
-                groupname = namelookup[groupname]
-                if debug : 
-                    print('vgroup    : %s (%s/%s verts) %s'%(groupname,len(vindices),len(vweights),'bone' if groupname in tokens else ''))
-
-                #if debug : print('matrix : %s\n%s'%(type(mat),mat))
-                
-                groupnames.append(groupname)
-                groupindices.append(vindices)
-                groupweights.append(vweights)
-                
-        ob = bel.mesh.write(obname,tokenname, 
-                            verts, edges, faces, 
-                            matslots, facemats, uvs, 
-                            groupnames, groupindices, groupweights,
-                            use_smooth_groups,
-                            naming_method)
-        
-        return ob
-                           
-    ## here we go
-     
-    file = os.path.basename(filepath)
-    
-    print('\nimporting %s...'%file)
-    start = time.clock()
-    path = os.path.dirname(filepath)
-    filepath = os.fsencode(filepath)
-    data = open(filepath,'rb')
-    header = dXheader(data)
-
-    if global_matrix is None:
-        global_matrix = mathutils.Matrix()
-
-    if header :
-        minor, major, format, accuracy = header
-        
-        if show_geninfo :
-            print('\n%s directX header'%file)
-            print('  minor  : %s'%(minor))
-            print('  major  : %s'%(major))
-            print('  format : %s'%(format))
-            print('  floats are %s bits'%(accuracy))
-
-        if format in [ 'txt' ] : #, 'bin' ] :
-
-            ## FILE READ : STEP 1 : STRUCTURE
-            if show_geninfo : print('\nBuilding internal .x tree')
-            t = time.clock()
-            tokens, templates, tokentypes = dXtree(data,quickmode)
-            readstruct_time = time.clock()-t
-            if show_geninfo : print('builded tree in %.2f\''%(readstruct_time)) # ,end='\r')
-
-            ## populate templates with datas
-            for tplname in templates :
-                readTemplate(data,tplname,show_templates)
-
-            ## DATA TREE CHECK
-            if show_tree :
-                print('\nDirectX Data Tree :\n')
-                walk_dXtree(tokens.keys())
-            
-            ## DATA IMPORTATION
-            if show_geninfo :
-                print('Root frames :\n %s'%rootTokens)
-            if parented :
-                import_dXtree(rootTokens)
-            else :
-                for tokenname in tokentypes['mesh'] :
-                    obname = tokens[tokenname]['parent']
-                    # object and mesh naming :
-                    # if parent frame has several meshes : obname = meshname = mesh token name,
-                    # if parent frame has only one mesh  : obname = parent frame name, meshname =  mesh token name.
-                    if obname :
-                        meshcount = 0
-                        for child in getChilds(obname) :
-                            if tokens[child]['type'] == 'mesh' : 
-                                meshcount += 1
-                                if meshcount == 2 :
-                                    obname = tokenname
-                                    break
-                    else : obname = tokenname
-
-                    ob = getMesh(obname,tokenname,show_geninfo)
-                    ob.matrix_world = global_matrix
-                    
-            print('done in %.2f\''%(time.clock()-start)) # ,end='\r')
-            
-        else :
-            print('only .x files in text format are currently supported')
-            print('please share your file to make the importer evolve')
-
-
-        return {'FINISHED'}
-        
diff --git a/release/scripts/addons_contrib/io_directx_bel/templates_x.py b/release/scripts/addons_contrib/io_directx_bel/templates_x.py
deleted file mode 100644
index 7b51e0c..0000000
--- a/release/scripts/addons_contrib/io_directx_bel/templates_x.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# dx 'strict' templates
-# lower() since some apps does not respect it,
-# and to keep the 'as it should be' syntax
-
-defaultTemplates={}
-templatesConvert={}
-
-# mesh template
-defaultTemplates['Mesh'.lower()] = {
-    'uuid' : '<3d82ab44-62da-11cf-ab39-0020af71e433>',
-    'restriction' : '[...]',
-    'members' : (
-        ('dword', 'nVertices'),
-        ('array', 'vector', 'vertices[nVertices]'),
-        ('dword', 'nFaces'),
-        ('array', 'MeshFace', 'faces[nFaces]'),
-    )
-}
-
-defaultTemplates['FrameTransformMatrix'.lower()] = {
-    'uuid' : '<f6f23f41-7686-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('matrix4x4', 'frameMatrix'),
-    )
-}
-
-templatesConvert['matrix4x4'] = 'Matrix( [fields[0][0:4], fields[0][4:8] , fields[0][8:12] , fields[0][12:16]] )'
-defaultTemplates['matrix4x4'.lower()] = {
-    'uuid' : '<f6f23f45-7686-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('array', 'float', 'matrix[16]'),
-    )
-}
-
-#returns [ [vid0,vid1,vid2], [vid1,vid2,vid3,vid4] .. ]
-templatesConvert['meshface'] = 'fields[1]'
-defaultTemplates['MeshFace'.lower()] = {
-    'uuid' : '<3d82ab5f-62da-11cf-ab39-0020af71e433>',
-    'restriction' : 'closed',
-    'members' : (
-        ('dword', 'nFaceVertexIndices'),
-        ('array', 'dword', 'faceVertexIndices[nFaceVertexIndices]')
-    )
-}
-
-defaultTemplates['vector'.lower()] = {
-    'uuid' : '<3d82ab5e-62da-11cf-ab39-0020af71e433>',
-    'restriction' : 'closed',
-    'members' : (
-        ('float', 'x'),
-        ('float', 'y'),
-        ('float', 'z')
-    )
-}
-
-defaultTemplates['Coords2d'.lower()] = {
-    'uuid' : '<f6f23f44-7686-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('float', 'u'),
-        ('float', 'v')
-    )
-}
-
-# returns [ uvAsVertsLocation ]
-templatesConvert['meshtexturecoords'] = 'fields[1]'
-defaultTemplates['MeshTextureCoords'.lower()] = {
-    'uuid' : '<f6f23f40-7686-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('dword', 'nTextureCoords'),
-        ('array', 'Coords2d', 'textureCoords[nTextureCoords]')
-    )
-}
-
-defaultTemplates['meshnormals'.lower()] = {
-    'uuid' : '<f6f23f43-7686-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('dword', 'nNormals'),
-        ('array', 'vector', 'normals[nNormals]'),
-        ('dword', 'nFaceNormals'),
-        ('array', 'MeshFace', 'faceNormals[nFaceNormals]')
-    )
-}
-
-# returns [ nMaterials, [ materialindex of each face ] ]
-templatesConvert['meshmateriallist'] = '[fields[0],fields[2]]'
-defaultTemplates['MeshMaterialList'.lower()] = {
-    'uuid' : '<f6f23f42-7686-11cf-8f52-0040333594a3>',
-    'restriction' : '[Material]',
-    'members' : (
-        ('dword', 'nMaterials'),
-        ('dword', 'nFaceIndexes'),
-        ('array', 'dword', 'faceIndexes[nFaceIndexes]')
-    )
-}
-
-defaultTemplates['Material'.lower()] = {
-    'uuid' : '<3d82ab4d-62da-11cf-ab39-0020af71e433>',
-    'restriction' : '[...]',
-    'members' : (
-        ('colorrgba', 'faceColor'),
-        ('float', 'power'),
-        ('colorrgb', 'specularColor'),
-        ('colorrgb', 'emissiveColor')
-    )
-}
-
-templatesConvert['colorrgba'] = 'fields[:3],fields[3]'
-defaultTemplates['colorrgba'.lower()] = {
-    'uuid' : '<35ff44e0-6c7c-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('float', 'red'),
-        ('float', 'green'),
-        ('float', 'blue'),
-        ('float', 'alpha')
-    )
-}
-
-defaultTemplates['colorrgb'.lower()] = {
-    'uuid' : '<d3e16e81-7835-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('float', 'red'),
-        ('float', 'green'),
-        ('float', 'blue')
-    )
-}
-
-defaultTemplates['TextureFilename'.lower()] = {
-    'uuid' : '<a42790e1-7810-11cf-8f52-0040333594a3>',
-    'restriction' : 'closed',
-    'members' : (
-        ('string', 'filename'),
-    )
-}
-
-defaultTemplates['SkinWeights'.lower()] = {
-    'uuid' : '<6f0d123b-bad2-4167-a0d0-80224f25fabb>',
-    'restriction' : 'closed',
-    'members' : (
-        ('string', 'transformNodeName'),
-        ('dword', 'nWeights'),
-        ('array', 'dword', 'vertexIndices[nWeights]'),
-        ('array', 'float', 'weights[nWeights]'),
-        ('matrix4x4', 'matrixOffset')
-    )
-}
-
-defaultTemplates['XSkinMeshHeader'.lower()] = {
-    'uuid' : '3cf169ce-ff7c-44ab-93c0-f78f62d172e2',
-    'restriction' : 'closed',
-    'members' : (
-        ('word', 'nMaxSkinWeightsPerVertex'),
-        ('word', 'nMaxSkinWeightsPerFace'),
-        ('word', 'nBones')
-    )
-}
diff --git a/release/scripts/addons_contrib/io_export_dxf/__init__.py b/release/scripts/addons_contrib/io_export_dxf/__init__.py
deleted file mode 100644
index d27a8cd..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/__init__.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#  ***** GPL LICENSE BLOCK *****
-#
-#  This program is free software: you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
-#  All rights reserved.
-#  ***** GPL LICENSE BLOCK *****
-
-bl_info = {
-    "name": "Export Autocad DXF Format (.dxf)",
-    "author": "Remigiusz Fiedler (AKA migius), Vaclav Klecanda",
-    "version": (2, 1, 2),
-    "blender": (2, 6, 0),
-    "location": "File > Export > Autodesk (.dxf)",
-    "description": "The script exports Blender geometry to DXF format r12 version.",
-    "warning": "Only subset of DXF specification is supported, work in progress.",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Import-Export/DXF_Exporter",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=28469",
-    "category": "Import-Export"
-}
-
-import bpy
-from .operator import DXFExporter
-
-def menu_func(self, context):
-    self.layout.operator(DXFExporter.bl_idname, text="Autocad (.dxf)")
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_file_export.append(menu_func)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_file_export.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_export_dxf/draw_blenders/__init__.py b/release/scripts/addons_contrib/io_export_dxf/draw_blenders/__init__.py
deleted file mode 100644
index 06e5e20..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/draw_blenders/__init__.py
+++ /dev/null
@@ -1,87 +0,0 @@
-""" NOTE:
-This stuff was in original code but it seems it will be no longer needed.
-NOT USED now.
-"""
-
-#-----------------------------------------------------
-def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
-    #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
-    ob = Object.New("Mesh",name)
-    me = Mesh.New(name)
-    #print 'deb: vertList=\n', vertList #---------
-    #print 'deb: edgeList=\n', edgeList #---------
-    #print 'deb: faceList=\n', faceList #---------
-    me.verts.extend(vertList)
-    if edgeList: me.edges.extend(edgeList)
-    if faceList: me.faces.extend(faceList)
-    if flatten:
-        for v in me.verts: v.co.z = 0.0
-    ob.link(me)
-    if link:
-        sce = Scene.getCurrent()
-        sce.objects.link(ob)
-        #me.triangleToQuad()
-        if AT_CUR:
-            cur_loc = Window.GetCursorPos()
-            ob.setLocation(cur_loc)
-        Blender.Redraw()
-    #return ob
-
-#-----------------------------------------------------
-def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True):
-    #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
-    ob = Object.New("Curve",name)
-    cu = Curve.New(name)
-    #print 'deb: vertList=\n', vertList #---------
-    curve = cu.appendNurb(BezTriple.New(vertList[0][0]))
-    for p in vertList[1:]:
-        curve.append(BezTriple.New(p[0]))
-    for point in curve:
-        #point.handleTypes = [VECT, VECT]
-        point.handleTypes = [FREE, FREE]
-        point.radius = 1.0
-    curve.flagU = closed # 0 sets the curve not cyclic=open
-    cu.setResolu(6)
-    cu.update() #important for handles calculation
-    if flatten:
-        for v in cu.verts: v.co.z = 0.0
-    ob.link(cu)
-    if link:
-        sce = Scene.getCurrent()
-        sce.objects.link(ob)
-        #me.triangleToQuad()
-        if AT_CUR:
-            cur_loc = Window.GetCursorPos()
-            ob.setLocation(cur_loc)
-        elif org_point:
-            cur_loc=org_point
-            ob.setLocation(cur_loc)
-        Blender.Redraw()
-    #return ob
-    
-#-----------------------------------------------------
-def drawClipBox(clip_box):
-    """debug tool: draws Clipping-Box of a Camera View
-    """
-    min_X1, max_X1, min_Y1, max_Y1,\
-    min_X2, max_X2, min_Y2, max_Y2,\
-        min_Z, max_Z = clip_box
-    verts = []
-    verts.append([min_X1, min_Y1, min_Z])
-    verts.append([max_X1, min_Y1, min_Z])
-    verts.append([max_X1, max_Y1, min_Z])
-    verts.append([min_X1, max_Y1, min_Z])
-    verts.append([min_X2, min_Y2, max_Z])
-    verts.append([max_X2, min_Y2, max_Z])
-    verts.append([max_X2, max_Y2, max_Z])
-    verts.append([min_X2, max_Y2, max_Z])
-    faces = [[0,1,2,3],[4,5,6,7]]
-    newmesh = Mesh.New()
-    newmesh.verts.extend(verts)
-    newmesh.faces.extend(faces)
-    
-    plan = Object.New('Mesh','clip_box')
-    plan.link(newmesh)
-    sce = Scene.GetCurrent()
-    sce.objects.link(plan)
-    plan.setMatrix(sce.objects.camera.matrix)
diff --git a/release/scripts/addons_contrib/io_export_dxf/export_dxf.py b/release/scripts/addons_contrib/io_export_dxf/export_dxf.py
deleted file mode 100644
index fb53e4d..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/export_dxf.py
+++ /dev/null
@@ -1,268 +0,0 @@
-import os
-import mathutils
-
-DEBUG = os.environ.get('BLENDER_DEBUG', False) #activates debug mode
-if DEBUG:
-	import sys
-	sys.path.append(os.environ['PYDEV_DEBUG_PATH'])
-	import pydevd
-	
-from .model.migiusModel import MigiusDXFLibDrawing
-
-SUPPORTED_TYPES = ('MESH')#,'CURVE','EMPTY','TEXT','CAMERA','LAMP')
-
-def exportDXF(context, filePath, settings):
-	"""
-	Main entry point into export facility.
-	"""
-	print("----------\nExporting to {}".format(filePath))
-	import time
-	time1 = time.clock()
-
-	if settings['verbose']:
-		print("Generating Object list for export... (Root parents only)")
-
-	scene = context.scene
-
-	if settings['onlySelected'] is True:
-		objects = (ob for ob in scene.objects if ob.is_visible(scene) and ob.select and ob.type in SUPPORTED_TYPES)
-	else:
-		objects = (ob for ob in scene.objects if ob.is_visible(scene) and ob.type in SUPPORTED_TYPES)
-		
-	if DEBUG: pydevd.settrace()
-	mw = get_view_projection_matrix(context, settings)
-
-	try:
-		# add Entities --------------------
-		#todo: fixme: seems to be the reason for missing BLOCK-export
-		#if APPLY_MODIFIERS: tmp_me = Mesh.New('tmp')
-		#else: tmp_me = None
-	
-		drawing = MigiusDXFLibDrawing()
-		exported = 0
-		for o in objects:
-			if _exportItem(context, o, mw, drawing, settings):
-				exported +=1
-	
-		if not drawing.isEmpty():
-			# NOTE: Only orthographic projection used now.
-	#		if PERSPECTIVE: # generate view border - passepartout
-	#			from .primitive_exporters.viewborder_exporter import ViewBorderDXFExporter
-	#			e = ViewBorderDXFExporter(settings)
-	#			e.export(drawing, ob, mx, mw)
-	
-			drawing.convert(filePath)
-			
-		duration = time.clock() - time1
-		print('%s objects exported in %.2f seconds. -----DONE-----' %\
-			(exported, duration))
-	except IOError:
-		print('DXF Exporter: Write Error: ', filePath)
-	except Exception as e:
-		print('Nothing exported. Error: %s' % str(e))
-
-	print("Finished")
-
-#-------------------------------------------------
-def getCommons(ob, settings):
-	"""set up common attributes for output style:
-	 color=None
-	 extrusion=None
-	 layer='0',
-	 lineType=None
-	 lineTypeScale=None
-	 lineWeight=None
-	 thickness=None
-	 parent=None
-	"""
-	
-	BYBLOCK=0 #DXF-attribute: assign property to BLOCK defaults
-	BYLAYER=None #256 #DXF-attribute: assign property to LAYER defaults
-	LAYERNAME_DEF='' #default layer name
-	LAYERCOLOR_DEF=7 #default layer color index
-	LAYERLTYPE_DEF=0 #'CONTINUOUS' - default layer lineType
-	ENTITYLAYER_DEF=LAYERNAME_DEF #default entity color index
-	ENTITYCOLOR_DEF=BYLAYER #default entity color index
-	ENTITYLTYPE_DEF=BYLAYER #default entity lineType
-
-	layers = ob.layers #gives a list e.g.[1,5,19]
-	if layers: ob_layer_nr = layers[0]
-	if DEBUG: print('ob_layer_nr=', ob_layer_nr) #--------------
-
-	materials = ob.material_slots
-	if materials:
-		ob_material = materials[0]
-		ob_mat_color = ob_material.material.diffuse_color
-	else: ob_mat_color, ob_material = None, None
-	if DEBUG: 
-		print('ob_mat_color, ob_material=', ob_mat_color, ob_material) #--------------
-
-	data_materials = ob.material_slots
-	if data_materials:
-		data_material = data_materials[0]
-		data_mat_color = data_material.material.diffuse_color
-	else: data_mat_color, data_material = None, None
-	if DEBUG:
-		print('data_mat_color, data_material=', data_mat_color, data_material) #--------------
-
-	entitylayer = ENTITYLAYER_DEF
-	c = settings['entitylayer_from']
-	#["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
-	if c=="default_LAYER":
-		entitylayer = LAYERNAME_DEF
-	elif c=="obj.layer" and ob_layer_nr:
-		entitylayer = 'LAYER'+ str(ob_layer_nr)
-	elif c=="obj.material" and ob_material:
-		entitylayer = ob_material.name
-	elif c=="obj.name":
-		entitylayer = ob.name
-	elif c=="obj.data.material" and ob_material:
-		entitylayer = data_material.name
-	elif c=="obj.data.name":
-		entitylayer = ob.data.name
-
-	entitycolor = ENTITYCOLOR_DEF
-	cfrom = settings['entitycolor_from']
-	if cfrom=="default_COLOR":
-		entitycolor = LAYERCOLOR_DEF
-	elif cfrom=="BYLAYER":
-		entitycolor = BYLAYER
-	elif cfrom=="BYBLOCK":
-		entitycolor = BYBLOCK
-	elif cfrom=="obj.layer" and ob_layer_nr:
-		entitycolor = ob_layer_nr
-	elif cfrom=="obj.color" and ob.color:
-		entitycolor = ob.color
-	elif cfrom=="obj.material" and ob_mat_color:
-		entitycolor = ob_mat_color
-	elif cfrom=="obj.data.material" and data_mat_color:
-		entitycolor = data_mat_color
-
-	entityltype = ENTITYLTYPE_DEF
-	etype = settings['entityltype_from']
-	if etype=="default_LTYPE":
-		entityltype = LAYERLTYPE_DEF
-	elif etype=="BYLAYER":
-		entityltype = BYLAYER
-	elif etype=="BYBLOCK":
-		entityltype = BYBLOCK
-	elif etype:
-		entityltype = etype
-
-	return entitylayer, entitycolor, entityltype
-
-def getCameraMatrix(cam):
-	raise NotImplementedError()
-#	camProps = cam.data
-#		mc0 = act_camera.matrix.copy()
-#				#print 'deb: camera.Matrix=\n', mc0 #------------------
-#				camera = Camera.Get(act_camera.getData(name_only=True))
-#				#print 'deb: camera=', dir(camera) #------------------
-#				if camera.type=='persp': PERSPECTIVE = 1
-#				elif camera.type=='ortho': PERSPECTIVE = 0
-#				# mcp is matrix.camera.perspective
-#				clip_box, mcp = getClipBox(camera)
-##				if PERSPECTIVE:
-##					# get border
-##					# lens = camera.lens
-##					min_X1, max_X1, min_Y1, max_Y1,\
-##					min_X2, max_X2, min_Y2, max_Y2,\
-##						min_Z, max_Z = clip_box
-##					verts = []
-##					verts.append([min_X1, min_Y1, min_Z])
-##					verts.append([max_X1, min_Y1, min_Z])
-##					verts.append([max_X1, max_Y1, min_Z])
-##					verts.append([min_X1, max_Y1, min_Z])
-##					border=verts
-#				mw = mc0.copy().invert()
-#			#ViewVector = mathutils.Vector(Window.GetViewVector())
-#			#print 'deb: ViewVector=\n', ViewVector #------------------
-#			#TODO: what is Window.GetViewOffset() for?
-#			#print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
-#			#Window.SetViewOffset([0,0,0])
-#			mw0 = Window.GetViewMatrix()
-#			#print 'deb: mwOrtho	=\n', mw0	 #---------
-#			mwp = Window.GetPerspMatrix() #TODO: how to get it working?
-#			#print 'deb: mwPersp	=\n', mwp	 #---------
-#			mw = mw0.copy()
-
-projectionMapping = {
-  'TOP' : mathutils.Vector((0, 0, -1)),
-  'BOTTOM' : mathutils.Vector((0, 0, 1)),
-  'LEFT' : mathutils.Vector((0, 1, 0)),
-  'RIGHT' : mathutils.Vector((0, -1, 0)),
-  'FRONT' : mathutils.Vector((-1, 0, 0)),
-  'REAR' : mathutils.Vector((1, 0, 0))
-}
-
-#-----------------------------------------------------
-def get_view_projection_matrix(context, settings):
-	"""
-	Returns view projection matrix.
-	Projection matrix is either identity if 3d export is selected or
-	camera projection if a camera or view is selected.
-	Currently only orthographic projection is used. (Subject to discussion).
-	"""	
-	cam = settings['projectionThrough']
-	if cam == None:
-		mw = mathutils.Matrix()
-		mw.identity()
-	elif cam in projectionMapping.keys():
-		projection = mathutils.Matrix.OrthoProjection(projectionMapping[cam], 4)
-		mw = projection
-	else: # get camera with given name
-		c = context.scene.objects[cam]
-		mw = getCameraMatrix(c)
-	return mw
-
-def _exportItem(ctx, o, mw, drawing, settings):
-	"""
-	Export one item from export list.
-	mw - modelview
-	"""
-	if settings['verbose']: print('Exporting %s' % o)
-	#mx = ob.matrix.copy()
-	#print 'deb: ob	=', ob	 #---------
-	#print 'deb: ob.type	=', ob.type	 #---------
-	#print 'deb: mx	=\n', mx	 #---------
-	#print 'deb: mw0	=\n', mw0	 #---------
-	#mx_n is trans-matrix for normal_vectors for front-side faces
-	mx = o.matrix_world
-	viewRotation = mw.to_euler().to_matrix()
-	mx_n = o.rotation_euler.to_matrix() * viewRotation
-	mx *= mw
-
-	#mx_inv = mx.copy().invert()
-	elayer, ecolor, eltype = getCommons(o, settings)
-	if settings['verbose']:
-		print('elayer=%s, ecolor=%s, eltype=%s' % (elayer, ecolor, eltype))
-	#TODO: use o.boundBox for drawing extends ??
-
-	if elayer != None and not drawing.containsLayer(elayer):
-		if ecolor!=None: tempcolor = ecolor
-		else: tempcolor = settings['layercolor_def']
-		drawing.addLayer(elayer, tempcolor)
-
-	if DEBUG: pydevd.settrace()
-	if (o.type == 'MESH') and settings['mesh_as']:
-		from .primitive_exporters.mesh_exporter import MeshDXFExporter
-		e = MeshDXFExporter(settings)
-	elif (o.type == 'CURVE') and settings['curve_as']:
-		from .primitive_exporters.curve_exporter import CurveDXFExporter
-		e = CurveDXFExporter(settings)
-	elif (o.type == 'EMPTY') and settings['empty_as']:
-		from .primitive_exporters.empty_exporter import EmptyDXFExporter
-		e = EmptyDXFExporter(settings)
-	elif (o.type == 'TEXT') and settings['text_as']:
-		from .primitive_exporters.text_exporter import TextDXFExporter
-		e = TextDXFExporter(settings)
-	elif (o.type == 'CAMERA') and settings['camera_as']:
-		from .primitive_exporters.camera_exporter import CameraDXFExporter
-		e = CameraDXFExporter(settings)
-	elif (o.type == 'LAMP') and settings['lamp_as']:
-		from .primitive_exporters.lamp_exporter import LampDXFExporter
-		e = LampDXFExporter(settings)
-
-	return e.export(ctx, drawing, o, mx, mx_n, color=ecolor, layer=elayer, lineType=eltype)
-
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/model/__init__.py b/release/scripts/addons_contrib/io_export_dxf/model/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/release/scripts/addons_contrib/io_export_dxf/model/dxfLibrary.py b/release/scripts/addons_contrib/io_export_dxf/model/dxfLibrary.py
deleted file mode 100644
index c1730d4..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/model/dxfLibrary.py
+++ /dev/null
@@ -1,927 +0,0 @@
-#dxfLibrary.py : provides functions for generating DXF files
-# --------------------------------------------------------------------------
-__version__ = "v1.35 - 2010.06.23"
-__author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)"
-__license__ = "GPL"
-__url__ = "http://wiki.blender.org/index.php/Extensions:2.4/Py/Scripts/Export/DXF"
-__bpydoc__ ="""The library to export geometry data to DXF format r12 version.
-
-Copyright %s
-Version %s
-License %s
-Homepage %s
-
-See the homepage for documentation.
-Dedicated thread on BlenderArtists: http://blenderartists.org/forum/showthread.php?t=136439
-
-IDEAs:
--
-
-TODO:
-- add support for DXFr14 version (needs extended file header)
-- add support for DXF-SPLINEs (possible first in DXFr14 version)
-- add support for DXF-MTEXT
-- add user preset for floating point precision (3-16?)
-
-History
-v1.35 - 2010.06.23 by migius
- - added (as default) writing to DXF file without RAM-buffering: faster and low-RAM-machines friendly
-v1.34 - 2010.06.20 by migius
- - bugfix POLYFACE
- - added DXF-flags for POLYLINE and VERTEX class (NURBS-export)
-v1.33 - 2009.07.03 by migius
- - fix MTEXT newline bug (not supported by DXF-Exporter yet)
- - modif _point(): converts all coords to floats
- - modif LineType class: implement elements
- - added VPORT class, incl. defaults
- - fix Insert class
-v1.32 - 2009.06.06 by migius
- - modif Style class: changed defaults to widthFactor=1.0, obliqueAngle=0.0
- - modif Text class: alignment parameter reactivated
-v1.31 - 2009.06.02 by migius
- - modif _Entity class: added paperspace,elevation
-v1.30 - 2009.05.28 by migius
- - bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0
-v1.29 - 2008.12.28 by Yorik
- - modif POLYLINE to support bulge segments
-v1.28 - 2008.12.13 by Steeve/BlenderArtists
- - bugfix for EXTMIN/EXTMAX to suit Cycas-CAD
-v1.27 - 2008.10.07 by migius
- - beautifying output code: keys whitespace prefix
- - refactoring DXF-strings format: NewLine moved to the end of
-v1.26 - 2008.10.05 by migius
- - modif POLYLINE to support POLYFACE
-v1.25 - 2008.09.28 by migius
- - modif FACE class for r12
-v1.24 - 2008.09.27 by migius
- - modif POLYLINE class for r12
- - changing output format from r9 to r12(AC1009)
-v1.1 (20/6/2005) by www.stani.be/python/sdxf
- - Python library to generate dxf drawings
-______________________________________________________________
-""" % (__author__,__version__,__license__,__url__)
-
-# --------------------------------------------------------------------------
-# DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani)
-#                       2008/2009 modif by Remigiusz Fiedler (AKA migius)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-
-#import Blender
-#from Blender import Mathutils, Window, Scene, sys, Draw
-#import BPyMessages
-
-try:
-	import copy
-	#from struct import pack
-except:
-	copy = None
-
-####1) Private (only for developpers)
-_HEADER_POINTS=['insbase','extmin','extmax']
-
-#---helper functions-----------------------------------
-def _point(x,index=0):
-	"""Convert tuple to a dxf point"""
-	return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
-
-def _points(plist):
-	"""Convert a list of tuples to dxf points"""
-	out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
-	return out
-
-#---base classes----------------------------------------
-class _Call:
-	"""Makes a callable class."""
-	def copy(self):
-		"""Returns a copy."""
-		return copy.deepcopy(self)
-
-	def __call__(self,**attrs):
-		"""Returns a copy with modified attributes."""
-		copied=self.copy()
-		for attr in attrs:setattr(copied,attr,attrs[attr])
-		return copied
-
-#-------------------------------------------------------
-class _Entity(_Call):
-	"""Base class for _common group codes for entities."""
-	def __init__(self,paperspace=None,color=None,layer='0',
-				 lineType=None,lineTypeScale=None,lineWeight=None,
-				 extrusion=None,elevation=None,thickness=None,
-				 parent=None):
-		"""None values will be omitted."""
-		self.paperspace	  = paperspace
-		self.color		  = color
-		self.layer		  = layer
-		self.lineType	   = lineType
-		self.lineTypeScale  = lineTypeScale
-		self.lineWeight	 = lineWeight
-		self.extrusion	  = extrusion
-		self.elevation	  = elevation
-		self.thickness	  = thickness
-		#self.visible	  = visible
-		self.parent		 = parent
-
-	def _common(self):
-		"""Return common group codes as a string."""
-		if self.parent:parent=self.parent
-		else:parent=self
-		result =''
-		if parent.paperspace==1: result+='  67\n1\n'
-		if parent.layer!=None: result+='  8\n%s\n'%parent.layer
-		if parent.color!=None: result+=' 62\n%s\n'%parent.color
-		if parent.lineType!=None: result+='  6\n%s\n'%parent.lineType
-		# TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
-		# TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
-		if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
-		if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
-		if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
-		if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
-		return result
-
-#--------------------------
-class _Entities:
-	"""Base class to deal with composed objects."""
-	def __dxf__(self):
-		return []
-
-	def __str__(self):
-		return ''.join([str(x) for x in self.__dxf__()])
-
-#--------------------------
-class _Collection(_Call):
-	"""Base class to expose entities methods to main object."""
-	def __init__(self,entities=[]):
-		self.entities=copy.copy(entities)
-		#link entities methods to drawing
-		for attr in dir(self.entities):
-			if attr[0]!='_':
-				attrObject=getattr(self.entities,attr)
-				if callable(attrObject):
-					setattr(self,attr,attrObject)
-
-####2) Constants
-#---color values
-BYBLOCK=0
-BYLAYER=256
-
-#---block-type flags (bit coded values, may be combined):
-ANONYMOUS =1  # This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application
-NON_CONSTANT_ATTRIBUTES =2  # This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all)
-XREF =4  # This block is an external reference (xref)
-XREF_OVERLAY =8  # This block is an xref overlay
-EXTERNAL =16 # This block is externally dependent
-RESOLVED =32 # This is a resolved external reference, or dependent of an external reference (ignored on input)
-REFERENCED =64 # This definition is a referenced external reference (ignored on input)
-
-#---mtext flags
-#attachment point
-TOP_LEFT = 1
-TOP_CENTER = 2
-TOP_RIGHT = 3
-MIDDLE_LEFT = 4
-MIDDLE_CENTER = 5
-MIDDLE_RIGHT	= 6
-BOTTOM_LEFT = 7
-BOTTOM_CENTER = 8
-BOTTOM_RIGHT = 9
-#drawing direction
-LEFT_RIGHT = 1
-TOP_BOTTOM = 3
-BY_STYLE = 5 #the flow direction is inherited from the associated text style
-#line spacing style (optional):
-AT_LEAST = 1 #taller characters will override
-EXACT = 2 #taller characters will not override
-
-#---polyline flag 70
-CLOSED =1	  # This is a closed polyline (or a polygon mesh closed in the M direction)
-CURVE_FIT =2	  # Curve-fit vertices have been added
-SPLINE_FIT =4	  # Spline-fit vertices have been added
-POLYLINE_3D =8	  # This is a 3D polyline
-POLYGON_MESH =16	 # This is a 3D polygon mesh
-CLOSED_N =32	 # The polygon mesh is closed in the N direction
-POLYFACE_MESH =64	 # The polyline is a polyface mesh
-CONTINOUS_LINETYPE_PATTERN =128	# The linetype pattern is generated continuously around the vertices of this polyline
-
-#---polyline flag 75, = curve type
-QUADRIC_NURBS = 5
-CUBIC_NURBS = 6
-BEZIER_CURVE = 8
-
-
-#---text flags
-#horizontal
-LEFT = 0
-CENTER = 1
-RIGHT = 2
-ALIGNED = 3 #if vertical alignment = 0
-MIDDLE = 4 #if vertical alignment = 0
-FIT = 5 #if vertical alignment = 0
-#vertical
-BASELINE = 0
-BOTTOM	= 1
-MIDDLE = 2
-TOP = 3
-
-####3) Classes
-#---entitities -----------------------------------------------
-#--------------------------
-class Arc(_Entity):
-	"""Arc, angles in degrees."""
-	def __init__(self,center=(0,0,0),radius=1,
-				 startAngle=0.0,endAngle=90,**common):
-		"""Angles in degrees."""
-		_Entity.__init__(self,**common)
-		self.center=center
-		self.radius=radius
-		self.startAngle=startAngle
-		self.endAngle=endAngle
-	def __str__(self):
-		return '  0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
-			   (self._common(),_point(self.center),
-				self.radius,self.startAngle,self.endAngle)
-
-#-----------------------------------------------
-class Circle(_Entity):
-	"""Circle"""
-	def __init__(self,center=(0,0,0),radius=1,**common):
-		_Entity.__init__(self,**common)
-		self.center=center
-		self.radius=radius
-	def __str__(self):
-		return '  0\nCIRCLE\n%s%s\n 40\n%s\n'%\
-			   (self._common(),_point(self.center),self.radius)
-
-#-----------------------------------------------
-class Face(_Entity):
-	"""3dface"""
-	def __init__(self,points,**common):
-		_Entity.__init__(self,**common)
-		while len(points)<4: #fix for r12 format
-			points.append(points[-1])
-		self.points=points
-		
-	def __str__(self):
-		out = '  0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
-		return out
-
-#-----------------------------------------------
-class Insert(_Entity):
-	"""Block instance."""
-	def __init__(self,name,point=(0,0,0),
-				 xscale=None,yscale=None,zscale=None,
-				 cols=None,colspacing=None,rows=None,rowspacing=None,
-				 rotation=None,
-				 **common):
-		_Entity.__init__(self,**common)
-		self.name=name
-		self.point=point
-		self.xscale=xscale
-		self.yscale=yscale
-		self.zscale=zscale
-		self.cols=cols
-		self.colspacing=colspacing
-		self.rows=rows
-		self.rowspacing=rowspacing
-		self.rotation=rotation
-
-	def __str__(self):
-		result='  0\nINSERT\n  2\n%s\n%s%s\n'%\
-				(self.name,self._common(),_point(self.point))
-		if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
-		if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
-		if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
-		if self.rotation:result+=' 50\n%s\n'%self.rotation
-		if self.cols!=None:result+=' 70\n%s\n'%self.cols
-		if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
-		if self.rows!=None:result+=' 71\n%s\n'%self.rows
-		if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
-		return result
-
-#-----------------------------------------------
-class Line(_Entity):
-	"""Line"""
-	def __init__(self,points,**common):
-		_Entity.__init__(self,**common)
-		self.points=points
-	def __str__(self):
-		return '  0\nLINE\n%s%s\n' %(
-				self._common(), _points(self.points))
-
-
-#-----------------------------------------------
-class PolyLine(_Entity):
-	def __init__(self,points,org_point=[0,0,0],flag70=0,flag75=0,width=None,**common):
-		#width = number, or width = list [width_start=None, width_end=None]
-		#for 2d-polyline: points = [ [[x, y, z], vflag=None, [width_start=None, width_end=None], bulge=0 or None] ...]
-		#for 3d-polyline: points = [ [[x, y, z], vflag=None], ...]
-		#for polyface: points = [points_list, faces_list]
-		_Entity.__init__(self,**common)
-		self.points=points
-		self.org_point=org_point
-		self.pflag70 = flag70
-		self.pflag75 = flag75
-		self.polyface = False
-		self.polyline2d = False
-		self.faces = [] # dummy value
-		self.width= None # dummy value
-		if self.pflag70 & POLYFACE_MESH:
-			self.polyface=True
-			self.points=points[0]
-			self.faces=points[1]
-			self.p_count=len(self.points)
-			self.f_count=len(self.faces)
-		elif not (self.pflag70 & POLYLINE_3D):
-			self.polyline2d = True
-			if width:
-				if type(width)!='list':  width=[width,width]
-				self.width=width
-
-	def __str__(self):
-		result= '  0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.pflag70)
-		result+=' 66\n1\n'
-		result+='%s\n' %_point(self.org_point)
-		if self.polyface:
-			result+=' 71\n%s\n' %self.p_count
-			result+=' 72\n%s\n' %self.f_count
-		elif self.polyline2d:
-			if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
-		if self.pflag75:
-			result+=' 75\n%s\n' %self.pflag75
-		for point in self.points:
-			result+='  0\nVERTEX\n'
-			result+='  8\n%s\n' %self.layer
-			if self.polyface:
-				result+='%s\n' %_point(point)
-				result+=' 70\n192\n'
-			elif self.polyline2d:
-				result+='%s\n' %_point(point[0])
-				flag = point[1]
-				if len(point)>2:
-					[width1, width2] = point[2]
-					if width1!=None: result+=' 40\n%s\n' %width1
-					if width2!=None: result+=' 41\n%s\n' %width2
-				if len(point)==4:
-					bulge = point[3]
-					if bulge: result+=' 42\n%s\n' %bulge
-				if flag:
-						result+=' 70\n%s\n' %flag
-			else:
-				result+='%s\n' %_point(point[0])
-				flag = point[1]
-				if flag:
-						result+=' 70\n%s\n' %flag
-
-		for face in self.faces:
-			result+='  0\nVERTEX\n'
-			result+='  8\n%s\n' %self.layer
-			result+='%s\n' %_point(self.org_point)
-			result+=' 70\n128\n'
-			result+=' 71\n%s\n' %face[0]
-			result+=' 72\n%s\n' %face[1]
-			result+=' 73\n%s\n' %face[2]
-			if len(face)==4: result+=' 74\n%s\n' %face[3]
-		result+='  0\nSEQEND\n'
-		result+='  8\n%s\n' %self.layer
-		return result
-
-#-----------------------------------------------
-class Point(_Entity):
-	"""Point."""
-	def __init__(self,points=None,**common):
-		_Entity.__init__(self,**common)
-		self.points=points
-	def __str__(self): # TODO:
-		return '  0\nPOINT\n%s%s\n' %(self._common(),
-			 _points(self.points)
-			)
-
-#-----------------------------------------------
-class Solid(_Entity):
-	"""Colored solid fill."""
-	def __init__(self,points=None,**common):
-		_Entity.__init__(self,**common)
-		self.points=points
-	def __str__(self):
-		return '  0\nSOLID\n%s%s\n' %(self._common(),
-			 _points(self.points[:2]+[self.points[3],self.points[2]])
-			)
-
-
-#-----------------------------------------------
-class Text(_Entity):
-	"""Single text line."""
-	def __init__(self,text='',point=(0,0,0),alignment=None,
-				 flag=None,height=1,justifyhor=None,justifyver=None,
-				 rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
-		_Entity.__init__(self,**common)
-		self.text=text
-		self.point=point
-		self.alignment=alignment
-		self.flag=flag
-		self.height=height
-		self.justifyhor=justifyhor
-		self.justifyver=justifyver
-		self.rotation=rotation
-		self.obliqueAngle=obliqueAngle
-		self.style=style
-		self.xscale=xscale
-	def __str__(self):
-		result= '  0\nTEXT\n%s%s\n 40\n%s\n  1\n%s\n'%\
-				(self._common(),_point(self.point),self.height,self.text)
-		if self.rotation: result+=' 50\n%s\n'%self.rotation
-		if self.xscale: result+=' 41\n%s\n'%self.xscale
-		if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
-		if self.style: result+='  7\n%s\n'%self.style
-		if self.flag: result+=' 71\n%s\n'%self.flag
-		if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
-		if self.alignment: result+='%s\n'%_point(self.alignment,1)
-		if self.justifyver: result+=' 73\n%s\n'%self.justifyver
-		return result
-
-#-----------------------------------------------
-class Mtext(Text):
-	"""Surrogate for mtext, generates some Text instances."""
-	def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
-		Text.__init__(self,text=text,point=point,**options)
-		if down:spacingFactor*=-1
-		self.spacingFactor=spacingFactor
-		self.spacingWidth=spacingWidth
-		self.width=width
-		self.down=down
-	def __str__(self):
-		texts=self.text.replace('\r\n','\n').split('\n')
-		if not self.down:texts.reverse()
-		result=''
-		x=y=0
-		if self.spacingWidth:spacingWidth=self.spacingWidth
-		else:spacingWidth=self.height*self.spacingFactor
-		for text in texts:
-			while text:
-				result+='%s' %Text(text[:self.width],
-					point=(self.point[0]+x*spacingWidth,
-						   self.point[1]+y*spacingWidth,
-						   self.point[2]),
-					alignment=self.alignment,flag=self.flag,height=self.height,
-					justifyhor=self.justifyhor,justifyver=self.justifyver,
-					rotation=self.rotation,obliqueAngle=self.obliqueAngle,
-					style=self.style,xscale=self.xscale,parent=self
-				)
-				text=text[self.width:]
-				if self.rotation:x+=1
-				else:y+=1
-		return result[1:]
-
-#-----------------------------------------------
-##class _Mtext(_Entity):
-	"""Mtext not functioning for minimal dxf."""
-	"""
-	def __init__(self,text='',point=(0,0,0),attachment=1,
-				 charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
-				 spacingStyle=None,spacingFactor=None,style=None,width=100,
-				 xdirection=None,**common):
-		_Entity.__init__(self,**common)
-		self.text=text
-		self.point=point
-		self.attachment=attachment
-		self.charWidth=charWidth
-		self.charHeight=charHeight
-		self.direction=direction
-		self.height=height
-		self.rotation=rotation
-		self.spacingStyle=spacingStyle
-		self.spacingFactor=spacingFactor
-		self.style=style
-		self.width=width
-		self.xdirection=xdirection
-	def __str__(self):
-		input=self.text
-		text=''
-		while len(input)>250:
-			text+='3\n%s\n'%input[:250]
-			input=input[250:]
-		text+='1\n%s\n'%input
-		result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
-				(self._common(),_point(self.point),self.charHeight,self.width,
-				 self.attachment,self.direction,text,
-				 self.height,
-				 self.rotation)
-		if self.style:result+='7\n%s\n'%self.style
-		if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
-		if self.charWidth:result+='42\n%s\n'%self.charWidth
-		if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
-		if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
-		return result
-	"""
-
-
-#---tables ---------------------------------------------------
-#-----------------------------------------------
-class Block(_Collection):
-	"""Use list methods to add entities, eg append."""
-	def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
-		self.entities=copy.copy(entities)
-		_Collection.__init__(self,entities)
-		self.layer=layer
-		self.name=name
-		self.flag=0
-		self.base=base
-	def __str__(self): # TODO:
-		e=''.join([str(x)for x in self.entities])
-		return '  0\nBLOCK\n  8\n%s\n  2\n%s\n 70\n%s\n%s\n  3\n%s\n%s  0\nENDBLK\n'%\
-			   (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
-
-#-----------------------------------------------
-class Layer(_Call):
-	"""Layer"""
-	def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
-		self.name=name
-		self.color=color
-		self.lineType=lineType
-		self.flag=flag
-	def __str__(self):
-		return '  0\nLAYER\n  2\n%s\n 70\n%s\n 62\n%s\n  6\n%s\n'%\
-			   (self.name.upper(),self.flag,self.color,self.lineType)
-
-#-----------------------------------------------
-class LineType(_Call):
-	"""Custom linetype"""
-	def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
-		self.name=name
-		self.description=description
-		self.elements=copy.copy(elements)
-		self.flag=flag
-	def __str__(self):
-		result = '  0\nLTYPE\n  2\n%s\n 70\n%s\n  3\n%s\n 72\n65\n'%\
-			(self.name.upper(),self.flag,self.description)
-		if self.elements:
-			elements = ' 73\n%s\n' %(len(self.elements)-1)
-			elements += ' 40\n%s\n' %(self.elements[0])
-			for e in self.elements[1:]:
-				elements += ' 49\n%s\n' %e
-			result += elements
-		return result
-		 
-
-#-----------------------------------------------
-class Style(_Call):
-	"""Text style"""
-	def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
-				 mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
-		self.name=name
-		self.flag=flag
-		self.height=height
-		self.widthFactor=widthFactor
-		self.obliqueAngle=obliqueAngle
-		self.mirror=mirror
-		self.lastHeight=lastHeight
-		self.font=font
-		self.bigFont=bigFont
-	def __str__(self):
-		return '  0\nSTYLE\n  2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
-			   (self.name.upper(),self.flag,self.flag,self.widthFactor,
-				self.obliqueAngle,self.mirror,self.lastHeight,
-				self.font.upper(),self.bigFont.upper())
-
-#-----------------------------------------------
-class VPort(_Call):
-	def __init__(self,name,flag=0,
-				leftBottom=(0.0,0.0),
-				rightTop=(1.0,1.0),
-				center=(0.5,0.5),
-				snap_base=(0.0,0.0),
-				snap_spacing=(0.1,0.1),
-				grid_spacing=(0.1,0.1),
-				direction=(0.0,0.0,1.0),
-				target=(0.0,0.0,0.0),
-				height=1.0,
-				ratio=1.0,
-				lens=50.0,
-				frontClipping=0.0,
-				backClipping=0.0,
-				snap_rotation=0.0,
-				twist=0.0,
-				mode=0,
-				circle_zoom=100,
-				fast_zoom=1,
-				ucsicon=1,
-				snap_on=0,
-				grid_on=0,
-				snap_style=0,
-				snap_isopair=0
-				):
-		self.name=name
-		self.flag=flag
-		self.leftBottom=leftBottom
-		self.rightTop=rightTop
-		self.center=center
-		self.snap_base=snap_base
-		self.snap_spacing=snap_spacing
-		self.grid_spacing=grid_spacing
-		self.direction=direction
-		self.target=target
-		self.height=float(height)
-		self.ratio=float(ratio)
-		self.lens=float(lens)
-		self.frontClipping=float(frontClipping)
-		self.backClipping=float(backClipping)
-		self.snap_rotation=float(snap_rotation)
-		self.twist=float(twist)
-		self.mode=mode
-		self.circle_zoom=circle_zoom
-		self.fast_zoom=fast_zoom
-		self.ucsicon=ucsicon
-		self.snap_on=snap_on
-		self.grid_on=grid_on
-		self.snap_style=snap_style
-		self.snap_isopair=snap_isopair
-	def __str__(self):
-		output = ['  0', 'VPORT',
-			'  2', self.name,
-			' 70', self.flag,
-			_point(self.leftBottom),
-			_point(self.rightTop,1),
-			_point(self.center,2), # View center point (in DCS)
-			_point(self.snap_base,3),
-			_point(self.snap_spacing,4),
-			_point(self.grid_spacing,5),
-			_point(self.direction,6), #view direction from target (in WCS)
-			_point(self.target,7),
-			' 40', self.height,
-			' 41', self.ratio,
-			' 42', self.lens,
-			' 43', self.frontClipping,
-			' 44', self.backClipping,
-			' 50', self.snap_rotation,
-			' 51', self.twist,
-			' 71', self.mode,
-			' 72', self.circle_zoom,
-			' 73', self.fast_zoom,
-			' 74', self.ucsicon,
-			' 75', self.snap_on,
-			' 76', self.grid_on,
-			' 77', self.snap_style,
-			' 78', self.snap_isopair
-			]
-
-		output_str = ''
-		for s in output:
-			output_str += '%s\n' %s
-		return output_str
-
-
-
-#-----------------------------------------------
-class View(_Call):
-	def __init__(self,name,flag=0,
-			width=1.0,
-			height=1.0,
-			center=(0.5,0.5),
-			direction=(0.0,0.0,1.0),
-			target=(0.0,0.0,0.0),
-			lens=50.0,
-			frontClipping=0.0,
-			backClipping=0.0,
-			twist=0.0,mode=0
-			):
-		self.name=name
-		self.flag=flag
-		self.width=float(width)
-		self.height=float(height)
-		self.center=center
-		self.direction=direction
-		self.target=target
-		self.lens=float(lens)
-		self.frontClipping=float(frontClipping)
-		self.backClipping=float(backClipping)
-		self.twist=float(twist)
-		self.mode=mode
-	def __str__(self):
-		output = ['  0', 'VIEW',
-			'  2', self.name,
-			' 70', self.flag,
-			' 40', self.height,
-			_point(self.center),
-			' 41', self.width,
-			_point(self.direction,1),
-			_point(self.target,2),
-			' 42', self.lens,
-			' 43', self.frontClipping,
-			' 44', self.backClipping,
-			' 50', self.twist,
-			' 71', self.mode
-			]
-		output_str = ''
-		for s in output:
-			output_str += '%s\n' %s
-		return output_str
-
-#-----------------------------------------------
-def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options):
-	width=abs(rightTop[0]-leftBottom[0])
-	height=abs(rightTop[1]-leftBottom[1])
-	center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
-	return View(name=name,width=width,height=height,center=center,**options)
-
-#---drawing
-#-----------------------------------------------
-class Drawing(_Collection):
-	"""Dxf drawing. Use append or any other list methods to add objects."""
-	def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
-				 layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
-				 views=[],vports=[],entities=None,fileName='test.dxf'):
-		# TODO: replace list with None,arial
-		if not entities:
-			entities=[]
-		_Collection.__init__(self,entities)
-		self.insbase=insbase
-		self.extmin=extmin
-		self.extmax=extmax
-		self.layers=copy.copy(layers)
-		self.linetypes=copy.copy(linetypes)
-		self.styles=copy.copy(styles)
-		self.views=copy.copy(views)
-		self.vports=copy.copy(vports)
-		self.blocks=copy.copy(blocks)
-		self.fileName=fileName
-		#print 'deb: blocks=',blocks #----------
-		#private
-		#self.acadver='9\n$ACADVER\n1\nAC1006\n'
-		self.acadver='  9\n$ACADVER\n  1\nAC1009\n'
-		"""DXF AutoCAD-Release format codes:
-		AC1021  2008, 2007 
-		AC1018  2006, 2005, 2004 
-		AC1015  2002, 2000i, 2000 
-		AC1014  R14,14.01 
-		AC1012  R13    
-		AC1009  R12,11 
-		AC1006  R10    
-		AC1004  R9    
-		AC1002  R2.6  
-		AC1.50  R2.05 
-		"""
-
-	def _name(self,x):
-		"""Helper function for self._point"""
-		return '  9\n$%s\n' %x.upper()
-
-	def _point(self,name,x):
-		"""Point setting from drawing like extmin,extmax,..."""
-		return '%s%s' %(self._name(name),_point(x))
-
-	def _section(self,name,x):
-		"""Sections like tables,blocks,entities,..."""
-		if x: xstr=''.join(x)
-		else: xstr=''
-		return '  0\nSECTION\n  2\n%s\n%s  0\nENDSEC\n'%(name.upper(),xstr)
-
-	def _table(self,name,x):
-		"""Tables like ltype,layer,style,..."""
-		if x: xstr=''.join(x)
-		else: xstr=''
-		return '  0\nTABLE\n  2\n%s\n 70\n%s\n%s  0\nENDTAB\n'%(name.upper(),len(x),xstr)
-
-	def __str__(self):
-		"""Returns drawing as dxf string."""
-		header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
-		header=self._section('header',header)
-
-		tables=[self._table('vport',[str(x) for x in self.vports]),
-				self._table('ltype',[str(x) for x in self.linetypes]),
-				self._table('layer',[str(x) for x in self.layers]),
-				self._table('style',[str(x) for x in self.styles]),
-				self._table('view',[str(x) for x in self.views]),
-		]
-		tables=self._section('tables',tables)
-		blocks=self._section('blocks',[str(x) for x in self.blocks])
-		entities=self._section('entities',[str(x) for x in self.entities])
-		all=''.join([header,tables,blocks,entities,'  0\nEOF\n'])
-		return all
-		
-	def _write_section(self,file,name,data):
-		file.write('  0\nSECTION\n  2\n%s\n'%name.upper())
-		for x in data:
-			file.write(str(x))
-		file.write('  0\nENDSEC\n')
-
-	def saveas(self,fileName,buffer=0):
-		"""Writes DXF file. Needs target file name. If optional parameter buffer>0, then switch to old behavior: store entire output string in RAM.
-		"""
-		self.fileName=fileName
-		if buffer: self.save()
-		else: self.export()
-
-	def save(self):
-		outfile=open(self.fileName,'w')
-		outfile.write(str(self))
-		outfile.close()
-
-	def export(self):
-		outfile=open(self.fileName,'w')
-		header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
-		self._write_section(outfile,'header',header)
-		tables=[self._table('vport',[str(x) for x in self.vports]),
-			self._table('ltype',[str(x) for x in self.linetypes]),
-			self._table('layer',[str(x) for x in self.layers]),
-			self._table('style',[str(x) for x in self.styles]),
-			self._table('view',[str(x) for x in self.views]),
-			]
-		self._write_section(outfile,'tables',tables)
-		self._write_section(outfile,'blocks',self.blocks)
-		self._write_section(outfile,'entities',self.entities)
-		outfile.write('  0\nEOF\n')
-		outfile.close()
-
-
-#---extras
-#-----------------------------------------------
-class Rectangle(_Entity):
-	"""Rectangle, creates lines."""
-	def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
-		_Entity.__init__(self,**common)
-		self.point=point
-		self.width=width
-		self.height=height
-		self.solid=solid
-		self.line=line
-	def __str__(self):
-		result=''
-		points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
-			(self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
-			(self.point[0],self.point[1]+self.height,self.point[2]),self.point]
-		if self.solid:
-			result+= Solid(points=points[:-1],parent=self.solid)
-		if self.line:
-			for i in range(4):
-				result+= Line(points=[points[i],points[i+1]],parent=self)
-		return result[1:]
-
-#-----------------------------------------------
-class LineList(_Entity):
-	"""Like polyline, but built of individual lines."""
-	def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
-		_Entity.__init__(self,**common)
-		self.closed=closed
-		self.points=copy.copy(points)
-	def __str__(self):
-		if self.closed:
-			points=self.points+[self.points[0]]
-		else: points=self.points
-		result=''
-		for i in range(len(points)-1):
-			result+= Line(points=[points[i][0],points[i+1][0]],parent=self)
-		return result[1:]
-
-#-----------------------------------------------------
-def test():
-	#Blocks
-	b=Block('test')
-	b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
-	b.append(Arc(center=(1,0,0),color=2))
-
-	#Drawing
-	d=Drawing()
-	#tables
-	d.blocks.append(b)  #table blocks
-	d.styles.append(Style())  #table styles
-	d.views.append(View('Normal'))  #table view
-	d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1)))  #idem
-
-	#entities
-	d.append(Circle(center=(1,1,0),color=3))
-	d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
-	d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
-	d.append(Line(points=[(0,0,0),(1,1,1)]))
-	d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
-	d.append(Text('Please donate!',point=(3,0,1)))
-	#d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
-	d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
-	#d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
-
-	#d.saveas('c:\\test.dxf')
-	d.saveas('test.dxf')
-
-#-----------------------------------------------------
-if __name__=='__main__':
-	if not copy:
-		Draw.PupMenu('Error%t|This script requires a full python install')
-	else: test()
-	
diff --git a/release/scripts/addons_contrib/io_export_dxf/model/migiusModel.py b/release/scripts/addons_contrib/io_export_dxf/model/migiusModel.py
deleted file mode 100644
index bfdba96..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/model/migiusModel.py
+++ /dev/null
@@ -1,122 +0,0 @@
-'''
-Created on Sep 2, 2011
-
- at author: vencax
-'''
-
-from .model import DxfDrawing
-
-try:
-    from . import dxfLibrary as DXF
-    #reload(DXF)
-    #reload(dxfLibrary)
-    #from dxfLibrary import *
-except Exception:
-    raise Exception("No dxfLibrary.py module in Blender script folder found!")
-        
-#------------------------------------------------------
-#def col2RGB(color):
-#    return [int(floor(255*color[0])),
-#            int(floor(255*color[1])),
-#            int(floor(255*color[2]))]
-#
-#global dxfColors
-#dxfColors=None
-#
-##------------------------------------------------------
-#def col2DXF(rgbcolor):
-#    global dxfColors
-#    if dxfColors is None:
-#        from dxfColorMap import color_map
-#        dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
-#        dxfColors.sort()
-#    entry = (tuple(rgbcolor), -1)
-#    dxfColors.append(entry)
-#    dxfColors.sort()
-#    i = dxfColors.index(entry)
-#    dxfColors.pop(i)
-#    return dxfColors[i-1][1]
-
-"""
-v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
-28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,\
-123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,\
-151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,\
-171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,\
-191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,\
-211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,\
-231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
-invalid = ''.join([chr(i) for i in v])
-del v, i
-"""
-#TODO: validDXFr14 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.'
-validDXFr12 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
-NAMELENGTH_MAX = 80   #max_obnamelength in DXF, (limited to 256? )
-#------------------------------------------------------
-def cleanName(name, valid):
-    validname = ''
-    for ch in name:
-        if ch not in valid:    ch = '_'
-        validname += ch
-    return validname
-
-#------------------------------------------------------
-def validDXFr12name(str_name):
-    dxfname = str(str_name)
-    dxfname = dxfname[:NAMELENGTH_MAX].upper()
-    dxfname = cleanName(dxfname, validDXFr12)
-    return dxfname
-
-class MigiusDXFLibDrawing(DxfDrawing):
-    """ Drawing that can convert itself into MIGIUS DXFLib stuff objects """
-
-    def convert(self, file, **kwargs):
-        drawing = self._write()
-        for type, ents in self._entities.items():
-            self._processEntityArray(drawing, type, ents)
-        for v in self._views:
-            drawing.views.append(DXF.View(**v))
-        for v in self._vports:
-            drawing.vports.append(DXF.VPort(**v))
-#        for l in self._layers:
-        drawing.saveas(file)
-
-    def _write(self):        
-        # init Drawing ---------------------
-        d=DXF.Drawing()
-        # add Tables -----------------
-        # initialized automatic: d.blocks.append(b)                 #section BLOCKS
-        # initialized automatic: d.styles.append(DXF.Style())            #table STYLE
-    
-        #table LTYPE ---------------
-        #d.linetypes.append(DXF.LineType(name='CONTINUOUS',description='--------',elements=[0.0]))
-        d.linetypes.append(DXF.LineType(name='DOT',description='. . . . . . .',elements=[0.25, 0.0, -0.25]))
-        d.linetypes.append(DXF.LineType(name='DASHED',description='__ __ __ __ __',elements=[0.8, 0.5, -0.3]))
-        d.linetypes.append(DXF.LineType(name='DASHDOT',description='__ . __ . __ .',elements=[1.0, 0.5, -0.25, 0.0, -0.25]))
-        d.linetypes.append(DXF.LineType(name='DIVIDE',description='____ . . ____ . . ',elements=[1.25, 0.5, -0.25, 0.0, -0.25, 0.0, -0.25]))
-        d.linetypes.append(DXF.LineType(name='BORDER',description='__ __ . __ __ . ',elements=[1.75, 0.5, -0.25, 0.5, -0.25, 0.0, -0.25]))
-        d.linetypes.append(DXF.LineType(name='HIDDEN',description='__ __ __ __ __',elements=[0.4, 0.25, -0.25]))
-        d.linetypes.append(DXF.LineType(name='CENTER',description='____ _ ____ _ __',elements=[2.0, 1.25, -0.25, 0.25, -0.25]))
-    
-        #d.vports.append(DXF.VPort('*ACTIVE'))
-        d.vports.append(DXF.VPort('*ACTIVE',center=(-5.0,1.0),height=10.0))
-        #d.vports.append(DXF.VPort('*ACTIVE',leftBottom=(-100.0,-60.0),rightTop=(100.0,60.0)))
-        #d.views.append(DXF.View('Normal'))      #table view
-        d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60)))  #idem
-        
-        return d
-
-    def _processEntityArray(self, drawing, type, ents):
-        if type=='Point':
-            for e in ents:
-                drawing.append(DXF.Point(**e))
-        elif type=='Line':
-            for e in ents:
-                drawing.append(DXF.Line(**e))
-        elif type=='PolyLine':
-            for e in ents:
-                drawing.append(DXF.PolyLine(**e))
-        elif type=='Face':
-            for e in ents:
-                drawing.append(DXF.Face(**e))
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/model/model.py b/release/scripts/addons_contrib/io_export_dxf/model/model.py
deleted file mode 100644
index bff3733..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/model/model.py
+++ /dev/null
@@ -1,38 +0,0 @@
-
-class DxfDrawing(object):
-	"""
-	Represents intermediate model of DXF drawing. It is useful in iterating
-	through exported object and for easy change the DXF handling library.
-	"""
-	def __init__(self):
-		self._entities = {}
-		self._layers = {}
-		self._views = []
-		self._vports = []
-		self._blocks = []
-		
-	def isEmpty(self):
-		return len(self._entities) == 0
-
-	def addEntity(self, type, **kwargs):
-		if type not in self._entities:
-			self._entities[type] = []
-		self._entities[type].append(kwargs)
-
-	def addLayer(self, name, color):
-		self._layers[name] = color
-
-	def containsLayer(self, name):
-		return name in self._layers
-
-	def addBlock(self, block):
-		self._blocks.append(block)
-
-	def containsBlock(self, blockname):
-		return blockname in self._blocks
-
-	def convert(self, **kwargs):
-		""" Converts this drawing into DXF representation object """
-		raise NotImplementedError()
-	
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/operator.py b/release/scripts/addons_contrib/io_export_dxf/operator.py
deleted file mode 100644
index bf07e9e..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/operator.py
+++ /dev/null
@@ -1,283 +0,0 @@
-
-
-import bpy
-from bpy.props import StringProperty, EnumProperty, BoolProperty
-
-class DXFExporter(bpy.types.Operator):
-    """
-    Export to the Autocad model format (.dxf)
-    """
-    bl_idname = "export.dxf"
-    bl_label = "Export DXF"
-    filepath = StringProperty(subtype='FILE_PATH')
-
-    entitylayer_from_items = (
-        ('default_LAYER', 'Default Layer', ''),
-        ('obj.name', 'Object name', ''),
-        ('obj.layer', 'Object layer', ''),
-        ('obj.material', 'Object material', ''),
-        ('obj.data.name', 'Object\' data name', ''),
-#        ('obj.data.material', 'Material of data', ''),
-        ('..vertexgroup', 'Vertex Group', ''),
-        ('..group', 'Group', ''),
-        ('..map_table', 'Table', '')
-    )
-    layerColorFromItems = (
-        ('default_COLOR', 'Vertex Group', ''),
-        ('BYLAYER', 'BYLAYER', ''),
-        ('BYBLOCK', 'BYBLOCK', ''),
-        ('obj.layer', 'Object Layer', ''),
-        ('obj.color', 'Object Color', ''),
-        ('obj.material', 'Object material', ''),
-        # I don'd know ?
-#        ('obj.data.material', 'Vertex Group', ''),
-#        ('..map_table', 'Vertex Group', ''),
-    )
-    layerNameFromItems = (
-        ('LAYERNAME_DEF', 'Default Name', ''),
-        ('drawing_name', 'From Drawing name', ''),
-        ('scene_name', 'From scene name', '')
-    )
-
-    exportModeItems = (
-        ('ALL', 'All Objects', ''),
-        ('SELECTION', 'Selected Objects', ''),
-    )
-#    spaceItems = (
-#        ('1', 'Paper-Space', ''),
-#        ('2', 'Model-Space', '')
-#    )
-
-    entityltype_fromItems = (
-        ('default_LTYPE', 'default_LTYPE', ''),
-        ('BYLAYER', 'BYLAYER', ''),
-        ('BYBLOCK', 'BYBLOCK', ''),
-        ('CONTINUOUS', 'CONTINUOUS', ''),
-        ('DOT', 'DOT', ''),
-        ('DASHED', 'DASHED', ''),
-        ('DASHDOT', 'DASHDOT', ''),
-        ('BORDER', 'BORDER', ''),
-        ('HIDDEN', 'HIDDEN', '')
-    )
-    material_toItems = (
-        ('NO', 'Do not export', ''),
-        ('COLOR', 'COLOR', ''),
-        ('LAYER', 'LAYER', ''),
-        ('..LINESTYLE', '..LINESTYLE', ''),
-        ('..BLOCK', '..BLOCK', ''),
-        ('..XDATA', '..XDATA', ''),
-        ('..INI-File', '..INI-File', '')
-    )    
-    projectionItems=(
-        ('NO', 'No projection', 'Export 3D scene without any 2D projection'),
-        ('TOP', 'TOP view', 'Use TOP view for projection'),
-        ('BOTTOM', 'BOTTOM view', 'Use BOTTOM view for projection'),
-        ('LEFT', 'LEFT view', 'Use LEFT view for projection'),
-        ('RIGHT', 'RIGHT view', 'Use RIGHT view for projection'),
-        ('FRONT', 'FRONT view', 'Use FRONT view for projection'),
-        ('REAR', 'REAR view', 'Use REAR view for projection')
-    )
-    mesh_asItems = (
-        ('NO', 'Do not export', ''),
-        ('3DFACEs', '3DFACEs', ''),
-        ('POLYFACE', 'POLYFACE', ''),
-        ('POLYLINE', 'POLYLINE', ''),
-        ('LINEs', 'LINEs', 'export Mesh as multiple LINEs'),
-        ('POINTs', 'POINTs', 'Export Mesh as multiple POINTs')
-    )
-#    curve_asItems  = (
-#        ('NO', 'Do not export', ''),
-#        ('LINEs', 'LINEs', ''),
-#        ('POLYLINE', 'POLYLINE', ''),
-#        ('..LWPOLYLINE r14', '..LWPOLYLINE r14', ''),
-#        ('..SPLINE r14', '..SPLINE r14', ''),
-#        ('POINTs', 'POINTs',  '')
-#    )
-#    surface_asItems  = (
-#        ('NO', 'Do not export', ''),
-#        ('..3DFACEs', '..3DFACEs', ''),
-#        ('..POLYFACE', '..POLYFACE', ''),
-#        ('..POINTs', '..POINTs', ''),
-#        ('..NURBS', '..NURBS', '')
-#    )
-#    meta_asItems  = (
-#        ('NO', 'Do not export', ''),
-#        ('..3DFACEs', '..3DFACEs', ''),
-#        ('..POLYFACE', '..POLYFACE', ''),
-#        ('..3DSOLID', '..3DSOLID', '')
-#    )
-#    text_asItems  = (
-#        ('NO', 'Do not export', ''),
-#        ('TEXT', 'TEXT', ''),
-#        ('..MTEXT', '..MTEXT', ''),
-#        ('..ATTRIBUT', '..ATTRIBUT', '')
-#    )
-#    empty_asItems  = (
-#        ('NO', 'Do not export', ''),
-#        ('POINT', 'POINT', ''),
-#        ('..INSERT', '..INSERT', ''),
-#        ('..XREF', '..XREF', '')
-#    )
-#    group_asItems  = (
-#        ('NO', 'Do not export', ''),
-#        ('..GROUP', '..GROUP', ''),
-#        ('..BLOCK', '..BLOCK', ''),
-#        ('..ungroup', '..ungroup', '')
-#    )
-##    parent_asItems = ['..BLOCK','..ungroup'] # ???
-#    proxy_asItems = (
-#        ('NO', 'Do not export', ''),
-#        ('..BLOCK','..BLOCK', ''),
-#        ('..XREF', '..XREF', ''),
-#        ('..ungroup', '..ungroup', ''),
-#        ('..POINT', '..POINT', '')
-#    )
-#    camera_asItems = (
-#        ('NO', 'Do not export', ''),
-#        ('..BLOCK', '..BLOCK', ''),
-#        ('..A_CAMERA', '..A_CAMERA', ''),
-#        ('VPORT', 'VPORT', ''),
-#        ('VIEW', 'VIEW', ''),
-#        ('POINT', 'POINT', '')
-#    )
-#    lamp_asItems = (
-#        ('NO', 'Do not export', ''),
-#        ('..BLOCK', '..BLOCK', ''),
-#        ('..A_LAMP', '..A_LAMP', ''),
-#        ('POINT', 'POINT', '')
-#    )
-    # --------- CONTROL PROPERTIES --------------------------------------------
-    projectionThrough = EnumProperty(name="Projection", default="NO",
-                                    description="Select camera for use to 2D projection",
-                                    items=projectionItems)
-    
-    onlySelected = BoolProperty(name="Only selected", default=True,
-                              description="What object will be exported? Only selected / all objects.")
-    
-    apply_modifiers = BoolProperty(name="Apply modifiers", default=True,
-                           description="Shall be modifiers applied during export?")
-    # GUI_B -----------------------------------------
-    mesh_as = EnumProperty( name="Export Mesh As", default='3DFACEs',
-                            description="Select representation of a mesh",
-                            items=mesh_asItems)
-#    curve_as = EnumProperty( name="Export Curve As:", default='NO',
-#                            description="Select representation of a curve",
-#                            items=curve_asItems)
-#    surface_as = EnumProperty( name="Export Surface As:", default='NO',
-#                            description="Select representation of a surface",
-#                            items=surface_asItems)
-#    meta_as = EnumProperty( name="Export meta As:", default='NO',
-#                            description="Select representation of a meta",
-#                            items=meta_asItems)
-#    text_as = EnumProperty( name="Export text As:", default='NO',
-#                            description="Select representation of a text",
-#                            items=text_asItems)
-#    empty_as = EnumProperty( name="Export empty As:", default='NO',
-#                            description="Select representation of a empty",
-#                            items=empty_asItems)
-#    group_as = EnumProperty( name="Export group As:", default='NO',
-#                            description="Select representation of a group",
-#                            items=group_asItems)
-##    parent_as = EnumProperty( name="Export parent As:", default='NO',
-##                            description="Select representation of a parent",
-##                            items=parent_asItems)
-#    proxy_as = EnumProperty( name="Export proxy As:", default='NO',
-#                            description="Select representation of a proxy",
-#                            items=proxy_asItems)
-#    camera_as = EnumProperty( name="Export camera As:", default='NO',
-#                            description="Select representation of a camera",
-#                            items=camera_asItems)
-#    lamp_as = EnumProperty( name="Export lamp As:", default='NO',
-#                            description="Select representation of a lamp",
-#                            items=lamp_asItems)
-    # ----------------------------------------------------------
-    entitylayer_from = EnumProperty(name="Entity Layer", default="obj.data.name",
-                                    description="Entity LAYER assigned to?",
-                                    items=entitylayer_from_items)
-    entitycolor_from = EnumProperty(name="Entity Color", default="default_COLOR",
-                                    description="Entity COLOR assigned to?",
-                                    items=layerColorFromItems)
-    entityltype_from = EnumProperty(name="Entity Linetype", default="CONTINUOUS",
-                                    description="Entity LINETYPE assigned to?",
-                                    items=entityltype_fromItems)
-
-    layerName_from = EnumProperty(name="Layer Name", default="LAYERNAME_DEF",
-                                    description="From where will layer name be taken?",
-                                    items=layerNameFromItems)
-    # GUI_A -----------------------------------------
-#    layFrozen_on = BoolProperty(name="LAYER.frozen status", description="(*todo) Support LAYER.frozen status   on/off", default=False)
-#    materialFilter_on = BoolProperty(name="Material filtering", description="(*todo) Material filtering   on/off", default=False)
-#    colorFilter_on = BoolProperty(name="Color filtering", description="(*todo) Color filtering   on/off", default=False)
-#    groupFilter_on = BoolProperty(name="Group filtering", description="(*todo) Group filtering   on/off", default=False)
-#    objectFilter_on = BoolProperty(name="Object filtering", description="(*todo) Object filtering   on/off", default=False)
-#    paper_space_on = EnumProperty(name="Space of export:", default="2",
-#                                    description="Select space that will be taken for export.",
-#                                    items=spaceItems)
-#    material_to = EnumProperty(name="Material assigned to?:", default="NO",
-#                                    description="Material assigned to?.",
-#                                    items=material_toItems)
-
-#    prefix_def = StringProperty(name="Prefix for LAYERs", default="DX_",
-#                                    description='Type Prefix for LAYERs')
-#    layername_def = StringProperty(name="default LAYER name", default="DEF_LAY",
-#                                    description='Type default LAYER name')
-#    layercolor_def = StringProperty(name="Default layer color:", default="1",
-#                                    description='Set default COLOR. (0=BYBLOCK,256=BYLAYER)')
-#    layerltype_def = StringProperty(name="Default LINETYPE", default="DEF_LAY_TYPE",
-#                                    description='Set default LINETYPE')
-    
-    verbose = BoolProperty(name="Verbose", default=False,
-                           description="Run the exporter in debug mode.  Check the console for output.")
-
-    def execute(self, context):
-        filePath = bpy.path.ensure_ext(self.filepath, ".dxf")
-        config = {
-            'projectionThrough' : self._checkNO(self.projectionThrough),
-            'onlySelected' : self.onlySelected,
-            'apply_modifiers' : self.apply_modifiers,
-            # GUI B
-            'mesh_as' : self._checkNO(self.mesh_as),
-#            'curve_as' : self._checkNO(self.curve_as),
-#            'surface_as' : self._checkNO(self.surface_as),
-#            'meta_as' : self._checkNO(self.meta_as),
-#            'text_as' : self._checkNO(self.text_as),
-#            'empty_as' : self._checkNO(self.empty_as),
-#            'group_as' : self._checkNO(self.group_as),
-#            'proxy_as' : self._checkNO(self.proxy_as),
-#            'camera_as' : self._checkNO(self.camera_as),
-#            'lamp_as' : self._checkNO(self.lamp_as),
-
-            'entitylayer_from' : self.entitylayer_from,
-            'entitycolor_from' : self.entitycolor_from,
-            'entityltype_from' : self.entityltype_from,      
-            'layerName_from' : self.layerName_from,
-            
-            # NOT USED
-#            'layFrozen_on' : self.layFrozen_on,
-#            'materialFilter_on' : self.materialFilter_on,
-#            'colorFilter_on' : self.colorFilter_on,
-#            'groupFilter_on' : self.groupFilter_on,
-#            'objectFilter_on' : self.objectFilter_on,
-#            'paper_space_on' : self.paper_space_on,
-#            'layercolor_def' : self.layercolor_def,
-#            'material_to' : self.material_to,
-
-            'verbose' : self.verbose
-        }
-
-        from .export_dxf import exportDXF
-        exportDXF(context, filePath, config)
-        return {"FINISHED"}
-
-    def _checkNO(self, val):
-        if val == 'NO': return None
-        else: return val
-
-    def invoke(self, context, event):
-        if not self.filepath:
-            self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".dxf")
-        WindowManager = context.window_manager
-        WindowManager.fileselect_add(self)
-        return {"RUNNING_MODAL"}
-
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/__init__.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/__init__.py
deleted file mode 100644
index 8e49ba0..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
-This package contains actual primitive exporter classes.
-They are imported and instantiated according object type
-that is being exported from export_dxf.py in ../
-
-NOTE: Only MESH exporter has been ported since it is imho
-mostly used. I am not specialist on Autocad so I cannot
-guest how many time the other primitive are used. That's
-why they are left unported. 
-"""
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/base_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/base_exporter.py
deleted file mode 100644
index b85dc12..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/base_exporter.py
+++ /dev/null
@@ -1,195 +0,0 @@
-import mathutils
-
-class BasePrimitiveDXFExporter(object):
-    
-    INSTANCES = False
-    PROJECTION = False
-    HIDDEN_LINES = False
-    
-    def __init__(self, settings):
-        self._settings = settings
-    
-    def projected_co(self, verts, matrix):
-        """ converts coordinates of points from OCS to WCS->ScreenCS
-        needs matrix: a projection matrix
-        needs verts: a list of vectors[x,y,z]
-        returns a list of [x,y,z]
-        """
-        #print 'deb:projected_co()  verts=', verts #---------
-        temp_verts = [matrix*mathutils.Vector(v) for v in verts]
-        #print 'deb:projected_co()  temp_verts=', temp_verts #---------
-    
-    #    if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val
-    #    else:locZ = 0.0
-        locZ = 0.0
-    
-        if self.PROJECTION:
-            if self.PERSPECTIVE:
-                clipStart = 10.0
-                for v in temp_verts:
-                    coef = - clipStart / v[2]
-                    v[0] *= coef
-                    v[1] *= coef
-                    v[2] = locZ
-            for v in temp_verts:
-                v[2] = locZ
-        temp_verts = [v[:3] for v in temp_verts]
-        #print 'deb:projected_co()  out_verts=', temp_verts #---------
-        return temp_verts
-    
-    def isLeftHand(self, matrix):
-        #Is the matrix a left-hand-system, or not?
-        ma = matrix.to_euler().to_matrix()
-        crossXY = self.M_CrossVecs(ma[0], ma[1])
-        check = self.M_DotVecs(ma[2], crossXY)
-        if check < 0.00001: return 1
-        return 0
-    
-    #-----------------------------------------------------
-    def hidden_status(self, faces, mx, mx_n):
-        # sort out back-faces = with normals pointed away from camera
-        #print 'HIDDEN_LINES: caution! not full implemented yet'
-        front_faces = []
-        front_edges = []
-        for f in faces:
-            #print 'deb: face=', f #---------
-            #print 'deb: dir(face)=', dir(f) #---------
-            # get its normal-vector in localCS
-            vec_normal = f.no.copy()
-            #print 'deb: vec_normal=', vec_normal #------------------
-            # must be transfered to camera/view-CS
-            vec_normal *= mx_n
-            #vec_normal *= mb.rotationPart()
-            #print 'deb:2vec_normal=', vec_normal #------------------
-            #vec_normal *= mw0.rotationPart()
-            #print 'deb:3vec_normal=', vec_normal, '\n' #------------------
-    
-            
-            frontFace = False
-            if not self.PERSPECTIVE: #for ortho mode ----------
-                # normal must point the Z direction-hemisphere
-                if vec_normal[2] > 0.00001:
-                    frontFace = True
-            else:
-                v = f.verts[0]
-                vert = mathutils.Vector(v.co) * mx
-                if mathutils.DotVecs(vert, vec_normal) < 0.00001:
-                    frontFace = True
-    
-            if frontFace:
-                front_faces.append(f.index)
-                for key in f.edge_keys:
-                    #this test can be done faster with set()
-                    if key not in front_edges:
-                        front_edges.append(key)
-    
-        #print 'deb: amount of visible faces=', len(front_faces) #---------
-        #print 'deb: visible faces=', front_faces #---------
-        #print 'deb: amount of visible edges=', len(front_edges) #---------
-        #print 'deb: visible edges=', front_edges #---------
-        return front_faces, front_edges
-
-    #-----------------------------------------------------
-    def toGlobalOrigin(self, points):
-        """relocates points to the new location
-        needs a list of points [x,y,z]
-        """
-    #    if GUI_A['g_origin_on'].val:
-    #        for p in points:
-    #            p[0] += G_ORIGIN[0]
-    #            p[1] += G_ORIGIN[1]
-    #            p[2] += G_ORIGIN[2]
-        return points
-    
-    #---- migration to 2.49-------------------------------------------------
-
-    #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!')
-    def M_CrossVecs(self, v1,v2):
-        if 'cross' in dir(mathutils.Vector()):
-            return v1.cross(v2) #for up2.49
-        else:
-            return mathutils.CrossVecs(v1,v2) #for pre2.49
-        
-    def M_DotVecs(self, v1,v2):
-        if 'cross' in dir(mathutils.Vector()):
-            return v1.dot(v2) #for up2.49
-        else:
-            return mathutils.DotVecs(v1,v2) #for pre2.49    
-
-#-----------------------------------------------------
-    def getExtrusion(self, matrix):
-        """ calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors """
-        AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector
-        Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]]
-        if AZaxis[2]==1.0:
-            Extrusion = None
-            AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
-        else:
-            threshold = 1.0 / 64.0
-            if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold:
-                # AXaxis is the intersection WorldPlane and ExtrusionPlane
-                AXaxis = self.M_CrossVecs(WORLDY,AZaxis)
-            else:
-                AXaxis = self.M_CrossVecs(WORLDZ,AZaxis)
-        #print 'deb:\n' #-------------
-        #print 'deb:getExtrusion()  Extrusion=', Extrusion #---------
-        return Extrusion, AXaxis.normalize()
-    
-    #-----------------------------------------------------
-#    def getZRotation(AXaxis, rot_matrix_invert):
-#        """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis
-#    
-#        """
-#        # this works: Xaxis is the obj.matrix-Xaxis vector
-#        # but not correct for all orientations
-#        #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
-#        ##Xaxis.normalize() # = ArbitraryXvector
-#        #ZRotation = - mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians
-#    
-#        # this works for all orientations, maybe a bit faster
-#        # transform AXaxis into OCS:Object-Coord-System
-#        #rot_matrix = normalizeMat(matrix.rotationPart())
-#        #rot_matrix_invert = rot_matrix.invert()
-#        vec = AXaxis * rot_matrix_invert
-#        ##vec = AXaxis * matrix.copy().invert()
-#        ##vec.normalize() # not needed for atan2()
-#        #print '\ndeb:getExtrusion()  vec=', vec #---------
-#        ZRotation = - atan2(vec[1],vec[0]) #output in radians
-#    
-#        #print 'deb:ZRotation()  ZRotation=', ZRotation*r2d #---------
-#        return ZRotation
-#    
-#    
-#    #-----------------------------------------------------
-#    def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ):
-#        """given
-#        """
-#        if 1:
-#            rot_matrix = normalizeMat(mx.to_euler().to_matrix())
-#            #TODO: workaround for blender negative-matrix.invert()
-#            # partially done: works only for rotX,rotY==0.0
-#            if sizeX<0.0: rot_matrix[0] *= -1
-#            if sizeY<0.0: rot_matrix[1] *= -1
-#            #if sizeZ<0.0: rot_matrix[2] *= -1
-#            rot_matrix_invert = rot_matrix.invert()
-#        else: #TODO: to check, why below rot_matrix_invert is not equal above one
-#            rot_euler_matrix = euler2matrix(rotX,rotY,rotZ)
-#            rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ)
-#    
-#        # OCS_origin is Global_Origin in ObjectCoordSystem
-#        OCS_origin = mathutils.Vector(WCS_loc) * rot_matrix_invert
-#        #print 'deb: OCS_origin=', OCS_origin #---------
-#    
-#        ZRotation = rotZ
-#        if Extrusion!=None:
-#            ZRotation = getZRotation(AXaxis,rot_matrix_invert)
-#        #Zrotmatrix = mathutils.RotationMatrix(-ZRotation, 3, "Z")
-#        rs, rc = sin(ZRotation), cos(ZRotation)
-#        Zrotmatrix = mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0])
-#        #print 'deb: Zrotmatrix=\n', Zrotmatrix #--------------
-#    
-#        # ECS_origin is Global_Origin in EntityCoordSystem
-#        ECS_origin = OCS_origin * Zrotmatrix
-#        #print 'deb: ECS_origin=', ECS_origin #---------
-#        #TODO: it doesnt work yet for negative scaled curve-objects!
-#        return ZRotation,Zrotmatrix,OCS_origin,ECS_origin
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/camera_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/camera_exporter.py
deleted file mode 100644
index e31166e..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/camera_exporter.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from .base_exporter import BasePrimitiveDXFExporter
-
-
-class CameraDXFExporter(BasePrimitiveDXFExporter):
-    pass
-
-
-#-----------------------------------------------------
-def exportCamera(ob, mx, mw, **common):
-    """converts Camera-Object to desired projection and representation(DXF-Entity type)
-    """
-    location =  mathutils.Vector(ob.loc)
-    [location] = projected_co([location], mx)
-    [location] = toGlobalOrigin([location])
-    view_name=validDXFr12name(('CAM_'+ ob.name))
-
-    camera = Camera.Get(ob.getData(name_only=True))
-    #print 'deb: camera=', dir(camera) #------------------
-    if camera.type=='persp':
-        mode = 1+2+4+16
-        # mode flags: 1=persp, 2=frontclip, 4=backclip,16=FrontZ
-    elif camera.type=='ortho':
-        mode = 0+2+4+16
-
-    leftBottom=(0.0,0.0) # default
-    rightTop=(1.0,1.0) # default
-    center=(0.0,0.0) # default
-
-    direction = mathutils.Vector(0.0,0.0,1.0) * mx.to_euler().to_matrix() # in W-C-S
-    direction.normalize()
-    target=mathutils.Vector(ob.loc) - direction # in W-C-S
-    #ratio=1.0
-    width=height= camera.scale # for ortho-camera
-    lens = camera.lens # for persp-camera
-    frontClipping = -(camera.clipStart - 1.0)
-    backClipping = -(camera.clipEnd - 1.0)
-
-    entities, vport, view = [], None, None
-    c = camera_as_list[GUI_A['camera_as'].val]
-    if c=="POINT": # export as POINT
-        dxfPOINT = DXF.Point(points=[location],**common)
-        entities.append(dxfPOINT)
-    elif c=="VIEW": # export as VIEW
-        view = DXF.View(name=view_name,
-            center=center, width=width, height=height,
-            frontClipping=frontClipping,backClipping=backClipping,
-            direction=direction,target=target,lens=lens,mode=mode
-            )
-    elif c=="VPORT": # export as VPORT
-        vport = DXF.VPort(name=view_name,
-            center=center, ratio=1.0, height=height,
-            frontClipping=frontClipping,backClipping=backClipping,
-            direction=direction,target=target,lens=lens,mode=mode
-            )
-    return entities, vport, view
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/curve_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/curve_exporter.py
deleted file mode 100644
index d74a459..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/curve_exporter.py
+++ /dev/null
@@ -1,260 +0,0 @@
-from .base_exporter import BasePrimitiveDXFExporter
-
-
-class CurveDXFExporter(BasePrimitiveDXFExporter):
-    pass
-
-#-----------------------------------------------------
-def exportCurve(ob, mx, mw, **common):
-    """converts Curve-Object to desired projection and representation(DXF-Entity type)
-    """
-    entities = []
-    block = None
-    curve = ob.getData()
-    #print 'deb: curve=', dir(curve) #---------
-    # TODO: should be: if curve.users>1 and not (PERSPECTIVE or (PROJECTION and HIDDEN_MODE):
-    if INSTANCES and curve.users>1 and not PROJECTION:
-        if curve.name in BLOCKREGISTRY.keys():
-            insert_name = BLOCKREGISTRY[curve.name]
-            # write INSERT to entities
-            entities = exportInsert(ob, mx,insert_name, **common)
-        else:
-            # generate geom_output in ObjectCS
-            imx = mathutils.Matrix().identity()
-            WCS_loc = [0,0,0] # WCS_loc is object location in WorldCoordSystem
-            #print 'deb: WCS_loc=', WCS_loc #---------
-            sizeX = sizeY = sizeZ = 1.0
-            rotX  = rotY  = rotZ = 0.0
-            Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
-            ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
-            AXaxis = imx[0].copy().resize3D() # = ArbitraryXvector
-            OCS_origin = [0,0,0]
-            if not PROJECTION:
-                #Extrusion, ZRotation, Elevation = getExtrusion(mx)
-                Extrusion, AXaxis = getExtrusion(imx)
-        
-                # no thickness/width for POLYLINEs converted into Screen-C-S
-                #print 'deb: curve.ext1=', curve.ext1 #---------
-                if curve.ext1: Thickness = curve.ext1 * sizeZ
-                if curve.ext2 and sizeX==sizeY:
-                    Width = curve.ext2 * sizeX
-                if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
-                    ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(imx,Extrusion,\
-                        AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
-
-            entities = writeCurveEntities(curve, imx,
-                Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
-                WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
-                **common)
-
-            if entities: # if not empty block
-                # write BLOCK definition and INSERT entity
-                # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
-                BLOCKREGISTRY[curve.name]=validDXFr12name(('CU_'+ curve.name))
-                insert_name = BLOCKREGISTRY[curve.name]
-                block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
-                # write INSERT as entity
-                entities = exportInsert(ob, mx, insert_name, **common)
-
-    else: # no other instances, so go the standard way
-        WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
-        #print 'deb: WCS_loc=', WCS_loc #---------
-        sizeX = ob.SizeX
-        sizeY = ob.SizeY
-        sizeZ = ob.SizeZ
-        rotX  = ob.RotX
-        rotY  = ob.RotY
-        rotZ  = ob.RotZ
-        #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
-    
-        Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
-        ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
-        AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
-        OCS_origin = [0,0,0]
-        if not PROJECTION:
-            #Extrusion, ZRotation, Elevation = getExtrusion(mx)
-            Extrusion, AXaxis = getExtrusion(mx)
-    
-            # no thickness/width for POLYLINEs converted into Screen-C-S
-            #print 'deb: curve.ext1=', curve.ext1 #---------
-            if curve.ext1: Thickness = curve.ext1 * sizeZ
-            if curve.ext2 and sizeX==sizeY:
-                Width = curve.ext2 * sizeX
-            if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
-                ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
-                    AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
-        entities = writeCurveEntities(curve, mx,
-                Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
-                WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
-                **common)
-
-    return entities, block
-
-
-#-------------------------------------------------
-def writeCurveEntities(curve, mx,
-        Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
-        WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
-        **common):
-    """help routine for exportCurve()
-    """
-    entities = []
-    width1,width2 = None, None
-    if 1:
-        for cur in curve:
-            #print 'deb: START cur=', cur #--------------
-            #print 'deb:  dir(curve):',dir(cur)  #---------
-            #print 'deb:  curve.type:',cur.type  #---------
-            points = []
-            flags = []
-            pflag70, pflag75 = 0,0
-
-            if cur.type==4: # is NURBS
-                #if cur.isNurb():
-                #print 'deb:isNurb --------------'  #---------
-                pflag70 = 4
-                orderU = cur.orderU
-                # curve type:
-                # 0: curvNoFitted
-                # 5: curvQuadraticBspline
-                # 6: curvCubicBspline
-                # 8: curvBezier
-                if orderU<=4: pflag75 = 5
-                elif orderU>=5: pflag75 = 6
-
-                vflag70 = 16
-                i = -2
-                for point in cur:
-                    #print 'deb:isNurb point=', point #---------
-                    i+=1
-                    if i==orderU-1: i = 0
-                    if i:
-                        flags.append([16, [width1,width2]])
-                    else:
-                        flags.append([8, [width1,width2]])
-                    vec = point[0:3]
-                    #print 'deb: vec=', vec #---------
-                    pkt = mathutils.Vector(vec)
-                    #print 'deb: pkt=', pkt #---------
-                    points.append(pkt)
-                if not cur.isCyclic():
-                    points = points[1:-1]
-                    flags = flags[1:-1]
-            elif cur.type==1: # is Bezier
-                #print 'deb:isBezier --------------'  #---------
-                pflag75 = 8
-                vflag70 = 1
-                for point in cur:
-                    #print 'deb:isBezier point=', point #---------
-                    #print 'deb:isBezier point=', point.getTriple() #---------
-                    ptan1,pfit,ptan2 = point.getTriple()
-                    #print 'deb: point=', pt #---------
-                    ptan1 = mathutils.Vector(ptan1)
-                    pfit = mathutils.Vector(pfit)
-                    ptan2 = mathutils.Vector(ptan2)
-                    #print 'deb: pkt=', pkt #---------
-                    points.append(ptan1)
-                    flags.append([2, [width1,width2]])
-                    points.append(pfit)
-                    flags.append([1, [width1,width2]])
-                    points.append(ptan2)
-                    flags.append([2, [width1,width2]])
-                if not cur.isCyclic():
-                    points = points[1:-1]
-                    flags = flags[1:-1]
-            elif cur.type==0: # is Polygon
-                #print 'deb:isPolygon --------------'  #---------
-                #pflag70 = 4
-                pflag75 = 0
-                for point in cur:
-                    #print 'deb:isPoly point=', point #---------
-                    vec = point[0:3]
-                    #print 'deb: vec=', vec #---------
-                    pkt = mathutils.Vector(vec)
-                    #print 'deb: pkt=', pkt #---------
-                    points.append(pkt)
-                    flags.append([None, [width1,width2]])
-    
-            #print 'deb: points', points #--------------
-            if len(points)>1:
-                c = curve_as_list[GUI_A['curve_as'].val]
-
-                if c=="POLYLINE": # export Curve as POLYLINE
-                    if not PROJECTION:
-                        # recalculate points(2d=X,Y) into Entity-Coords-System
-                        for p in points: # list of vectors
-                            p[0] *= sizeX
-                            p[1] *= sizeY
-                            p2 = p * Zrotmatrix
-                            p2[0] += ECS_origin[0]
-                            p2[1] += ECS_origin[1]
-                            p[0],p[1] = p2[0],p2[1]
-                    else:
-                        points = projected_co(points, mx)
-                    #print 'deb: points', points #--------------
-    
-                    if cur.isCyclic(): closed = 1
-                    else: closed = 0
-                    points = toGlobalOrigin(points)
-                    points_temp = []
-                    for p,f in zip(points,flags):
-                        points_temp.append([p,f[0],f[1]])    
-                    points = points_temp
-                    #print 'deb: points', points #--------------
-
-                    if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
-
-                    common['extrusion']= Extrusion
-                    ##common['rotation']= ZRotation
-                    ##common['elevation']= Elevation
-                    common['thickness']= Thickness
-                    #print 'deb: common=', common #------------------
-    
-                    flag70, flag75 = pflag70+closed, pflag75
-                    if 0: #DEBUG
-                        p=AXaxis[:3]
-                        entities.append(DXF.Line([[0,0,0], p],**common))
-                        p=ECS_origin[:3]
-                        entities.append(DXF.Line([[0,0,0], p],**common))
-                        common['color']= 5
-                        p=OCS_origin[:3]
-                        entities.append(DXF.Line([[0,0,0], p],**common))
-                        #OCS_origin=[0,0,0] #only debug----------------
-                        dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common)
-                        entities.append(dxfPLINE)
-    
-                    dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common)
-                    entities.append(dxfPLINE)
-                    if Thickness:
-                        common['thickness']= -Thickness
-                        dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common)
-                        entities.append(dxfPLINE)
-    
-                elif c=="LINEs": # export Curve as multiple LINEs
-                    points = projected_co(points, mx)
-                    if cur.isCyclic(): points.append(points[0])
-                    #print 'deb: points', points #--------------
-                    points = toGlobalOrigin(points)
-    
-                    if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
-                    common['extrusion']= Extrusion
-                    common['elevation']= Elevation
-                    common['thickness']= Thickness
-                    #print 'deb: common=', common #------------------
-                    for i in range(len(points)-1):
-                        linepoints = [points[i], points[i+1]]
-                        dxfLINE = DXF.Line(linepoints,**common)
-                        entities.append(dxfLINE)
-                    if Thickness:
-                        common['thickness']= -Thickness
-                        for i in range(len(points)-1):
-                            linepoints = [points[i], points[i+1]]
-                            dxfLINE = DXF.Line(linepoints,**common)
-                            entities.append(dxfLINE)
-    
-                elif c=="POINTs": # export Curve as multiple POINTs
-                    points = projected_co(points, mx)
-                    for p in points:
-                        dxfPOINT = DXF.Point(points=[p],**common)
-                        entities.append(dxfPOINT)
-    return entities
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/empty_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/empty_exporter.py
deleted file mode 100644
index e849409..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/empty_exporter.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from .base_exporter import BasePrimitiveDXFExporter
-
-
-class EmptyDXFExporter(BasePrimitiveDXFExporter):
-    pass
-
-#-----------------------------------------------------
-def exportEmpty(ob, mx, mw, **common):
-    """converts Empty-Object to desired projection and representation(DXF-Entity type)
-    """
-    p =  mathutils.Vector(ob.loc)
-    [p] = projected_co([p], mx)
-    [p] = toGlobalOrigin([p])
-
-    entities = []
-    c = empty_as_list[GUI_A['empty_as'].val]
-    if c=="POINT": # export Empty as POINT
-        dxfPOINT = DXF.Point(points=[p],**common)
-        entities.append(dxfPOINT)
-    return entities
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/insert_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/insert_exporter.py
deleted file mode 100644
index 80cf7db..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/insert_exporter.py
+++ /dev/null
@@ -1,75 +0,0 @@
-
-from .base_exporter import BasePrimitiveDXFExporter
-
-
-class InsertDXFExporter(BasePrimitiveDXFExporter):
-    pass
-
-#-----------------------------------------------------
-def exportInsert(ob, mx, insert_name, **common):
-    """converts Object to DXF-INSERT in given orientation
-    """
-    WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
-    sizeX = ob.SizeX
-    sizeY = ob.SizeY
-    sizeZ = ob.SizeZ
-    rotX  = ob.RotX
-    rotY  = ob.RotY
-    rotZ  = ob.RotZ
-    #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
-
-    Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
-
-    AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
-    if not PROJECTION:
-        #Extrusion, ZRotation, Elevation = getExtrusion(mx)
-        Extrusion, AXaxis = getExtrusion(mx)
-
-    entities = []
-
-    if 1:
-        if not PROJECTION:
-            ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
-                AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
-            ZRotation *= r2d
-            point = ECS_origin
-        else:    #TODO: fails correct location
-            point1 = mathutils.Vector(ob.loc)
-            [point] = projected_co([point1], mx)
-            if PERSPECTIVE:
-                clipStart = 10.0
-                coef = -clipStart / (point1*mx)[2]
-                #print 'deb: coef=', coef #--------------
-                #TODO: ? sizeX *= coef
-                #sizeY *= coef
-                #sizeZ *= coef
-    
-        #print 'deb: point=', point #--------------
-        [point] = toGlobalOrigin([point])
-
-        #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
-        common['extrusion']= Extrusion
-        #common['elevation']= Elevation
-        #print 'deb: common=', common #------------------
-        if 0: #DEBUG
-            #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
-            linepoints = [[0,0,0], point]
-            dxfLINE = DXF.Line(linepoints,**common)
-            entities.append(dxfLINE)
-
-        xscale=sizeX
-        yscale=sizeY
-        zscale=sizeZ
-        cols=None
-        colspacing=None
-        rows=None
-        rowspacing=None
-
-        dxfINSERT = DXF.Insert(insert_name,point=point,rotation=ZRotation,\
-            xscale=xscale,yscale=yscale,zscale=zscale,\
-            cols=cols,colspacing=colspacing,rows=rows,rowspacing=rowspacing,\
-            **common)
-        entities.append(dxfINSERT)
-
-    return entities
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/lamp_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/lamp_exporter.py
deleted file mode 100644
index 01a65ab..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/lamp_exporter.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from .base_exporter import BasePrimitiveDXFExporter
-
-
-class LampDXFExporter(BasePrimitiveDXFExporter):
-    pass
-
-#-----------------------------------------------------
-def exportLamp(ob, mx, mw, **common):
-    """converts Lamp-Object to desired projection and representation(DXF-Entity type)
-    """
-    p =  mathutils.Vector(ob.loc)
-    [p] = projected_co([p], mx)
-    [p] = toGlobalOrigin([p])
-
-    entities = []
-    c = lamp_as_list[GUI_A['lamp_as'].val]
-    if c=="POINT": # export as POINT
-        dxfPOINT = DXF.Point(points=[p],**common)
-        entities.append(dxfPOINT)
-    return entities
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py
deleted file mode 100644
index cf61954..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/mesh_exporter.py
+++ /dev/null
@@ -1,151 +0,0 @@
-
-import mathutils
-from .base_exporter import BasePrimitiveDXFExporter
-import copy
-
-class MeshDXFExporter(BasePrimitiveDXFExporter):
-    
-    def export(self, ctx, drawing, ob, mx, mx_n, **kwargs):
-        """
-        Converts Mesh-Object to desired projection and representation(DXF-Entity type)
-        """
-        me = self._getMeshData(ctx, ob, self._settings)
-        # idea: me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
-        # the .transform-method is fast, but bad, cause invasive:
-        # it manipulates original geometry and by retransformation lefts back rounding-errors
-        # we dont want to manipulate original data!
-        #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
-        if me.vertices:    
-            # check if there are more instances of this mesh (if used by other objects), then write to BLOCK/INSERT
-            if self.INSTANCES and me.users>1 and not self.PROJECTION and not (ob.modifiers and self._settings['apply_modifiers']):
-                if drawing.containsBlock(me.name):
-                    entities = self._writeInsert(drawing, ob, mx, me.name)
-                else:
-                    # generate geom_output in ObjectCS
-                    allpoints = [v.co for v in me.verts]
-                    identity_matrix = mathutils.Matrix().identity()
-                    allpoints = self.projected_co(allpoints, identity_matrix)
-                    #allpoints = toGlobalOrigin(allpoints)
-                    faces=[]
-                    edges=[]
-                    for e in me.edges: edges.append(e.key)
-                    faces = [[v.index for v in f.verts] for f in me.faces]
-                    entities = self._writeMeshEntities(allpoints, edges, faces, **kwargs)
-                    if entities: # if not empty block
-                        # write BLOCK definition and INSERT entity
-                        # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
-#                        BLOCKREGISTRY[me.name]=self.validDXFr12name(('ME_'+ me.name))
-#                        insert_name = BLOCKREGISTRY[me.name]
-                        drawing.addBlock(me.name, flag=0,base=(0,0,0),entities=entities)
-#                        block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
-                        # write INSERT as entity
-                        entities = self._writeInsert(ob, mx, me.name, **(kwargs))
-    
-            else: # no other instances, so go the standard way
-                return self._standard_way(drawing, me, mx, mx_n)
-    
-    def _writeInsert(self, drawing, ob, mx, insert_name, **kwargs):
-        from insert_exporter import InsertDXFExporter
-        ex = InsertDXFExporter(self._settings)
-        ex.export(drawing, ob, mx, insert_name, **(kwargs))
-        
-    def _getMeshData(self, ctx, obj, settings):
-        if obj.modifiers and settings['apply_modifiers']:
-            #this gets mesh with applied modifiers
-            data = obj.to_mesh(ctx.scene, True, 'PREVIEW')
-        else:
-    #        me = ob.getData(mesh=1) # is a Mesh if mesh>0 (otherwise it is a NMesh)
-            data = obj.data
-        return data
-    
-    def _standard_way(self, drawing, me, mx, mx_n, **kwargs):
-        allpoints = [v.co for v in me.vertices]
-        allpoints = self.projected_co(allpoints, mx)
-        allpoints = self.toGlobalOrigin(allpoints)
-        faces=[]
-        edges=[]
-        if me.faces and self.PROJECTION and self.HIDDEN_LINES:
-            #if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #---------
-            faces, edges = self.hidden_status(me.faces, mx, mx_n)
-            faces = [[v.index for v in me.faces[f_nr].vertices] for f_nr in faces]
-        else:
-            #if DEBUG: print 'deb:exportMesh STANDARD mode' #---------
-            for e in me.edges: edges.append(e.key)
-            #faces = [f.index for f in me.faces]
-            ##faces = [[v.index for v in f.vertices] for f in me.faces]
-            faces = me.faces
-            #faces = [[allpoints[v.index] for v in f.vertices] for f in me.faces]
-        #print('deb: allpoints=\n', allpoints) #---------
-        #print('deb: edges=\n', edges) #---------
-        #print('deb: faces=\n', faces) #---------
-        if self.isLeftHand(mx): # then change vertex-order in every face
-            for f in faces:
-                f.reverse()
-                #f = [f[-1]] + f[:-1] #TODO: might be needed
-            #print('deb: faces=\n', faces) #---------
-        entities = self._writeMeshEntities(allpoints, edges, faces, **kwargs)
-        # TODO: rewrite
-        for type, args in entities:
-            drawing.addEntity(type, **(args))
-        return True
-    
-    def _writeMeshEntities(self, allpoints, edges, faces, **kwargs):
-        """help routine for exportMesh()
-        """
-        entities = []
-        c = self._settings['mesh_as']
-        if c=='POINTs': # export Mesh as multiple POINTs
-            for p in allpoints:
-                args = copy.copy(kwargs)
-                args['points'] = [p]
-                entities.append(('Point', args))
-        elif c=='LINEs' or (not faces):
-            if edges and allpoints:
-#                if exportsettings['verbose']:
-#                    mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene
-                for e in edges:
-                    points = [allpoints[e[0]], allpoints[e[1]]]
-                    args = copy.copy(kwargs)
-                    args['points'] = points
-                    entities.append(('Line', args))
-        elif c in {'POLYFACE','POLYLINE'}:
-            if faces and allpoints:
-                #TODO: purge allpoints: left only vertices used by faces
-#                    if exportsettings['verbose']: 
-#                        mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
-                if not (self.PROJECTION and self.HIDDEN_LINES):
-                    faces = [[v+1 for v in f.vertices] for f in faces]
-                else:
-                    # for back-Faces-mode remove face-free vertices
-                    map=verts_state= [0]*len(allpoints)
-                    for f in faces:
-                        for v in f:
-                            verts_state[v]=1
-                    if 0 in verts_state: # if dirty state
-                        i,newverts=0,[]
-                        for used_i,used in enumerate(verts_state):
-                            if used:
-                                newverts.append(allpoints[used_i])    
-                                map[used_i]=i
-                                i+=1
-                        allpoints = newverts
-                        faces = [[map[v]+1 for v in f] for f in faces]
-                args = copy.copy(kwargs)
-                args['flag70'] = 64
-                args['flag75'] = 0
-                args['width'] = 0.0
-                args['points'] = [allpoints, faces]
-                entities.append(('PolyLine', args))
-        elif c=='3DFACEs':
-            if faces and allpoints:
-#                if exportsettings['verbose']: 
-#                    mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
-                for f in faces:
-                    points = [allpoints[v_id] for v_id in f.vertices]
-                    args = copy.copy(kwargs)
-                    args['points'] = points
-#                    print(args)
-                    entities.append(('Face', args))
-    
-
-        return entities
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/text_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/text_exporter.py
deleted file mode 100644
index c7e9d17..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/text_exporter.py
+++ /dev/null
@@ -1,89 +0,0 @@
-from .base_exporter import BasePrimitiveDXFExporter
-
-
-class TextDXFExporter(BasePrimitiveDXFExporter):
-    pass
-
-#-----------------------------------------------------
-def exportText(ob, mx, mw, **common):
-    """converts Text-Object to desired projection and representation(DXF-Entity type)
-    """
-    text3d = ob.getData()
-    textstr = text3d.getText()
-    WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
-    sizeX = ob.SizeX
-    sizeY = ob.SizeY
-    sizeZ = ob.SizeZ
-    rotX  = ob.RotX
-    rotY  = ob.RotY
-    rotZ  = ob.RotZ
-    #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
-
-    Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
-
-    AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
-    if not PROJECTION:
-        #Extrusion, ZRotation, Elevation = getExtrusion(mx)
-        Extrusion, AXaxis = getExtrusion(mx)
-
-        # no thickness/width for TEXTs converted into ScreenCS
-        if text3d.getExtrudeDepth():
-            Thickness = text3d.getExtrudeDepth() * sizeZ
-
-    #Horizontal text justification type, code 72, (optional, default = 0)
-    # integer codes (not bit-coded)
-    #0=left, 1=center, 2=right
-    #3=aligned, 4=middle, 5=fit
-    Alignment = None
-    alignment = text3d.getAlignment().value
-    if alignment in (1,2): Alignment = alignment
-
-    textHeight = text3d.getSize() / 1.7
-    textFlag = 0
-    if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored
-    if sizeZ < 0.0: textFlag |= 4 # vertical mirrored
-
-    entities = []
-    c = text_as_list[GUI_A['text_as'].val]
-
-    if c=="TEXT": # export text as TEXT
-        if not PROJECTION:
-            ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
-                AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
-            ZRotation *= r2d
-            point = ECS_origin
-        else:    #TODO: fails correct location
-            point1 = mathutils.Vector(ob.loc)
-            [point] = projected_co([point1], mx)
-            if PERSPECTIVE:
-                clipStart = 10.0
-                coef = -clipStart / (point1*mx)[2]
-                textHeight *= coef
-                #print 'deb: coef=', coef #--------------
-    
-        #print 'deb: point=', point #--------------
-        [point] = toGlobalOrigin([point])
-        point2 = point
-
-        #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
-        common['extrusion']= Extrusion
-        #common['elevation']= Elevation
-        common['thickness']= Thickness
-        #print 'deb: common=', common #------------------
-        if 0: #DEBUG
-            #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
-            linepoints = [[0,0,0], point]
-            dxfLINE = DXF.Line(linepoints,**common)
-            entities.append(dxfLINE)
-
-        dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
-            flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
-        entities.append(dxfTEXT)
-        if Thickness:
-            common['thickness']= -Thickness
-            dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
-                flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
-            entities.append(dxfTEXT)
-    return entities
-
-
diff --git a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/viewborder_exporter.py b/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/viewborder_exporter.py
deleted file mode 100644
index 680e4a5..0000000
--- a/release/scripts/addons_contrib/io_export_dxf/primitive_exporters/viewborder_exporter.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from base_exporter import BasePrimitiveDXFExporter
-
-
-class ViewBorderDXFExporter(BasePrimitiveDXFExporter):
-
-    def export(self, ob, mx, mw, **common):
-        """converts Lamp-Object to desired projection and representation(DXF-Entity type)
-        """
-        identity_matrix = mathutils.Matrix().identity()
-        points = projected_co(border, identity_matrix)
-        closed = 1
-        points = toGlobalOrigin(points)
-        c = settings['curve_as']
-        if c=="LINEs": # export Curve as multiple LINEs
-            for i in range(len(points)-1):
-                linepoints = [points[i], points[i+1]]
-                dxfLINE = DXF.Line(linepoints,paperspace=espace,color=LAYERCOLOR_DEF)
-                entities.append(dxfLINE)
-        else:
-            fag70, flag75 = closed, 0
-            dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag70=flag70, flag75=flag70, width=0.0, paperspace=espace, color=LAYERCOLOR_DEF)
-            #dxfPLINE = DXF.PolyLine(points,points[0],[closed,0,0], paperspace=espace, color=LAYERCOLOR_DEF)
-            d.append(dxfPLINE)
-
diff --git a/release/scripts/addons_contrib/io_export_marmalade.py b/release/scripts/addons_contrib/io_export_marmalade.py
deleted file mode 100644
index 1641677..0000000
--- a/release/scripts/addons_contrib/io_export_marmalade.py
+++ /dev/null
@@ -1,1479 +0,0 @@
-# ***** GPL LICENSE BLOCK *****
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
-# All rights reserved.
-# ***** GPL LICENSE BLOCK *****
-
-# Marmalade SDK is not responsible in any case of the following code.
-# This Blender add-on is freely shared for the Blender and Marmalade user communities.
-
-
-bl_info = {
-    "name": "Marmalade Cross-platform Apps (.group)",
-    "author": "Benoit Muller",
-    "version": (0, 6, 1),
-    "blender": (2, 6, 3),
-    "location": "File > Export > Marmalade cross-platform Apps (.group)",
-    "description": "Export Marmalade Format files (.group)",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
-        "Scripts/Import-Export/Marmalade_Exporter",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "",
-    "category": "Import-Export"}
-
-import os
-import shutil
-from math import radians
-
-import bpy
-from mathutils import Matrix
-
-import mathutils
-import math
-
-import datetime
-
-import subprocess
-
-
-#Container for the exporter settings
-class MarmaladeExporterSettings:
-
-    def __init__(self,
-                 context,
-                 FilePath,
-                 CoordinateSystem=1,
-                 FlipNormals=False,
-                 ApplyModifiers=False,
-                 Scale=100,
-                 AnimFPS=30,
-                 ExportVertexColors=True,
-                 ExportMaterialColors=True,
-                 ExportTextures=True,
-                 CopyTextureFiles=True,
-                 ExportArmatures=False,
-                 ExportAnimationFrames=0,
-                 ExportAnimationActions=0,
-                 ExportMode=1,
-                 MergeModes=0,
-                 Verbose=False):
-        self.context = context
-        self.FilePath = FilePath
-        self.CoordinateSystem = int(CoordinateSystem)
-        self.FlipNormals = FlipNormals
-        self.ApplyModifiers = ApplyModifiers
-        self.Scale = Scale
-        self.AnimFPS = AnimFPS
-        self.ExportVertexColors = ExportVertexColors
-        self.ExportMaterialColors = ExportMaterialColors
-        self.ExportTextures = ExportTextures
-        self.CopyTextureFiles = CopyTextureFiles
-        self.ExportArmatures = ExportArmatures
-        self.ExportAnimationFrames = int(ExportAnimationFrames)
-        self.ExportAnimationActions = int(ExportAnimationActions)
-        self.ExportMode = int(ExportMode)
-        self.MergeModes = int(MergeModes)
-        self.Verbose = Verbose
-        self.WarningList = []
-
-
-def ExportMadeWithMarmaladeGroup(Config):
-    print("----------\nExporting to {}".format(Config.FilePath))
-    if Config.Verbose:
-        print("Opening File...")
-    Config.File = open(Config.FilePath, "w")
-
-    if Config.Verbose:
-        print("Done")
-
-    if Config.Verbose:
-        print("writing group header")
-
-    Config.File.write('// Marmalade group file exported from : %s\n' % bpy.data.filepath)
-    Config.File.write('// Exported %s\n' % str(datetime.datetime.now()))
-    Config.File.write("CIwResGroup\n{\n\tname \"%s\"\n" % bpy.path.display_name_from_filepath(Config.FilePath))
-
-    if Config.Verbose:
-        print("Generating Object list for export... (Root parents only)")
-    if Config.ExportMode == 1:
-        Config.ExportList = [Object for Object in Config.context.scene.objects
-                             if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}
-                             and Object.parent is None]
-    else:
-        ExportList = [Object for Object in Config.context.selected_objects
-                      if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}]
-        Config.ExportList = [Object for Object in ExportList
-                             if Object.parent not in ExportList]
-    if Config.Verbose:
-        print("  List: {}\nDone".format(Config.ExportList))
-
-    if Config.Verbose:
-        print("Setting up...")
-
-    if Config.ExportAnimationFrames:
-        if Config.Verbose:
-            print(bpy.context.scene)
-            print(bpy.context.scene.frame_current)
-        CurrentFrame = bpy.context.scene.frame_current
-        #comment because it crashes Blender on some old blend file: bpy.context.scene.frame_current = bpy.context.scene.frame_current
-    if Config.Verbose:
-        print("Done")
-    
-    Config.ObjectList = []
-    if Config.Verbose:
-        print("Writing Objects...")
-    WriteObjects(Config, Config.ExportList)
-    if Config.Verbose:
-        print("Done")
-
-    if Config.Verbose:
-        print("Objects Exported: {}".format(Config.ExportList))
-
-    if Config.ExportAnimationFrames:
-        if Config.Verbose:
-            print("Writing Animation...")
-        WriteKeyedAnimationSet(Config, bpy.context.scene)
-        bpy.context.scene.frame_current = CurrentFrame
-        if Config.Verbose:
-            print("Done")
-    Config.File.write("}\n")
-    CloseFile(Config)
-    print("Finished")
-
-
-def GetObjectChildren(Parent):
-    return [Object for Object in Parent.children
-            if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}]
-
-
-#Returns the file path of first image texture from Material.
-def GetMaterialTextureFullPath(Config, Material):
-    if Material:
-        #Create a list of Textures that have type "IMAGE"
-        ImageTextures = [Material.texture_slots[TextureSlot].texture for TextureSlot in Material.texture_slots.keys() if Material.texture_slots[TextureSlot].texture.type == "IMAGE"]
-        #Refine a new list with only image textures that have a file source
-        TexImages = [Texture.image for Texture in ImageTextures if getattr(Texture.image, "source", "") == "FILE"]
-        ImageFiles = [Texture.image.filepath for Texture in ImageTextures if getattr(Texture.image, "source", "") == "FILE"]
-        if TexImages:
-            filepath = TexImages[0].filepath
-            if TexImages[0].packed_file:
-                TexImages[0].unpack()
-            if not os.path.exists(filepath):
-                #try relative path to the blend file
-                filepath = os.path.dirname(bpy.data.filepath) + filepath
-            #Marmalade doesn't like jpeg/tif so try to convert in png on the fly
-            if (TexImages[0].file_format == 'JPEG' or TexImages[0].file_format == 'TIFF') and os.path.exists(filepath):
-                marmaladeConvert = os.path.expandvars("%S3E_DIR%\\..\\tools\\ImageMagick\\win32\\convert.exe")
-                if (os.path.exists(marmaladeConvert)):
-                    srcImagefilepath = filepath
-                    filepath = os.path.splitext(filepath)[0] + '.png'
-                    if Config.Verbose:
-                        print("  /!\\ Converting Texture %s in PNG: %s{}..." % (TexImages[0].file_format, filepath))
-                        print('"%s" "%s" "%s"' % (marmaladeConvert, srcImagefilepath, filepath))
-                    subprocess.call([marmaladeConvert, srcImagefilepath, filepath])
-            return filepath
-    return None
-
-
-def WriteObjects(Config, ObjectList, geoFile=None, mtlFile=None, GeoModel=None,  bChildObjects=False):
-    Config.ObjectList += ObjectList
-
-    if bChildObjects == False and Config.MergeModes > 0:
-        if geoFile == None:
-            #we merge objects, so use name of group file for the name of Geo
-            geoFile, mtlFile = CreateGeoMtlFiles(Config, bpy.path.display_name_from_filepath(Config.FilePath))
-            GeoModel = CGeoModel(bpy.path.display_name_from_filepath(Config.FilePath))
-
-    for Object in ObjectList:
-        if Config.Verbose:
-            print("  Writing Object: {}...".format(Object.name))
-        
-        if Config.ExportArmatures and Object.type == "ARMATURE":           
-            Armature = Object.data
-            ParentList = [Bone for Bone in Armature.bones if Bone.parent is None]
-            if Config.Verbose:
-                print("    Writing Armature Bones...")
-            #Create the skel file
-            skelfullname = os.path.dirname(Config.FilePath) + "\models\%s.skel" % (StripName(Object.name))
-            ensure_dir(skelfullname)
-            if Config.Verbose:
-                print("      Creating skel file %s" % (skelfullname))
-
-            skelFile = open(skelfullname, "w")
-            skelFile.write('// skel file exported from : %r\n' % os.path.basename(bpy.data.filepath))   
-            skelFile.write("CIwAnimSkel\n")
-            skelFile.write("{\n")
-            skelFile.write("\tnumBones %d\n" % (len(Armature.bones)))
-            Config.File.write("\t\".\models\%s.skel\"\n" % (StripName(Object.name)))
-
-            WriteArmatureParentRootBones(Config, Object, ParentList, skelFile)
-
-            skelFile.write("}\n")
-            skelFile.close()
-            if Config.Verbose:
-                print("    Done")
-
-        ChildList = GetObjectChildren(Object)
-        if Config.ExportMode == 2:  # Selected Objects Only
-            ChildList = [Child for Child in ChildList
-                         if Child in Config.context.selected_objects]
-        if Config.Verbose:
-            print("    Writing Children...")
-        WriteObjects(Config, ChildList, geoFile, mtlFile, GeoModel, True)
-        if Config.Verbose:
-            print("    Done Writing Children")
-
-        if Object.type == "MESH":
-            if Config.Verbose:
-                print("    Generating Mesh...")
-            if Config.ApplyModifiers:
-                if Config.ExportArmatures:
-                    #Create a copy of the object and remove all armature modifiers so an unshaped
-                    #mesh can be created from it.
-                    Object2 = Object.copy()
-                    for Modifier in [Modifier for Modifier in Object2.modifiers if Modifier.type == "ARMATURE"]:
-                        Object2.modifiers.remove(Modifier)
-                    Mesh = Object2.to_mesh(bpy.context.scene, True, "PREVIEW")
-                else:
-                    Mesh = Object.to_mesh(bpy.context.scene, True, "PREVIEW")
-            else:
-                Mesh = Object.to_mesh(bpy.context.scene, False, "PREVIEW")
-            if Config.Verbose:
-                print("    Done")
-                print("    Writing Mesh...")
-
-            # Flip ZY axis (Blender Z up: Marmalade: Y up) ans Scale appropriately
-            X_ROT = mathutils.Matrix.Rotation(-math.pi / 2, 4, 'X')
-
-            if Config.MergeModes == 0:
-                # No merge, so all objects are exported in MODEL SPACE and not in world space
-                # Calculate Scale of the Export
-                meshScale = Object.matrix_world.to_scale()  # Export is working, even if user doesn't have use apply scale in Edit mode.
-
-                scalematrix = Matrix()
-                scalematrix[0][0] = meshScale.x * Config.Scale
-                scalematrix[1][1] = meshScale.y * Config.Scale
-                scalematrix[2][2] = meshScale.z * Config.Scale
-
-                meshRot = Object.matrix_world.to_quaternion()  # Export is working, even if user doesn't have use apply Rotation in Edit mode.
-                Mesh.transform(X_ROT * meshRot.to_matrix().to_4x4() * scalematrix)
-            else:
-                # In Merge mode, we need to keep relative postion of each objects, so we export in WORLD SPACE
-                SCALE_MAT = mathutils.Matrix.Scale(Config.Scale, 4)
-                Mesh.transform(SCALE_MAT * X_ROT * Object.matrix_world)
-
-             # manage merge options
-   
-            if Config.MergeModes == 0:
-                #one geo per Object, so use name of Object for the Geo file
-                geoFile, mtlFile = CreateGeoMtlFiles(Config, StripName(Object.name))
-                GeoModel = CGeoModel(StripName(Object.name))  
-                
-            # Write the Mesh in the Geo file   
-            WriteMesh(Config, Object, Mesh, geoFile, mtlFile, GeoModel)
-
-            if Config.MergeModes == 0:
-                # no merge so finalize the file, and discard the file and geo class
-                FinalizeGeoMtlFiles(Config, geoFile, mtlFile)
-                geoFile = None
-                mtlFile = None
-                GeoModel = None
-            elif Config.MergeModes == 1:
-                # merge in one Mesh, so keep the Geo class and prepare to change object
-                GeoModel.NewObject() 
-            elif Config.MergeModes == 2:
-                # merge several Meshes in one file: so clear the mesh data that we just written in the file,
-                # but keep Materials info that need to be merged across objects
-                GeoModel.ClearAllExceptMaterials()
-
-            if Config.Verbose:
-                print("    Done")
-
-            if Config.ApplyModifiers and Config.ExportArmatures:
-                bpy.data.objects.remove(Object2)
-            bpy.data.meshes.remove(Mesh)
-
-        if Config.Verbose:
-            print("  Done Writing Object: {}".format(Object.name))
-
-    if bChildObjects == False:
-        # we have finish to do all objects
-        if GeoModel:
-            if Config.MergeModes == 1:
-                # we have Merges all objects in one Mesh, so time to write this big mesh in the file
-                GeoModel.PrintGeoMesh(geoFile)
-                # time to write skinfile if any
-                if len(GeoModel.useBonesDict) > 0:
-                    # some mesh was not modified by the armature. so we must skinned the merged mesh.
-                    # So unskinned vertices from unarmatured meshes, are assigned to the root bone of the armature
-                    for i in range(0, len(GeoModel.vList)):
-                        if not i in GeoModel.skinnedVertices:
-                            GeoModel.skinnedVertices.append(i)
-                            useBonesKey = pow(2, GeoModel.armatureRootBoneIndex)
-                            vertexGroupIndices = list((GeoModel.armatureRootBoneIndex,))
-                            if useBonesKey not in GeoModel.useBonesDict:                          
-                                GeoModel.mapVertexGroupNames[GeoModel.armatureRootBoneIndex] = StripBoneName(GeoModel.armatureRootBone.name)
-                                VertexList = []
-                                VertexList.append("\t\tvertWeights { %d, 1.0}" % i)
-                                GeoModel.useBonesDict[useBonesKey] = (vertexGroupIndices, VertexList)
-                            else:
-                                pair_ListGroupIndices_ListAssignedVertices = GeoModel.useBonesDict[useBonesKey]
-                                pair_ListGroupIndices_ListAssignedVertices[1].append("\t\tvertWeights { %d, 1.0}" % i)
-                                GeoModel.useBonesDict[useBonesKey] = pair_ListGroupIndices_ListAssignedVertices
-                    # now generates the skin file
-                    PrintSkinWeights(Config, GeoModel.armatureObjectName, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, GeoModel.name)
-            if Config.MergeModes > 0:
-                WriteMeshMaterialsForGeoModel(Config, mtlFile, GeoModel)
-                FinalizeGeoMtlFiles(Config, geoFile, mtlFile)
-        geoFile = None
-        mtlFile = None
-        GeoModel = None
-
-
-def CreateGeoMtlFiles(Config, Name):
-    #Create the geo file
-    geofullname = os.path.dirname(Config.FilePath) + ("\models\%s.geo" % Name)
-    ensure_dir(geofullname)
-    if Config.Verbose:
-        print("      Creating geo file %s" % (geofullname))  
-    geoFile = open(geofullname, "w")
-    geoFile.write('// geo file exported from : %r\n' % os.path.basename(bpy.data.filepath))
-    geoFile.write("CIwModel\n")
-    geoFile.write("{\n")
-    geoFile.write("\tname \"%s\"\n" % Name)
-    # add it to the group
-    Config.File.write("\t\".\models\%s.geo\"\n" % Name)
-
-    # Create the mtl file
-    mtlfullname = os.path.dirname(Config.FilePath) + "\models\%s.mtl" % (Name)
-    ensure_dir(mtlfullname)
-    if Config.Verbose:
-        print("      Creating mtl file %s" % (mtlfullname))
-    mtlFile = open(mtlfullname, "w")
-    mtlFile.write('// mtl file exported from : %r\n' % os.path.basename(bpy.data.filepath))   
-    return geoFile, mtlFile
-
-
-def FinalizeGeoMtlFiles(Config, geoFile, mtlFile):
-    if Config.Verbose:
-        print("      Closing geo file")  
-    geoFile.write("}\n")
-    geoFile.close()
-    if Config.Verbose:
-        print("      Closing mtl file")  
-    mtlFile.close()
-
-
-def WriteMesh(Config, Object, Mesh,  geoFile=None, mtlFile=None, GeoModel=None):
-    if geoFile == None or mtlFile == None:
-        print (" ERROR not geo file arguments in WriteMesh method")
-        return
-
-    if GeoModel == None:
-        print (" ERROR not GeoModel arguments in WriteMesh method")
-        return
-
-    BuildOptimizedGeo(Config, Object, Mesh, GeoModel)
-    if Config.MergeModes == 0 or Config.MergeModes == 2:
-        #if we don't merge, or if we write several meshes into one file ... write the mesh everytime we do an object
-        GeoModel.PrintGeoMesh(geoFile)
- 
-    if Config.Verbose:
-        print("      Done\n      Writing Mesh Materials...")
-
-    if Config.MergeModes == 0:
-        #No merge, so we can diretly write the Mtl file associated to this object
-        WriteMeshMaterialsForGeoModel(Config, mtlFile, GeoModel)
-
-    if Config.Verbose:
-        print("      Done")
-  
-    if Config.ExportArmatures:
-        if Config.Verbose:
-            print("      Writing Mesh Weights...")
-        WriteMeshSkinWeightsForGeoModel(Config, Object, Mesh, GeoModel)
-        if Config.Verbose:
-            print("      Done")
-
-
-###### optimized version fo Export, can be used also to merge several object in one single geo File ######
-
-# CGeoModel
-#  -> List Vertices
-#  -> List Normales
-#  -> List uv 0
-#  -> List uv 1
-#  -> List Vertex Colors
-#  -> List Materials
-#       -> Material name
-#       -> Blender Material Object
-#       -> List Tris -> Stream Indices v,vn,uv0,uv1,vc
-#       -> List Quads -> Stream Indices v,vn,uv0,uv1,vc
-
-
-#############
-#Store one Point of a Quad or Tri in marmalade geo format: //index-list is: { <int> <int> <int> <int> <int> }   //v,vn,uv0,uv1,vc
-#############                           
-class CGeoIndexList:
-    __slots__ = "v", "vn", "uv0", "uv1", "vc"
-    
-    def __init__(self, v, vn, uv0, uv1, vc):
-        self.v = v
-        self.vn = vn
-        self.uv0 = uv0
-        self.uv1 = uv1
-        self.vc = vc
-
-        
-#############
-#Store a Quad or a Tri in marmalade geo format : 3 or 4 CIndexList depending it is a Tri or a Quad
-#############                        
-class CGeoPoly:
-    __slots__ = "pointsList",
-    
-    def __init__(self):
-        self.pointsList = []
-
-    def AddPoint(self, v, vn, uv0, uv1, vc):
-        self.pointsList.append( CGeoIndexList(v, vn, uv0, uv1, vc))
-
-    def PointsCount(self):
-        return len(self.pointsList)
-
-    def PrintPoly(self, geoFile):
-        if len(self.pointsList) == 3:
-            geoFile.write("\t\t\t\tt ")
-        if len(self.pointsList) == 4:
-            geoFile.write("\t\t\t\tq ")
-        for point in self.pointsList:
-            geoFile.write(" {%d, %d, %d, %d, %d}" % (point.v, point.vn, point.uv0, point.uv1, point.vc))
-        geoFile.write("\n")
-
-
-#############
-#Store all the poly (tri or quad) assigned to a Material in marmalade geo format
-#############                        
-class CGeoMaterialPolys:
-    __slots__ = "name", "material", "quadList", "triList", "currentPoly"
-    
-    def __init__(self, name, material=None):
-        self.name = name
-        self.material = material
-        self.quadList = []
-        self.triList = []
-        self.currentPoly = None
-
-    def BeginPoly(self):
-        self.currentPoly = CGeoPoly()
-
-    def AddPoint(self, v, vn, uv0, uv1, vc):
-        self.currentPoly.AddPoint(v, vn, uv0, uv1, vc)       
-             
-    def EndPoly(self):
-        if (self.currentPoly.PointsCount() == 3):
-            self.triList.append(self.currentPoly)
-        if (self.currentPoly.PointsCount() == 4):
-            self.quadList.append(self.currentPoly)
-        self.currentPoly = None
-
-    def ClearPolys(self):
-        self.quadList = []
-        self.triList = []
-        self.currentPoly = None
-
-    def PrintMaterialPolys(self, geoFile):
-        geoFile.write("\t\tCSurface\n")
-        geoFile.write("\t\t{\n")
-        geoFile.write("\t\t\tmaterial \"%s\"\n" % self.name)
-        if self.triList:
-            geoFile.write("\t\t\tCTris\n")
-            geoFile.write("\t\t\t{\n")
-            geoFile.write("\t\t\t\tnumTris %d\n" % (len(self.triList)))
-            for poly in self.triList:
-                poly.PrintPoly(geoFile)
-            geoFile.write("\t\t\t}\n")
-
-        if self.quadList:
-            geoFile.write("\t\t\tCQuads\n")
-            geoFile.write("\t\t\t{\n")
-            geoFile.write("\t\t\t\tnumQuads %d\n" % (len(self.quadList)))
-            for poly in self.quadList:
-                poly.PrintPoly(geoFile)
-            geoFile.write("\t\t\t}\n")
-        geoFile.write("\t\t}\n")
-
-
-#############
-#Store all the information on a Model/Mesh (vertices, normal, certcies color, uv0, uv1, TRI, QUAD) in marmalade geo format
-#############  
-class CGeoModel:
-    __slots__ = ("name", "MaterialsDict", "vList", "vnList", "vcList", "uv0List", "uv1List",
-                "currentMaterialPolys", "vbaseIndex","vnbaseIndex", "uv0baseIndex", "uv1baseIndex",
-                "armatureObjectName", "useBonesDict", "mapVertexGroupNames", "armatureRootBone", "armatureRootBoneIndex", "skinnedVertices")
-                
-    def __init__(self, name):
-        self.name = name
-        self.MaterialsDict = {}
-        self.vList = []
-        self.vnList = []
-        self.vcList = []
-        self.uv0List = []
-        self.uv1List = []
-        self.currentMaterialPolys = None
-        #used xx baseIndex are used when merging several blender objects into one Mesh in the geo file (internal offset)
-        self.vbaseIndex = 0
-        self.vnbaseIndex = 0
-        self.uv0baseIndex = 0
-        self.uv1baseIndex = 0
-
-        # Store some information for skin management , when we merge several object in one big mesh (MergeModes 1)
-        # can only work if in the object list only one is rigged with an armature... and if it is located in 0,0,0
-        self.armatureObjectName = ""
-        #useBonesKey : bit field, where each bit is a VertexGroup.Index): Sum(2^VertGroupIndex).
-        #useBonesDict[useBonesKey] = tuple(VertexGroups.group, list(Vertex))
-        self.useBonesDict = {}
-        self.mapVertexGroupNames = {}
-        self.armatureRootBone = None
-        self.armatureRootBoneIndex = 0
-        self.skinnedVertices = []
-
-
-
-    def AddVertex(self, vertex):
-        self.vList.append(vertex.copy())
-
-    def AddVertexNormal(self, vertexN):
-        self.vnList.append(vertexN.copy())
-
-    # add a uv coordiantes and return the current Index in the stream (index is local to the object, when we merge several object into a one Mesh)
-    def AddVertexUV0(self, u, v):
-        self.uv0List.append((u, v))
-        return len(self.uv0List) - 1 - self.uv0baseIndex 
-
-    def AddVertexUV1(self, u, v):
-        self.uv1List.append((u, v))
-        return len(self.uv1List) - 1 - self.uv1baseIndex 
-
-    # add a vertexcolor if it doesn't already exist and return the current Index in the stream (index is global to all objects, when we merge several object into a one Mesh)
-    def AddVertexColor(self, r, g, b, a):
-        for i in range(0, len(self.vcList)):
-            col = self.vcList[i]
-            if col[0] == r and col[1] == g and col[2] == b and col[3] == a:
-                return i
-
-        self.vcList.append((r, g, b, a))
-        return len(self.vcList)-1
-
-    def BeginPoly(self, MaterialName, material=None):
-        if MaterialName not in self.MaterialsDict:
-            self.currentMaterialPolys = CGeoMaterialPolys(MaterialName, material)
-        else:
-            self.currentMaterialPolys = self.MaterialsDict[MaterialName]
-        self.currentMaterialPolys.BeginPoly()
-
-    def AddPoint(self, v, vn, uv0, uv1, vc):
-        if v != -1:
-            v += self.vbaseIndex
-        if vn != -1:
-            vn += self.vnbaseIndex
-        if uv0 != -1:
-            uv0 += self.uv0baseIndex
-        if uv1 != -1:
-            uv1 += self.uv1baseIndex
-                
-        self.currentMaterialPolys.AddPoint(v, vn, uv0, uv1, vc)       
-                              
-    def EndPoly(self):
-        self.currentMaterialPolys.EndPoly()
-        self.MaterialsDict[self.currentMaterialPolys.name] = self.currentMaterialPolys
-        self.currentMaterialPolys = None
-
-    def NewObject(self):
-        #used in Merge mode 1: allows to merge several blender objects into one Mesh.
-        self.vbaseIndex = len(self.vList)
-        self.vnbaseIndex = len(self.vnList)
-        self.uv0baseIndex = len(self.uv0List)
-        self.uv1baseIndex = len(self.uv1List)
-
-    def ClearAllExceptMaterials(self):
-        #used in Merge mode 2: one geo with several mesh
-        self.vList = []
-        self.vnList = []
-        self.vcList = []
-        self.uv0List = []
-        self.uv1List = []
-        self.currentMaterialPolys = None
-        self.vbaseIndex = 0
-        self.vnbaseIndex = 0
-        self.uv0baseIndex = 0
-        self.uv1baseIndex = 0
-        for GeoMaterialPolys in self.MaterialsDict.values():
-            GeoMaterialPolys.ClearPolys()
-        self.useBonesDict = {}
-        self.mapVertexGroupNames = {}
-        self.armatureObjectName = ""
-        self.armatureRootBone = None
-        self.armatureRootBoneIndex = 0
-        self.skinnedVertices = []
-
-    def PrintGeoMesh(self, geoFile):
-        geoFile.write("\tCMesh\n")
-        geoFile.write("\t{\n")
-        geoFile.write("\t\tname \"%s\"\n" % (StripName(self.name)))
-
-        if self.vList:
-            geoFile.write("\t\tCVerts\n")
-            geoFile.write("\t\t{\n")
-            geoFile.write("\t\t\tnumVerts %d\n" % len(self.vList))
-            for vertex in self.vList:
-                geoFile.write("\t\t\tv { %.9f, %.9f, %.9f }\n" % (vertex[0], vertex[1], vertex[2]))                      
-            geoFile.write("\t\t}\n")
-
-        if self.vnList:
-            geoFile.write("\t\tCVertNorms\n")
-            geoFile.write("\t\t{\n")
-            geoFile.write("\t\t\tnumVertNorms  %d\n" % len(self.vnList))
-            for vertexn in self.vnList:
-                geoFile.write("\t\t\tvn { %.9f, %.9f, %.9f }\n" % (vertexn[0], vertexn[1], vertexn[2]))                      
-            geoFile.write("\t\t}\n")
-
-        if self.vcList:
-            geoFile.write("\t\tCVertCols\n")
-            geoFile.write("\t\t{\n")
-            geoFile.write("\t\t\tnumVertCols %d\n" % len(self.vcList))
-            for color in self.vcList:
-                geoFile.write("\t\t\tcol { %.6f, %.6f, %.6f, %.6f }\n" % (color[0], color[1], color[2], color[3])) #alpha is not supported on blender for vertex colors           
-            geoFile.write("\t\t}\n")
-
-        if self.uv0List:
-            geoFile.write("\t\tCUVs\n")
-            geoFile.write("\t\t{\n")
-            geoFile.write("\t\t\tsetID 0\n")
-            geoFile.write("\t\t\tnumUVs %d\n" % len(self.uv0List))
-            for uv in self.uv0List:
-                 geoFile.write("\t\t\tuv { %.9f, %.9f }\n" % (uv[0], uv[1]))                       
-            geoFile.write("\t\t}\n")
-
-        if self.uv1List:
-            geoFile.write("\t\tCUVs\n")
-            geoFile.write("\t\t{\n")
-            geoFile.write("\t\t\tsetID 1\n")
-            geoFile.write("\t\t\tnumUVs %d\n" % len(self.uv1List))
-            for uv in self.uv1List:
-                 geoFile.write("\t\t\tuv { %.9f, %.9f }\n" % (uv[0], uv[1]))                       
-            geoFile.write("\t\t}\n")
-
-        for GeoMaterialPolys in self.MaterialsDict.values():
-            GeoMaterialPolys.PrintMaterialPolys(geoFile)
-        geoFile.write("\t}\n")
-
-    def GetMaterialList(self):
-        return list(self.MaterialsDict.keys())
-
-    def GetMaterialByName(self, name):
-        if name in self.MaterialsDict:
-            return self.MaterialsDict[name].material
-        else:
-            return None       
-
-
-
-#############
-# iterates faces, vertices ... and store the information in the GeoModel container
-def BuildOptimizedGeo(Config, Object, Mesh, GeoModel):
-    if GeoModel == None:
-        GeoModel = CGeoModel(filename, Object.name)
-
-    #Ensure tessfaces data are here
-    Mesh.update (calc_tessface=True)
-    
-    #Store Vertex stream, and Normal stream (use directly the order from blender collection
-    for Vertex in Mesh.vertices:
-        GeoModel.AddVertex(Vertex.co)
-        Normal = Vertex.normal
-        if Config.FlipNormals:
-            Normal = -Normal
-        GeoModel.AddVertexNormal(Normal)
-    #Check if some colors have been defined
-    vertexColours = None
-    if Config.ExportVertexColors and (len(Mesh.vertex_colors) > 0):
-        vertexColours = Mesh.tessface_vertex_colors[0].data
-
-    #Check if some uv coordinates have been defined
-    UVCoordinates = None
-    if Config.ExportTextures and (len(Mesh.uv_textures) > 0):
-        for UV in Mesh.tessface_uv_textures:
-            if UV.active_render:
-                UVCoordinates = UV.data
-                break
-
-    #Iterate on Faces and Store the poly (quad or tri) and the associate colors,UVs
-    for Face in Mesh.tessfaces:
-        # stream for vertex (we use the same for normal)
-        Vertices = list(Face.vertices)
-        if Config.CoordinateSystem == 1:
-            Vertices = Vertices[::-1]
-        # stream for vertex colors
-        if vertexColours:
-            MeshColor = vertexColours[Face.index]
-            if len(Vertices) == 3:
-                FaceColors = list((MeshColor.color1, MeshColor.color2, MeshColor.color3))
-            else:
-                FaceColors = list((MeshColor.color1, MeshColor.color2, MeshColor.color3, MeshColor.color4))
-            if Config.CoordinateSystem == 1:
-                FaceColors = FaceColors[::-1]
-            colorIndex = []
-            for color in FaceColors:
-                index = GeoModel.AddVertexColor(color[0], color[1], color[2], 1)  #rgba => no alpha on vertex color in Blender so use 1
-                colorIndex.append(index)
-        else:
-            colorIndex = list((-1,-1,-1,-1))
-
-        # stream for UV0 coordinates
-        if UVCoordinates:
-            uvFace = UVCoordinates[Face.index]
-            uvVertices = []
-            for uvVertex in uvFace.uv:
-                uvVertices.append(tuple(uvVertex))
-            if Config.CoordinateSystem == 1:
-                uvVertices = uvVertices[::-1]
-            uv0Index = []
-            for uvVertex in uvVertices:
-                index = GeoModel.AddVertexUV0(uvVertex[0], 1 - uvVertex[1]) 
-                uv0Index.append(index)
-        else:
-            uv0Index = list((-1, -1, -1, -1))
-
-        # stream for UV1 coordinates
-        uv1Index = list((-1, -1, -1, -1))
-
-        mat = None
-        # find the associated material
-        if Face.material_index < len(Mesh.materials):
-            mat = Mesh.materials[Face.material_index]
-        if mat:
-            matName =  mat.name
-        else:
-            matName = "NoMaterialAssigned"  # There is no material assigned in blender !!!, exporter have generated a default one          
-            
-        # now on the material, generates the tri/quad in v,vn,uv0,uv1,vc stream index
-        GeoModel.BeginPoly(matName, mat)
-
-        for i in range(0, len(Vertices)):
-            GeoModel.AddPoint(Vertices[i], Vertices[i], uv0Index[i], uv1Index[i], colorIndex[i])
-
-        GeoModel.EndPoly()
-
-
-                              
-#############
-# Get the list of Material in use by the CGeoModel
-def WriteMeshMaterialsForGeoModel(Config, mtlFile, GeoModel):
-    for matName in GeoModel.GetMaterialList():
-        Material = GeoModel.GetMaterialByName(matName)
-        WriteMaterial(Config, mtlFile, Material)
-
-
-def WriteMaterial(Config, mtlFile, Material=None):
-    mtlFile.write("CIwMaterial\n")
-    mtlFile.write("{\n")
-    if Material:
-        mtlFile.write("\tname \"%s\"\n" % Material.name)
-
-        if Config.ExportMaterialColors:
-            #if bpy.context.scene.world:
-            #    MatAmbientColor = Material.ambient * bpy.context.scene.world.ambient_color
-            MatAmbientColor = Material.ambient * Material.diffuse_color
-            mtlFile.write("\tcolAmbient {%.2f,%.2f,%.2f,%.2f} \n" % (min(255, MatAmbientColor[0] * 255), min(255, MatAmbientColor[1] * 255), min(255, MatAmbientColor[2] * 255), min(255, Material.alpha * 255)))
-            MatDiffuseColor = 255 * Material.diffuse_intensity * Material.diffuse_color
-            MatDiffuseColor = min((255, 255, 255)[:],MatDiffuseColor[:])
-            mtlFile.write("\tcolDiffuse  {%.2f,%.2f,%.2f} \n" % (MatDiffuseColor[:]))
-            MatSpecularColor = 255 * Material.specular_intensity * Material.specular_color
-            MatSpecularColor = min((255, 255, 255)[:],MatSpecularColor[:])
-            mtlFile.write("\tcolSpecular  {%.2f,%.2f,%.2f} \n" % (MatSpecularColor[:]))
-            # EmitColor = Material.emit * Material.diffuse_color
-            # mtlFile.write("\tcolEmissive {%.2f,%.2f,%.2f} \n" % (EmitColor* 255)[:])    
-    else:
-        mtlFile.write("\tname \"NoMaterialAssigned\" // There is no material assigned in blender !!!, exporter have generated a default one\n")
-
-    #Copy texture
-    if Config.ExportTextures:
-        Texture = GetMaterialTextureFullPath(Config, Material)
-        if Texture:
-            mtlFile.write("\ttexture0 .\\textures\\%s\n" % (bpy.path.basename(Texture)))
-            
-            if Config.CopyTextureFiles:
-                if not os.path.exists(Texture):
-                    #try relative path to the blend file
-                    Texture = os.path.dirname(bpy.data.filepath) + Texture
-                if os.path.exists(Texture):
-                    textureDest = os.path.dirname(Config.FilePath) + "\\models\\textures\\%s" % (bpy.path.basename(Texture))
-                    ensure_dir(textureDest)
-                    if Config.Verbose:
-                        print("      Copying the texture file %s ---> %s" % (Texture, textureDest))
-                    shutil.copy(Texture, textureDest)
-                else:
-                    if Config.Verbose:
-                        print("      CANNOT Copy texture file (not found) %s" % (Texture))
-    mtlFile.write("}\n")
-
-def GetFirstRootBone(ArmatureObject):
-    ArmatureBones = ArmatureObject.data.bones
-    ParentBoneList = [Bone for Bone in ArmatureBones if Bone.parent is None]
-    if ParentBoneList:
-        return ParentBoneList[0]
-    return None
-
-
-def GetVertexGroupFromBone(Object, Bone):
-    if Bone:
-        vertexGroupList = [VertexGroup for VertexGroup in Object.vertex_groups  if VertexGroup.name == Bone.name]
-        if vertexGroupList:
-            return vertexGroupList[0]
-    return None
-
-
-def GetBoneListNames(Bones):
-    boneList = []
-    for Bone in Bones:
-        boneList.append(Bone.name)
-        boneList += GetBoneListNames(Bone.children)
-    return boneList
-
-
-def FindUniqueIndexForRootBone(Object, RootVertexGroup):
-    if RootVertexGroup:
-        return RootVertexGroup.index
-    else:
-        #If there is not VertexGroup associated to the root bone name, we don't have a vertex index.
-        #so use the next available free index
-        return len(Object.vertex_groups)
-
-         
-def WriteMeshSkinWeightsForGeoModel(Config, Object, Mesh, GeoModel):
-    ArmatureList = [Modifier for Modifier in Object.modifiers if Modifier.type == "ARMATURE"]
-    if ArmatureList:
-        ArmatureObject = ArmatureList[0].object
-        if ArmatureObject is None:
-            return
-        RootBone = GetFirstRootBone(ArmatureObject)
-        RootVertexGroup = GetVertexGroupFromBone(Object, RootBone)
-        BoneNames = GetBoneListNames(ArmatureObject.data.bones)
-
-        GeoModel.armatureObjectName = StripName(ArmatureObject.name)
-        if RootBone:
-            GeoModel.armatureRootBone = RootBone
-            GeoModel.armatureRootBoneIndex = FindUniqueIndexForRootBone(Object, RootVertexGroup)
-
-        # Marmalade need to declare a vertex per list of affected bones
-        # so first we have to get all the combinations of affected bones that exist in the mesh
-        # to build thoses groups, we build a unique key (like a bit field, where each bit is a VertexGroup.Index): Sum(2^VertGroupIndex)... so we have a unique Number per combinations
-        
-        for Vertex in Mesh.vertices:
-            VertexIndex = Vertex.index + GeoModel.vbaseIndex
-            AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup, BoneNames)
-            GeoModel.skinnedVertices.append(VertexIndex)
-
-        if Config.MergeModes != 1:
-            # write skin file directly
-            PrintSkinWeights(Config, GeoModel.armatureObjectName, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, StripName(Object.name))
-
-
-def PrintSkinWeights(Config, ArmatureObjectName, useBonesDict, mapVertexGroupNames, GeoName):        
-        #Create the skin file
-        skinfullname = os.path.dirname(Config.FilePath) + "\models\%s.skin" % GeoName
-        ensure_dir(skinfullname)
-        if Config.Verbose:
-            print("      Creating skin file %s" % (skinfullname))
-        skinFile = open(skinfullname, "w")
-        skinFile.write('// skin file exported from : %r\n' % os.path.basename(bpy.data.filepath))   
-        skinFile.write("CIwAnimSkin\n")
-        skinFile.write("{\n")
-        skinFile.write("\tskeleton \"%s\"\n" % ArmatureObjectName)
-        skinFile.write("\tmodel \"%s\"\n" % GeoName)
-
-        # now we have Bones grouped in the dictionary , along with the associated influenced vertex weighting
-        # So simply iterate the dictionary
-        Config.File.write("\t\".\models\%s.skin\"\n" % GeoName)
-        for pair_ListGroupIndices_ListAssignedVertices in useBonesDict.values():
-            skinFile.write("\tCIwAnimSkinSet\n")
-            skinFile.write("\t{\n")
-            skinFile.write("\t\tuseBones {")
-            for vertexGroupIndex in pair_ListGroupIndices_ListAssignedVertices[0]:
-                skinFile.write(" %s" % mapVertexGroupNames[vertexGroupIndex])
-            skinFile.write(" }\n")
-            skinFile.write("\t\tnumVerts %d\n" % len(pair_ListGroupIndices_ListAssignedVertices[1]))
-            for VertexWeightString in pair_ListGroupIndices_ListAssignedVertices[1]:
-                skinFile.write(VertexWeightString)
-            skinFile.write("\t}\n")
-
-        skinFile.write("}\n")
-        skinFile.close()
-
-
-def AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, useBonesDict, mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup, BoneNames):
-    #build useBones
-    useBonesKey = 0
-    vertexGroupIndices = []
-    weightTotal = 0.0
-    if (len(Vertex.groups)) > 4:
-        print ("ERROR Vertex %d is influenced by more than 4 bones\n" % (VertexIndex))
-    for VertexGroup in Vertex.groups:
-        if (VertexGroup.weight > 0):
-            groupName = Object.vertex_groups[VertexGroup.group].name
-            if groupName in BoneNames:
-                mapVertexGroupNames[VertexGroup.group] = StripBoneName(groupName)
-                if (len(vertexGroupIndices))<4:  #ignore if more 4 bones are influencing the vertex
-                    useBonesKey = useBonesKey + pow(2, VertexGroup.group)
-                    vertexGroupIndices.append(VertexGroup.group)
-                    weightTotal = weightTotal + VertexGroup.weight
-    if (weightTotal == 0):
-        bWeightTotZero = True  #avoid divide by zero later on
-        if (RootBone):
-            if Config.Verbose:
-                print(" Warning Weight is ZERO for vertex %d => Add it to the root bone" % (VertexIndex))
-            RootBoneGroupIndex = FindUniqueIndexForRootBone(Object, RootVertexGroup)
-            mapVertexGroupNames[RootBoneGroupIndex] = StripBoneName(RootBone.name)
-            useBonesKey = pow(2, RootBoneGroupIndex)
-            vertexGroupIndices = list((RootBoneGroupIndex,))
-
-            weightTotal = 1
-    else:
-        bWeightTotZero = False
-    
-    if len(vertexGroupIndices) > 0:
-        vertexGroupIndices.sort();
-           
-        #build the vertex weight string: vertex indices, followed by influence weight for each bone
-        VertexWeightString = "\t\tvertWeights { %d" % (VertexIndex)
-        for vertexGroupIndex in vertexGroupIndices:
-            #get the weight of this specific VertexGroup (aka bone)
-            boneWeight = 1
-            for VertexGroup in Vertex.groups:
-                if VertexGroup.group == vertexGroupIndex:
-                    boneWeight = VertexGroup.weight
-            #calculate the influence of this bone compared to the total of weighting applied to this Vertex
-            if not bWeightTotZero:
-                VertexWeightString += ", %.7f" % (boneWeight / weightTotal)
-            else:
-                VertexWeightString += ", %.7f" % (1.0 / len(vertexGroupIndices))
-        VertexWeightString += "}"
-        if bWeightTotZero:
-            VertexWeightString += " // total weight was zero in blender , export assign it to the RootBone with weight 1." 
-        if (len(Vertex.groups)) > 4:
-            VertexWeightString += " // vertex is associated to more than 4 bones in blender !! skip some bone association (was associated to %d bones)." % (len(Vertex.groups))
-        VertexWeightString += "\n"
-           
-        #store in dictionnary information
-        if useBonesKey not in useBonesDict:
-            VertexList = []
-            VertexList.append(VertexWeightString)
-            useBonesDict[useBonesKey] = (vertexGroupIndices, VertexList)
-        else:
-            pair_ListGroupIndices_ListAssignedVertices = useBonesDict[useBonesKey]
-            pair_ListGroupIndices_ListAssignedVertices[1].append(VertexWeightString)
-            useBonesDict[useBonesKey] = pair_ListGroupIndices_ListAssignedVertices
-    else:
-        print ("ERROR Vertex %d is not skinned (it doesn't belong to any vertex group\n" % (VertexIndex)) 
-
-
-
-############# ARMATURE: Bone export, and Bone animation export 
-
-         
-def WriteArmatureParentRootBones(Config, Object, RootBonesList, skelFile):
-
-    if len(RootBonesList) > 1:
-        print(" /!\\  WARNING ,Marmelade need only one ROOT bone per armature, there is %d root bones " % len(RootBonesList))
-        print(RootBonesList)
-        
-    PoseBones = Object.pose.bones
-    for Bone in RootBonesList:
-        if Config.Verbose:
-            print("      Writing Root Bone: {}...".format(Bone.name))
-
-        PoseBone = PoseBones[Bone.name]
-        WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True)
-        if Config.Verbose:
-            print("      Done")
-        WriteArmatureChildBones(Config, Object, Bone.children, skelFile)
-
-            
-def WriteArmatureChildBones(Config, Object, BonesList, skelFile):
-    PoseBones = Object.pose.bones
-    for Bone in BonesList:
-        if Config.Verbose:
-            print("      Writing Child Bone: {}...".format(Bone.name))
-        PoseBone = PoseBones[Bone.name]
-        WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True)
-        if Config.Verbose:
-            print("      Done")
-            
-        WriteArmatureChildBones(Config, Object, Bone.children, skelFile)
-
-
-def WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, File, isRestPoseNotAnimPose):
-    # Compute armature scale : 
-    # Many others exporter require sthe user to do Apply Scale in Object Mode to have 1,1,1 scale and so that anim data are correctly scaled
-    # Here we retreive the Scale of the Armture Object.matrix_world.to_scale() and we use it to scale the bones :-)
-    # So new Blender user should not complain about bad animation export if they forgot to apply the Scale to 1,1,1
-    
-    armScale = Object.matrix_world.to_scale()
-    armRot = Object.matrix_world.to_quaternion()
-    if isRestPoseNotAnimPose:
-        #skel file, bone header
-        File.write("\tCIwAnimBone\n")
-        File.write("\t{\n")
-        File.write("\t\tname \"%s\"\n" % StripBoneName(Bone.name))
-        #get bone local matrix for rest pose
-        if Bone.parent:
-            File.write("\t\tparent \"%s\"\n" % StripBoneName(Bone.parent.name))
-            localmat = Bone.parent.matrix_local.inverted() * Bone.matrix_local
-        else:
-            localmat = Bone.matrix_local
-    else:
-        #anim file, bone header
-        File.write("\t\t\n")
-        File.write("\t\tbone \"%s\" \n" % StripBoneName(Bone.name))
-        localmat = PoseBone.matrix
-        #get bone local matrix for current anim pose
-        if Bone.parent:
-            ParentPoseBone = PoseBones[Bone.parent.name]
-            localmat = ParentPoseBone.matrix.inverted() * PoseBone.matrix
-        else:
-            localmat = PoseBone.matrix
-
-    if not Bone.parent:
-        #Flip Y Z axes (only on root bone, other bones are local to root bones, so no need to rotate)
-        X_ROT = mathutils.Matrix.Rotation(-math.pi / 2, 4, 'X')
-        if Config.MergeModes > 0:
-            # Merge mode is in world coordinates and not in model coordinates: so apply the world coordinate on the rootbone
-            localmat = X_ROT * Object.matrix_world * localmat
-            armScale.x =  armScale.y = armScale.z = 1
-        else:
-            localmat= X_ROT * armRot.to_matrix().to_4x4() * localmat #apply the armature rotation on the root bone
-
-    
-    loc = localmat.to_translation()
-    quat = localmat.to_quaternion()
-
-    #Scale the bone
-    loc.x *= (armScale.x * Config.Scale)
-    loc.y *= (armScale.y * Config.Scale)
-    loc.z *= (armScale.z * Config.Scale)
-    
-    File.write("\t\tpos { %.9f, %.9f, %.9f }\n" % (loc[0], loc[1], loc[2]))
-    File.write("\t\trot { %.9f, %.9f, %.9f, %.9f }\n" % (quat.w, quat.x, quat.y, quat.z))
-
-    if isRestPoseNotAnimPose:
-        File.write("\t}\n")
-
-      
-def WriteKeyedAnimationSet(Config, Scene):  
-    for Object in [Object for Object in Config.ObjectList if Object.animation_data]:
-        if Config.Verbose:
-            print("  Writing Animation Data for Object: {}".format(Object.name))
-        actions = []
-        if Config.ExportAnimationActions == 0 and Object.animation_data.action:
-            actions.append(Object.animation_data.action)
-        else:
-            actions = bpy.data.actions[:]   
-            DefaultAction = Object.animation_data.action
-        
-        for Action in actions:
-            if Config.ExportAnimationActions == 0:
-                animFileName = StripName(Object.name)
-            else:
-                Object.animation_data.action = Action
-                animFileName = "%s_%s" % (StripName(Object.name),StripName(Action.name))
-                          
-            #Object animated (aka single bone object)
-            #build key frame time list
-
-            keyframeTimes = set()
-            if Config.ExportAnimationFrames == 1:
-                # Exports only key frames
-                for FCurve in Action.fcurves:
-                    for Keyframe in FCurve.keyframe_points:
-                        if Keyframe.co[0] < Scene.frame_start:
-                            keyframeTimes.add(Scene.frame_start)
-                        elif Keyframe.co[0] > Scene.frame_end:
-                            keyframeTimes.add(Scene.frame_end)
-                        else:
-                            keyframeTimes.add(int(Keyframe.co[0]))
-            else:
-                # Exports all frames
-                keyframeTimes.update(range(Scene.frame_start, Scene.frame_end + 1, 1))
-            keyframeTimes = list(keyframeTimes)
-            keyframeTimes.sort()
-            if len(keyframeTimes):
-                #Create the anim file for offset animation (or single bone animation
-                animfullname = os.path.dirname(Config.FilePath) + "\\anims\\%s_offset.anim" % animFileName
-                #not yet supported
-                """
-                ##    ensure_dir(animfullname)
-                ##    if Config.Verbose:
-                ##        print("      Creating anim file (single bone animation) %s" % (animfullname))
-                ##    animFile = open(animfullname, "w")
-                ##    animFile.write('// anim file exported from : %r\n' % os.path.basename(bpy.data.filepath))   
-                ##    animFile.write("CIwAnim\n")
-                ##    animFile.write("{\n")
-                ##    animFile.write("\tent \"%s\"\n" % (StripName(Object.name)))
-                ##    animFile.write("\tskeleton \"SingleBone\"\n")
-                ##    animFile.write("\t\t\n")
-                ##
-                ##    Config.File.write("\t\".\\anims\\%s_offset.anim\"\n" % animFileName))
-                ##
-                ##    for KeyframeTime in keyframeTimes:
-                ##        #Scene.frame_set(KeyframeTime)    
-                ##        animFile.write("\tCIwAnimKeyFrame\n")
-                ##        animFile.write("\t{\n")
-                ##        animFile.write("\t\ttime %.2f // frame num %d \n" % (KeyframeTime/Config.AnimFPS, KeyframeTime))
-                ##        animFile.write("\t\t\n")
-                ##        animFile.write("\t\tbone \"SingleBone\" \n")
-                ##        #postion
-                ##        posx = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "location" and FCurve.array_index == 0: posx = FCurve.evaluate(KeyframeTime)
-                ##        posy = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "location" and FCurve.array_index == 1: posy = FCurve.evaluate(KeyframeTime)
-                ##        posz = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "location" and FCurve.array_index == 2: posz = FCurve.evaluate(KeyframeTime)
-                ##        animFile.write("\t\tpos {%.9f,%.9f,%.9f}\n" % (posx, posy, posz))
-                ##        #rotation
-                ##        rot = Euler()
-                ##        rot[0] = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "rotation_euler" and FCurve.array_index == 1: rot[0] = FCurve.evaluate(KeyframeTime)
-                ##        rot[1] = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "rotation_euler" and FCurve.array_index == 2: rot[1] = FCurve.evaluate(KeyframeTime)
-                ##        rot[2] = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "rotation_euler" and FCurve.array_index == 3: rot[2] = FCurve.evaluate(KeyframeTime)
-                ##        rot = rot.to_quaternion()
-                ##        animFile.write("\t\trot {%.9f,%.9f,%.9f,%.9f}\n" % (rot[0], rot[1], rot[2], rot[3]))
-                ##        #scale
-                ##        scalex = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "scale" and FCurve.array_index == 0: scalex = FCurve.evaluate(KeyframeTime)
-                ##        scaley = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "scale" and FCurve.array_index == 1: scaley = FCurve.evaluate(KeyframeTime)
-                ##        scalez = 0
-                ##        for FCurve in Action.fcurves:
-                ##            if FCurve.data_path == "scale" and FCurve.array_index == 2: scalez = FCurve.evaluate(KeyframeTime)
-                ##        animFile.write("\t\t//scale {%.9f,%.9f,%.9f}\n" % (scalex, scaley, scalez))
-                ##        #keyframe done
-                ##        animFile.write("\t}\n")
-                ##    animFile.write("}\n")
-                ##    animFile.close()
-                """
-            else:
-                if Config.Verbose:
-                    print("    Object %s has no useable animation data." % (StripName(Object.name)))
-
-            if Config.ExportArmatures and Object.type == "ARMATURE":
-                if Config.Verbose:
-                    print("    Writing Armature Bone Animation Data...\n")
-                PoseBones = Object.pose.bones
-                Bones = Object.data.bones
-                #riged bones animated 
-                #build key frame time list
-                keyframeTimes = set()
-                if Config.ExportAnimationFrames == 1:
-                    # Exports only key frames
-                    for FCurve in Action.fcurves:
-                        for Keyframe in FCurve.keyframe_points:
-                            if Keyframe.co[0] < Scene.frame_start:
-                                keyframeTimes.add(Scene.frame_start)
-                            elif Keyframe.co[0] > Scene.frame_end:
-                                keyframeTimes.add(Scene.frame_end)
-                            else:
-                                keyframeTimes.add(int(Keyframe.co[0]))
-                else:
-                    # Exports all frame
-                    keyframeTimes.update(range(Scene.frame_start, Scene.frame_end + 1, 1))
-                   
-                keyframeTimes = list(keyframeTimes)
-                keyframeTimes.sort()
-                if Config.Verbose:
-                    print("Exporting frames: ")
-                    print(keyframeTimes)
-                    if (Scene.frame_preview_end > Scene.frame_end):
-                        print(" WARNING: END Frame of animation in UI preview is Higher than the Scene Frame end:\n Scene.frame_end %d versus Scene.frame_preview_end %d.\n"
-                              % (Scene.frame_end, Scene.frame_preview_end))
-                        print(" => You might need to change the Scene End Frame, to match the current UI preview frame end...\n=> if you don't want to miss end of animation.\n")
-
-                if len(keyframeTimes):
-                    #Create the anim file
-                    animfullname = os.path.dirname(Config.FilePath) + "\\anims\\%s.anim" % animFileName
-                    ensure_dir(animfullname)
-                    if Config.Verbose:
-                        print("      Creating anim file (bones animation) %s\n" % (animfullname))
-                        print("      Frame count %d \n" % (len(keyframeTimes)))
-                    animFile = open(animfullname, "w")
-                    animFile.write('// anim file exported from : %r\n' % os.path.basename(bpy.data.filepath))   
-                    animFile.write("CIwAnim\n")
-                    animFile.write("{\n")
-                    animFile.write("\tskeleton \"%s\"\n" % (StripName(Object.name)))
-                    animFile.write("\t\t\n")
-
-                    Config.File.write("\t\".\\anims\\%s.anim\"\n" % animFileName)
-
-                    for KeyframeTime in keyframeTimes:
-                        if Config.Verbose:
-                            print("     Writing Frame %d:" % KeyframeTime)
-                        animFile.write("\tCIwAnimKeyFrame\n")
-                        animFile.write("\t{\n")
-                        animFile.write("\t\ttime %.2f // frame num %d \n" % (KeyframeTime / Config.AnimFPS, KeyframeTime))
-                        #for every frame write bones positions
-                        Scene.frame_set(KeyframeTime)
-                        for PoseBone in PoseBones:
-                            if Config.Verbose:
-                                print("      Writing Bone: {}...".format(PoseBone.name))
-                            animFile.write("\t\t\n")
-
-                            Bone = Bones[PoseBone.name]
-                            WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, animFile, False)
-                        #keyframe done
-                        animFile.write("\t}\n")
-                    animFile.write("}\n")
-                    animFile.close()
-            else:
-                if Config.Verbose:
-                    print("    Object %s has no useable animation data." % (StripName(Object.name)))
-        if Config.ExportAnimationActions == 1:
-            #set back the original default animation
-            Object.animation_data.action = DefaultAction
-        if Config.Verbose:
-            print("  Done") #Done with Object
- 
-
-                                
- 
-################## Utilities
-            
-def StripBoneName(name):
-    return name.replace(" ", "")
-
-
-def StripName(Name):
-    
-    def ReplaceSet(String, OldSet, NewChar):
-        for OldChar in OldSet:
-            String = String.replace(OldChar, NewChar)
-        return String
-    
-    import string
-    
-    NewName = ReplaceSet(Name, string.punctuation + " ", "_")
-    return NewName
-
-
-def ensure_dir(f):
-    d = os.path.dirname(f)
-    if not os.path.exists(d):
-        os.makedirs(d)
-        
-
-def CloseFile(Config):
-    if Config.Verbose:
-        print("Closing File...")
-    Config.File.close()
-    if Config.Verbose:
-        print("Done")
-
-
-CoordinateSystems = (
-    ("1", "Left-Handed", ""),
-    ("2", "Right-Handed", ""),
-    )
-
-
-AnimationFrameModes = (
-    ("0", "None", ""),
-    ("1", "Keyframes Only", ""),
-    ("2", "Full Animation", ""),
-    )
-
-AnimationActions = (
-    ("0", "Default Animation", ""),
-    ("1", "All Animations", ""),
-    )
-
-ExportModes = (
-    ("1", "All Objects", ""),
-    ("2", "Selected Objects", ""),
-    )
-
-MergeModes = (
-    ("0", "None", ""),
-    ("1", "Merge in one big Mesh", ""),
-    ("2", "Merge in unique Geo File containing several meshes", ""),
-    )
-
-
-from bpy.props import StringProperty, EnumProperty, BoolProperty, IntProperty
-
-
-class MarmaladeExporter(bpy.types.Operator):
-    """Export to the Marmalade model format (.group)"""
-
-    bl_idname = "export.marmalade"
-    bl_label = "Export Marmalade"
-
-    filepath = StringProperty(subtype='FILE_PATH')
-     #Export Mode
-    ExportMode = EnumProperty(
-        name="Export",
-        description="Select which objects to export. Only Mesh, Empty, " \
-                    "and Armature objects will be exported",
-        items=ExportModes,
-        default="1")
-
-    MergeModes = EnumProperty(
-        name="Merge",
-        description="Select if objects should be merged in one Geo File (it can be usefull if a scene is done by several cube/forms)." \
-                    "Do not merge rigged character that have an armature.",
-        items=MergeModes,
-        default="0")
-    
-    #General Options
-    Scale = IntProperty(
-        name="Scale Percent",
-        description="Scale percentage applied for export",
-        default=100, min=1, max=1000)
-    
-    FlipNormals = BoolProperty(
-        name="Flip Normals",
-        description="",
-        default=False)
-    ApplyModifiers = BoolProperty(
-        name="Apply Modifiers",
-        description="Apply object modifiers before export",
-        default=False)
-    ExportVertexColors = BoolProperty(
-        name="Export Vertices Colors",
-        description="Export colors set on vertices, if any",
-        default=True)
-    ExportMaterialColors = BoolProperty(
-        name="Export Material Colors",
-        description="Ambient color is exported on the Material",
-        default=True)
-    ExportTextures = BoolProperty(
-        name="Export Textures and UVs",
-        description="Exports UVs and Reference external image files to be used by the model",
-        default=True)
-    CopyTextureFiles = BoolProperty(
-        name="Copy Textures Files",
-        description="Copy referenced Textures files in the models\\textures directory",
-        default=True)
-    ExportArmatures = BoolProperty(
-        name="Export Armatures",
-        description="Export the bones of any armatures to deform meshes",
-        default=True)
-    ExportAnimationFrames = EnumProperty(
-        name="Animations Frames",
-        description="Select the type of animations to export. Only object " \
-                    "and armature bone animations can be exported. Keyframes exports only the keyed frames" \
-                    "Full Animation exports every frames, None disables animationq export. ",
-        items=AnimationFrameModes,
-        default="1")
-    ExportAnimationActions = EnumProperty(
-        name="Animations Actions",
-        description="By default only the Default Animation Action assoiated to an armature is exported." \
-                    "However if you have defined several animations on the same armature,"\
-                    "you can select to export all animations. You can see the list of animation actions in the DopeSheet window.",
-        items=AnimationActions,
-        default="0")
-    if bpy.context.scene:
-        defFPS = bpy.context.scene.render.fps
-    else:
-        defFPS = 30                 
-    AnimFPS = IntProperty(
-        name="Animation FPS",
-        description="Frame rate used to export animation in seconds (can be used to artficially slow down the exported animation, or to speed up it",
-        default=defFPS, min=1, max=300)
-
-    #Advance Options
-    CoordinateSystem = EnumProperty(
-        name="System",
-        description="Select a coordinate system to export to",
-        items=CoordinateSystems,
-        default="1")
-    
-    Verbose = BoolProperty(
-        name="Verbose",
-        description="Run the exporter in debug mode. Check the console for output",
-        default=True)
-
-    def execute(self, context):
-        #Append .group
-        FilePath = bpy.path.ensure_ext(self.filepath, ".group")
-
-        Config = MarmaladeExporterSettings(context,
-                                         FilePath,
-                                         CoordinateSystem=self.CoordinateSystem,
-                                         FlipNormals=self.FlipNormals,
-                                         ApplyModifiers=self.ApplyModifiers,
-                                         Scale=self.Scale,
-                                         AnimFPS=self.AnimFPS,
-                                         ExportVertexColors=self.ExportVertexColors,
-                                         ExportMaterialColors=self.ExportMaterialColors,
-                                         ExportTextures=self.ExportTextures,
-                                         CopyTextureFiles=self.CopyTextureFiles,
-                                         ExportArmatures=self.ExportArmatures,
-                                         ExportAnimationFrames=self.ExportAnimationFrames,
-                                         ExportAnimationActions=self.ExportAnimationActions,
-                                         ExportMode=self.ExportMode,
-                                         MergeModes=self.MergeModes,
-                                         Verbose=self.Verbose)
-
-        # Exit edit mode before exporting, so current object states are exported properly.
-        if bpy.ops.object.mode_set.poll():
-            bpy.ops.object.mode_set(mode='OBJECT')
-
-        ExportMadeWithMarmaladeGroup(Config)
-        return {"FINISHED"}
-
-    def invoke(self, context, event):
-        if not self.filepath:
-            self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".group")
-        WindowManager = context.window_manager
-        WindowManager.fileselect_add(self)
-        return {"RUNNING_MODAL"}
-
-
-def menu_func(self, context):
-    self.layout.operator(MarmaladeExporter.bl_idname, text="Marmalade cross-platform Apps (.group)")
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_file_export.append(menu_func)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_file_export.remove(menu_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_export_md3.py b/release/scripts/addons_contrib/io_export_md3.py
deleted file mode 100644
index 6c163a7..0000000
--- a/release/scripts/addons_contrib/io_export_md3.py
+++ /dev/null
@@ -1,694 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    'name': 'Quake Model 3 (.md3)',
-    'author': 'Xembie',
-    'version': (0, 7),
-    'blender': (2, 5, 3),
-    'location': 'File > Export',
-    'description': 'Save a Quake Model 3 File)',
-    'warning': '', # used for warning icon and text in addons panel
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\
-        'Scripts/',
-    'tracker_url': 'http://projects.blender.org/tracker/index.php?'\
-        'func=detail&aid=23160',
-    'category': 'Import-Export'}
-
-
-import bpy,struct,math,os
-
-MAX_QPATH = 64
-
-MD3_IDENT = "IDP3"
-MD3_VERSION = 15
-MD3_MAX_TAGS = 16
-MD3_MAX_SURFACES = 32
-MD3_MAX_FRAMES = 1024
-MD3_MAX_SHADERS = 256
-MD3_MAX_VERTICES = 4096
-MD3_MAX_TRIANGLES = 8192
-MD3_XYZ_SCALE = 64.0
-
-class md3Vert:
-    xyz = []
-    normal = 0
-    binaryFormat = "<3hH"
-    
-    def __init__(self):
-        self.xyz = [0.0, 0.0, 0.0]
-        self.normal = 0
-        
-    def GetSize(self):
-        return struct.calcsize(self.binaryFormat)
-    
-    # copied from PhaethonH <phaethon at linux.ucla.edu> md3.py
-    def Decode(self, latlng):
-        lat = (latlng >> 8) & 0xFF;
-        lng = (latlng) & 0xFF;
-        lat *= math.pi / 128;
-        lng *= math.pi / 128;
-        x = math.cos(lat) * math.sin(lng)
-        y = math.sin(lat) * math.sin(lng)
-        z =                 math.cos(lng)
-        retval = [ x, y, z ]
-        return retval
-    
-    # copied from PhaethonH <phaethon at linux.ucla.edu> md3.py
-    def Encode(self, normal):
-        x = normal[0]
-        y = normal[1]
-        z = normal[2]
-        # normalize
-        l = math.sqrt((x*x) + (y*y) + (z*z))
-        if l == 0:
-            return 0
-        x = x/l
-        y = y/l
-        z = z/l
-        
-        if (x == 0.0) & (y == 0.0) :
-            if z > 0.0:
-                return 0
-            else:
-                return (128 << 8)
-        
-        lng = math.acos(z) * 255 / (2 * math.pi)
-        lat = math.atan2(y, x) * 255 / (2 * math.pi)
-        retval = ((int(lat) & 0xFF) << 8) | (int(lng) & 0xFF)
-        return retval
-        
-    def Save(self, file):
-        tmpData = [0] * 4
-        tmpData[0] = int(self.xyz[0] * MD3_XYZ_SCALE)
-        tmpData[1] = int(self.xyz[1] * MD3_XYZ_SCALE)
-        tmpData[2] = int(self.xyz[2] * MD3_XYZ_SCALE)
-        tmpData[3] = self.normal
-        data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1], tmpData[2], tmpData[3])
-        file.write(data)
-        
-class md3TexCoord:
-    u = 0.0
-    v = 0.0
-
-    binaryFormat = "<2f"
-
-    def __init__(self):
-        self.u = 0.0
-        self.v = 0.0
-        
-    def GetSize(self):
-        return struct.calcsize(self.binaryFormat)
-
-    def Save(self, file):
-        tmpData = [0] * 2
-        tmpData[0] = self.u
-        tmpData[1] = 1.0 - self.v
-        data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1])
-        file.write(data)
-
-class md3Triangle:
-    indexes = []
-
-    binaryFormat = "<3i"
-
-    def __init__(self):
-        self.indexes = [ 0, 0, 0 ]
-        
-    def GetSize(self):
-        return struct.calcsize(self.binaryFormat)
-
-    def Save(self, file):
-        tmpData = [0] * 3
-        tmpData[0] = self.indexes[0]
-        tmpData[1] = self.indexes[2] # reverse
-        tmpData[2] = self.indexes[1] # reverse
-        data = struct.pack(self.binaryFormat,tmpData[0], tmpData[1], tmpData[2])
-        file.write(data)
-
-class md3Shader:
-    name = ""
-    index = 0
-    
-    binaryFormat = "<%dsi" % MAX_QPATH
-
-    def __init__(self):
-        self.name = ""
-        self.index = 0
-        
-    def GetSize(self):
-        return struct.calcsize(self.binaryFormat)
-
-    def Save(self, file):
-        tmpData = [0] * 2
-        tmpData[0] = self.name
-        tmpData[1] = self.index
-        data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1])
-        file.write(data)
-
-class md3Surface:
-    ident = ""
-    name = ""
-    flags = 0
-    numFrames = 0
-    numShaders = 0
-    numVerts = 0
-    numTriangles = 0
-    ofsTriangles = 0
-    ofsShaders = 0
-    ofsUV = 0
-    ofsVerts = 0
-    ofsEnd = 0
-    shaders = []
-    triangles = []
-    uv = []
-    verts = []
-    
-    binaryFormat = "<4s%ds10i" % MAX_QPATH  # 1 int, name, then 10 ints
-    
-    def __init__(self):
-        self.ident = ""
-        self.name = ""
-        self.flags = 0
-        self.numFrames = 0
-        self.numShaders = 0
-        self.numVerts = 0
-        self.numTriangles = 0
-        self.ofsTriangles = 0
-        self.ofsShaders = 0
-        self.ofsUV = 0
-        self.ofsVerts = 0
-        self.ofsEnd
-        self.shaders = []
-        self.triangles = []
-        self.uv = []
-        self.verts = []
-        
-    def GetSize(self):
-        sz = struct.calcsize(self.binaryFormat)
-        self.ofsTriangles = sz
-        for t in self.triangles:
-            sz += t.GetSize()
-        self.ofsShaders = sz
-        for s in self.shaders:
-            sz += s.GetSize()
-        self.ofsUV = sz
-        for u in self.uv:
-            sz += u.GetSize()
-        self.ofsVerts = sz
-        for v in self.verts:
-            sz += v.GetSize()
-        self.ofsEnd = sz
-        return self.ofsEnd
-    
-    def Save(self, file):
-        self.GetSize()
-        tmpData = [0] * 12
-        tmpData[0] = self.ident
-        tmpData[1] = self.name
-        tmpData[2] = self.flags
-        tmpData[3] = self.numFrames
-        tmpData[4] = self.numShaders
-        tmpData[5] = self.numVerts
-        tmpData[6] = self.numTriangles
-        tmpData[7] = self.ofsTriangles
-        tmpData[8] = self.ofsShaders
-        tmpData[9] = self.ofsUV
-        tmpData[10] = self.ofsVerts
-        tmpData[11] = self.ofsEnd
-        data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7],tmpData[8],tmpData[9],tmpData[10],tmpData[11])
-        file.write(data)
-
-        # write the tri data
-        for t in self.triangles:
-            t.Save(file)
-
-        # save the shader coordinates
-        for s in self.shaders:
-            s.Save(file)
-
-        # save the uv info
-        for u in self.uv:
-            u.Save(file)
-
-        # save the verts
-        for v in self.verts:
-            v.Save(file)
-
-class md3Tag:
-    name = ""
-    origin = []
-    axis = []
-    
-    binaryFormat="<%ds3f9f" % MAX_QPATH
-    
-    def __init__(self):
-        self.name = ""
-        self.origin = [0, 0, 0]
-        self.axis = [0, 0, 0, 0, 0, 0, 0, 0, 0]
-        
-    def GetSize(self):
-        return struct.calcsize(self.binaryFormat)
-        
-    def Save(self, file):
-        tmpData = [0] * 13
-        tmpData[0] = self.name
-        tmpData[1] = float(self.origin[0])
-        tmpData[2] = float(self.origin[1])
-        tmpData[3] = float(self.origin[2])
-        tmpData[4] = float(self.axis[0])
-        tmpData[5] = float(self.axis[1])
-        tmpData[6] = float(self.axis[2])
-        tmpData[7] = float(self.axis[3])
-        tmpData[8] = float(self.axis[4])
-        tmpData[9] = float(self.axis[5])
-        tmpData[10] = float(self.axis[6])
-        tmpData[11] = float(self.axis[7])
-        tmpData[12] = float(self.axis[8])
-        data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6], tmpData[7], tmpData[8], tmpData[9], tmpData[10], tmpData[11], tmpData[12])
-        file.write(data)
-    
-class md3Frame:
-    mins = 0
-    maxs = 0
-    localOrigin = 0
-    radius = 0.0
-    name = ""
-    
-    binaryFormat="<3f3f3ff16s"
-    
-    def __init__(self):
-        self.mins = [0, 0, 0]
-        self.maxs = [0, 0, 0]
-        self.localOrigin = [0, 0, 0]
-        self.radius = 0.0
-        self.name = ""
-        
-    def GetSize(self):
-        return struct.calcsize(self.binaryFormat)
-
-    def Save(self, file):
-        tmpData = [0] * 11
-        tmpData[0] = self.mins[0]
-        tmpData[1] = self.mins[1]
-        tmpData[2] = self.mins[2]
-        tmpData[3] = self.maxs[0]
-        tmpData[4] = self.maxs[1]
-        tmpData[5] = self.maxs[2]
-        tmpData[6] = self.localOrigin[0]
-        tmpData[7] = self.localOrigin[1]
-        tmpData[8] = self.localOrigin[2]
-        tmpData[9] = self.radius
-        tmpData[10] = self.name
-        data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7], tmpData[8], tmpData[9], tmpData[10])
-        file.write(data)
-
-class md3Object:
-    # header structure
-    ident = ""            # this is used to identify the file (must be IDP3)
-    version = 0            # the version number of the file (Must be 15)
-    name = ""
-    flags = 0
-    numFrames = 0
-    numTags = 0
-    numSurfaces = 0
-    numSkins = 0
-    ofsFrames = 0
-    ofsTags = 0
-    ofsSurfaces = 0
-    ofsEnd = 0
-    frames = []
-    tags = []
-    surfaces = []
-
-    binaryFormat="<4si%ds9i" % MAX_QPATH  # little-endian (<), 17 integers (17i)
-
-    def __init__(self):
-        self.ident = 0
-        self.version = 0
-        self.name = ""
-        self.flags = 0
-        self.numFrames = 0
-        self.numTags = 0
-        self.numSurfaces = 0
-        self.numSkins = 0
-        self.ofsFrames = 0
-        self.ofsTags = 0
-        self.ofsSurfaces = 0
-        self.ofsEnd = 0
-        self.frames = []
-        self.tags = []
-        self.surfaces = []
-
-    def GetSize(self):
-        self.ofsFrames = struct.calcsize(self.binaryFormat)
-        self.ofsTags = self.ofsFrames
-        for f in self.frames:
-            self.ofsTags += f.GetSize()
-        self.ofsSurfaces += self.ofsTags
-        for t in self.tags:
-            self.ofsSurfaces += t.GetSize()
-        self.ofsEnd = self.ofsSurfaces
-        for s in self.surfaces:
-            self.ofsEnd += s.GetSize()
-        return self.ofsEnd
-        
-    def Save(self, file):
-        self.GetSize()
-        tmpData = [0] * 12
-        tmpData[0] = self.ident
-        tmpData[1] = self.version
-        tmpData[2] = self.name
-        tmpData[3] = self.flags
-        tmpData[4] = self.numFrames
-        tmpData[5] = self.numTags
-        tmpData[6] = self.numSurfaces
-        tmpData[7] = self.numSkins
-        tmpData[8] = self.ofsFrames
-        tmpData[9] = self.ofsTags
-        tmpData[10] = self.ofsSurfaces
-        tmpData[11] = self.ofsEnd
-
-        data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7], tmpData[8], tmpData[9], tmpData[10], tmpData[11])
-        file.write(data)
-
-        for f in self.frames:
-            f.Save(file)
-            
-        for t in self.tags:
-            t.Save(file)
-            
-        for s in self.surfaces:
-            s.Save(file)
-
-
-def message(log,msg):
-  if log:
-    log.write(msg + "\n")
-  else:
-    print(msg)
-
-class md3Settings:
-  def __init__(self,
-               savepath,
-               name,
-               logpath,
-               overwrite=True,
-               dumpall=False,
-               ignoreuvs=False,
-               scale=1.0,
-               offsetx=0.0,
-               offsety=0.0,
-               offsetz=0.0):
-    self.savepath = savepath
-    self.name = name
-    self.logpath = logpath
-    self.overwrite = overwrite
-    self.dumpall = dumpall
-    self.ignoreuvs = ignoreuvs
-    self.scale = scale
-    self.offsetx = offsetx
-    self.offsety = offsety
-    self.offsetz = offsetz
-
-def print_md3(log,md3,dumpall):
-  message(log,"Header Information")
-  message(log,"Ident: " + str(md3.ident))
-  message(log,"Version: " + str(md3.version))
-  message(log,"Name: " + md3.name)
-  message(log,"Flags: " + str(md3.flags))
-  message(log,"Number of Frames: " + str(md3.numFrames))
-  message(log,"Number of Tags: " + str(md3.numTags))
-  message(log,"Number of Surfaces: " + str(md3.numSurfaces))
-  message(log,"Number of Skins: " + str(md3.numSkins))
-  message(log,"Offset Frames: " + str(md3.ofsFrames))
-  message(log,"Offset Tags: " + str(md3.ofsTags))
-  message(log,"Offset Surfaces: " + str(md3.ofsSurfaces))
-  message(log,"Offset end: " + str(md3.ofsEnd))
-  if dumpall:
-    message(log,"Frames:")
-    for f in md3.frames:
-      message(log," Mins: " + str(f.mins[0]) + " " + str(f.mins[1]) + " " + str(f.mins[2]))
-      message(log," Maxs: " + str(f.maxs[0]) + " " + str(f.maxs[1]) + " " + str(f.maxs[2]))
-      message(log," Origin(local): " + str(f.localOrigin[0]) + " " + str(f.localOrigin[1]) + " " + str(f.localOrigin[2]))
-      message(log," Radius: " + str(f.radius))
-      message(log," Name: " + f.name)
-
-    message(log,"Tags:")
-    for t in md3.tags:
-      message(log," Name: " + t.name)
-      message(log," Origin: " + str(t.origin[0]) + " " + str(t.origin[1]) + " " + str(t.origin[2]))
-      message(log," Axis[0]: " + str(t.axis[0]) + " " + str(t.axis[1]) + " " + str(t.axis[2]))
-      message(log," Axis[1]: " + str(t.axis[3]) + " " + str(t.axis[4]) + " " + str(t.axis[5]))
-      message(log," Axis[2]: " + str(t.axis[6]) + " " + str(t.axis[7]) + " " + str(t.axis[8]))
-
-    message(log,"Surfaces:")
-    for s in md3.surfaces:
-      message(log," Ident: " + s.ident)
-      message(log," Name: " + s.name)
-      message(log," Flags: " + str(s.flags))
-      message(log," # of Frames: " + str(s.numFrames))
-      message(log," # of Shaders: " + str(s.numShaders))
-      message(log," # of Verts: " + str(s.numVerts))
-      message(log," # of Triangles: " + str(s.numTriangles))
-      message(log," Offset Triangles: " + str(s.ofsTriangles))
-      message(log," Offset UVs: " + str(s.ofsUV))
-      message(log," Offset Verts: " + str(s.ofsVerts))
-      message(log," Offset End: " + str(s.ofsEnd))
-      message(log," Shaders:")
-      for shader in s.shaders:
-        message(log,"  Name: " + shader.name)
-        message(log,"  Index: " + str(shader.index))
-      message(log," Triangles:")
-      for tri in s.triangles:
-        message(log,"  Indexes: " + str(tri.indexes[0]) + " " + str(tri.indexes[1]) + " " + str(tri.indexes[2]))
-      message(log," UVs:")
-      for uv in s.uv:
-        message(log,"  U: " + str(uv.u))
-        message(log,"  V: " + str(uv.v)) 
-      message(log," Verts:")
-      for vert in s.verts:
-        message(log,"  XYZ: " + str(vert.xyz[0]) + " " + str(vert.xyz[1]) + " " + str(vert.xyz[2]))
-        message(log,"  Normal: " + str(vert.normal))
-
-  shader_count = 0
-  vert_count = 0
-  tri_count = 0
-  for surface in md3.surfaces:
-    shader_count += surface.numShaders
-    tri_count += surface.numTriangles
-    vert_count += surface.numVerts
-
-  if md3.numTags >= MD3_MAX_TAGS:
-    message(log,"!Warning: Tag limit reached! " + str(md3.numTags))
-  if md3.numSurfaces >= MD3_MAX_SURFACES:
-    message(log,"!Warning: Surface limit reached! " + str(md3.numSurfaces))
-  if md3.numFrames >= MD3_MAX_FRAMES:
-    message(log,"!Warning: Frame limit reached! " + str(md3.numFrames))
-  if shader_count >= MD3_MAX_SHADERS:
-    message(log,"!Warning: Shader limit reached! " + str(shader_count))
-  if vert_count >= MD3_MAX_VERTICES:
-    message(log,"!Warning: Vertex limit reached! " + str(vert_count))
-  if tri_count >= MD3_MAX_TRIANGLES:
-    message(log,"!Warning: Triangle limit reached! " + str(tri_count))
-
-def save_md3(settings):
-  if settings.logpath:
-    if settings.overwrite:
-      log = open(settings.logpath,"w")
-    else:
-      log = open(settings.logpath,"a")
-  else:
-    log = 0
-  message(log,"##########Exporting MD3##########")
-  bpy.ops.object.mode_set(mode='OBJECT')
-  md3 = md3Object()
-  md3.ident = MD3_IDENT
-  md3.version = MD3_VERSION
-  md3.name = settings.name
-  md3.numFrames = (bpy.context.scene.frame_end + 1) - bpy.context.scene.frame_start
-
-  for obj in bpy.context.selected_objects:
-    if obj.type == 'MESH':
-      nsurface = md3Surface()
-      nsurface.name = obj.name
-      nsurface.ident = MD3_IDENT
- 
-      vertlist = []
-
-      for f,face in enumerate(obj.data.faces):
-        ntri = md3Triangle()
-        if len(face.verts) != 3:
-          message(log,"Found a nontriangle face in object " + obj.name)
-          continue
-
-        for v,vert_index in enumerate(face.verts):
-          uv_u = round(obj.data.active_uv_texture.data[f].uv[v][0],5)
-          uv_v = round(obj.data.active_uv_texture.data[f].uv[v][1],5)
-
-          match = 0
-          match_index = 0
-          for i,vi in enumerate(vertlist):
-            if vi == vert_index:
-              if settings.ignoreuvs:
-                match = 1#there is a uv match for all
-                match_index = i
-              else:
-                if nsurface.uv[i].u == uv_u and nsurface.uv[i].v == uv_v:
-                  match = 1
-                  match_index = i
-
-          if match == 0:
-            vertlist.append(vert_index)
-            ntri.indexes[v] = nsurface.numVerts
-            ntex = md3TexCoord()
-            ntex.u = uv_u
-            ntex.v = uv_v
-            nsurface.uv.append(ntex)
-            nsurface.numVerts += 1
-          else:
-            ntri.indexes[v] = match_index
-        nsurface.triangles.append(ntri)
-        nsurface.numTriangles += 1
-
-      if obj.data.active_uv_texture:
-        nshader = md3Shader()
-        nshader.name = obj.data.active_uv_texture.name
-        nshader.index = nsurface.numShaders
-        nsurface.shaders.append(nshader)
-        nsurface.numShaders += 1
-      if nsurface.numShaders < 1: #we should add a blank as a placeholder
-        nshader = md3Shader()
-        nshader.name = "NULL"
-        nsurface.shaders.append(nshader)
-        nsurface.numShaders += 1
-
-      for frame in range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1):
-        bpy.context.scene.set_frame(frame)
-        fobj = obj.create_mesh(bpy.context.scene,True,'PREVIEW')
-        fobj.calc_normals()
-        nframe = md3Frame()
-        nframe.name = str(frame)
-        for vi in vertlist:
-            vert = fobj.verts[vi]
-            nvert = md3Vert()
-            nvert.xyz = vert.co * obj.matrix_world
-            nvert.xyz[0] = (round(nvert.xyz[0] + obj.matrix_world[3][0],5) * settings.scale) + settings.offsetx
-            nvert.xyz[1] = (round(nvert.xyz[1] + obj.matrix_world[3][1],5) * settings.scale) + settings.offsety
-            nvert.xyz[2] = (round(nvert.xyz[2] + obj.matrix_world[3][2],5) * settings.scale) + settings.offsetz
-            nvert.normal = nvert.Encode(vert.normal)
-            for i in range(0,3):
-              nframe.mins[i] = min(nframe.mins[i],nvert.xyz[i])
-              nframe.maxs[i] = max(nframe.maxs[i],nvert.xyz[i])
-            minlength = math.sqrt(math.pow(nframe.mins[0],2) + math.pow(nframe.mins[1],2) + math.pow(nframe.mins[2],2))
-            maxlength = math.sqrt(math.pow(nframe.maxs[0],2) + math.pow(nframe.maxs[1],2) + math.pow(nframe.maxs[2],2))
-            nframe.radius = round(max(minlength,maxlength),5)
-            nsurface.verts.append(nvert) 
-        md3.frames.append(nframe)
-        nsurface.numFrames += 1
-        bpy.data.meshes.remove(fobj)
-      md3.surfaces.append(nsurface)
-      md3.numSurfaces += 1
-
-    elif obj.type == 'EMPTY':
-      md3.numTags += 1
-      for frame in range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1):
-        bpy.context.scene.set_frame(frame)
-        ntag = md3Tag()
-        ntag.origin[0] = (round(obj.matrix_world[3][0] * settings.scale,5)) + settings.offsetx
-        ntag.origin[1] = (round(obj.matrix_world[3][1] * settings.scale,5)) + settings.offsety
-        ntag.origin[2] = (round(obj.matrix_world[3][2] * settings.scale,5)) + settings.offsetz
-        ntag.axis[0] = obj.matrix_world[0][0]
-        ntag.axis[1] = obj.matrix_world[0][1]
-        ntag.axis[2] = obj.matrix_world[0][2]
-        ntag.axis[3] = obj.matrix_world[1][0]
-        ntag.axis[4] = obj.matrix_world[1][1]
-        ntag.axis[5] = obj.matrix_world[1][2]
-        ntag.axis[6] = obj.matrix_world[2][0]
-        ntag.axis[7] = obj.matrix_world[2][1]
-        ntag.axis[8] = obj.matrix_world[2][2]
-        md3.tags.append(ntag)
-  
-  if md3.numSurfaces < 1:
-    message(log,"Select a mesh to export!")
-    if log:
-      log.close()
-    return
-
-  file = open(settings.savepath, "wb")
-  md3.Save(file)
-  print_md3(log,md3,settings.dumpall)
-  file.close()
-
-  message(log,"MD3: " + settings.name + " saved to " + settings.savepath)
-  if log:
-    print("Logged to",settings.logpath)
-    log.close()
-
-from bpy.props import *
-class ExportMD3(bpy.types.Operator):
-  '''Export to Quake Model 3 (.md3)'''
-  bl_idname = "export.md3"
-  bl_label = 'Export MD3'
-
-  filepath = StringProperty(subtype = 'FILE_PATH',name="File Path", description="Filepath for exporting", maxlen= 1024, default= "")
-  md3name = StringProperty(name="MD3 Name", description="MD3 header name / skin path (64 bytes)",maxlen=64,default="")
-  md3log = StringProperty(name="MD3 Log", description="MD3 log file path",maxlen=1024,default="export_md3.log")
-  md3overwritelog = BoolProperty(name="Overwrite log", description="Overwrite log (off == append)", default=True)
-  md3dumpall = BoolProperty(name="Dump all", description="Dump all data for md3 to log",default=False)
-  md3ignoreuvs = BoolProperty(name="Ignore UVs", description="Ignores uv influence on mesh generation. Use if uv map not made.",default=False)
-  md3scale = FloatProperty(name="Scale", description="Scale all objects from world origin (0,0,0)",default=1.0,precision=5)
-  md3offsetx = FloatProperty(name="Offset X", description="Transition scene along x axis",default=0.0,precision=5)
-  md3offsety = FloatProperty(name="Offset Y", description="Transition scene along y axis",default=0.0,precision=5)
-  md3offsetz = FloatProperty(name="Offset Z", description="Transition scene along z axis",default=0.0,precision=5)
-
-  def execute(self, context):
-   settings = md3Settings(savepath = self.properties.filepath,
-                          name = self.properties.md3name,
-                          logpath = self.properties.md3log,
-                          overwrite = self.properties.md3overwritelog,
-                          dumpall = self.properties.md3dumpall,
-                          ignoreuvs = self.properties.md3ignoreuvs,
-                          scale = self.properties.md3scale,
-                          offsetx = self.properties.md3offsetx,
-                          offsety = self.properties.md3offsety,
-                          offsetz = self.properties.md3offsetz)
-   save_md3(settings)
-   return {'FINISHED'}
-
-  def invoke(self, context, event):
-    wm = context.window_manager
-    wm.fileselect_add(self)
-    return {'RUNNING_MODAL'}
-
-  @classmethod
-  def poll(cls, context):
-    return context.active_object is not None
-
-def menu_func(self, context):
-  newpath = os.path.splitext(bpy.context.blend_data.filepath)[0] + ".md3"
-  self.layout.operator(ExportMD3.bl_idname, text="Quake Model 3 (.md3)").filepath = newpath 
-
-def register():
-  bpy.types.INFO_MT_file_export.append(menu_func)
-
-def unregister():
-  bpy.types.INFO_MT_file_export.remove(menu_func)
-
-if __name__ == "__main__":
-  register()
diff --git a/release/scripts/addons_contrib/io_import_BrushSet.py b/release/scripts/addons_contrib/io_import_BrushSet.py
deleted file mode 100644
index a440419..0000000
--- a/release/scripts/addons_contrib/io_import_BrushSet.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-# ----------------------------------------------------------------------------#    
-
-'''
-todo:
-- add file selection for single and multiple files
-
-changelog:
-    "version": (1,1,4),
-        filename will be used as texture name (still limited by stringlength)
-
-
-    "version": (1,1,3),
-    fixed operator and registration
-    added tracker and wiki url\
-    
-version": (1,1,2)
-    replaced image.new() with image.load()
-    changed addon category
-    removed some unused/old code    
-    
-version":1.11:
-    added type arg to texture.new() [L48]
-    cleared default filename
-''' 
-
-# ----------------------------------------------------------------------------#    
-
-import bpy
-import os
-from bpy.props import *
-
-#addon description
-bl_info = {
-    "name": "import BrushSet",
-    "author": "Daniel Grauer",
-    "version": (1, 1, 5),
-    "blender": (2, 5, 6),
-    "category": "Import-Export",
-    "location": "File > Import > BrushSet",
-    "description": "imports all image files from a folder",
-    "warning": '', # used for warning icon and text in addons panel
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Import-Export/BrushSet",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25702&group_id=153&atid=467",
-    }
-
-print(" ")
-print("*------------------------------------------------------------------------------*")
-print("*                          initializing BrushSet import                        *")
-print("*------------------------------------------------------------------------------*")
-print(" ")
-
-#extension filter (alternative use mimetypes)
-ext_list = ['jpg',
-            'bmp',
-            'iris',
-            'png',
-            'jpeg',
-            'targa',
-            'tga'];
-
-def LoadBrushSet(filepath, filename):
-    for file in os.listdir(filepath):
-        path = (filepath + file)
-        #get folder name
-        (f1, f2) = os.path.split(filepath)
-        (f3, foldername) = os.path.split(f1)
-        
-        texturename = foldername         # file        "texture"    foldername
-        
-        #filter ext_list
-        if file.split('.')[-1].lower() in ext_list: 
-            #create new texture
-            texture = bpy.data.textures.new(texturename, 'IMAGE')    #watch it, string limit 21 ?!
-
-            #create new image
-            image = bpy.data.images.load(path)
-            image.source = "FILE"
-            image.filepath = path
-            bpy.data.textures[texture.name].image = image
-            
-            print("imported: " + file)
-    print("Brush Set imported!")  
-
-# ----------------------------------------------------------------------------#    
-
-class BrushSetImporter(bpy.types.Operator):
-    '''Load Brush Set'''
-    bl_idname = "import_image.brushset"
-    bl_label = "Import BrushSet"
-
-    filename = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE')
-    filepath = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE')
-    
-    def execute(self, context):
-        LoadBrushSet(self.properties.filepath, self.properties.filename)
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        wm = context.window_manager
-        wm.fileselect_add(self)
-        return {'RUNNING_MODAL'}
-
-# ----------------------------------------------------------------------------#    
-
-def menu_func(self, context):
-    #clear the default name for import
-    default_name = "" 
-
-    self.layout.operator(BrushSetImporter.bl_idname, text="Brush Set").filename = default_name
-
-# ----------------------------------------------------------------------------#    
-
-def register():    
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_file_import.append(menu_func)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_file_import.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
-
-print(" ")
-print("*------------------------------------------------------------------------------*")
-print(" ")
diff --git a/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py b/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py
deleted file mode 100644
index 61188ee..0000000
--- a/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py
+++ /dev/null
@@ -1,640 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "LRO Lola & MGS Mola img Importer",
-    "author": "Valter Battioli (ValterVB)",
-    "version": (1, 1, 8),
-    "blender": (2, 5, 8),
-    "location": "3D window > Tool Shelf",
-    "description": "Import DTM from LRO Lola and MGS Mola",
-    "warning": "May consume a lot of memory",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Import-Export/NASA_IMG_Importer",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=25462",
-    "category": "Import-Export"}
-
-
-#***********************************************************************
-#ver. 0.0.1: -First version
-#ver. 0.0.2: -Add check on path and file
-#            -Check on selected coordinates more complete
-#ver. 1.1.0: -Optimized for less memory
-#ver. 1.1.1: -Correct bug for real value of the High (bad error).
-#             now it's less artistic, bat more real Always possible use
-#             the old formula. check Magnify (x4)
-#            -Correct the bug for directory with dot in the name
-#            -Add some warning and more information
-#            -Add slider for the scale and info on it
-#ver. 1.1.2: -Word correction
-#            -Correct the problem for Unix (Upper lower case)
-#              If the Ext of the file selected from user is upper
-#              than the second file is Upper and Viceversa.
-#              (I can't verify because i have Win)
-#ver. 1.1.3: -Little fix for previous fix on upper/lower case
-#ver. 1.1.4: -Fix for recent API changes. Thanks to Filiciss.
-#            -Some code cleaning (PEP8)
-#ver. 1.1.5: -Fix for recent API changes. Thanks to Filiciss.
-#ver. 1.1.6: -Fix for API changes, and restore Scale factor
-#ver. 1.1.7: -Fix for API changes. Move some code out of draw
-#ver. 1.1.8: -Add a reset button
-#************************************************************************
-
-import bpy
-import os.path
-import math
-import array
-import mathutils
-from mathutils import *
-
-TO_RAD = math.pi / 180  # From degrees to radians
-
-# turning off relative path - it causes an error if it was true
-if bpy.context.user_preferences.filepaths.use_relative_paths == True:
-    bpy.context.user_preferences.filepaths.use_relative_paths = False
-
-
-# A very simple "bridge" tool.
-# Connects two equally long vertex rows with faces.
-# Returns a list of the new faces (list of  lists)
-#
-# vertIdx1 ... First vertex list (list of vertex indices).
-# vertIdx2 ... Second vertex list (list of vertex indices).
-# closed ... Creates a loop (first & last are closed).
-# flipped ... Invert the normal of the face(s).
-#
-# Note: You can set vertIdx1 to a single vertex index to create a fan/star
-#       of faces.
-# Note: If both vertex idx list are the same length they have to have at
-#       least 2 vertices.
-def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
-    faces = []
-
-    if not vertIdx1 or not vertIdx2:
-        return None
-
-    if len(vertIdx1) < 2 and len(vertIdx2) < 2:
-        return None
-
-    fan = False
-    if (len(vertIdx1) != len(vertIdx2)):
-        if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
-            fan = True
-        else:
-            return None
-
-    total = len(vertIdx2)
-
-    if closed:
-        # Bridge the start with the end.
-        if flipped:
-            face = [
-                vertIdx1[0],
-                vertIdx2[0],
-                vertIdx2[total - 1]]
-            if not fan:
-                face.append(vertIdx1[total - 1])
-            faces.append(face)
-
-        else:
-            face = [vertIdx2[0], vertIdx1[0]]
-            if not fan:
-                face.append(vertIdx1[total - 1])
-            face.append(vertIdx2[total - 1])
-            faces.append(face)
-
-    # Bridge the rest of the faces.
-    for num in range(total - 1):
-        if flipped:
-            if fan:
-                face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
-            else:
-                face = [vertIdx2[num], vertIdx1[num],
-                    vertIdx1[num + 1], vertIdx2[num + 1]]
-            faces.append(face)
-        else:
-            if fan:
-                face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
-            else:
-                face = [vertIdx1[num], vertIdx2[num],
-                    vertIdx2[num + 1], vertIdx1[num + 1]]
-            faces.append(face)
-    return faces
-
-
-#Utility Function ********************************************************
-#
-#Input: Latitude Output: Number of the line (1 to n)
-def LatToLine(Latitude):
-    tmpLines = round((MAXIMUM_LATITUDE - Latitude) * MAP_RESOLUTION + 1.0)
-    if tmpLines > LINES:
-        tmpLines = LINES
-    return tmpLines
-
-
-#Input: Number of the line (1 to n) Output: Latitude
-def LineToLat(Line):
-    if MAP_RESOLUTION == 0:
-        return 0
-    else:
-        return float(MAXIMUM_LATITUDE - (Line - 1) / MAP_RESOLUTION)
-
-
-#Input: Longitude Output: Number of the point (1 to n)
-def LongToPoint(Longitude):
-    tmpPoints = round((Longitude - WESTERNMOST_LONGITUDE) *
-                       MAP_RESOLUTION + 1.0)
-    if tmpPoints > LINE_SAMPLES:
-        tmpPoints = LINE_SAMPLES
-    return tmpPoints
-
-
-#Input: Number of the Point (1 to n) Output: Longitude
-def PointToLong(Point):
-    if MAP_RESOLUTION == 0:
-        return 0
-    else:
-        return float(WESTERNMOST_LONGITUDE + (Point - 1) / MAP_RESOLUTION)
-
-
-#Input: Latitude Output: Neareast real Latitude on grid
-def RealLat(Latitude):
-    return float(LineToLat(LatToLine(Latitude)))
-
-
-#Input: Longitude Output: Neareast real Longitude on grid
-def RealLong(Longitude):
-    return float(PointToLong(LongToPoint(Longitude)))
-#**************************************************************************
-
-
-def MakeMaterialMars(obj):
-    #Copied from io_convert_image_to_mesh_img
-    mat = bpy.data.materials.new("Mars")
-    mat.diffuse_shader = 'MINNAERT'
-    mat.diffuse_color = (0.426, 0.213, 0.136)
-    mat.darkness = 0.8
-
-    mat.specular_shader = 'WARDISO'
-    mat.specular_color = (1.000, 0.242, 0.010)
-    mat.specular_intensity = 0.010
-    mat.specular_slope = 0.100
-    obj.data.materials.append(mat)
-
-
-def MakeMaterialMoon(obj):
-    #Same as Mars Material, but i have canged the color
-    mat = bpy.data.materials.new("Moon")
-    mat.diffuse_shader = 'MINNAERT'
-    mat.diffuse_color = (0.426, 0.426, 0.426)
-    mat.darkness = 0.8
-
-    mat.specular_shader = 'WARDISO'
-    mat.specular_color = (0.6, 0.6, 0.6)
-    mat.specular_intensity = 0.010
-    mat.specular_slope = 0.100
-    obj.data.materials.append(mat)
-
-
-#Read the LBL file
-def ReadLabel(FileName):
-    global FileAndPath
-    global LINES, LINE_SAMPLES, SAMPLE_TYPE, SAMPLE_BITS, UNIT, MAP_RESOLUTION
-    global MAXIMUM_LATITUDE, MINIMUM_LATITUDE, WESTERNMOST_LONGITUDE
-    global EASTERNMOST_LONGITUDE, SCALING_FACTOR, OFFSET, RadiusUM, TARGET_NAME
-    global Message
-
-    if FileName == '':
-        return
-    LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
-    MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
-    WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
-    OFFSET = SCALING_FACTOR = 0.0
-    SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
-
-    FileAndPath = FileName
-    FileAndExt = os.path.splitext(FileAndPath)
-    try:
-        #Check for UNIX that is case sensitive
-        #If the Ext of the file selected from user is Upper, than the second
-        #file is Upper and Viceversa
-        if FileAndExt[1].isupper():
-            f = open(FileAndExt[0] + ".LBL", 'r')  # Open the label file
-        else:
-            f = open(FileAndExt[0] + ".lbl", 'r')  # Open the label file
-        Message = ""
-    except:
-        Message = "FILE LBL NOT AVAILABLE OR YOU HAVEN'T SELECTED A FILE"
-        return
-
-    block = ""
-    OFFSET = 0
-    for line in f:
-        tmp = line.split("=")
-        if tmp[0].strip() == "OBJECT" and tmp[1].strip() == "IMAGE":
-            block = "IMAGE"
-        elif tmp[0].strip() == "OBJECT" and tmp[1].strip() == "IMAGE_MAP_PROJECTION":
-            block = "IMAGE_MAP_PROJECTION"
-        elif tmp[0].strip() == "END_OBJECT" and tmp[1].strip() == "IMAGE":
-            block = ""
-        elif tmp[0].strip() == "END_OBJECT" and tmp[1].strip() == "IMAGE_MAP_PROJECTION":
-            block = ""
-        elif tmp[0].strip() == "TARGET_NAME":
-            block = ""
-            TARGET_NAME = tmp[1].strip()
-        if block == "IMAGE":
-            if line.find("LINES") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                LINES = int(tmp[1].strip())
-            elif line.find("LINE_SAMPLES") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                LINE_SAMPLES = int(tmp[1].strip())
-            elif line.find("UNIT") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                UNIT = tmp[1].strip()
-            elif line.find("SAMPLE_TYPE") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                SAMPLE_TYPE = tmp[1].strip()
-            elif line.find("SAMPLE_BITS") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                SAMPLE_BITS = int(tmp[1].strip())
-            elif line.find("SCALING_FACTOR") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                SCALING_FACTOR = float(tmp[0].replace(" ", ""))
-            elif line.find("OFFSET") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                if tmp[0].find("OFFSET") != -1 and len(tmp) > 1:
-                    tmp = tmp[1].split("<")
-                    tmp[0] = tmp[0].replace(".", "")
-                    OFFSET = float(tmp[0].replace(" ", ""))
-        elif block == "IMAGE_MAP_PROJECTION":
-            if line.find("A_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                A_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
-                RadiusUM = tmp[1].rstrip().replace(">", "")
-            elif line.find("B_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                B_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
-            elif line.find("C_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                C_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
-            elif line.find("MAXIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                MAXIMUM_LATITUDE = float(tmp[0].replace(" ", ""))
-            elif line.find("MINIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                MINIMUM_LATITUDE = float(tmp[0].replace(" ", ""))
-            elif line.find("WESTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                WESTERNMOST_LONGITUDE = float(tmp[0].replace(" ", ""))
-            elif line.find("EASTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                EASTERNMOST_LONGITUDE = float(tmp[0].replace(" ", ""))
-            elif line.find("MAP_RESOLUTION") != -1 and not(line.startswith("/*")):
-                tmp = line.split("=")
-                tmp = tmp[1].split("<")
-                MAP_RESOLUTION = float(tmp[0].replace(" ", ""))
-    f.close
-    MAXIMUM_LATITUDE = MAXIMUM_LATITUDE - 1 / MAP_RESOLUTION / 2
-    MINIMUM_LATITUDE = MINIMUM_LATITUDE + 1 / MAP_RESOLUTION / 2
-    WESTERNMOST_LONGITUDE = WESTERNMOST_LONGITUDE + 1 / MAP_RESOLUTION / 2
-    EASTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE - 1 / MAP_RESOLUTION / 2
-    if OFFSET == 0:  # When OFFSET isn't available I use the medium of the radius
-        OFFSET = (A_AXIS_RADIUS + B_AXIS_RADIUS + C_AXIS_RADIUS) / 3
-    else:
-        OFFSET = OFFSET / 1000  # Convert m to Km
-    if SCALING_FACTOR == 0:
-        SCALING_FACTOR = 1.0  # When isn'tavailable I set it to 1
-
-
-def update_fpath(self, context):
-    global start_up
-    start_up=False
-    ReadLabel(bpy.context.scene.fpath)
-    if Message != "":
-        start_up=True
-    else:
-        typ = bpy.types.Scene
-        var = bpy.props
-        typ.FromLat = var.FloatProperty(description="From Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE), precision=3, default=0.0)
-        typ.ToLat = var.FloatProperty(description="To Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE), precision=3)
-        typ.FromLong = var.FloatProperty(description="From Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE), precision=3)
-        typ.ToLong = var.FloatProperty(description="To Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE), precision=3)
-        typ.Scale = var.IntProperty(description="Scale", min=1, max=100, default=1)
-        typ.Magnify = var.BoolProperty(description="Magnify", default=False)
-
-
-#Import the data and draw the planet
-class Import(bpy.types.Operator):
-    bl_idname = 'import.lro_and_mgs'
-    bl_label = 'Start Import'
-    bl_description = 'Import the data'
-
-    def execute(self, context):
-        From_Lat = RealLat(bpy.context.scene.FromLat)
-        To_Lat = RealLat(bpy.context.scene.ToLat)
-        From_Long = RealLong(bpy.context.scene.FromLong)
-        To_Long = RealLong(bpy.context.scene.ToLong)
-        BlenderScale = bpy.context.scene.Scale
-        Exag = bpy.context.scene.Magnify
-        Vertex = []  # Vertex array
-        Faces = []  # Faces arrays
-        FirstRow = []
-        SecondRow = []
-        print('*** Start create vertex ***')
-        FileAndPath = bpy.context.scene.fpath
-        FileAndExt = os.path.splitext(FileAndPath)
-        #Check for UNIX that is case sensitive
-        #If the Ext of the file selected from user is Upper, than the second file is Upper and Viceversa
-        if FileAndExt[1].isupper():
-            FileName = FileAndExt[0] + ".IMG"
-        else:
-            FileName = FileAndExt[0] + ".img"
-        f = open(FileName, 'rb')
-        f.seek(int((int(LatToLine(From_Lat)) - 1) * (LINE_SAMPLES * (SAMPLE_BITS / 8))), 1)  # Skip the first n line of point
-        SkipFirstPoint = int((LongToPoint(From_Long) - 1) * (SAMPLE_BITS / 8))  # Nunmber of points to skip
-        PointsToRead = (LongToPoint(To_Long) - LongToPoint(From_Long) + 1) * (int(SAMPLE_BITS) / 8)  # Number of points to be read
-        SkipLastPoint = (LINE_SAMPLES * (SAMPLE_BITS / 8)) - PointsToRead - SkipFirstPoint  # Nunmber of points to skip
-        LatToRead = From_Lat
-        while (LatToRead >= To_Lat):
-            f.seek(SkipFirstPoint, 1)  # Skip the first n point
-            Altitudes = f.read(int(PointsToRead))  # Read all the point
-            Altitudes = array.array("h", Altitudes)  # Change to Array of signed short
-            if SAMPLE_TYPE == "MSB_INTEGER":
-                Altitudes.byteswap()  # Change from MSB (big endian) to LSB (little endian)
-            LongToRead = From_Long
-            PointToRead = 0
-            while (LongToRead <= To_Long):
-                if Exag:
-                    tmpRadius = (Altitudes[PointToRead] / SCALING_FACTOR / 1000 + OFFSET) / BlenderScale  # Old formula (High*4)
-                else:
-                    tmpRadius = ((Altitudes[PointToRead] * SCALING_FACTOR) / 1000 + OFFSET) / BlenderScale  # Correct scale
-                CurrentRadius = tmpRadius * (math.cos(LatToRead * TO_RAD))
-                X = CurrentRadius * (math.sin(LongToRead * TO_RAD))
-                Y = tmpRadius * math.sin(LatToRead * TO_RAD)
-                Z = CurrentRadius * math.cos(LongToRead * TO_RAD)
-                Vertex.append(Vector((float(X), float(Y), float(Z))))
-                LongToRead += (1 / MAP_RESOLUTION)
-                PointToRead += 1
-            f.seek(int(SkipLastPoint), 1)
-            LatToRead -= (1 / MAP_RESOLUTION)
-        f.close
-        del Altitudes
-        print('*** End create Vertex   ***')
-
-        print('*** Start create faces ***')
-        LinesToRead = int(LatToLine(To_Lat) - LatToLine(From_Lat) + 1)   # Number of the lines to read
-        PointsToRead = int(LongToPoint(To_Long) - LongToPoint(From_Long) + 1)  # Number of the points to read
-        for Point in range(0, PointsToRead):
-            FirstRow.append(Point)
-            SecondRow.append(Point + PointsToRead)
-        if int(PointsToRead) == LINE_SAMPLES:
-            FaceTemp = createFaces(FirstRow, SecondRow, closed=True, flipped=True)
-        else:
-            FaceTemp = createFaces(FirstRow, SecondRow, closed=False, flipped=True)
-        Faces.extend(FaceTemp)
-
-        FaceTemp = []
-        for Line in range(1, (LinesToRead - 1)):
-            FirstRow = SecondRow
-            SecondRow = []
-            FacesTemp = []
-            for Point in range(0, PointsToRead):
-                SecondRow.append(Point + (Line + 1) * PointsToRead)
-            if int(PointsToRead) == LINE_SAMPLES:
-                FaceTemp = createFaces(FirstRow, SecondRow, closed=True, flipped=True)
-            else:
-                FaceTemp = createFaces(FirstRow, SecondRow, closed=False, flipped=True)
-            Faces.extend(FaceTemp)
-        del FaceTemp
-        print('*** End create faces   ***')
-
-        print ('*** Start draw ***')
-        mesh = bpy.data.meshes.new(TARGET_NAME)
-        mesh.from_pydata(Vertex, [], Faces)
-        del Faces
-        del Vertex
-        mesh.update()
-        ob_new = bpy.data.objects.new(TARGET_NAME, mesh)
-        ob_new.data = mesh
-        scene = bpy.context.scene
-        scene.objects.link(ob_new)
-        scene.objects.active = ob_new
-        ob_new.select = True
-        print ('*** End draw   ***')
-        print('*** Start Smooth ***')
-        bpy.ops.object.shade_smooth()
-        print('*** End Smooth   ***')
-        if TARGET_NAME == "MOON":
-            MakeMaterialMoon(ob_new)
-        elif TARGET_NAME == "MARS":
-            MakeMaterialMars(ob_new)
-        print('*** FINISHED ***')
-        return {'FINISHED'}
-
-
-# User inteface
-class Img_Importer(bpy.types.Panel):
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOL_PROPS"
-    bl_label = "LRO Lola & MGS Mola IMG Importer"
-    
-    def __init__(self):
-        typ = bpy.types.Scene
-        var = bpy.props
-
-    def draw(self, context):
-        layout = self.layout
-        if start_up:
-            layout.prop(context.scene, "fpath")
-            col = layout.column()
-            split = col.split(align=True)
-            if Message != "":
-                split.label("Message: " + Message)
-        else:
-            col = layout.column()
-            split = col.split(align=True)
-            split.label("Minimum Latitude: " + str(MINIMUM_LATITUDE) + " deg")
-            split.label("Maximum Latitude: " + str(MAXIMUM_LATITUDE) + " deg")
-
-            split = col.split(align=True)
-            split.label("Westernmost Longitude: " + str(WESTERNMOST_LONGITUDE) + " deg")
-            split.label("Easternmost Longitude: " + str(EASTERNMOST_LONGITUDE) + " deg")
-
-            split = col.split(align=True)
-            split.label("Lines: " + str(LINES))
-            split.label("Line samples: " + str(LINE_SAMPLES))
-
-            split = col.split(align=True)
-            split.label("Sample type: " + str(SAMPLE_TYPE))
-            split.label("Sample bits: " + str(SAMPLE_BITS))
-
-            split = col.split(align=True)
-            split.label("Unit: " + UNIT)
-            split.label("Map resolution: " + str(MAP_RESOLUTION) + " pix/deg")
-
-            split = col.split(align=True)
-            split.label("Radius: " + str(OFFSET) + " " + RadiusUM)
-            split.label("Scale: " + str(SCALING_FACTOR))
-
-            split = col.split(align=True)
-            split.label("Target: ")
-            split.label(TARGET_NAME)
-
-            col = layout.column()
-            split = col.split(align=True)
-            split.prop(context.scene, "FromLat", "Northernmost Lat.")
-            split.prop(context.scene, "ToLat", "Southernmost Lat.")
-            if bpy.context.scene.FromLat < bpy.context.scene.ToLat:
-                col = layout.column()
-                split = col.split(align=True)
-                split.label("Warning: Northernmost must be greater than Southernmost")
-
-            col = layout.column()
-            split = col.split(align=True)
-            split.prop(context.scene, "FromLong", "Westernmost Long.")
-            split.prop(context.scene, "ToLong", "Easternmost Long.")
-            if bpy.context.scene.FromLong > bpy.context.scene.ToLong:
-                col = layout.column()
-                split = col.split(align=True)
-                split.label("Warning: Easternmost must be greater than Westernmost")
-
-            col = layout.column()
-            split = col.split(align=True)
-            split.prop(context.scene, "Scale", "Scale")
-            split.prop(context.scene, "Magnify", "Magnify (x4)")
-            if bpy.context.scene.fpath != "":
-                col = layout.column()
-                split = col.split(align=True)
-                split.label("1 Blender unit = " + str(bpy.context.scene.Scale) + RadiusUM)
-
-            if Message != "":
-                col = layout.column()
-                split = col.split(align=True)
-                split.label("Message: " + Message)
-
-            if bpy.context.scene.fpath.upper().endswith("IMG") or bpy.context.scene.fpath.upper().endswith("LBL"):  # Check if is selected the correct file
-                VertNumbers = (((RealLat(bpy.context.scene.FromLat) - RealLat(bpy.context.scene.ToLat)) * MAP_RESOLUTION) + 1) * ((RealLong(bpy.context.scene.ToLong) - RealLong(bpy.context.scene.FromLong)) * MAP_RESOLUTION + 1)
-            else:
-                VertNumbers = 0
-            #If I have 4 or plus vertex and at least 2 row and at least 2 point, I can import
-            if VertNumbers > 3 and (RealLat(bpy.context.scene.FromLat) > RealLat(bpy.context.scene.ToLat)) and (RealLong(bpy.context.scene.FromLong) < RealLong(bpy.context.scene.ToLong)):  # If I have 4 or plus vertex I can import
-                split = col.split(align=True)
-                split.label("Map resolution on the equator: ")
-                split.label(str(2 * math.pi * OFFSET / 360 / MAP_RESOLUTION) + " " + RadiusUM + "/pix")
-                col = layout.column()
-                split = col.split(align=True)
-                split.label("Real Northernmost Lat.: " + str(RealLat(bpy.context.scene.FromLat)) + " deg")
-                split.label("Real Southernmost Long.: " + str(RealLat(bpy.context.scene.ToLat)) + " deg")
-                split = col.split(align=True)
-                split.label("Real Westernmost Long.: " + str(RealLong(bpy.context.scene.FromLong)) + " deg")
-                split.label("Real Easternmost Long.: " + str(RealLong(bpy.context.scene.ToLong)) + "deg")
-                split = col.split(align=True)
-                split.label("Numbers of vertex to be imported: " + str(int(VertNumbers)))
-                col.separator()
-                col.operator('import.lro_and_mgs', text='Import')
-                col.separator()
-                col.operator('import.reset', text='Reset')
-
-
-#Reset the UI
-class Reset(bpy.types.Operator):
-    bl_idname = 'import.reset'
-    bl_label = 'Start Import'
-
-    def execute(self, context):
-        clear_properties()
-        return {'FINISHED'}
-
-
-def initialize():
-    global MAXIMUM_LATITUDE, MINIMUM_LATITUDE
-    global WESTERNMOST_LONGITUDE, EASTERNMOST_LONGITUDE
-    global LINES, LINE_SAMPLES, SAMPLE_BITS, MAP_RESOLUTION
-    global OFFSET, SCALING_FACTOR
-    global SAMPLE_TYPE, UNIT, TARGET_NAME, RadiusUM, Message
-    global start_up
-
-    LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
-    MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
-    WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
-    OFFSET = SCALING_FACTOR = 0.0
-    SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
-    start_up=True
-            
-    bpy.types.Scene.fpath = bpy.props.StringProperty(
-        name="Import File ", 
-        description="Select your img file", 
-        subtype="FILE_PATH", 
-        default="", 
-        update=update_fpath)
-
-def clear_properties():
-    # can happen on reload
-    if bpy.context.scene is None:
-        return
-    global MAXIMUM_LATITUDE, MINIMUM_LATITUDE
-    global WESTERNMOST_LONGITUDE, EASTERNMOST_LONGITUDE
-    global LINES, LINE_SAMPLES, SAMPLE_BITS, MAP_RESOLUTION
-    global OFFSET, SCALING_FACTOR
-    global SAMPLE_TYPE, UNIT, TARGET_NAME, RadiusUM, Message
-    global start_up
-
-    LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
-    MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
-    WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
-    OFFSET = SCALING_FACTOR = 0.0
-    SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
-    start_up=True
-
-    props = ["FromLat", "ToLat", "FromLong", "ToLong", "Scale", "Magnify", "fpath"]
-    for p in props:
-        if p in bpy.types.Scene.bl_rna.properties:
-            exec("del bpy.types.Scene." + p)
-        if p in bpy.context.scene:
-            del bpy.context.scene[p]
-    bpy.types.Scene.fpath = bpy.props.StringProperty(
-        name="Import File ", 
-        description="Select your img file", 
-        subtype="FILE_PATH", 
-        default="", 
-        update=update_fpath)
-
-
-# registering the script
-def register():
-    initialize()
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    clear_properties()
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_import_fbx.py b/release/scripts/addons_contrib/io_import_fbx.py
deleted file mode 100644
index 6953275..0000000
--- a/release/scripts/addons_contrib/io_import_fbx.py
+++ /dev/null
@@ -1,510 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-    "name": "Import: Autodesk FBX",
-    "author": "Campbell Barton",
-    "version": (0, 0, 1),
-    "blender": (2, 5, 6),
-    "location": "File > Import ",
-    "description": "This script is WIP and not intended for general use yet!",
-    "warning": "Work in progress",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Import-Export"}
-
-
-def parse_fbx(path, fbx_data):
-    DEBUG = False
-
-    f = open(path, "rU", encoding="utf-8")
-    lines = f.readlines()
-
-    # remove comments and \n
-    lines = [l[:-1].rstrip() for l in lines if not l.lstrip().startswith(";")]
-
-    # remove whitespace
-    lines = [l for l in lines if l]
-
-    # remove multiline float lists
-    def unmultiline(i):
-        lines[i - 1] = lines[i - 1] + lines.pop(i).lstrip()
-
-    # Multiline floats, used for verts and matricies, this is harderto read so detect and make into 1 line.
-    i = 0
-    while i < len(lines):
-        l = lines[i].strip()
-        if l.startswith(","):
-            unmultiline(i)
-            i -= 1
-        try:
-            float(l.split(",", 1)[0])
-            unmultiline(i)
-            i -= 1
-        except:
-            pass
-
-        i += 1
-
-    CONTAINER = [None]
-
-    def is_int(val):
-        try:
-            CONTAINER[0] = int(val)
-            return True
-        except:
-            return False
-
-    def is_int_array(val):
-        try:
-            CONTAINER[0] = tuple([int(v) for v in val.split(",")])
-            return True
-        except:
-            return False
-
-    def is_float(val):
-        try:
-            CONTAINER[0] = float(val)
-            return True
-        except:
-            return False
-
-    def is_float_array(val):
-        try:
-            CONTAINER[0] = tuple([float(v) for v in val.split(",")])
-            return True
-        except:
-            return False
-
-    def read_fbx(i, ls):
-        if DEBUG:
-            print("LINE:", lines[i])
-
-        tag, val = lines[i].split(":", 1)
-        tag = tag.lstrip()
-        val = val.strip()
-
-        if val == "":
-            ls.append((tag, None, None))
-        if val.endswith("{"):
-            name = val[:-1].strip()  # remove the trailing {
-            if name == "":
-                name = None
-
-            sub_ls = []
-            ls.append((tag, name, sub_ls))
-
-            i += 1
-            while lines[i].strip() != "}":
-                i = read_fbx(i, sub_ls)
-
-        elif val.startswith('"') and val.endswith('"'):
-            ls.append((tag, None, val[1:-1]))  # remove quotes
-        elif is_int(val):
-            ls.append((tag, None, CONTAINER[0]))
-        elif is_float(val):
-            ls.append((tag, None, CONTAINER[0]))
-        elif is_int_array(val):
-            ls.append((tag, None, CONTAINER[0]))
-        elif is_float_array(val):
-            ls.append((tag, None, CONTAINER[0]))
-        elif tag == 'Property':
-            ptag, ptype, punknown, pval = val.split(",", 3)
-            ptag = ptag.strip().strip("\"")
-            ptype = ptype.strip().strip("\"")
-            punknown = punknown.strip().strip("\"")
-            pval = pval.strip()
-
-            if val.startswith('"') and val.endswith('"'):
-                pval = pval[1:-1]
-            elif is_int(pval):
-                pval = CONTAINER[0]
-            elif is_float(pval):
-                pval = CONTAINER[0]
-            elif is_int_array(pval):
-                pval = CONTAINER[0]
-            elif is_float_array(pval):
-                pval = CONTAINER[0]
-
-            ls.append((tag, None, (ptag, ptype, punknown, pval)))
-        else:
-            # IGNORING ('Property', None, '"Lcl Scaling", "Lcl Scaling", "A+",1.000000000000000,1.000000000000000,1.000000000000000')
-            print("\tParser Skipping:", (tag, None, val))
-
-        # name = .lstrip()[0]
-        if DEBUG:
-            print("TAG:", tag)
-            print("VAL:", val)
-        return i + 1
-
-    i = 0
-    while i < len(lines):
-        i = read_fbx(i, fbx_data)
-
-
-def parse_connections(fbx_data):
-    c = {}
-    for tag, name, value in fbx_data:
-        type, child, parent = [i.strip() for i in value.replace('"', '').split(',')]
-        if type == "OO":
-            parent = parent.replace('Model::', '').replace('Material::', '')
-            child = child.replace('Model::', '').replace('Material::', '')
-
-            c[child] = parent
-
-    return c
-
-# Blender code starts here:
-import bpy
-
-
-def import_fbx(path):
-    import math
-    import mathutils
-
-    mtx_x90 = mathutils.Matrix.Rotation(math.pi / 2.0, 3, 'X')
-
-    fbx_data = []
-    objects = {}
-    materials = {}
-    parse_fbx(path, fbx_data)
-    # Now lets get in the mesh data for fun.
-
-    def tag_get_iter(data, tag):
-        for tag_iter, name, value in data:
-            if tag_iter == tag:
-                yield (name, value)
-
-    def tag_get_single(data, tag):
-        for tag_iter, name, value in data:
-            if tag_iter == tag:
-                return (name, value)
-        return (None, None)
-
-    def tag_get_prop(data, prop):
-        for tag_iter, name, value in data:
-            if tag_iter == "Property":
-                if value[0] == prop:
-                    return value[3]
-        return None
-
-    scene = bpy.context.scene
-
-    connections = parse_connections(tag_get_single(fbx_data, "Connections")[1])
-
-    for tag1, name1, value1 in fbx_data:
-        if tag1 == "Objects":
-            for tag2, name2, value2 in value1:
-                if tag2 == "Model":
-                    '''
-                    print("")
-                    print(tag2)
-                    print(name2)
-                    print(value2)
-                    '''
-
-                    # check we import an object
-                    obj = None
-
-                    # "Model::MyCamera", "Camera"  -->  MyCamera
-                    fbx_name = name2.split(',')[0].strip()[1:-1].split("::", 1)[-1]
-                    # we dont parse this part properly
-                    # the name2 can be somtrhing like
-                    # Model "Model::kimiko", "Mesh"
-                    if name2.endswith(" \"Mesh\""):
-
-                        verts = tag_get_single(value2, "Vertices")[1]
-                        faces = tag_get_single(value2, "PolygonVertexIndex")[1]
-                        edges = tag_get_single(value2, "Edges")[1]
-
-                        # convert odd fbx verts and faces to a blender mesh.
-                        if verts and faces:
-                            me = bpy.data.meshes.new(name=fbx_name)
-                            # get a list of floats as triples
-                            blen_verts = [verts[i - 3:i] for i in range(3, len(verts) + 3, 3)]
-
-                            # get weirdo face indicies and proper edge indexs
-                            # edge_points Collects faces index, first and last verts.
-
-                            face = []
-                            edge_points = {}
-                            blen_faces = [face]
-                            blen_faces_edges = []  # faces that have a length of 2
-                            blen_poly_mapping = {}
-                            poly_idx = 0
-
-                            for idx, f in enumerate(faces):
-
-                                if f < 0:
-                                    face.append(f ^ -1)
-                                    edge_points[idx] = [face[-1], face[0]]
-                                    face = []
-
-                                    if len(blen_faces[-1]) == 2:
-                                        blen_faces_edges.append(blen_faces.pop())
-                                    else:
-                                        blen_poly_mapping[poly_idx] = len(blen_faces) - 1
-
-                                    blen_faces.append(face)
-                                    poly_idx += 1
-                                else:
-                                    face.append(f)
-
-                            edge_final = []
-
-                            if len(faces) == 2:  # Special case if there is only one edge in scene.
-                                edge1 = faces[0]
-                                if edge1 < 0:
-                                    edge1 ^= -1
-                                edge2 = faces[1]
-                                if edge2 < 0:
-                                    edge2 ^= -1
-                                edge_final.append((edge1, edge2))
-
-                            else:  # More than one edges
-                                for idx, e in enumerate(edges):
-
-                                    if faces[e] < 0:  # If this is the faces last point, use edge_points to create edge between last and first points of face
-                                        edge1 = edge_points[e][0]
-                                        edge2 = edge_points[e][1]
-                                    else:
-                                        edge1 = faces[e]
-                                        edge2 = faces[e + 1]
-                                        if edge2 < 0:
-                                            edge2 ^= -1
-
-                                    edge_final.append((edge1, edge2))
-
-                            if not blen_faces[-1]:
-                                del blen_faces[-1]
-
-                            me.from_pydata(blen_verts, edge_final, blen_faces)
-                            me.update()
-
-                            # Handle smoothing
-                            for i in tag_get_iter(value2, "LayerElementSmoothing"):
-                                i = i[1]
-                                type = tag_get_single(i, "MappingInformationType")[1]
-
-                                if type == "ByPolygon":
-                                    smooth_faces = tag_get_single(i, "Smoothing")[1]
-
-                                    for idx, val in enumerate(smooth_faces):
-                                        new_idx = blen_poly_mapping.get(idx)
-                                        if new_idx is not None:
-                                            me.faces[new_idx].use_smooth = val
-                                elif type == "ByEdge":
-                                    smooth_edges = tag_get_single(i, "Smoothing")[1]
-
-                                    for idx, ed in enumerate(me.edges):
-                                        ed.use_edge_sharp = smooth_edges[idx]
-                                else:
-                                    print("WARNING: %s, unsupported smoothing type: %s" % (fbx_name, type))
-
-                            # Handle edge weighting
-                            for i in tag_get_iter(value2, "LayerElementEdgeCrease"):
-                                i = i[1]
-                                type = tag_get_single(i, "MappingInformationType")[1]
-
-                                if type == "ByPolygon":
-                                    crease_faces = tag_get_single(i, "Smoothing")[1]
-
-                                    for idx, f in enumerate(me.faces):
-                                        poly_idx = blen_poly_mapping.get(idx)
-                                        if poly_idx is not None:
-                                            f.use_smooth = crease_faces[idx]
-                                elif type == "ByEdge":
-                                    crease_edges = tag_get_single(i, "EdgeCrease")[1]
-
-                                    for idx, ed in enumerate(me.edges):
-                                        ed.crease = crease_edges[idx]
-                                else:
-                                    print("WARNING: %s, unsupported smoothing type: %s" % (fbx_name, type))
-
-                            # Create the Uv-sets
-                            for i in tag_get_iter(value2, "LayerElementUV"):
-                                i = i[1]
-                                uv_in = 0
-                                uv_face = []
-                                uv_name = tag_get_single(i, "Name")[1]
-                                print(uv_name)
-                                uv_verts = tag_get_single(i, "UV")[1]
-                                uv_index = tag_get_single(i, "UVIndex")[1]
-
-                                if(uv_verts):
-                                    blen_uv_verts = [uv_verts[i - 2:i] for i in range(2, len(uv_verts) + 2, 2)]
-
-                                    for ind, uv_i in enumerate(uv_index):
-                                        if(uv_i == -1):
-                                            uv_face.append([-0.1, -0.1])
-                                        else:
-                                            uv_face.append(blen_uv_verts[uv_i])
-                                            uv_in += 1
-
-                                    me.uv_textures.new(uv_name)
-                                    uv_layer = me.uv_textures[-1].data
-                                    uv_counter = 0
-                                    if uv_layer:
-                                        for fi, uv in enumerate(uv_layer):
-                                            if(len(me.faces[fi].vertices) == 4):
-                                                uv.uv1 = uv_face[uv_counter]
-                                                uv.uv2 = uv_face[uv_counter + 1]
-                                                uv.uv3 = uv_face[uv_counter + 2]
-                                                uv.uv4 = uv_face[uv_counter + 3]
-                                                uv_counter += 4
-                                            else:
-                                                uv.uv1 = uv_face[uv_counter]
-                                                uv.uv2 = uv_face[uv_counter + 1]
-                                                uv.uv3 = uv_face[uv_counter + 2]
-                                                uv_counter += 3
-
-                            obj = bpy.data.objects.new(fbx_name, me)
-                            base = scene.objects.link(obj)
-
-                    elif name2.endswith(" \"Camera\""):
-
-                        camera = bpy.data.cameras.new(name=fbx_name)
-
-                        props = tag_get_single(value2, "Properties60")[1]
-                        camera.angle = math.radians(tag_get_prop(props, "FieldOfView"))
-
-                        obj = bpy.data.objects.new(fbx_name, camera)
-                        base = scene.objects.link(obj)
-
-                    elif name2.endswith(" \"Light\""):
-
-                        light = bpy.data.lamps.new(name=fbx_name)
-
-                        props = tag_get_single(value2, "Properties60")[1]
-
-                        # Lamp types
-                        light_types = {0: 'POINT', 1: 'SUN', 2: 'SPOT'}
-
-                        light.type = light_types[tag_get_prop(props, "LightType")]
-                        light.energy = max(tag_get_prop(props, "Intensity") / 100.0, 0)
-                        light.color = tag_get_prop(props, "Color")
-                        light.distance = tag_get_prop(props, "DecayStart")
-
-                        if light.type == 'SPOT':
-                            light.spot_size = math.rad(tag_get_prop(props, "Cone angle"))
-
-                        # Todo: shadows
-
-                        obj = bpy.data.objects.new(fbx_name, light)
-                        base = scene.objects.link(obj)
-
-                    if obj:
-                        # Update our object dict
-                        objects[fbx_name] = obj
-
-                        # Take care of parenting (we assume the parent has already been processed)
-                        parent = connections.get(fbx_name)
-                        if parent and parent != "Scene" and not parent.startswith("DisplayLayer"):
-                            obj.parent = objects[parent]
-                            parent = obj.parent
-                        else:
-                            parent = None
-
-                        # apply transformation
-                        props = tag_get_single(value2, "Properties60")[1]
-
-                        loc = tag_get_prop(props, "Lcl Translation")
-                        rot = tag_get_prop(props, "Lcl Rotation")
-                        sca = tag_get_prop(props, "Lcl Scaling")
-
-                        # Convert rotation
-                        rot_mat = mathutils.Euler([math.radians(i) for i in rot]).to_matrix()
-                        if parent:
-                            rot_mat = parent.matrix_world.to_3x3().inverted() * rot_mat
-
-                        obj.location = loc
-                        obj.rotation_euler = rot_mat.to_euler()[:]
-                        obj.scale = sca
-
-                elif tag2 == "Material":
-
-                    # "Material::MyMaterial", ""  -->  MyMaterial
-                    fbx_name = name2.split(',')[0].strip()[1:-1].split("::", 1)[-1]
-
-                    mat = bpy.data.materials.new(name=fbx_name)
-
-                    props = tag_get_single(value2, "Properties60")[1]
-
-                    # We always use Lambert diffuse shader for now
-                    mat.diffuse_shader = 'LAMBERT'
-
-                    mat.diffuse_color = tag_get_prop(props, "DiffuseColor")
-                    mat.diffuse_intensity = tag_get_prop(props, "DiffuseFactor")
-                    mat.alpha = 1 - tag_get_prop(props, "TransparencyFactor")
-                    mat.specular_color = tag_get_prop(props, "SpecularColor")
-                    mat.specular_intensity = tag_get_prop(props, "SpecularFactor") * 2.0
-                    mat.specular_hardness = (tag_get_prop(props, "Shininess") * 5.10) + 1
-                    mat.ambient = tag_get_prop(props, "AmbientFactor")
-
-                    # Update material dict
-                    materials[fbx_name] = mat
-
-                    # Map to an object (we assume models are done before materials)
-                    obj = connections.get(fbx_name)
-                    if obj:
-                        obj = objects[obj]
-                        obj.data.materials.append(mat)
-
-    return {'FINISHED'}
-
-
-# Operator
-from bpy.props import StringProperty
-from bpy_extras.io_utils import ImportHelper
-
-
-class ImportFBX(bpy.types.Operator, ImportHelper):
-    ''''''
-    bl_idname = "import_scene.fbx"
-    bl_label = "Import FBX"
-
-    filename_ext = ".fbx"
-    filter_glob = StringProperty(default="*.fbx", options={'HIDDEN'})
-
-    def execute(self, context):
-        return import_fbx(self.filepath)
-
-
-# Registering / Unregister
-def menu_func(self, context):
-    self.layout.operator(ImportFBX.bl_idname, icon='PLUGIN')
-
-
-def register():
-    bpy.utils.register_class(ImportFBX)
-    bpy.types.INFO_MT_file_import.append(menu_func)
-
-
-def unregister():
-    bpy.utils.unregister_class(ImportFBX)
-    bpy.types.INFO_MT_file_import.remove(menu_func)
-
-
-if __name__ == "__main__":
-    register()
-
-
-if __name__ == "__main__":
-    import_fbx("/test.fbx")
diff --git a/release/scripts/addons_contrib/io_import_lipSync_Importer.py b/release/scripts/addons_contrib/io_import_lipSync_Importer.py
deleted file mode 100644
index ebdf860..0000000
--- a/release/scripts/addons_contrib/io_import_lipSync_Importer.py
+++ /dev/null
@@ -1,483 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "LipSync Importer & Blinker",
-    "author": "Yousef Harfoush - bat3a ;)",
-    "version": (0, 5, 0),
-    "blender": (2, 6, 2),
-    "location": "3D window > Tool Shelf",
-    "description": "Plot Moho (Papagayo, Jlipsync, Yolo) file to frames and adds automatic blinking",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.5/Py/Scripts/Import-Export/Lipsync_Importer",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=24080&group_id=153&atid=468",
-    "category": "Import-Export"}
-
-
-import bpy, re
-from random import random
-from bpy.props import *
-from bpy.props import IntProperty, FloatProperty, StringProperty
-
-global lastPhoneme
-lastPhoneme="nothing"
-
-# truning off relative path - it causes an error if it was true
-if bpy.context.user_preferences.filepaths.use_relative_paths == True:
-    bpy.context.user_preferences.filepaths.use_relative_paths = False
-
-# add blinking
-def blinker():
-    
-    scn = bpy.context.scene
-    obj = bpy.context.object
-
-    if scn.regMenuTypes.enumBlinkTypes == '0':
-        modifier = 0
-    elif scn.regMenuTypes.enumBlinkTypes == '1':
-        modifier = scn.blinkMod
-    
-    #creating keys with blinkNm count
-    for y in range(scn.blinkNm):
-        frame = y * scn.blinkSp + int(random()*modifier)
-        createShapekey('blink', frame)
-
-# -----------code contributed by dalai felinto adds armature support modified by me-------------------
-
-bone_keys = {
-"AI":   ('location', 0),
-"E":    ('location', 1),
-"FV":   ('location', 2),
-"L":    ('rotation_euler', 0),
-"MBP":  ('rotation_euler', 1),
-"O":    ('rotation_euler', 2),
-"U":    ('scale', 0),
-"WQ":   ('scale', 1),
-"etc":  ('scale', 2),
-"rest": ('ik_stretch', -1)
-}
-
-def lipsyncerBone():
-    # reading imported file & creating keys
-    object = bpy.context.object
-    scene = bpy.context.scene
-    bone = bpy.context.active_pose_bone
-    
-    resetBoneScale(bone)
-    
-    f=open(scene.fpath) # importing file
-    f.readline() # reading the 1st line that we don"t need
-    
-    for line in f:
-        # removing new lines
-        lsta = re.split("\n+", line)
-
-        # building a list of frames & shapes indexes
-        lst = re.split(":? ", lsta[0])# making a list of a frame & number 
-        frame = int(lst[0])
-        
-        for key,attribute in bone_keys.items():
-            if lst[1] == key:
-                createBoneKeys(key, bone, attribute, frame)
-
-def resetBoneScale(bone):
-    # set the attributes used by papagayo to 0.0
-    for attribute,index in bone_keys.values():
-        if index != -1:
-            #bone.location[0] = 0.0
-            exec("bone.%s[%d] = %f" % (attribute, index, 0.0))
-        else:
-            exec("bone.%s = %f" % (attribute, 0.0))
-
-def addBoneKey(bone, data_path, index=-1, value=None, frame=bpy.context.scene.frame_current, group=""):
-    # set a value and keyframe for the bone
-    # it assumes the 'bone' variable was defined before
-    # and it's the current selected bone
-
-    if value != None:
-        if index != -1:
-            # bone.location[0] = 0.0
-            exec("bone.%s[%d] = %f" % (data_path, index, value))
-        else:
-            exec("bone.%s = %f" % (data_path, value))
-
-    # bone.keyframe_insert("location", 0, 10.0, "Lipsync")
-    exec('bone.keyframe_insert("%s", %d, %f, "%s")' % (data_path, index, frame, group))
-
-# creating keys with offset and eases for a phonem @ the Skframe
-def createBoneKeys(phoneme, bone, attribute, frame):
-    global lastPhoneme
-    
-    scene = bpy.context.scene
-    object = bpy.context.object
-    
-    offst = scene.offset     # offset value
-    skVlu = scene.skscale    # shape key value
-    
-    #in case of Papagayo format
-    if scene.regMenuTypes.enumFileTypes == '0' :
-        frmIn = scene.easeIn     # ease in value
-        frmOut = scene.easeOut   # ease out value
-        hldIn = scene.holdGap    # holding time value
-        
-    #in case of Jlipsync format or Yolo
-    elif scene.regMenuTypes.enumFileTypes == '1' :
-        frmIn = 1
-        frmOut = 1
-        hldIn = 0
-
-    # inserting the In key only when phonem change or when blinking
-    if lastPhoneme!=phoneme or eval(scene.regMenuTypes.enumModeTypes) == 1:
-        addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame-frmIn, "Lipsync")
-
-    addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame, "Lipsync")
-    addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame+hldIn, "Lipsync")
-    addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame+hldIn+frmOut, "Lipsync")
-    
-    lastPhoneme=phoneme
-
-# -------------------------------------------------------------------------------
-
-# reading imported file & creating keys
-def lipsyncer():
-    
-    obj = bpy.context.object
-    scn = bpy.context.scene
-    
-    f=open(scn.fpath) # importing file
-    f.readline() # reading the 1st line that we don"t need
-    
-    for line in f:
-
-        # removing new lines
-        lsta = re.split("\n+", line)
-
-        # building a list of frames & shapes indexes
-        lst = re.split(":? ", lsta[0])# making a list of a frame & number 
-        frame = int(lst[0])
-        
-        for key in obj.data.shape_keys.key_blocks:
-            if lst[1] == key.name:
-                createShapekey(key.name, frame)
-
-# creating keys with offset and eases for a phonem @ the frame
-def createShapekey(phoneme, frame):
-    
-    global lastPhoneme
-    
-    scn = bpy.context.scene
-    obj = bpy.context.object
-    objSK = obj.data.shape_keys
-    
-    offst = scn.offset     # offset value
-    skVlu = scn.skscale    # shape key value
-    
-    #in case of Papagayo format
-    if scn.regMenuTypes.enumFileTypes == '0' :
-        frmIn = scn.easeIn     # ease in value
-        frmOut = scn.easeOut   # ease out value
-        hldIn = scn.holdGap    # holding time value
-        
-    #in case of Jlipsync format or Yolo
-    elif scn.regMenuTypes.enumFileTypes == '1' :
-        frmIn = 1
-        frmOut = 1
-        hldIn = 0
-
-    # inserting the In key only when phonem change or when blinking
-    if lastPhoneme!=phoneme or eval(scn.regMenuTypes.enumModeTypes) == 1:
-        objSK.key_blocks[phoneme].value=0.0
-        objSK.key_blocks[phoneme].keyframe_insert("value",
-            -1, offst+frame-frmIn, "Lipsync")
-            
-    objSK.key_blocks[phoneme].value=skVlu
-    objSK.key_blocks[phoneme].keyframe_insert("value", 
-        -1, offst+frame, "Lipsync")
-    
-    objSK.key_blocks[phoneme].value=skVlu
-    objSK.key_blocks[phoneme].keyframe_insert("value", 
-        -1, offst+frame+hldIn, "Lipsync")
-            
-    objSK.key_blocks[phoneme].value=0.0
-    objSK.key_blocks[phoneme].keyframe_insert("value", 
-    -1, offst+frame+hldIn+frmOut, "Lipsync")
-    
-    lastPhoneme = phoneme
-
-# lipsyncer operation start
-class btn_lipsyncer(bpy.types.Operator):
-    bl_idname = 'lipsync.go'
-    bl_label = 'Start Processing'
-    bl_description = 'Plots the voice file keys to timeline'
-
-    def execute(self, context):
-
-        scn = context.scene
-        obj = context.active_object
-
-        # testing if object is valid
-        if obj!=None:
-            if obj.type=="MESH":
-                if obj.data.shape_keys!=None:
-                    if scn.fpath!='': lipsyncer()
-                    else: print ("select a Moho file")
-                else: print("No shape keys")
-    
-            elif obj.type=="ARMATURE":
-                if 1:#XXX add prop test
-                    if scn.fpath!='': lipsyncerBone()
-                    else: print ("select a Moho file")
-                else: print("Create Pose properties")
-                
-            else: print ("Object is not a mesh ot bone")
-        else: print ("Select object")
-        return {'FINISHED'}
-
-# blinker operation start
-class btn_blinker(bpy.types.Operator):
-    bl_idname = 'blink.go'
-    bl_label = 'Start Processing'
-    bl_description = 'Add blinks at random or specifice frames'
-
-    def execute(self, context):
-        
-        scn = context.scene
-        obj = context.object
-
-         # testing if object is valid
-        if obj!=None:
-            if obj.type=="MESH":
-                if obj.data.shape_keys!=None:
-                    for key in obj.data.shape_keys.key_blocks:
-                        if key.name=='blink':
-                            blinker()
-                            #return
-                else: print("No shape keys")
-            else: print ("Object is not a mesh ot bone")
-        else: print ("Select object")
-        return {'FINISHED'}
-
-
-#defining custom enumeratos
-class menuTypes(bpy.types.PropertyGroup):
-
-    enumFileTypes = EnumProperty(items =(('0', 'Papagayo', ''), 
-                                         ('1', 'Jlipsync Or Yolo', '')
-                                       #,('2', 'Retarget', '')
-                                         ),
-                                 name = 'Choose FileType',
-                                 default = '0')
-
-    enumBlinkTypes = EnumProperty(items =(('0', 'Specific', ''),
-                                          ('1', 'Random','')),
-                                  name = 'Choose BlinkType',
-                                  default = '0')
-
-    enumModeTypes = EnumProperty(items =(('0', 'Lipsyncer',''),
-                                         ('1', 'Blinker','')),
-                                 name = 'Choose Mode',
-                                 default = '0')
-                                 
-# drawing the user interface
-class LipSyncBoneUI(bpy.types.Panel):
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "UI"
-    bl_label = "Phonemes"
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-
-        bone = bpy.context.active_pose_bone
-        
-        #showing the current object type
-        if bone: #and if scn.regMenuTypes.enumModeTypes == '0':
-            col.prop(bone, "location", index=0, text="AI")
-            col.prop(bone, "location", index=1, text="E")
-            col.prop(bone, "location", index=2, text="FV")
-            if bpy.context.scene.unit_settings.system_rotation == 'RADIANS':
-                col.prop(bone, "rotation_euler", index=0, text="L")
-                col.prop(bone, "rotation_euler", index=1, text="MBP")
-                col.prop(bone, "rotation_euler", index=2, text="O")
-            else:
-                row=col.row()
-                row.prop(bone, "rotation_euler", index=0, text="L")
-                row.label(text=str("%4.2f" % (bone.rotation_euler.x)))
-                row=col.row()
-                row.prop(bone, "rotation_euler", index=1, text="MBP")
-                row.label(text=str("%4.2f" % (bone.rotation_euler.y)))
-                row=col.row()
-                row.prop(bone, "rotation_euler", index=2, text="O")
-                row.label(text=str("%4.2f" % (bone.rotation_euler.z)))
-            col.prop(bone, "scale", index=0, text="U")
-            col.prop(bone, "scale", index=1, text="WQ")
-            col.prop(bone, "scale", index=2, text="etc")
-        else:
-            layout.label(text="No good bone is selected")
-            
-# drawing the user interface
-class LipSyncUI(bpy.types.Panel):
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOL_PROPS"
-    bl_label = "LipSync Importer & Blinker"
-    
-    newType= bpy.types.Scene
-    scn = bpy.context.scene
-    
-    newType.fpath = StringProperty(name="Import File ", description="Select your voice file", subtype="FILE_PATH")
-    newType.skscale = FloatProperty(description="Smoothing shape key values", min=0.1, max=1.0, default=0.8)
-    newType.offset = IntProperty(description="Offset your frames", default=0)
-
-    newType.easeIn = IntProperty(description="Smoothing In curve", min=1, default=3)
-    newType.easeOut = IntProperty(description="Smoothing Out curve", min=1, default=3)
-    newType.holdGap = IntProperty(description="Holding for slow keys", min=0, default=0)
-
-    newType.blinkSp = IntProperty(description="Space between blinks", min=1, default=100)
-    newType.blinkNm = IntProperty(description="Number of blinks", min=1, default=10)
-    
-    newType.blinkMod = IntProperty(description="Randomzing keyframe placment", min=1, default=10)
-    
-    def draw(self, context):
-        
-        obj = bpy.context.active_object
-        scn = bpy.context.scene
-        
-        layout = self.layout
-        col = layout.column()
-
-        # showing the current object type
-        if obj != None:
-            if obj.type == "MESH":
-                split = col.split(align=True)
-                split.label(text="The active object is: ", icon="OBJECT_DATA")
-                split.label(obj.name, icon="EDITMODE_HLT")
-            elif obj.type == "ARMATURE": # bone needs to be selected
-                if obj.mode == "POSE": # mode needs to be pose
-                    split = col.split(align=True)
-                    split.label(text="The active object is: ", icon="ARMATURE_DATA")
-                    split.label(obj.name, icon="EDITMODE_HLT")
-                else:
-                    col.label(text="You need to select Pose mode!", icon="OBJECT_DATA")
-            else:
-                col.label(text="The active object is not a Mesh or Armature!", icon="OBJECT_DATA")
-        else:
-            layout.label(text="No object is selected", icon="OBJECT_DATA")
-            
-        col.row().prop(scn.regMenuTypes, 'enumModeTypes')
-        col.separator()
-        
-        # the lipsyncer panel 
-        if scn.regMenuTypes.enumModeTypes == '0':
-            # choose the file format
-            col.row().prop(scn.regMenuTypes, 'enumFileTypes', text = ' ', expand = True)
-                
-            # Papagayo panel
-            if scn.regMenuTypes.enumFileTypes == '0':
-                col.prop(context.scene, "fpath")
-                split = col.split(align=True)
-                split.label("Key Value :")
-                split.prop(context.scene, "skscale")
-                split = col.split(align=True)
-                split.label("Frame Offset :")
-                split.prop(context.scene, "offset")
-                split = col.split(align=True)
-                split.prop(context.scene, "easeIn", "Ease In")
-                split.prop(context.scene, "holdGap", "Hold Gap")
-                split.prop(context.scene, "easeOut", "Ease Out")
-                
-                col.operator('lipsync.go', text='Plot Keys to the Timeline')
-
-            # Jlipsync & Yolo panel
-            elif scn.regMenuTypes.enumFileTypes == '1':
-                col.prop(context.scene, "fpath")
-                split = col.split(align=True)
-                split.label("Key Value :")
-                split.prop(context.scene, "skscale")
-                split = col.split(align=True)
-                split.label("Frame Offset :")
-                split.prop(context.scene, "offset")
-                
-                col.operator('lipsync.go', text='Plot Keys to the Timeline')
-        
-        # the blinker panel
-        elif scn.regMenuTypes.enumModeTypes == '1':
-            # choose blink type
-            col.row().prop(scn.regMenuTypes, 'enumBlinkTypes', text = ' ', expand = True)
-            
-            # specific panel
-            if scn.regMenuTypes.enumBlinkTypes == '0':
-                split = col.split(align=True)
-                split.label("Key Value :")
-                split.prop(context.scene, "skscale")
-                split = col.split(align=True)
-                split.label("Frame Offset :")
-                split.prop(context.scene, "offset")
-                split = col.split(align=True)
-                split.prop(context.scene, "easeIn", "Ease In")
-                split.prop(context.scene, "holdGap", "Hold Gap")
-                split.prop(context.scene, "easeOut", "Ease Out")
-                col.prop(context.scene, "blinkSp", "Spacing")
-                col.prop(context.scene, "blinkNm", "Times")
-                col.operator('blink.go', text='Add Keys to the Timeline')
-            
-            # Random panel
-            elif scn.regMenuTypes.enumBlinkTypes == '1':
-                split = col.split(align=True)
-                split.label("Key Value :")
-                split.prop(context.scene, "skscale")
-                split = col.split(align=True)
-                split.label("Frame Start :")
-                split.prop(context.scene, "offset")
-                split = col.split(align=True)
-                split.prop(context.scene, "easeIn", "Ease In")
-                split.prop(context.scene, "holdGap", "Hold Gap")
-                split.prop(context.scene, "easeOut", "Ease Out")
-                split = col.split(align=True)
-                split.prop(context.scene, "blinkSp", "Spacing")
-                split.prop(context.scene, "blinkMod", "Random Modifier")
-                col.prop(context.scene, "blinkNm", "Times")
-                col.operator('blink.go', text='Add Keys to the Timeline')
-        
-        
-# clearing vars
-def clear_properties():
-
-    # can happen on reload
-    if bpy.context.scene is None:
-        return
-     
-    props = ["fpath", "skscale", "offset", "easeIn", "easeOut", "holdGap", "blinkSp", "blinkNm", "blinkMod"]
-    for p in props:
-        if p in bpy.types.Scene.bl_rna.properties:
-            exec("del bpy.types.Scene."+p)
-        if p in bpy.context.scene:
-            del bpy.context.scene[p]
-
-# registering the script
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.Scene.regMenuTypes = PointerProperty(type = menuTypes)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    del bpy.context.scene.regMenuTypes
-
-    clear_properties()
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_import_voodoo_camera.py b/release/scripts/addons_contrib/io_import_voodoo_camera.py
deleted file mode 100644
index 730d717..0000000
--- a/release/scripts/addons_contrib/io_import_voodoo_camera.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Import Voodoo camera",
-    "author": "Fazekas Laszlo",
-    "version": (0, 7),
-    "blender": (2, 5, 7),
-    "location": "File > Import > Voodoo camera",
-    "description": "Imports a Blender (2.4x or 2.5x) Python script from the Voodoo camera tracker software.",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Import-Export/Voodoo_camera",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=22510",
-    "category": "Import-Export"}
-
-"""
-This script loads a Blender Python script from the Voodoo camera
-tracker program into Blender 2.5x.
-
-It processes the script as a text file and not as a Python executable
-because of the incompatible Python APIs of Blender 2.4x and 2.5x.
-"""
-
-import bpy
-from bpy.props import *
-import mathutils
-import os
-import string
-import math
-
-def voodoo_import(infile,ld_cam,ld_points):
-
-    checktype = os.path.splitext(infile)[1]
-
-    if checktype.upper() != '.PY':
-        print ("Selected file: ",infile)
-        raise IOError("The selected input file is not a *.py file")
-        return
-
-    print ("--------------------------------------------------")
-    print ("Importing Voodoo file: ", infile)
-
-    file = open(infile,'rU')
-    scene = bpy.context.scene
-    initfr = scene.frame_current
-    b24= True
-
-    dummy = bpy.data.objects.new('voodoo_scene', None)
-    dummy.location = (0.0, 0.0, 0.0)
-    dummy.rotation_euler = ( -3.141593/2, 0.0, 0.0)
-    dummy.scale = (0.2, 0.2, 0.2)
-    scene.objects.link(dummy)
-
-    if ld_cam:
-        data = bpy.data.cameras.new('voodoo_render_cam')
-        vcam = bpy.data.objects.new('voodoo_render_cam', data)
-        vcam.location = (0.0, 0.0, 0.0)
-        vcam.rotation_euler = (0.0, 0.0, 0.0)
-        vcam.scale = (1.0, 1.0, 1.0)
-        data.lens = 35.0
-        data.shift_x = 0.0
-        data.shift_y = 0.0
-        data.dof_distance = 0.0
-        data.clip_start = 0.1
-        data.clip_end = 1000.0
-        data.draw_size = 0.5
-        scene.objects.link(vcam)
-        vcam.parent = dummy
-
-    if ld_points:
-        data = bpy.data.meshes.new('voodoo_FP3D_cloud')
-        mesh = bpy.data.objects.new('voodoo_FP3D_cloud', data)
-        mesh.location = (0.0, 0.0, 0.0)
-        mesh.rotation_euler = (3.141593/2, 0.0, 0.0)
-        mesh.scale = (5.0, 5.0, 5.0)
-        scene.objects.link(mesh)
-        mesh.parent = dummy
-
-    verts = []
-
-    def process_line(line):
-        lineSplit = line.split()
-
-        if (line[0] == '#'): return
-
-        if b24:
-
-            # Blender 2.4x mode
-            # process camera commands
-
-            if ld_cam:
-                if (line[0] == 'c' and line[1] != 'r'):
-                    pos= line.find('.lens')
-
-                    if (pos != -1):
-                        fr = int(lineSplit[0][1:pos],10)
-                        scene.frame_set(fr)
-                        vcam.data.lens= float(lineSplit[2])
-                        vcam.data.keyframe_insert('lens')
-                        return
-
-                if (line[0] == 'o'):
-                    pos= line.find('.setMatrix')
-
-                    if (pos != -1):
-                        fr = int(lineSplit[0][1:pos],10)
-                        scene.frame_set(fr)
-                        # for up to 2.55
-                        # vcam.matrix_world = eval('mathutils.' + line.rstrip()[pos+21:-1])
-                        # for 2.56, from Michael (Meikel) Oetjen 
-                        # vcam.matrix_world = eval('mathutils.Matrix(' + line.rstrip()[pos+28:-2].replace('[','(',4).replace(']',')',4) + ')')
-                        # for 2.57
-                        vcam.matrix_world = eval('mathutils.Matrix([' + line.rstrip()[pos+28:-2] + '])')
-                        vcam.keyframe_insert('location')
-                        vcam.keyframe_insert('scale')
-                        vcam.keyframe_insert('rotation_euler')
-                        return
-
-            # process mesh commands
-
-            if ld_points:
-                if (line[0] == 'v'):
-                    pos= line.find('NMesh.Vert')
-
-                    if (pos != -1):
-                        verts.append(eval(line[pos+10:]))
-
-            return
-
-        # Blender 2.5x mode
-        # process camera commands
-
-        if ld_cam:
-            pos= line.find('set_frame')
-
-            if (pos == -1):
-                pos= line.find('frame_set')
-
-            if (pos != -1):
-                scene.frame_set(eval(line[pos+9:]))
-                return
-
-            pos= line.find('vcam.data.lens')
-
-            if (pos != -1):
-                vcam.data.lens= float(lineSplit[2])
-                vcam.data.keyframe_insert('lens')
-                return
-
-            pos= line.find('.Matrix')
-
-            if (pos != -1):
-
-                # for up to 2.55
-                # vcam.matrix_world = eval('mathutils' + line[pos:])
-
-                # for 2.56
-                # if (line[pos+8] == '['):
-                #   # from Michael (Meikel) Oetjen
-                #     vcam.matrix_world = eval('mathutils.Matrix((' + line.rstrip()[pos+9:-1].replace('[','(',3).replace(']',')',4) + ')')
-                # else:
-                #   vcam.matrix_world = eval('mathutils' + line[pos:])
-
-                # for 2.57
-                vcam.matrix_world = eval('mathutils.Matrix([' + line.rstrip()[pos+8:-1] + '])')
-                vcam.keyframe_insert('location')
-                vcam.keyframe_insert('scale')
-                vcam.keyframe_insert('rotation_euler')
-                return
-
-        # process mesh commands
-
-        if ld_points:
-            pos= line.find('.append')
-
-            if (pos != -1):
-                verts.append(eval(line[pos+8:-2]))
-
-    #read lines
-
-    for line in file.readlines():
-
-        if (b24 and (line.find('import') != -1) and (line.find('bpy') != -1)):
-            b24= False
-
-        process_line(line)
-
-    scene.frame_set(initfr)
-
-    if ld_points:
-        mesh.data.from_pydata(verts, [], [])
-
-    mesh.data.update()
-
-
-# Operator
-class ImportVoodooCamera(bpy.types.Operator):
-    ''''''
-    bl_idname = "import.voodoo_camera"
-    bl_label = "Import Voodoo camera"
-    bl_description = "Load a Blender export script from the Voodoo motion tracker"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    filepath = StringProperty(name="File Path",
-        description="Filepath used for processing the script",
-        maxlen= 1024,default= "")
-
-#    filter_python = BoolProperty(name="Filter python",
-#    description="",default=True,options={'HIDDEN'})
-
-    load_camera = BoolProperty(name="Load camera",
-        description="Load the camera",
-        default=True)
-    load_points = BoolProperty(name="Load points",
-        description="Load the FP3D point cloud",
-        default=True)
-
-    def execute(self, context):
-        voodoo_import(self.filepath,self.load_camera,self.load_points)
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        wm = context.window_manager
-        wm.fileselect_add(self)
-        return {'RUNNING_MODAL'}
-
-
-# Registering / Unregister
-def menu_func(self, context):
-    self.layout.operator(ImportVoodooCamera.bl_idname, text="Voodoo camera", icon='PLUGIN')
-
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_file_import.append(menu_func)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_file_import.remove(menu_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_mesh_xyz/__init__.py b/release/scripts/addons_contrib/io_mesh_xyz/__init__.py
deleted file mode 100644
index 0e870fc..0000000
--- a/release/scripts/addons_contrib/io_mesh_xyz/__init__.py
+++ /dev/null
@@ -1,820 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "XYZ Atomic Blender",
-    "description": "Loading and manipulating atoms from XYZ files",
-    "author": "Clemens Barth",
-    "version": (0,6),
-    "blender": (2,6),
-    "location": "File -> Import -> XYZ (.xyz), Panel: View 3D - Tools",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/"
-                "Import-Export/XYZ",
-    "tracker_url": "http://projects.blender.org/tracker/"
-                   "index.php?func=detail&aid=29646&group_id=153&atid=468",
-    "category": "Import-Export"
-}
-
-import os
-import io
-import bpy
-from bpy.types import Operator, Panel
-from bpy_extras.io_utils import ImportHelper
-from bpy.props import (StringProperty,
-                       BoolProperty,
-                       EnumProperty,
-                       IntProperty,
-                       FloatProperty)
-
-from . import import_xyz
-ATOM_XYZ_ERROR = ""
-ATOM_XYZ_NOTE  = ""
-ATOM_XYZ_PANEL = ""
-
-# -----------------------------------------------------------------------------
-#                                                                           GUI
-
-# This is the panel, which can be used to prepare the scene.
-# It is loaded after the file has been chosen via the menu 'File -> Import'
-class CLASS_atom_xyz_prepare_panel(Panel):
-    bl_label       = "XYZ - Atomic Blender"
-    bl_space_type  = "VIEW_3D"
-    bl_region_type = "TOOL_PROPS"
-
-    @classmethod
-    def poll(self, context):
-        global ATOM_XYZ_PANEL
-        
-        if ATOM_XYZ_PANEL == "0" and import_xyz.ATOM_XYZ_FILEPATH == "":
-            return False
-        if ATOM_XYZ_PANEL == "0" and import_xyz.ATOM_XYZ_FILEPATH != "":
-            return True
-        if ATOM_XYZ_PANEL == "1":
-            return True
-        if ATOM_XYZ_PANEL == "2":
-            return False
-        
-        return True
-
-
-    def draw(self, context):
-        layout = self.layout
-
-        if len(context.scene.atom_xyz) == 0:
-            bpy.context.scene.atom_xyz.add()
-
-        scn    = context.scene.atom_xyz[0]
-
-        row = layout.row()
-        row.label(text="Outputs and custom data file")
-        box = layout.box()
-        row = box.row()
-        row.label(text="Custom data file")
-        row = box.row()
-        col = row.column()
-        col.prop(scn, "datafile")
-        col.operator("atom_xyz.datafile_apply")
-        row = box.row()
-        col = row.column(align=True)
-        col.prop(scn, "XYZ_file")
-        row = box.row()
-        row.prop(scn, "number_atoms")
-        row = box.row()
-        row.operator("atom_xyz.button_distance")
-        row.prop(scn, "distance")
-        row = layout.row()
-        row.label(text="Choice of atom radii")
-        box = layout.box()
-        row = box.row()
-        row.label(text="All changes concern:")
-        row = box.row()
-        row.prop(scn, "radius_how")
-        row = box.row()
-        row.label(text="1. Change type of radii")
-        row = box.row()
-        row.prop(scn, "radius_type")
-        row = box.row()
-        row.label(text="2. Change atom radii in pm")
-        row = box.row()
-        row.prop(scn, "radius_pm_name")
-        row = box.row()
-        row.prop(scn, "radius_pm")
-        row = box.row()
-        row.label(text="3. Change atom radii by scale")
-        row = box.row()
-        col = row.column()
-        col.prop(scn, "radius_all")
-        col = row.column(align=True)
-        col.operator( "atom_xyz.radius_all_bigger" )
-        col.operator( "atom_xyz.radius_all_smaller" )
-
-        if bpy.context.mode == 'EDIT_MESH':
-            layout.separator()
-            row = box.row()
-            row.operator( "atom_xyz.separate_atom" )
-
-        row = layout.row()
-        row.label(text="Loading frames")
-        box = layout.box()
-        row = box.row()
-        col = row.column()
-        col.label(text="Frames")
-        col = row.column()
-        col.prop(scn, "number_frames")
-        row = box.row()
-        col = row.column()
-        col.label(text="Skip frames")
-        col = row.column()
-        col.prop(scn, "skip_frames")
-        row = box.row()
-        col = row.column()
-        col.label(text="Frames/key")
-        col = row.column()
-        col.prop(scn, "images_per_key")        
-        row = box.row()
-        row.operator("atom_xyz.load_frames")
-        row = box.row()
-        row.operator("atom_xyz.delete_keys")
-        row = box.row()
-        row.operator( "atom_xyz.create_command")
-        row = box.row()
-        row.operator( "atom_xyz.render")
-
-
-class CLASS_atom_xyz_Properties(bpy.types.PropertyGroup):
-
-    def Callback_radius_type(self, context):
-        scn = bpy.context.scene.atom_xyz[0]
-        import_xyz.DEF_atom_xyz_radius_type(
-                scn.radius_type,
-                scn.radius_how,)
-
-    def Callback_radius_pm(self, context):
-        scn = bpy.context.scene.atom_xyz[0]
-        import_xyz.DEF_atom_xyz_radius_pm(
-                scn.radius_pm_name,
-                scn.radius_pm,
-                scn.radius_how,)
-
-    # In the file dialog window
-    use_camera = BoolProperty(
-        name="Camera", default=False,
-        description="Do you need a camera?")
-    use_lamp = BoolProperty(
-        name="Lamp", default=False,
-        description = "Do you need a lamp?")
-    use_mesh = BoolProperty(
-        name = "Mesh balls", default=False,
-        description = "Do you want to use mesh balls instead of NURBS?")
-    mesh_azimuth = IntProperty(
-        name = "Azimuth", default=32, min=0,
-        description = "Number of sectors (azimuth)")
-    mesh_zenith = IntProperty(
-        name = "Zenith", default=32, min=0,
-        description = "Number of sectors (zenith)")
-    scale_ballradius = FloatProperty(
-        name = "Balls", default=1.0, min=0.0,
-        description = "Scale factor for all atom radii")
-    scale_distances = FloatProperty (
-        name = "Distances", default=1.0, min=0.0,
-        description = "Scale factor for all distances")
-    use_center = BoolProperty(
-        name = "Object to origin", default=False,
-        description = "Shall the object first put into the global origin "
-        "before applying the offsets on the left?")
-    atomradius = EnumProperty(
-        name="Type of radius",
-        description="Choose type of atom radius",
-        items=(('0', "Pre-defined", "Use pre-defined radii"),
-               ('1', "Atomic", "Use atomic radii"),
-               ('2', "van der Waals", "Use van der Waals radii")),
-               default='0',)
-    # In the panel, first part
-    datafile = StringProperty(
-        name = "", description="Path to your custom data file",
-        maxlen = 256, default = "", subtype='FILE_PATH')
-    XYZ_file = StringProperty(
-        name = "Path to file", default="",
-        description = "Path of the XYZ file")
-    number_atoms = StringProperty(name="",
-        default="Number", description = "This output shows "
-        "the number of atoms which have been loaded")
-    distance = StringProperty(
-        name="", default="Distance (A)",
-        description="Distance of 2 objects in Angstrom")
-    radius_how = EnumProperty(
-        name="",
-        description="Which objects shall be modified?",
-        items=(('ALL_ACTIVE',"all active objects", "in the current layer"),
-               ('ALL_IN_LAYER',"all"," in active layer(s)")),
-               default='ALL_ACTIVE',)
-    radius_type = EnumProperty(
-        name="Type",
-        description="Which type of atom radii?",
-        items=(('0',"predefined", "Use pre-defined radii"),
-               ('1',"atomic", "Use atomic radii"),
-               ('2',"van der Waals","Use van der Waals radii")),
-               default='0',update=Callback_radius_type)
-    radius_pm_name = StringProperty(
-        name="", default="Atom name",
-        description="Put in the name of the atom (e.g. Hydrogen)")
-    radius_pm = FloatProperty(
-        name="", default=100.0, min=0.0,
-        description="Put in the radius of the atom (in pm)",
-        update=Callback_radius_pm)
-    radius_all = FloatProperty(
-        name="Scale", default = 1.05, min=1.0, max=5.0,
-        description="Put in the scale factor")
-    # In the panel, second part
-    number_frames = StringProperty(
-        name="", default="0",
-        description="This is the total number of frames stored in the xyz file")
-    skip_frames = IntProperty(
-        name="", default=0, min=0,
-        description="Number of frames you want to skip.")
-    images_per_key = IntProperty(
-        name="", default=1, min=1,
-        description="Choose the number of images between 2 keys.")
-
-
-
-# Button for creating a file that contains the command for rendering
-class CLASS_atom_xyz_create_command(Operator):
-    bl_idname = "atom_xyz.create_command"
-    bl_label = "Create command"
-    bl_description = "Create a shell command for rendering the scene"
-
-    def execute(self, context):
-        global ATOM_XYZ_ERROR
-        global ATOM_XYZ_NOTE
- 
-        scn = bpy.context.scene
-
-        fstart = scn.frame_start
-        fend = scn.frame_end
-        file_blend = bpy.context.blend_data.filepath
-        
-        if file_blend == "":
-            ATOM_XYZ_ERROR = "Save your scene first !"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}
-            
-        cameras = []    
-        FOUND = False    
-        for obj in bpy.context.scene.objects:  
-            if obj.type == "CAMERA":
-                cameras.append(obj)
-                FOUND = True   
-        if FOUND == False:
-            ATOM_XYZ_ERROR = "No camera => no images !"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}      
-        if bpy.context.scene.camera == None:
-            bpy.context.scene.camera = cameras[0]
-            
-        KEYS_PRESENT = True
-        for element in import_xyz.STRUCTURE:
-            bpy.ops.object.select_all(action='DESELECT')
-            bpy.context.scene.objects.active = element
-            element.select = True
-            if element.data.shape_keys == None:
-                KEYS_PRESENT = False
-                break       
-        if KEYS_PRESENT == False:
-            ATOM_XYZ_ERROR = "No frames => no movie !"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}     
-        
-        bpy.ops.wm.save_mainfile()
-        file_name = bpy.path.basename(file_blend)
-        file_path = file_blend.replace(file_name,"")
-        file_movie = bpy.path.display_name_from_filepath(file_blend)
-        blender_exe = bpy.app.binary_path
-                
-        if os.name == "posix":
-            execute = (blender_exe+" -b \'"+file_blend+"\' -x 1 -o //"+file_movie+
-                  "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a")
-        else:
-            execute = ("\""+blender_exe+"\" -b "+file_blend+" -x 1 -o //"+file_movie+
-                  "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a")
-
-        if os.name == "posix":
-            command_file = file_path + file_movie + ".sh"
-        else:
-            command_file = file_path + file_movie + ".txt"
-        command_fp = open(command_file,"w")
-           
-        if os.name == "posix":        
-            command_fp.write("#!/bin/sh\n")   
-        command_fp.write("\n"+execute+"\n")     
-        command_fp.close()
-        
-        ATOM_XYZ_NOTE = "The command has been stored (dir. of the .blend file)"
-        bpy.ops.atom_xyz.note_dialog('INVOKE_DEFAULT')
-
-        return {'FINISHED'}
-
-
-# Button for rendering the scene in a terminal
-class CLASS_atom_xyz_render(Operator):
-    bl_idname = "atom_xyz.render"
-    bl_label = "Render"
-    bl_description = "Render the scene"
-
-    def execute(self, context):
-        global ATOM_XYZ_ERROR
-        scn = bpy.context.scene
-
-        fstart = scn.frame_start
-        fend = scn.frame_end
-        file_blend = bpy.context.blend_data.filepath
-        
-        if file_blend == "":
-            ATOM_XYZ_ERROR = "Save your scene first!"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}
-            
-        cameras = []    
-        FOUND = False    
-        for obj in bpy.context.scene.objects:  
-            if obj.type == "CAMERA":
-                cameras.append(obj)
-                FOUND = True   
-        if FOUND == False:
-            ATOM_XYZ_ERROR = "No camera => no images !"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}      
-        if bpy.context.scene.camera == None:
-            bpy.context.scene.camera = cameras[0]
-            
-            
-        KEYS_PRESENT = True
-        for element in import_xyz.STRUCTURE:
-            bpy.ops.object.select_all(action='DESELECT')
-            bpy.context.scene.objects.active = element
-            element.select = True
-            if element.data.shape_keys == None:
-                KEYS_PRESENT = False
-                break       
-        if KEYS_PRESENT == False:
-            ATOM_XYZ_ERROR = "No frames => no movie !"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}    
-            
-        bpy.ops.wm.save_mainfile()    
-        
-        file_name = bpy.path.basename(file_blend)
-        file_path = file_blend.replace(file_name,"")
-        file_movie = bpy.path.display_name_from_filepath(file_blend)
-        blender_exe = bpy.app.binary_path
- 
-        if os.name == "posix":
-            execute = (blender_exe+" -b \'"+file_blend+"\' -x 1 -o //"+file_movie+
-                  "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a")
-            os_str = "xterm -e \"" + execute + "\" &"
-        else:
-            execute = ("\""+blender_exe+"\" -b "+file_blend+" -x 1 -o //"+file_movie+
-                  "_ -F AVIJPEG -s "+str(fstart)+" -e "+str(scn.frame_end)+" -a")
-            os_str = "C:\WINDOWS\system32\cmd.exe /C " + execute
-             
-        os.system(os_str)    
-        
-        return {'FINISHED'}
-
-
-# Button deleting all shape keys of the structure
-class CLASS_atom_xyz_delete_keys(Operator):
-    bl_idname = "atom_xyz.delete_keys"
-    bl_label = "Delete keys"
-    bl_description = "Delete the shape keys"
-
-    def execute(self, context):
-        for element in import_xyz.STRUCTURE:
-            if element.data.shape_keys == None:
-                break
-        
-            bpy.ops.object.select_all(action='DESELECT')
-            bpy.context.scene.objects.active = element
-            element.select = True
-        
-            for key in element.data.shape_keys.key_blocks:
-                bpy.ops.object.shape_key_remove()
-        
-        return {'FINISHED'}
-
-
-# Button loading the shape keys
-class CLASS_atom_xyz_load_frames(Operator):
-    bl_idname = "atom_xyz.load_frames"
-    bl_label = "Load frames"
-    bl_description = "Load the frames"
-
-    def execute(self, context):
-        global ATOM_XYZ_ERROR
-        scn = bpy.context.scene.atom_xyz[0]
-        
-        KEYS_PRESENT = False
-        for element in import_xyz.STRUCTURE:
-            bpy.ops.object.select_all(action='DESELECT')
-            bpy.context.scene.objects.active = element
-            element.select = True
-            if element.data.shape_keys != None:
-                KEYS_PRESENT = True
-                break
-                
-        if KEYS_PRESENT == True:
-            ATOM_XYZ_ERROR = "Delete first the keys"
-            bpy.ops.atom_xyz.error_dialog('INVOKE_DEFAULT')
-            return {'FINISHED'}
-        
-        
-        import_xyz.DEF_atom_xyz_build_frames(scn.images_per_key, 
-                                             scn.skip_frames)
-
-        return {'FINISHED'}
-
-
-
-# Button loading a custom data file
-class CLASS_atom_xyz_datafile_apply(Operator):
-    bl_idname = "atom_xyz.datafile_apply"
-    bl_label = "Apply"
-    bl_description = "Use color and radii values stored in the custom file"
-
-    def execute(self, context):
-        scn = bpy.context.scene.atom_xyz[0]
-
-        if scn.datafile == "":
-            return {'FINISHED'}
-
-        import_xyz.DEF_atom_xyz_custom_datafile(scn.datafile)
-
-        # TODO, move this into 'import_xyz' and call the function
-        for obj in bpy.context.selected_objects:
-            if len(obj.children) != 0:
-                child = obj.children[0]
-                if child.type == "SURFACE" or child.type  == "MESH":
-                    for element in import_xyz.ATOM_XYZ_ELEMENTS:
-                        if element.name in obj.name:
-                            child.scale = (element.radii[0],) * 3
-                            child.active_material.diffuse_color = element.color
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    for element in import_xyz.ATOM_XYZ_ELEMENTS:
-                        if element.name in obj.name:
-                            obj.scale = (element.radii[0],) * 3
-                            obj.active_material.diffuse_color = element.color
-
-        return {'FINISHED'}
-
-
-# Button for separating a single atom from a structure
-class CLASS_atom_xyz_separate_atom(Operator):
-    bl_idname = "atom_xyz.separate_atom"
-    bl_label = "Separate atom"
-    bl_description = "Separate the atom you have chosen"
-
-    def execute(self, context):
-        scn = bpy.context.scene.atom_xyz[0]
-
-        # Get first all important properties from the atom which the user
-        # has chosen: location, color, scale
-        obj = bpy.context.edit_object
-        name = obj.name
-        loc_obj_vec = obj.location
-        scale = obj.children[0].scale
-        material = obj.children[0].active_material
-
-        # Separate the vertex from the main mesh and create a new mesh.
-        bpy.ops.mesh.separate()
-        new_object = bpy.context.scene.objects[0]
-        # Keep in mind the coordinates <= We only need this
-        loc_vec = new_object.data.vertices[0].co
-
-        # And now, switch to the OBJECT mode such that we can ...
-        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-        # ... delete the new mesh including the separated vertex
-        bpy.ops.object.select_all(action='DESELECT')
-        new_object.select = True
-        bpy.ops.object.delete()
-
-        # Create a new atom/vacancy at the position of the old atom
-        current_layers=bpy.context.scene.layers
-
-        if "Vacancy" not in name:
-            if scn.use_mesh == False:
-                bpy.ops.surface.primitive_nurbs_surface_sphere_add(
-                                    view_align=False, enter_editmode=False,
-                                    location=loc_vec+loc_obj_vec,
-                                    rotation=(0.0, 0.0, 0.0),
-                                    layers=current_layers)
-            else:
-                bpy.ops.mesh.primitive_uv_sphere_add(
-                                segments=scn.mesh_azimuth,
-                                ring_count=scn.mesh_zenith,
-                                size=1, view_align=False, enter_editmode=False,
-                                location=loc_vec+loc_obj_vec,
-                                rotation=(0, 0, 0),
-                                layers=current_layers)
-        else:
-            bpy.ops.mesh.primitive_cube_add(
-                               view_align=False, enter_editmode=False,
-                               location=loc_vec+loc_obj_vec,
-                               rotation=(0.0, 0.0, 0.0),
-                               layers=current_layers)
-
-        new_atom = bpy.context.scene.objects.active
-        # Scale, material and name it.
-        new_atom.scale = scale
-        new_atom.active_material = material
-        new_atom.name = name + "_sep"
-
-        # Switch back into the 'Edit mode' because we would like to seprate
-        # other atoms may be (more convinient)
-        new_atom.select = False
-        obj.select = True
-        bpy.context.scene.objects.active = obj
-        bpy.ops.object.select_all(action='DESELECT')
-        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-
-        return {'FINISHED'}
-
-
-# Button for measuring the distance of the active objects
-class CLASS_atom_xyz_distance_button(Operator):
-    bl_idname = "atom_xyz.button_distance"
-    bl_label = "Measure ..."
-    bl_description = "Measure the distance between two objects"
-
-    def execute(self, context):
-        scn  = bpy.context.scene.atom_xyz[0]
-        dist = import_xyz.DEF_atom_xyz_distance()
-
-        if dist != "N.A.":
-           # The string length is cut, 3 digits after the first 3 digits
-           # after the '.'. Append also "Angstrom".
-           # Remember: 1 Angstrom = 10^(-10) m
-           pos    = str.find(dist, ".")
-           dist   = dist[:pos+4]
-           dist   = dist + " A"
-
-        # Put the distance into the string of the output field.
-        scn.distance = dist
-        return {'FINISHED'}
-
-
-# Button for increasing the radii of all atoms
-class CLASS_atom_xyz_radius_all_bigger_button(Operator):
-    bl_idname = "atom_xyz.radius_all_bigger"
-    bl_label = "Bigger ..."
-    bl_description = "Increase the radii of the atoms"
-
-    def execute(self, context):
-        scn = bpy.context.scene.atom_xyz[0]
-        import_xyz.DEF_atom_xyz_radius_all(
-                scn.radius_all,
-                scn.radius_how,
-                )
-        return {'FINISHED'}
-
-
-# Button for decreasing the radii of all atoms
-class CLASS_atom_xyz_radius_all_smaller_button(Operator):
-    bl_idname = "atom_xyz.radius_all_smaller"
-    bl_label = "Smaller ..."
-    bl_description = "Decrease the radii of the atoms"
-
-    def execute(self, context):
-        scn = bpy.context.scene.atom_xyz[0]
-        import_xyz.DEF_atom_xyz_radius_all(
-                1.0/scn.radius_all,
-                scn.radius_how,
-                )
-        return {'FINISHED'}
-
-
-def DEF_panel_yes_no():
-    global ATOM_XYZ_PANEL
-
-    datafile_path = bpy.utils.user_resource('SCRIPTS', path='', create=False)
-    if os.path.isdir(datafile_path) == False:
-        bpy.utils.user_resource('SCRIPTS', path='', create=True)
-        
-    datafile_path = os.path.join(datafile_path, "presets")
-    if os.path.isdir(datafile_path) == False:
-        os.mkdir(datafile_path)   
-        
-    datafile = os.path.join(datafile_path, "io_mesh_xyz.pref")
-    if os.path.isfile(datafile):
-        datafile_fp = io.open(datafile, "r")
-        for line in datafile_fp:
-            if "Panel" in line:
-                ATOM_XYZ_PANEL = line[-2:]
-                ATOM_XYZ_PANEL = ATOM_XYZ_PANEL[0:1]
-                bpy.context.scene.use_panel = ATOM_XYZ_PANEL
-                break       
-        datafile_fp.close()
-    else:
-        DEF_panel_write_pref("0") 
-
-
-def DEF_panel_write_pref(value): 
-    datafile_path = bpy.utils.user_resource('SCRIPTS', path='', create=False)
-    datafile_path = os.path.join(datafile_path, "presets")
-    datafile = os.path.join(datafile_path, "io_mesh_xyz.pref")
-    datafile_fp = io.open(datafile, "w")
-    datafile_fp.write("Atomic Blender XYZ - Import/Export - Preferences\n")
-    datafile_fp.write("================================================\n")
-    datafile_fp.write("\n")
-    datafile_fp.write("Panel: "+value+"\n\n\n")
-    datafile_fp.close()
-
-
-class CLASS_atom_xyz_error_dialog(bpy.types.Operator):
-    bl_idname = "atom_xyz.error_dialog"
-    bl_label = "Attention !"
-    
-    def draw(self, context):
-        layout = self.layout
-        row = layout.row()
-        row.label(text="                          "+ATOM_XYZ_ERROR) 
-    def execute(self, context):
-        print("Atomic Blender - Error: "+ATOM_XYZ_ERROR+"\n")
-        return {'FINISHED'}
-    def invoke(self, context, event):
-        return context.window_manager.invoke_props_dialog(self)
-
-
-class CLASS_atom_xyz_note_dialog(bpy.types.Operator):
-    bl_idname = "atom_xyz.note_dialog"
-    bl_label = "Attention !"
-    
-    def draw(self, context):
-        layout = self.layout
-        row = layout.row()
-        row.label(text=ATOM_XYZ_NOTE) 
-    def execute(self, context):
-        print("Atomic Blender - Note: "+ATOM_XYZ_NOTE+"\n")
-        return {'FINISHED'}
-    def invoke(self, context, event):
-        return context.window_manager.invoke_props_dialog(self)
-
-
-# This is the class for the file dialog.
-class CLASS_ImportXYZ(Operator, ImportHelper):
-    bl_idname = "import_mesh.xyz"
-    bl_label  = "Import XYZ (*.xyz)"
-    bl_options = {'PRESET', 'UNDO'}
-    
-    filename_ext = ".xyz"
-    filter_glob  = StringProperty(default="*.xyz", options={'HIDDEN'},)
-
-    bpy.types.Scene.use_panel = EnumProperty(
-        name="Panel",
-        description="Choose whether the panel shall appear or not in the View 3D.",
-        items=(('0', "Once", "The panel appears only in this session"),
-               ('1', "Always", "The panel always appears when Blender is started"),
-               ('2', "Never", "The panel never appears")),
-               default='0') 
-    use_camera = BoolProperty(
-        name="Camera", default=False,
-        description="Do you need a camera?")
-    use_lamp = BoolProperty(
-        name="Lamp", default=False,
-        description = "Do you need a lamp?")
-    use_mesh = BoolProperty(
-        name = "Mesh balls", default=False,
-        description = "Use mesh balls instead of NURBS")
-    mesh_azimuth = IntProperty(
-        name = "Azimuth", default=32, min=1,
-        description = "Number of sectors (azimuth)")
-    mesh_zenith = IntProperty(
-        name = "Zenith", default=32, min=1,
-        description = "Number of sectors (zenith)")
-    scale_ballradius = FloatProperty(
-        name = "Balls", default=1.0, min=0.0001,
-        description = "Scale factor for all atom radii")
-    scale_distances = FloatProperty (
-        name = "Distances", default=1.0, min=0.0001,
-        description = "Scale factor for all distances")
-    atomradius = EnumProperty(
-        name="Type of radius",
-        description="Choose type of atom radius",
-        items=(('0', "Pre-defined", "Use pre-defined radius"),
-               ('1', "Atomic", "Use atomic radius"),
-               ('2', "van der Waals", "Use van der Waals radius")),
-               default='0',)            
-    use_center = BoolProperty(
-        name = "Object to origin", default=True,
-        description = "Put the object into the global origin")           
-    datafile = StringProperty(
-        name = "", description="Path to your custom data file",
-        maxlen = 256, default = "", subtype='FILE_PATH')    
-
-    def draw(self, context):
-        layout = self.layout
-        row = layout.row()
-        row.prop(self, "use_camera")
-        row.prop(self, "use_lamp")
-        row = layout.row()
-        col = row.column()
-        col.prop(self, "use_mesh")
-        col = row.column(align=True)
-        col.prop(self, "mesh_azimuth")
-        col.prop(self, "mesh_zenith")
-        row = layout.row()
-        col = row.column()
-        col.label(text="Scaling factors")
-        col = row.column(align=True)
-        col.prop(self, "scale_ballradius")
-        col.prop(self, "scale_distances")
-        row = layout.row()
-        row.prop(self, "use_center")
-        row = layout.row()
-        row.prop(self, "atomradius")
-        row = layout.row()
-        row.prop(bpy.context.scene, "use_panel")
-
-    def execute(self, context):
-        
-        import_xyz.ALL_FRAMES[:] = []
-        import_xyz.NUMBER_FRAMES = 0
-        import_xyz.ATOM_XYZ_ELEMENTS[:] = []
-        import_xyz.ATOM_XYZ_FILEPATH = ""
-        import_xyz.STRUCTURE[:] = []
-
-        # This is in order to solve this strange 'relative path' thing.
-        import_xyz.ATOM_XYZ_FILEPATH = bpy.path.abspath(self.filepath)
-
-        # Execute main routine
-        atom_number = import_xyz.DEF_atom_xyz_main(
-                      self.use_mesh,
-                      self.mesh_azimuth,
-                      self.mesh_zenith,
-                      self.scale_ballradius,
-                      self.atomradius,
-                      self.scale_distances,
-                      self.use_center,
-                      self.use_camera,
-                      self.use_lamp,
-                      self.datafile)
-                      
-        # Copy the whole bunch of values into the property collection.
-        scn = context.scene.atom_xyz[0]
-        scn.use_mesh = self.use_mesh
-        scn.mesh_azimuth = self.mesh_azimuth
-        scn.mesh_zenith = self.mesh_zenith
-        scn.scale_ballradius = self.scale_ballradius
-        scn.atomradius = self.atomradius
-        scn.scale_distances = self.scale_distances
-        scn.use_center = self.use_center
-        scn.use_camera = self.use_camera
-        scn.use_lamp = self.use_lamp
-        scn.datafile = self.datafile              
-                      
-        scn.number_atoms = str(atom_number) + " atoms"
-        scn.number_frames = str(import_xyz.NUMBER_FRAMES)
-        scn.XYZ_file = import_xyz.ATOM_XYZ_FILEPATH
-
-        global ATOM_XYZ_PANEL
-        ATOM_XYZ_PANEL = bpy.context.scene.use_panel
-        DEF_panel_write_pref(bpy.context.scene.use_panel)
-        
-        return {'FINISHED'}
-        
-
-# The entry into the menu 'file -> import'
-def menu_func(self, context):
-    self.layout.operator(CLASS_ImportXYZ.bl_idname, text="XYZ (.xyz)")
-
-
-def register():
-    DEF_panel_yes_no()
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_file_import.append(menu_func)
-    bpy.types.Scene.atom_xyz = bpy.props.CollectionProperty(type=CLASS_atom_xyz_Properties)    
-    bpy.context.scene.atom_xyz.add()
-    
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_file_import.remove(menu_func)
-
-if __name__ == "__main__":
-
-    register()
diff --git a/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat b/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat
deleted file mode 100644
index 5e00a5f..0000000
--- a/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat
+++ /dev/null
@@ -1,1536 +0,0 @@
-Atom
-====
-Number           : 1
-Name             : Hydrogen
-Short name       : H
-Color            : 0.99,0.99,0.99
-Radius used      : 0.320000
-Radius, covalent : 0.320000
-Radius, atomic   : 0.790000
-Charge state     : -1
-Radius, ionic    : 1.540000
-
-
-Atom
-====
-Number           : 2
-Name             : Helium
-Short name       : He
-Color            : 0.84,0.99,0.99
-Radius used      : 0.930000
-Radius, covalent : 0.930000
-Radius, atomic   : 0.490000
-
-
-Atom
-====
-Number           : 3
-Name             : Lithium
-Short name       : Li
-Color            : 0.79,0.5,0.99
-Radius used      : 1.230000
-Radius, covalent : 1.230000
-Radius, atomic   : 2.050000
-Charge state     : 1
-Radius, ionic    : 0.680000
-
-
-Atom
-====
-Number           : 4
-Name             : Beryllium
-Short name       : Be
-Color            : 0.75,0.99,0.0
-Radius used      : 0.900000
-Radius, covalent : 0.900000
-Radius, atomic   : 1.400000
-Charge state     : 1
-Radius, ionic    : 0.440000
-Charge state     : 2
-Radius, ionic    : 0.350000
-
-
-Atom
-====
-Number           : 5
-Name             : Boron
-Short name       : B
-Color            : 0.99,0.70,0.70
-Radius used      : 0.820000
-Radius, covalent : 0.820000
-Radius, atomic   : 1.170000
-Charge state     : 1
-Radius, ionic    : 0.350000
-Charge state     : 3
-Radius, ionic    : 0.230000
-
-
-Atom
-====
-Number           : 6
-Name             : Carbon
-Short name       : C
-Color            : 0.3,0.3,0.3
-Radius used      : 0.910000
-Radius, covalent : 0.770000
-Radius, atomic   : 0.910000
-Charge state     : -4
-Radius, ionic    : 2.600000
-Charge state     : 4
-Radius, ionic    : 0.160000
-
-
-Atom
-====
-Number           : 7
-Name             : Nitrogen
-Short name       : N
-Color            : 0.18,0.31,0.96
-Radius used      : 0.750000
-Radius, covalent : 0.750000
-Radius, atomic   : 0.750000
-Charge state     : -3
-Radius, ionic    : 1.710000
-Charge state     : 1
-Radius, ionic    : 0.250000
-Charge state     : 3
-Radius, ionic    : 0.160000
-Charge state     : 5
-Radius, ionic    : 0.130000
-
-
-Atom
-====
-Number           : 8
-Name             : Oxygen
-Short name       : O
-Color            : 0.99,0.05,0.05
-Radius used      : 0.730000
-Radius, covalent : 0.730000
-Radius, atomic   : 0.650000
-Charge state     : -2
-Radius, ionic    : 1.320000
-Charge state     : -1
-Radius, ionic    : 1.760000
-Charge state     : 1
-Radius, ionic    : 0.220000
-Charge state     : 6
-Radius, ionic    : 0.090000
-
-
-Atom
-====
-Number           : 9
-Name             : Fluorine
-Short name       : F
-Color            : 0.0,1.0,0.0
-Radius used      : 1.330000
-Radius, covalent : 0.720000
-Radius, atomic   : 0.570000
-Charge state     : -1
-Radius, ionic    : 1.330000
-Charge state     : 7
-Radius, ionic    : 0.080000
-
-
-Atom
-====
-Number           : 10
-Name             : Neon
-Short name       : Ne
-Color            : 0.69,0.88,0.95
-Radius used      : 0.710000
-Radius, covalent : 0.710000
-Radius, atomic   : 0.510000
-Charge state     : 1
-Radius, ionic    : 1.120000
-
-
-Atom
-====
-Number           : 11
-Name             : Sodium
-Short name       : Na
-Color            : 0.5,0.5,0.5
-Radius used      : 0.970000
-Radius, covalent : 1.540000
-Radius, atomic   : 2.230000
-Charge state     : 1
-Radius, ionic    : 0.970000
-
-
-Atom
-====
-Number           : 12
-Name             : Magnesium
-Short name       : Mg
-Color            : 0.38,0.066,1.0
-Radius used      : 0.660000
-Radius, covalent : 1.360000
-Radius, atomic   : 1.720000
-Charge state     : 1
-Radius, ionic    : 0.820000
-Charge state     : 2
-Radius, ionic    : 0.660000
-
-
-Atom
-====
-Number           : 13
-Name             : Aluminium
-Short name       : Al
-Color            : 0.74,0.64,0.64
-Radius used      : 1.180000
-Radius, covalent : 1.180000
-Radius, atomic   : 1.820000
-Charge state     : 3
-Radius, ionic    : 0.510000
-
-
-Atom
-====
-Number           : 14
-Name             : Silicon
-Short name       : Si
-Color            : 0.93,0.78,0.62
-Radius used      : 1.110000
-Radius, covalent : 1.110000
-Radius, atomic   : 1.460000
-Charge state     : -4
-Radius, ionic    : 2.710000
-Charge state     : -1
-Radius, ionic    : 3.840000
-Charge state     : 1
-Radius, ionic    : 0.650000
-Charge state     : 4
-Radius, ionic    : 0.420000
-
-
-Atom
-====
-Number           : 15
-Name             : Phosphorus
-Short name       : P
-Color            : 0.99,0.5,0.0
-Radius used      : 1.060000
-Radius, covalent : 1.060000
-Radius, atomic   : 1.230000
-Charge state     : -3
-Radius, ionic    : 2.120000
-Charge state     : 3
-Radius, ionic    : 0.440000
-Charge state     : 5
-Radius, ionic    : 0.350000
-
-
-Atom
-====
-Number           : 16
-Name             : Sulfur
-Short name       : S
-Color            : 0.99,0.99,0.18
-Radius used      : 1.020000
-Radius, covalent : 1.020000
-Radius, atomic   : 1.090000
-Charge state     : -2
-Radius, ionic    : 1.840000
-Charge state     : 2
-Radius, ionic    : 2.190000
-Charge state     : 4
-Radius, ionic    : 0.370000
-Charge state     : 6
-Radius, ionic    : 0.300000
-
-
-Atom
-====
-Number           : 17
-Name             : Chlorine
-Short name       : Cl
-Color            : 0.095,0.411,1.0
-Radius used      : 1.810000
-Radius, covalent : 0.990000
-Radius, atomic   : 0.970000
-Charge state     : -1
-Radius, ionic    : 1.810000
-Charge state     : 5
-Radius, ionic    : 0.340000
-Charge state     : 7
-Radius, ionic    : 0.270000
-
-
-Atom
-====
-Number           : 18
-Name             : Argon
-Short name       : Ar
-Color            : 0.5,0.81,0.88
-Radius used      : 0.980000
-Radius, covalent : 0.980000
-Radius, atomic   : 0.880000
-Charge state     : 1
-Radius, ionic    : 1.540000
-
-
-Atom
-====
-Number           : 19
-Name             : Potassium
-Short name       : K
-Color            : 0.55,0.25,0.82
-Radius used      : 2.030000
-Radius, covalent : 2.030000
-Radius, atomic   : 2.770000
-Charge state     : 1
-Radius, ionic    : 0.810000
-
-
-Atom
-====
-Number           : 20
-Name             : Calcium
-Short name       : Ca
-Color            : 0.23,0.99,0.0
-Radius used      : 1.740000
-Radius, covalent : 1.740000
-Radius, atomic   : 2.230000
-Charge state     : 1
-Radius, ionic    : 1.180000
-Charge state     : 2
-Radius, ionic    : 0.990000
-
-
-Atom
-====
-Number           : 21
-Name             : Scandium
-Short name       : Sc
-Color            : 0.89,0.89,0.89
-Radius used      : 1.440000
-Radius, covalent : 1.440000
-Radius, atomic   : 2.090000
-Charge state     : 3
-Radius, ionic    : 0.732000
-
-
-Atom
-====
-Number           : 22
-Name             : Titanium
-Short name       : Ti
-Color            : 0.74,0.75,0.77
-Radius used      : 1.320000
-Radius, covalent : 1.320000
-Radius, atomic   : 2.000000
-Charge state     : 1
-Radius, ionic    : 0.960000
-Charge state     : 2
-Radius, ionic    : 0.940000
-Charge state     : 3
-Radius, ionic    : 0.760000
-Charge state     : 4
-Radius, ionic    : 0.680000
-
-
-Atom
-====
-Number           : 23
-Name             : Vanadium
-Short name       : V
-Color            : 0.64,0.64,0.66
-Radius used      : 1.220000
-Radius, covalent : 1.220000
-Radius, atomic   : 1.920000
-Charge state     : 2
-Radius, ionic    : 0.880000
-Charge state     : 3
-Radius, ionic    : 0.740000
-Charge state     : 4
-Radius, ionic    : 0.630000
-Charge state     : 5
-Radius, ionic    : 0.590000
-
-
-Atom
-====
-Number           : 24
-Name             : Chromium
-Short name       : Cr
-Color            : 0.53,0.59,0.77
-Radius used      : 1.180000
-Radius, covalent : 1.180000
-Radius, atomic   : 1.850000
-Charge state     : 1
-Radius, ionic    : 0.810000
-Charge state     : 2
-Radius, ionic    : 0.890000
-Charge state     : 3
-Radius, ionic    : 0.630000
-Charge state     : 6
-Radius, ionic    : 0.520000
-
-
-Atom
-====
-Number           : 25
-Name             : Manganese
-Short name       : Mn
-Color            : 0.60,0.47,0.77
-Radius used      : 1.170000
-Radius, covalent : 1.170000
-Radius, atomic   : 1.790000
-Charge state     : 2
-Radius, ionic    : 0.800000
-Charge state     : 3
-Radius, ionic    : 0.660000
-Charge state     : 4
-Radius, ionic    : 0.600000
-Charge state     : 7
-Radius, ionic    : 0.460000
-
-
-Atom
-====
-Number           : 26
-Name             : Iron
-Short name       : Fe
-Color            : 0.87,0.39,0.19
-Radius used      : 1.170000
-Radius, covalent : 1.170000
-Radius, atomic   : 1.720000
-Charge state     : 2
-Radius, ionic    : 0.740000
-Charge state     : 3
-Radius, ionic    : 0.640000
-
-
-Atom
-====
-Number           : 27
-Name             : Cobalt
-Short name       : Co
-Color            : 0.93,0.56,0.62
-Radius used      : 1.160000
-Radius, covalent : 1.160000
-Radius, atomic   : 1.670000
-Charge state     : 2
-Radius, ionic    : 0.720000
-Charge state     : 3
-Radius, ionic    : 0.630000
-
-
-Atom
-====
-Number           : 28
-Name             : Nickel
-Short name       : Ni
-Color            : 0.31,0.81,0.31
-Radius used      : 1.150000
-Radius, covalent : 1.150000
-Radius, atomic   : 1.620000
-Charge state     : 2
-Radius, ionic    : 0.690000
-
-
-Atom
-====
-Number           : 29
-Name             : Copper
-Short name       : Cu
-Color            : 0.78,0.5,0.19
-Radius used      : 1.170000
-Radius, covalent : 1.170000
-Radius, atomic   : 1.570000
-Charge state     : 1
-Radius, ionic    : 0.960000
-Charge state     : 2
-Radius, ionic    : 0.720000
-
-
-Atom
-====
-Number           : 30
-Name             : Zinc
-Short name       : Zn
-Color            : 0.48,0.5,0.68
-Radius used      : 1.250000
-Radius, covalent : 1.250000
-Radius, atomic   : 1.530000
-Charge state     : 1
-Radius, ionic    : 0.880000
-Charge state     : 2
-Radius, ionic    : 0.740000
-
-
-Atom
-====
-Number           : 31
-Name             : Gallium
-Short name       : Ga
-Color            : 0.75,0.55,0.55
-Radius used      : 1.260000
-Radius, covalent : 1.260000
-Radius, atomic   : 1.810000
-Charge state     : 1
-Radius, ionic    : 0.810000
-Charge state     : 3
-Radius, ionic    : 0.620000
-
-
-Atom
-====
-Number           : 32
-Name             : Germanium
-Short name       : Ge
-Color            : 0.39,0.55,0.55
-Radius used      : 1.220000
-Radius, covalent : 1.220000
-Radius, atomic   : 1.520000
-Charge state     : -4
-Radius, ionic    : 2.720000
-Charge state     : 2
-Radius, ionic    : 0.730000
-Charge state     : 4
-Radius, ionic    : 0.530000
-
-
-Atom
-====
-Number           : 33
-Name             : Arsenic
-Short name       : As
-Color            : 0.73,0.5,0.88
-Radius used      : 1.200000
-Radius, covalent : 1.200000
-Radius, atomic   : 1.330000
-Charge state     : -3
-Radius, ionic    : 2.220000
-Charge state     : 3
-Radius, ionic    : 0.580000
-Charge state     : 5
-Radius, ionic    : 0.460000
-
-
-Atom
-====
-Number           : 34
-Name             : Selenium
-Short name       : Se
-Color            : 0.99,0.62,0.0
-Radius used      : 1.160000
-Radius, covalent : 1.160000
-Radius, atomic   : 1.220000
-Charge state     : -2
-Radius, ionic    : 1.910000
-Charge state     : -1
-Radius, ionic    : 2.320000
-Charge state     : 1
-Radius, ionic    : 0.660000
-Charge state     : 4
-Radius, ionic    : 0.500000
-Charge state     : 6
-Radius, ionic    : 0.420000
-
-
-Atom
-====
-Number           : 35
-Name             : Bromine
-Short name       : Br
-Color            : 0.64,0.16,0.16
-Radius used      : 1.140000
-Radius, covalent : 1.140000
-Radius, atomic   : 1.120000
-Charge state     : -1
-Radius, ionic    : 1.960000
-Charge state     : 5
-Radius, ionic    : 0.470000
-Charge state     : 7
-Radius, ionic    : 0.390000
-
-
-Atom
-====
-Number           : 36
-Name             : Krypton
-Short name       : Kr
-Color            : 0.35,0.71,0.81
-Radius used      : 1.310000
-Radius, covalent : 1.310000
-Radius, atomic   : 1.240000
-
-
-Atom
-====
-Number           : 37
-Name             : Rubidium
-Short name       : Rb
-Color            : 0.43,0.17,0.68
-Radius used      : 2.160000
-Radius, covalent : 2.160000
-Radius, atomic   : 2.980000
-Charge state     : 1
-Radius, ionic    : 1.470000
-
-
-Atom
-====
-Number           : 38
-Name             : Strontium
-Short name       : Sr
-Color            : 0.0,0.99,0.0
-Radius used      : 1.910000
-Radius, covalent : 1.910000
-Radius, atomic   : 2.450000
-Charge state     : 2
-Radius, ionic    : 1.120000
-
-
-Atom
-====
-Number           : 39
-Name             : Yttrium
-Short name       : Y
-Color            : 0.57,0.99,0.99
-Radius used      : 1.620000
-Radius, covalent : 1.620000
-Radius, atomic   : 2.270000
-Charge state     : 3
-Radius, ionic    : 0.893000
-
-
-Atom
-====
-Number           : 40
-Name             : Zirconium
-Short name       : Zr
-Color            : 0.57,0.87,0.87
-Radius used      : 1.450000
-Radius, covalent : 1.450000
-Radius, atomic   : 2.160000
-Charge state     : 1
-Radius, ionic    : 1.090000
-Charge state     : 4
-Radius, ionic    : 0.790000
-
-
-Atom
-====
-Number           : 41
-Name             : Niobium
-Short name       : Nb
-Color            : 0.44,0.75,0.78
-Radius used      : 1.340000
-Radius, covalent : 1.340000
-Radius, atomic   : 2.080000
-Charge state     : 1
-Radius, ionic    : 1.000000
-Charge state     : 4
-Radius, ionic    : 0.740000
-Charge state     : 5
-Radius, ionic    : 0.690000
-
-
-Atom
-====
-Number           : 42
-Name             : Molybdenum
-Short name       : Mo
-Color            : 0.32,0.70,0.70
-Radius used      : 1.300000
-Radius, covalent : 1.300000
-Radius, atomic   : 2.010000
-Charge state     : 1
-Radius, ionic    : 0.930000
-Charge state     : 4
-Radius, ionic    : 0.700000
-Charge state     : 6
-Radius, ionic    : 0.620000
-
-
-Atom
-====
-Number           : 43
-Name             : Technetium
-Short name       : Tc
-Color            : 0.23,0.61,0.61
-Radius used      : 1.270000
-Radius, covalent : 1.270000
-Radius, atomic   : 1.950000
-Charge state     : 7
-Radius, ionic    : 0.979000
-
-
-Atom
-====
-Number           : 44
-Name             : Ruthenium
-Short name       : Ru
-Color            : 0.14,0.55,0.55
-Radius used      : 1.250000
-Radius, covalent : 1.250000
-Radius, atomic   : 1.890000
-Charge state     : 4
-Radius, ionic    : 0.670000
-
-
-Atom
-====
-Number           : 45
-Name             : Rhodium
-Short name       : Rh
-Color            : 0.03,0.48,0.54
-Radius used      : 1.250000
-Radius, covalent : 1.250000
-Radius, atomic   : 1.830000
-Charge state     : 3
-Radius, ionic    : 0.680000
-
-
-Atom
-====
-Number           : 46
-Name             : Palladium
-Short name       : Pd
-Color            : 0.0,0.41,0.51
-Radius used      : 1.280000
-Radius, covalent : 1.280000
-Radius, atomic   : 1.790000
-Charge state     : 2
-Radius, ionic    : 0.800000
-Charge state     : 4
-Radius, ionic    : 0.650000
-
-
-Atom
-====
-Number           : 47
-Name             : Silver
-Short name       : Ag
-Color            : 0.75,0.75,0.75
-Radius used      : 1.340000
-Radius, covalent : 1.340000
-Radius, atomic   : 1.750000
-Charge state     : 1
-Radius, ionic    : 1.260000
-Charge state     : 2
-Radius, ionic    : 0.890000
-
-
-Atom
-====
-Number           : 48
-Name             : Cadmium
-Short name       : Cd
-Color            : 0.99,0.84,0.55
-Radius used      : 1.480000
-Radius, covalent : 1.480000
-Radius, atomic   : 1.710000
-Charge state     : 1
-Radius, ionic    : 1.140000
-Charge state     : 2
-Radius, ionic    : 0.970000
-
-
-Atom
-====
-Number           : 49
-Name             : Indium
-Short name       : In
-Color            : 0.64,0.45,0.44
-Radius used      : 1.440000
-Radius, covalent : 1.440000
-Radius, atomic   : 2.000000
-Charge state     : 3
-Radius, ionic    : 0.810000
-
-
-Atom
-====
-Number           : 50
-Name             : Tin
-Short name       : Sn
-Color            : 0.39,0.5,0.5
-Radius used      : 1.410000
-Radius, covalent : 1.410000
-Radius, atomic   : 1.720000
-Charge state     : -4
-Radius, ionic    : 2.940000
-Charge state     : -1
-Radius, ionic    : 3.700000
-Charge state     : 2
-Radius, ionic    : 0.930000
-Charge state     : 4
-Radius, ionic    : 0.710000
-
-
-Atom
-====
-Number           : 51
-Name             : Antimony
-Short name       : Sb
-Color            : 0.61,0.38,0.70
-Radius used      : 1.400000
-Radius, covalent : 1.400000
-Radius, atomic   : 1.530000
-Charge state     : -3
-Radius, ionic    : 2.450000
-Charge state     : 3
-Radius, ionic    : 0.760000
-Charge state     : 5
-Radius, ionic    : 0.620000
-
-
-Atom
-====
-Number           : 52
-Name             : Tellurium
-Short name       : Te
-Color            : 0.82,0.47,0.0
-Radius used      : 1.360000
-Radius, covalent : 1.360000
-Radius, atomic   : 1.420000
-Charge state     : -2
-Radius, ionic    : 2.110000
-Charge state     : -1
-Radius, ionic    : 2.500000
-Charge state     : 1
-Radius, ionic    : 0.820000
-Charge state     : 4
-Radius, ionic    : 0.700000
-Charge state     : 6
-Radius, ionic    : 0.560000
-
-
-Atom
-====
-Number           : 53
-Name             : Iodine
-Short name       : I
-Color            : 0.57,0.0,0.57
-Radius used      : 1.330000
-Radius, covalent : 1.330000
-Radius, atomic   : 1.320000
-Charge state     : -1
-Radius, ionic    : 2.200000
-Charge state     : 5
-Radius, ionic    : 0.620000
-Charge state     : 7
-Radius, ionic    : 0.500000
-
-
-Atom
-====
-Number           : 54
-Name             : Xenon
-Short name       : Xe
-Color            : 0.25,0.61,0.68
-Radius used      : 1.310000
-Radius, covalent : 1.310000
-Radius, atomic   : 1.240000
-
-
-Atom
-====
-Number           : 55
-Name             : Caesium
-Short name       : Cs
-Color            : 0.33,0.08,0.55
-Radius used      : 2.350000
-Radius, covalent : 2.350000
-Radius, atomic   : 3.350000
-Charge state     : 1
-Radius, ionic    : 1.670000
-
-
-Atom
-====
-Number           : 56
-Name             : Barium
-Short name       : Ba
-Color            : 0.0,0.78,0.0
-Radius used      : 1.980000
-Radius, covalent : 1.980000
-Radius, atomic   : 2.780000
-Charge state     : 1
-Radius, ionic    : 1.530000
-Charge state     : 2
-Radius, ionic    : 1.340000
-
-
-Atom
-====
-Number           : 57
-Name             : Lanthanum
-Short name       : La
-Color            : 0.43,0.82,0.99
-Radius used      : 1.690000
-Radius, covalent : 1.690000
-Radius, atomic   : 2.740000
-Charge state     : 1
-Radius, ionic    : 1.390000
-Charge state     : 3
-Radius, ionic    : 1.061000
-
-
-Atom
-====
-Number           : 58
-Name             : Cerium
-Short name       : Ce
-Color            : 0.99,0.99,0.77
-Radius used      : 1.650000
-Radius, covalent : 1.650000
-Radius, atomic   : 2.700000
-Charge state     : 1
-Radius, ionic    : 1.270000
-Charge state     : 3
-Radius, ionic    : 1.034000
-Charge state     : 4
-Radius, ionic    : 0.920000
-
-
-Atom
-====
-Number           : 59
-Name             : Praseodymium
-Short name       : Pr
-Color            : 0.84,0.99,0.77
-Radius used      : 1.650000
-Radius, covalent : 1.650000
-Radius, atomic   : 2.670000
-Charge state     : 3
-Radius, ionic    : 1.013000
-Charge state     : 4
-Radius, ionic    : 0.900000
-
-
-Atom
-====
-Number           : 60
-Name             : Neodymium
-Short name       : Nd
-Color            : 0.77,0.99,0.77
-Radius used      : 1.640000
-Radius, covalent : 1.640000
-Radius, atomic   : 2.640000
-Charge state     : 3
-Radius, ionic    : 0.995000
-
-
-Atom
-====
-Number           : 61
-Name             : Promethium
-Short name       : Pm
-Color            : 0.63,0.99,0.77
-Radius used      : 1.630000
-Radius, covalent : 1.630000
-Radius, atomic   : 2.620000
-Charge state     : 3
-Radius, ionic    : 0.979000
-
-
-Atom
-====
-Number           : 62
-Name             : Samarium
-Short name       : Sm
-Color            : 0.55,0.99,0.77
-Radius used      : 1.620000
-Radius, covalent : 1.620000
-Radius, atomic   : 2.590000
-Charge state     : 3
-Radius, ionic    : 0.964000
-
-
-Atom
-====
-Number           : 63
-Name             : Europium
-Short name       : Eu
-Color            : 0.37,0.99,0.77
-Radius used      : 1.850000
-Radius, covalent : 1.850000
-Radius, atomic   : 2.560000
-Charge state     : 2
-Radius, ionic    : 1.090000
-Charge state     : 3
-Radius, ionic    : 0.950000
-
-
-Atom
-====
-Number           : 64
-Name             : Gadolinium
-Short name       : Gd
-Color            : 0.26,0.99,0.77
-Radius used      : 1.610000
-Radius, covalent : 1.610000
-Radius, atomic   : 2.540000
-Charge state     : 3
-Radius, ionic    : 0.938000
-
-
-Atom
-====
-Number           : 65
-Name             : Terbium
-Short name       : Tb
-Color            : 0.18,0.99,0.77
-Radius used      : 1.590000
-Radius, covalent : 1.590000
-Radius, atomic   : 2.510000
-Charge state     : 3
-Radius, ionic    : 0.923000
-Charge state     : 4
-Radius, ionic    : 0.840000
-
-
-Atom
-====
-Number           : 66
-Name             : Dysprosium
-Short name       : Dy
-Color            : 0.12,0.99,0.77
-Radius used      : 1.590000
-Radius, covalent : 1.590000
-Radius, atomic   : 2.490000
-Charge state     : 3
-Radius, ionic    : 0.908000
-
-
-Atom
-====
-Number           : 67
-Name             : Holmium
-Short name       : Ho
-Color            : 0.0,0.99,0.60
-Radius used      : 1.580000
-Radius, covalent : 1.580000
-Radius, atomic   : 2.470000
-Charge state     : 3
-Radius, ionic    : 0.894000
-
-
-Atom
-====
-Number           : 68
-Name             : Erbium
-Short name       : Er
-Color            : 0.0,0.89,0.45
-Radius used      : 1.570000
-Radius, covalent : 1.570000
-Radius, atomic   : 2.450000
-Charge state     : 3
-Radius, ionic    : 0.881000
-
-
-Atom
-====
-Number           : 69
-Name             : Thulium
-Short name       : Tm
-Color            : 0.0,0.82,0.32
-Radius used      : 1.560000
-Radius, covalent : 1.560000
-Radius, atomic   : 2.420000
-Charge state     : 3
-Radius, ionic    : 0.870000
-
-
-Atom
-====
-Number           : 70
-Name             : Ytterbium
-Short name       : Yb
-Color            : 0.0,0.74,0.21
-Radius used      : 1.740000
-Radius, covalent : 1.740000
-Radius, atomic   : 2.400000
-Charge state     : 2
-Radius, ionic    : 0.930000
-Charge state     : 3
-Radius, ionic    : 0.858000
-
-
-Atom
-====
-Number           : 71
-Name             : Lutetium
-Short name       : Lu
-Color            : 0.0,0.66,0.14
-Radius used      : 1.560000
-Radius, covalent : 1.560000
-Radius, atomic   : 2.250000
-Charge state     : 3
-Radius, ionic    : 0.850000
-
-
-Atom
-====
-Number           : 72
-Name             : Hafnium
-Short name       : Hf
-Color            : 0.30,0.75,0.99
-Radius used      : 1.440000
-Radius, covalent : 1.440000
-Radius, atomic   : 2.160000
-Charge state     : 4
-Radius, ionic    : 0.780000
-
-
-Atom
-====
-Number           : 73
-Name             : Tantalum
-Short name       : Ta
-Color            : 0.30,0.64,0.99
-Radius used      : 1.340000
-Radius, covalent : 1.340000
-Radius, atomic   : 2.090000
-Charge state     : 5
-Radius, ionic    : 0.680000
-
-
-Atom
-====
-Number           : 74
-Name             : Tungsten
-Short name       : W
-Color            : 0.12,0.57,0.83
-Radius used      : 1.300000
-Radius, covalent : 1.300000
-Radius, atomic   : 2.020000
-Charge state     : 4
-Radius, ionic    : 0.700000
-Charge state     : 6
-Radius, ionic    : 0.620000
-
-
-Atom
-====
-Number           : 75
-Name             : Rhenium
-Short name       : Re
-Color            : 0.14,0.48,0.66
-Radius used      : 1.280000
-Radius, covalent : 1.280000
-Radius, atomic   : 1.970000
-Charge state     : 4
-Radius, ionic    : 0.720000
-Charge state     : 7
-Radius, ionic    : 0.560000
-
-
-Atom
-====
-Number           : 76
-Name             : Osmium
-Short name       : Os
-Color            : 0.14,0.39,0.58
-Radius used      : 1.260000
-Radius, covalent : 1.260000
-Radius, atomic   : 1.920000
-Charge state     : 4
-Radius, ionic    : 0.880000
-Charge state     : 6
-Radius, ionic    : 0.690000
-
-
-Atom
-====
-Number           : 77
-Name             : Iridium
-Short name       : Ir
-Color            : 0.08,0.32,0.52
-Radius used      : 1.270000
-Radius, covalent : 1.270000
-Radius, atomic   : 1.870000
-Charge state     : 4
-Radius, ionic    : 0.680000
-
-
-Atom
-====
-Number           : 78
-Name             : Platinium
-Short name       : Pt
-Color            : 0.81,0.81,0.87
-Radius used      : 1.300000
-Radius, covalent : 1.300000
-Radius, atomic   : 1.830000
-Charge state     : 2
-Radius, ionic    : 0.800000
-Charge state     : 4
-Radius, ionic    : 0.650000
-
-
-Atom
-====
-Number           : 79
-Name             : Gold
-Short name       : Au
-Color            : 0.99,0.81,0.13
-Radius used      : 1.340000
-Radius, covalent : 1.340000
-Radius, atomic   : 1.790000
-Charge state     : 1
-Radius, ionic    : 1.370000
-Charge state     : 3
-Radius, ionic    : 0.850000
-
-
-Atom
-====
-Number           : 80
-Name             : Mercury
-Short name       : Hg
-Color            : 0.71,0.71,0.81
-Radius used      : 1.490000
-Radius, covalent : 1.490000
-Radius, atomic   : 1.760000
-Charge state     : 1
-Radius, ionic    : 1.270000
-Charge state     : 2
-Radius, ionic    : 1.100000
-
-
-Atom
-====
-Number           : 81
-Name             : Thallium
-Short name       : Tl
-Color            : 0.64,0.32,0.30
-Radius used      : 1.480000
-Radius, covalent : 1.480000
-Radius, atomic   : 2.080000
-Charge state     : 1
-Radius, ionic    : 1.470000
-Charge state     : 3
-Radius, ionic    : 0.950000
-
-
-Atom
-====
-Number           : 82
-Name             : Lead
-Short name       : Pb
-Color            : 0.33,0.34,0.37
-Radius used      : 1.470000
-Radius, covalent : 1.470000
-Radius, atomic   : 1.810000
-Charge state     : 2
-Radius, ionic    : 1.200000
-Charge state     : 4
-Radius, ionic    : 0.840000
-
-
-Atom
-====
-Number           : 83
-Name             : Bismuth
-Short name       : Bi
-Color            : 0.61,0.30,0.70
-Radius used      : 1.460000
-Radius, covalent : 1.460000
-Radius, atomic   : 1.630000
-Charge state     : 1
-Radius, ionic    : 0.980000
-Charge state     : 3
-Radius, ionic    : 0.960000
-Charge state     : 5
-Radius, ionic    : 0.740000
-
-
-Atom
-====
-Number           : 84
-Name             : Polonium
-Short name       : Po
-Color            : 0.66,0.35,0.0
-Radius used      : 1.460000
-Radius, covalent : 1.460000
-Radius, atomic   : 1.530000
-Charge state     : 6
-Radius, ionic    : 0.670000
-
-
-Atom
-====
-Number           : 85
-Name             : Astatine
-Short name       : At
-Color            : 0.45,0.30,0.26
-Radius used      : 1.450000
-Radius, covalent : 1.450000
-Radius, atomic   : 1.430000
-Charge state     : -3
-Radius, ionic    : 2.220000
-Charge state     : 3
-Radius, ionic    : 0.850000
-Charge state     : 5
-Radius, ionic    : 0.460000
-
-
-Atom
-====
-Number           : 86
-Name             : Radon
-Short name       : Rn
-Color            : 0.25,0.50,0.58
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.340000
-
-
-Atom
-====
-Number           : 87
-Name             : Francium
-Short name       : Fr
-Color            : 0.25,0.0,0.39
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 1
-Radius, ionic    : 1.800000
-
-
-Atom
-====
-Number           : 88
-Name             : Radium
-Short name       : Ra
-Color            : 0.0,0.48,0.0
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 2
-Radius, ionic    : 1.430000
-
-
-Atom
-====
-Number           : 89
-Name             : Actinium
-Short name       : Ac
-Color            : 0.43,0.66,0.97
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 3
-Radius, ionic    : 1.180000
-
-
-Atom
-====
-Number           : 90
-Name             : Thorium
-Short name       : Th
-Color            : 0.0,0.72,0.99
-Radius used      : 1.650000
-Radius, covalent : 1.650000
-Radius, atomic   : 1.000000
-Charge state     : 4
-Radius, ionic    : 1.020000
-
-
-Atom
-====
-Number           : 91
-Name             : Protactinium
-Short name       : Pa
-Color            : 0.0,0.62,0.99
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 3
-Radius, ionic    : 1.130000
-Charge state     : 4
-Radius, ionic    : 0.980000
-Charge state     : 5
-Radius, ionic    : 0.890000
-
-
-Atom
-====
-Number           : 92
-Name             : Uranium
-Short name       : U
-Color            : 0.0,0.55,0.99
-Radius used      : 1.420000
-Radius, covalent : 1.420000
-Radius, atomic   : 1.000000
-Charge state     : 4
-Radius, ionic    : 0.970000
-Charge state     : 6
-Radius, ionic    : 0.800000
-
-
-Atom
-====
-Number           : 93
-Name             : Neptunium
-Short name       : Np
-Color            : 0.0,0.5,0.99
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 3
-Radius, ionic    : 1.100000
-Charge state     : 4
-Radius, ionic    : 0.950000
-Charge state     : 7
-Radius, ionic    : 0.710000
-
-
-Atom
-====
-Number           : 94
-Name             : Plutonium
-Short name       : Pu
-Color            : 0.0,0.41,0.99
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 3
-Radius, ionic    : 1.080000
-Charge state     : 4
-Radius, ionic    : 0.930000
-
-
-Atom
-====
-Number           : 95
-Name             : Americium
-Short name       : Am
-Color            : 0.32,0.35,0.94
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-Charge state     : 3
-Radius, ionic    : 1.070000
-Charge state     : 4
-Radius, ionic    : 0.920000
-
-
-Atom
-====
-Number           : 96
-Name             : Curium
-Short name       : Cm
-Color            : 0.46,0.35,0.88
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 97
-Name             : Berkelium
-Short name       : Bk
-Color            : 0.53,0.30,0.88
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 98
-Name             : Californium
-Short name       : Cf
-Color            : 0.62,0.21,0.82
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 99
-Name             : Einsteinium
-Short name       : Es
-Color            : 0.69,0.12,0.82
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 100
-Name             : Fermium
-Short name       : Fm
-Color            : 0.69,0.12,0.72
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 101
-Name             : Mendelevium
-Short name       : Md
-Color            : 0.69,0.05,0.64
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 102
-Name             : Nobelium
-Short name       : No
-Color            : 0.73,0.05,0.52
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 103
-Name             : Lawrencium
-Short name       : Lr
-Color            : 0.77,0.0,0.39
-Radius used      : 1.000000
-Radius, covalent : 1.000000
-Radius, atomic   : 1.000000
-
-
-Atom
-====
-Number           : 104
-Name             : Vacancy
-Short name       : Vac
-Color            : 0.5,0.5,0.5
-Radius used      : 1.2
-Radius, covalent : 1.0
-Radius, atomic   : 1.0
-
-
-Atom
-====
-Number           : 105
-Name             : Default
-Short name       : Default
-Color            : 0.5,0.5,0.5
-Radius used      : 1.0
-Radius, covalent : 1.0
-Radius, atomic   : 1.0
-
-
-Atom
-====
-Number           : 106
-Name             : Stick
-Short name       : Stick
-Color            : 0.5,0.5,0.5
-Radius used      : 1.0
-Radius, covalent : 1.0
-Radius, atomic   : 1.0
diff --git a/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py b/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py
deleted file mode 100644
index d9f9499..0000000
--- a/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py
+++ /dev/null
@@ -1,921 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-#
-#
-#  Authors           : Clemens Barth (Blendphys at root-1.de), ...
-#
-#  Homepage(Wiki)    : http://development.root-1.de/Atomic_Blender.php
-#  Tracker           : ... soon
-#
-#  Start of project              : 2011-12-01 by Clemens Barth
-#  First publication in Blender  : 2011-12-18
-#  Last modified                 : 2012-04-18
-#
-#  Acknowledgements: Thanks to ideasman, meta_androcto, truman, kilon,
-#  dairin0d, PKHG, Valter, etc
-#
-
-import bpy
-import io
-import math
-import os
-from math import pi, cos, sin
-from mathutils import Vector, Matrix
-
-# These are variables, which contain the name of the XYZ file and
-# the path of the XYZ file.
-# They are used almost everywhere, which is the reason why they
-# should stay global. First, they are empty and get 'filled' directly
-# after having chosen the XYZ file (see 'class LoadXYZ' further below).
-
-ATOM_XYZ_FILEPATH = ""
-
-# Some string stuff for the console.
-ATOM_XYZ_STRING = "Atomic Blender\n==================="
-
-
-# -----------------------------------------------------------------------------
-#                                                  Atom and element data
-
-
-# This is a list that contains some data of all possible elements. The structure
-# is as follows:
-#
-# 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54   means
-#
-# No., name, short name, color, radius (used), radius (covalent), radius (atomic),
-#
-# charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
-# charge states for any atom are listed, if existing.
-# The list is fixed and cannot be changed ... (see below)
-
-ATOM_XYZ_ELEMENTS_DEFAULT = (
-( 1,      "Hydrogen",        "H", (  1.0,   1.0,   1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
-( 2,        "Helium",       "He", ( 0.85,   1.0,   1.0), 0.93, 0.93, 0.49 ),
-( 3,       "Lithium",       "Li", (  0.8,  0.50,   1.0), 1.23, 1.23, 2.05 ,  1 , 0.68 ),
-( 4,     "Beryllium",       "Be", ( 0.76,   1.0,   0.0), 0.90, 0.90, 1.40 ,  1 , 0.44 ,  2 , 0.35 ),
-( 5,         "Boron",        "B", (  1.0,  0.70,  0.70), 0.82, 0.82, 1.17 ,  1 , 0.35 ,  3 , 0.23 ),
-( 6,        "Carbon",        "C", ( 0.56,  0.56,  0.56), 0.77, 0.77, 0.91 , -4 , 2.60 ,  4 , 0.16 ),
-( 7,      "Nitrogen",        "N", ( 0.18,  0.31,  0.97), 0.75, 0.75, 0.75 , -3 , 1.71 ,  1 , 0.25 ,  3 , 0.16 ,  5 , 0.13 ),
-( 8,        "Oxygen",        "O", (  1.0,  0.05,  0.05), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 ,  1 , 0.22 ,  6 , 0.09 ),
-( 9,      "Fluorine",        "F", ( 0.56,  0.87,  0.31), 0.72, 0.72, 0.57 , -1 , 1.33 ,  7 , 0.08 ),
-(10,          "Neon",       "Ne", ( 0.70,  0.89,  0.96), 0.71, 0.71, 0.51 ,  1 , 1.12 ),
-(11,        "Sodium",       "Na", ( 0.67,  0.36,  0.94), 1.54, 1.54, 2.23 ,  1 , 0.97 ),
-(12,     "Magnesium",       "Mg", ( 0.54,   1.0,   0.0), 1.36, 1.36, 1.72 ,  1 , 0.82 ,  2 , 0.66 ),
-(13,     "Aluminium",       "Al", ( 0.74,  0.65,  0.65), 1.18, 1.18, 1.82 ,  3 , 0.51 ),
-(14,       "Silicon",       "Si", ( 0.94,  0.78,  0.62), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 ,  1 , 0.65 ,  4 , 0.42 ),
-(15,    "Phosphorus",        "P", (  1.0,  0.50,   0.0), 1.06, 1.06, 1.23 , -3 , 2.12 ,  3 , 0.44 ,  5 , 0.35 ),
-(16,        "Sulfur",        "S", (  1.0,   1.0,  0.18), 1.02, 1.02, 1.09 , -2 , 1.84 ,  2 , 2.19 ,  4 , 0.37 ,  6 , 0.30 ),
-(17,      "Chlorine",       "Cl", ( 0.12,  0.94,  0.12), 0.99, 0.99, 0.97 , -1 , 1.81 ,  5 , 0.34 ,  7 , 0.27 ),
-(18,         "Argon",       "Ar", ( 0.50,  0.81,  0.89), 0.98, 0.98, 0.88 ,  1 , 1.54 ),
-(19,     "Potassium",        "K", ( 0.56,  0.25,  0.83), 2.03, 2.03, 2.77 ,  1 , 0.81 ),
-(20,       "Calcium",       "Ca", ( 0.23,   1.0,   0.0), 1.74, 1.74, 2.23 ,  1 , 1.18 ,  2 , 0.99 ),
-(21,      "Scandium",       "Sc", ( 0.90,  0.90,  0.90), 1.44, 1.44, 2.09 ,  3 , 0.73 ),
-(22,      "Titanium",       "Ti", ( 0.74,  0.76,  0.78), 1.32, 1.32, 2.00 ,  1 , 0.96 ,  2 , 0.94 ,  3 , 0.76 ,  4 , 0.68 ),
-(23,      "Vanadium",        "V", ( 0.65,  0.65,  0.67), 1.22, 1.22, 1.92 ,  2 , 0.88 ,  3 , 0.74 ,  4 , 0.63 ,  5 , 0.59 ),
-(24,      "Chromium",       "Cr", ( 0.54,   0.6,  0.78), 1.18, 1.18, 1.85 ,  1 , 0.81 ,  2 , 0.89 ,  3 , 0.63 ,  6 , 0.52 ),
-(25,     "Manganese",       "Mn", ( 0.61,  0.47,  0.78), 1.17, 1.17, 1.79 ,  2 , 0.80 ,  3 , 0.66 ,  4 , 0.60 ,  7 , 0.46 ),
-(26,          "Iron",       "Fe", ( 0.87,   0.4,   0.2), 1.17, 1.17, 1.72 ,  2 , 0.74 ,  3 , 0.64 ),
-(27,        "Cobalt",       "Co", ( 0.94,  0.56,  0.62), 1.16, 1.16, 1.67 ,  2 , 0.72 ,  3 , 0.63 ),
-(28,        "Nickel",       "Ni", ( 0.31,  0.81,  0.31), 1.15, 1.15, 1.62 ,  2 , 0.69 ),
-(29,        "Copper",       "Cu", ( 0.78,  0.50,   0.2), 1.17, 1.17, 1.57 ,  1 , 0.96 ,  2 , 0.72 ),
-(30,          "Zinc",       "Zn", ( 0.49,  0.50,  0.69), 1.25, 1.25, 1.53 ,  1 , 0.88 ,  2 , 0.74 ),
-(31,       "Gallium",       "Ga", ( 0.76,  0.56,  0.56), 1.26, 1.26, 1.81 ,  1 , 0.81 ,  3 , 0.62 ),
-(32,     "Germanium",       "Ge", (  0.4,  0.56,  0.56), 1.22, 1.22, 1.52 , -4 , 2.72 ,  2 , 0.73 ,  4 , 0.53 ),
-(33,       "Arsenic",       "As", ( 0.74,  0.50,  0.89), 1.20, 1.20, 1.33 , -3 , 2.22 ,  3 , 0.58 ,  5 , 0.46 ),
-(34,      "Selenium",       "Se", (  1.0,  0.63,   0.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 ,  1 , 0.66 ,  4 , 0.50 ,  6 , 0.42 ),
-(35,       "Bromine",       "Br", ( 0.65,  0.16,  0.16), 1.14, 1.14, 1.12 , -1 , 1.96 ,  5 , 0.47 ,  7 , 0.39 ),
-(36,       "Krypton",       "Kr", ( 0.36,  0.72,  0.81), 1.31, 1.31, 1.24 ),
-(37,      "Rubidium",       "Rb", ( 0.43,  0.18,  0.69), 2.16, 2.16, 2.98 ,  1 , 1.47 ),
-(38,     "Strontium",       "Sr", (  0.0,   1.0,   0.0), 1.91, 1.91, 2.45 ,  2 , 1.12 ),
-(39,       "Yttrium",        "Y", ( 0.58,   1.0,   1.0), 1.62, 1.62, 2.27 ,  3 , 0.89 ),
-(40,     "Zirconium",       "Zr", ( 0.58,  0.87,  0.87), 1.45, 1.45, 2.16 ,  1 , 1.09 ,  4 , 0.79 ),
-(41,       "Niobium",       "Nb", ( 0.45,  0.76,  0.78), 1.34, 1.34, 2.08 ,  1 , 1.00 ,  4 , 0.74 ,  5 , 0.69 ),
-(42,    "Molybdenum",       "Mo", ( 0.32,  0.70,  0.70), 1.30, 1.30, 2.01 ,  1 , 0.93 ,  4 , 0.70 ,  6 , 0.62 ),
-(43,    "Technetium",       "Tc", ( 0.23,  0.61,  0.61), 1.27, 1.27, 1.95 ,  7 , 0.97 ),
-(44,     "Ruthenium",       "Ru", ( 0.14,  0.56,  0.56), 1.25, 1.25, 1.89 ,  4 , 0.67 ),
-(45,       "Rhodium",       "Rh", ( 0.03,  0.49,  0.54), 1.25, 1.25, 1.83 ,  3 , 0.68 ),
-(46,     "Palladium",       "Pd", (  0.0,  0.41,  0.52), 1.28, 1.28, 1.79 ,  2 , 0.80 ,  4 , 0.65 ),
-(47,        "Silver",       "Ag", ( 0.75,  0.75,  0.75), 1.34, 1.34, 1.75 ,  1 , 1.26 ,  2 , 0.89 ),
-(48,       "Cadmium",       "Cd", (  1.0,  0.85,  0.56), 1.48, 1.48, 1.71 ,  1 , 1.14 ,  2 , 0.97 ),
-(49,        "Indium",       "In", ( 0.65,  0.45,  0.45), 1.44, 1.44, 2.00 ,  3 , 0.81 ),
-(50,           "Tin",       "Sn", (  0.4,  0.50,  0.50), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 ,  2 , 0.93 ,  4 , 0.71 ),
-(51,      "Antimony",       "Sb", ( 0.61,  0.38,  0.70), 1.40, 1.40, 1.53 , -3 , 2.45 ,  3 , 0.76 ,  5 , 0.62 ),
-(52,     "Tellurium",       "Te", ( 0.83,  0.47,   0.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 ,  1 , 0.82 ,  4 , 0.70 ,  6 , 0.56 ),
-(53,        "Iodine",        "I", ( 0.58,   0.0,  0.58), 1.33, 1.33, 1.32 , -1 , 2.20 ,  5 , 0.62 ,  7 , 0.50 ),
-(54,         "Xenon",       "Xe", ( 0.25,  0.61,  0.69), 1.31, 1.31, 1.24 ),
-(55,       "Caesium",       "Cs", ( 0.34,  0.09,  0.56), 2.35, 2.35, 3.35 ,  1 , 1.67 ),
-(56,        "Barium",       "Ba", (  0.0,  0.78,   0.0), 1.98, 1.98, 2.78 ,  1 , 1.53 ,  2 , 1.34 ),
-(57,     "Lanthanum",       "La", ( 0.43,  0.83,   1.0), 1.69, 1.69, 2.74 ,  1 , 1.39 ,  3 , 1.06 ),
-(58,        "Cerium",       "Ce", (  1.0,   1.0,  0.78), 1.65, 1.65, 2.70 ,  1 , 1.27 ,  3 , 1.03 ,  4 , 0.92 ),
-(59,  "Praseodymium",       "Pr", ( 0.85,   1.0,  0.78), 1.65, 1.65, 2.67 ,  3 , 1.01 ,  4 , 0.90 ),
-(60,     "Neodymium",       "Nd", ( 0.78,   1.0,  0.78), 1.64, 1.64, 2.64 ,  3 , 0.99 ),
-(61,    "Promethium",       "Pm", ( 0.63,   1.0,  0.78), 1.63, 1.63, 2.62 ,  3 , 0.97 ),
-(62,      "Samarium",       "Sm", ( 0.56,   1.0,  0.78), 1.62, 1.62, 2.59 ,  3 , 0.96 ),
-(63,      "Europium",       "Eu", ( 0.38,   1.0,  0.78), 1.85, 1.85, 2.56 ,  2 , 1.09 ,  3 , 0.95 ),
-(64,    "Gadolinium",       "Gd", ( 0.27,   1.0,  0.78), 1.61, 1.61, 2.54 ,  3 , 0.93 ),
-(65,       "Terbium",       "Tb", ( 0.18,   1.0,  0.78), 1.59, 1.59, 2.51 ,  3 , 0.92 ,  4 , 0.84 ),
-(66,    "Dysprosium",       "Dy", ( 0.12,   1.0,  0.78), 1.59, 1.59, 2.49 ,  3 , 0.90 ),
-(67,       "Holmium",       "Ho", (  0.0,   1.0,  0.61), 1.58, 1.58, 2.47 ,  3 , 0.89 ),
-(68,        "Erbium",       "Er", (  0.0,  0.90,  0.45), 1.57, 1.57, 2.45 ,  3 , 0.88 ),
-(69,       "Thulium",       "Tm", (  0.0,  0.83,  0.32), 1.56, 1.56, 2.42 ,  3 , 0.87 ),
-(70,     "Ytterbium",       "Yb", (  0.0,  0.74,  0.21), 1.74, 1.74, 2.40 ,  2 , 0.93 ,  3 , 0.85 ),
-(71,      "Lutetium",       "Lu", (  0.0,  0.67,  0.14), 1.56, 1.56, 2.25 ,  3 , 0.85 ),
-(72,       "Hafnium",       "Hf", ( 0.30,  0.76,   1.0), 1.44, 1.44, 2.16 ,  4 , 0.78 ),
-(73,      "Tantalum",       "Ta", ( 0.30,  0.65,   1.0), 1.34, 1.34, 2.09 ,  5 , 0.68 ),
-(74,      "Tungsten",        "W", ( 0.12,  0.58,  0.83), 1.30, 1.30, 2.02 ,  4 , 0.70 ,  6 , 0.62 ),
-(75,       "Rhenium",       "Re", ( 0.14,  0.49,  0.67), 1.28, 1.28, 1.97 ,  4 , 0.72 ,  7 , 0.56 ),
-(76,        "Osmium",       "Os", ( 0.14,   0.4,  0.58), 1.26, 1.26, 1.92 ,  4 , 0.88 ,  6 , 0.69 ),
-(77,       "Iridium",       "Ir", ( 0.09,  0.32,  0.52), 1.27, 1.27, 1.87 ,  4 , 0.68 ),
-(78,     "Platinium",       "Pt", ( 0.81,  0.81,  0.87), 1.30, 1.30, 1.83 ,  2 , 0.80 ,  4 , 0.65 ),
-(79,          "Gold",       "Au", (  1.0,  0.81,  0.13), 1.34, 1.34, 1.79 ,  1 , 1.37 ,  3 , 0.85 ),
-(80,       "Mercury",       "Hg", ( 0.72,  0.72,  0.81), 1.49, 1.49, 1.76 ,  1 , 1.27 ,  2 , 1.10 ),
-(81,      "Thallium",       "Tl", ( 0.65,  0.32,  0.30), 1.48, 1.48, 2.08 ,  1 , 1.47 ,  3 , 0.95 ),
-(82,          "Lead",       "Pb", ( 0.34,  0.34,  0.38), 1.47, 1.47, 1.81 ,  2 , 1.20 ,  4 , 0.84 ),
-(83,       "Bismuth",       "Bi", ( 0.61,  0.30,  0.70), 1.46, 1.46, 1.63 ,  1 , 0.98 ,  3 , 0.96 ,  5 , 0.74 ),
-(84,      "Polonium",       "Po", ( 0.67,  0.36,   0.0), 1.46, 1.46, 1.53 ,  6 , 0.67 ),
-(85,      "Astatine",       "At", ( 0.45,  0.30,  0.27), 1.45, 1.45, 1.43 , -3 , 2.22 ,  3 , 0.85 ,  5 , 0.46 ),
-(86,         "Radon",       "Rn", ( 0.25,  0.50,  0.58), 1.00, 1.00, 1.34 ),
-(87,      "Francium",       "Fr", ( 0.25,   0.0,   0.4), 1.00, 1.00, 1.00 ,  1 , 1.80 ),
-(88,        "Radium",       "Ra", (  0.0,  0.49,   0.0), 1.00, 1.00, 1.00 ,  2 , 1.43 ),
-(89,      "Actinium",       "Ac", ( 0.43,  0.67,  0.98), 1.00, 1.00, 1.00 ,  3 , 1.18 ),
-(90,       "Thorium",       "Th", (  0.0,  0.72,   1.0), 1.65, 1.65, 1.00 ,  4 , 1.02 ),
-(91,  "Protactinium",       "Pa", (  0.0,  0.63,   1.0), 1.00, 1.00, 1.00 ,  3 , 1.13 ,  4 , 0.98 ,  5 , 0.89 ),
-(92,       "Uranium",        "U", (  0.0,  0.56,   1.0), 1.42, 1.42, 1.00 ,  4 , 0.97 ,  6 , 0.80 ),
-(93,     "Neptunium",       "Np", (  0.0,  0.50,   1.0), 1.00, 1.00, 1.00 ,  3 , 1.10 ,  4 , 0.95 ,  7 , 0.71 ),
-(94,     "Plutonium",       "Pu", (  0.0,  0.41,   1.0), 1.00, 1.00, 1.00 ,  3 , 1.08 ,  4 , 0.93 ),
-(95,     "Americium",       "Am", ( 0.32,  0.36,  0.94), 1.00, 1.00, 1.00 ,  3 , 1.07 ,  4 , 0.92 ),
-(96,        "Curium",       "Cm", ( 0.47,  0.36,  0.89), 1.00, 1.00, 1.00 ),
-(97,     "Berkelium",       "Bk", ( 0.54,  0.30,  0.89), 1.00, 1.00, 1.00 ),
-(98,   "Californium",       "Cf", ( 0.63,  0.21,  0.83), 1.00, 1.00, 1.00 ),
-(99,   "Einsteinium",       "Es", ( 0.70,  0.12,  0.83), 1.00, 1.00, 1.00 ),
-(100,       "Fermium",       "Fm", ( 0.70,  0.12,  0.72), 1.00, 1.00, 1.00 ),
-(101,   "Mendelevium",       "Md", ( 0.70,  0.05,  0.65), 1.00, 1.00, 1.00 ),
-(102,      "Nobelium",       "No", ( 0.74,  0.05,  0.52), 1.00, 1.00, 1.00 ),
-(103,    "Lawrencium",       "Lr", ( 0.78,   0.0,   0.4), 1.00, 1.00, 1.00 ),
-(104,       "Vacancy",      "Vac", (  0.5,   0.5,   0.5), 1.00, 1.00, 1.00),
-(105,       "Default",  "Default", (  1.0,   1.0,   1.0), 1.00, 1.00, 1.00),
-(106,         "Stick",    "Stick", (  0.5,   0.5,   0.5), 1.00, 1.00, 1.00),
-)
-
-# This list here contains all data of the elements and will be used during
-# runtime. It is a list of classes.
-# During executing Atomic Blender, the list will be initialized with the fixed
-# data from above via the class structure below (CLASS_atom_xyz_Elements). We
-# have then one fixed list (above), which will never be changed, and a list of
-# classes with same data. The latter can be modified via loading a separate
-# custom data file for instance.
-ATOM_XYZ_ELEMENTS = []
-
-# This is the list, which contains all atoms of all frames! Each item is a 
-# list which contains the atoms of a single frame. It is a list of  
-# 'CLASS_atom_xyz_atom'.
-ALL_FRAMES = []
-NUMBER_FRAMES = 0
-
-# A list of ALL balls which are put into the scene
-STRUCTURE = []
-
-# This is the class, which stores the properties for one element.
-class CLASS_atom_xyz_Elements(object):
-    __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic')
-    def __init__(self, number, name, short_name, color, radii, radii_ionic):
-        self.number = number
-        self.name = name
-        self.short_name = short_name
-        self.color = color
-        self.radii = radii
-        self.radii_ionic = radii_ionic
-
-# This is the class, which stores the properties of one atom.
-class CLASS_atom_xyz_atom(object):  
-    __slots__ = ('element', 'name', 'location', 'radius', 'color', 'material')
-    def __init__(self, element, name, location, radius, color, material):
-        self.element = element
-        self.name = name
-        self.location = location
-        self.radius = radius
-        self.color = color
-        self.material = material
-        
-
-# -----------------------------------------------------------------------------
-#                                                          Some small routines
-
-
-
-# This function measures the distance between two objects (atoms),
-# which are active.
-def DEF_atom_xyz_distance():
-
-    if len(bpy.context.selected_bases) > 1:
-        object_1 = bpy.context.selected_objects[0]
-        object_2 = bpy.context.selected_objects[1]
-    else:
-        return "N.A."
-
-    dv = object_2.location - object_1.location
-    return str(dv.length)
-
-
-# Routine to modify the radii via the type:
-#
-#        pre-defined, atomic or van der Waals
-#
-# Explanations here are also valid for the next 3 DEFs.
-def DEF_atom_xyz_radius_type(rtype,how):
-
-    if how == "ALL_IN_LAYER":
-
-        # Note all layers that are active.
-        layers = []
-        for i in range(20):
-            if bpy.context.scene.layers[i] == True:
-                layers.append(i)
-        # Put all objects, which are in the layers, into a list.
-        change_objects = []
-        for obj in bpy.context.scene.objects:
-            for layer in layers:
-                if obj.layers[layer] == True:
-                    change_objects.append(obj)
-        # Consider all objects, which are in the list 'change_objects'.
-        for obj in change_objects:
-            if len(obj.children) != 0:
-                if obj.children[0].type == "SURFACE" or obj.children[0].type  == "MESH":
-                    for element in ATOM_XYZ_ELEMENTS:
-                        if element.name in obj.name:
-                            obj.children[0].scale = (element.radii[int(rtype)],) * 3
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    for element in ATOM_XYZ_ELEMENTS:
-                        if element.name in obj.name:
-                            obj.scale = (element.radii[int(rtype)],) * 3
-
-    if how == "ALL_ACTIVE":
-        for obj in bpy.context.selected_objects:
-            if len(obj.children) != 0:
-                if obj.children[0].type == "SURFACE" or obj.children[0].type  == "MESH":
-                    for element in ATOM_XYZ_ELEMENTS:
-                        if element.name in obj.name:
-                            obj.children[0].scale = (element.radii[int(rtype)],) * 3
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    for element in ATOM_XYZ_ELEMENTS:
-                        if element.name in obj.name:
-                            obj.scale = (element.radii[int(rtype)],) * 3
-
-
-# Routine to modify the radii in picometer of a specific type of atom
-def DEF_atom_xyz_radius_pm(atomname, radius_pm, how):
-
-    if how == "ALL_IN_LAYER":
-
-        layers = []
-        for i in range(20):
-            if bpy.context.scene.layers[i] == True:
-                layers.append(i)
-        change_objects = []
-        for obj in bpy.context.scene.objects:
-            for layer in layers:
-                if obj.layers[layer] == True:
-                    change_objects.append(obj)
-        for obj in change_objects:
-            if len(obj.children) != 0:
-                if obj.children[0].type == "SURFACE" or obj.children[0].type  == "MESH":
-                    if atomname in obj.name:
-                        obj.children[0].scale = (radius_pm/100,) * 3
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    if atomname in obj.name:
-                        obj.scale = (radius_pm/100,) * 3
-
-    if how == "ALL_ACTIVE":
-        for obj in bpy.context.selected_objects:
-            if len(obj.children) != 0:
-                if obj.children[0].type == "SURFACE" or obj.children[0].type  == "MESH":
-                    if atomname in obj.name:
-                        obj.children[0].scale = (radius_pm/100,) * 3
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    if atomname in obj.name:
-                        obj.scale = (radius_pm/100,) * 3
-
-
-# Routine to scale the radii of all atoms
-def DEF_atom_xyz_radius_all(scale, how):
-
-    if how == "ALL_IN_LAYER":
-
-        layers = []
-        for i in range(20):
-            if bpy.context.scene.layers[i] == True:
-                layers.append(i)
-        change_objects = []
-        for obj in bpy.context.scene.objects:
-            for layer in layers:
-                if obj.layers[layer] == True:
-                    change_objects.append(obj)
-        for obj in change_objects:
-            if len(obj.children) != 0:
-                if obj.children[0].type == "SURFACE" or obj.children[0].type  == "MESH":
-                    obj.children[0].scale *= scale
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    obj.scale *= scale
-
-    if how == "ALL_ACTIVE":
-        for obj in bpy.context.selected_objects:
-            if len(obj.children) != 0:
-                if obj.children[0].type == "SURFACE" or obj.children[0].type  == "MESH":
-                    obj.children[0].scale *= scale
-            else:
-                if obj.type == "SURFACE" or obj.type == "MESH":
-                    obj.scale *= scale
-
-
-def DEF_atom_xyz_read_elements():
-
-    ATOM_XYZ_ELEMENTS[:] = []
-
-    for item in ATOM_XYZ_ELEMENTS_DEFAULT:
-
-        # All three radii into a list
-        radii = [item[4],item[5],item[6]]
-        # The handling of the ionic radii will be done later. So far, it is an
-        # empty list.
-        radii_ionic = []
-
-        li = CLASS_atom_xyz_Elements(item[0],item[1],item[2],item[3],
-                                     radii,radii_ionic)
-        ATOM_XYZ_ELEMENTS.append(li)
-
-
-def DEF_atom_xyz_read_xyz_file(filepath,radiustype):
-
-    global NUMBER_FRAMES
-
-    # Open the file ...
-    ATOM_XYZ_FILEPATH_p = io.open(ATOM_XYZ_FILEPATH, "r")
-
-    #Go through the whole file.
-    FLAG = False
-    for line in ATOM_XYZ_FILEPATH_p:
-
-        # ... the loop is broken here (EOF) ...
-        if line == "":
-            continue
-
-        split_list = line.rsplit()
-
-        if len(split_list) == 1:
-            number_atoms = int(split_list[0])
-            FLAG = True
-            
-        if FLAG == True:
-        
-            line = ATOM_XYZ_FILEPATH_p.readline()
-            line = line.rstrip()
-            comment = line
-            
-            all_atoms= []
-            for i in range(number_atoms):
-            
-                line = ATOM_XYZ_FILEPATH_p.readline()
-                line = line.rstrip()
-                split_list = line.rsplit()
-                short_name = str(split_list[0])
-                     
-                # Go through all elements and find the element of the current atom.
-                FLAG_FOUND = False
-                for element in ATOM_XYZ_ELEMENTS:
-                    if str.upper(short_name) == str.upper(element.short_name):
-                        # Give the atom its proper names, color and radius:
-                        name = element.name
-                        # int(radiustype) => type of radius:
-                        # pre-defined (0), atomic (1) or van der Waals (2)
-                        radius = float(element.radii[int(radiustype)])
-                        color = element.color
-                        FLAG_FOUND = True
-                        break
-                
-                # Is it a vacancy or an 'unknown atom' ?
-                if FLAG_FOUND == False:
-                    # Give this atom also a name. If it is an 'X' then it is a
-                    # vacancy. Otherwise ...
-                    if "X" in short_name:
-                        short_name = "VAC"
-                        name = "Vacancy"
-                        radius = float(ATOM_XYZ_ELEMENTS[-3].radii[int(radiustype)])
-                        color = ATOM_XYZ_ELEMENTS[-3].color
-                    # ... take what is written in the xyz file. These are somewhat
-                    # unknown atoms. This should never happen, the element list is
-                    # almost complete. However, we do this due to security reasons.
-                    else:
-                        name = str.upper(short_name)
-                        radius = float(ATOM_XYZ_ELEMENTS[-2].radii[int(radiustype)])
-                        color = ATOM_XYZ_ELEMENTS[-2].color
-              
-                x = float(split_list[1])
-                y = float(split_list[2])
-                z = float(split_list[3])
-                
-                location = Vector((x,y,z))
-            
-                all_atoms.append([short_name, name, location, radius, color])
-            
-            # We note here all elements. This needs to be done only once. 
-            if NUMBER_FRAMES == 0:
-                elements = []
-                for atom in all_atoms:
-                    FLAG_FOUND = False
-                    for element in elements:
-                        # If the atom name is already in the list, 
-                        # FLAG on 'True'.
-                        if element == atom[1]:
-                            FLAG_FOUND = True
-                            break
-                    # No name in the current list has been found? => New entry.
-                    if FLAG_FOUND == False:
-                        # Stored are: Atom label (e.g. 'Na'), the corresponding 
-                        # atom name (e.g. 'Sodium') and its color.
-                        elements.append(atom[1])
-            
-            structure = []
-            for element in elements:
-                atoms_one_type = []
-                for atom in all_atoms:
-                    if atom[1] == element:
-                        atoms_one_type.append(CLASS_atom_xyz_atom(
-                                                           atom[0],
-                                                           atom[1],
-                                                           atom[2],
-                                                           atom[3],
-                                                           atom[4],[]))
-                structure.append(atoms_one_type)
-
-            ALL_FRAMES.append(structure)
-            NUMBER_FRAMES += 1
-            FLAG = False
-
-    ATOM_XYZ_FILEPATH_p.close()
-    
-    """
-    for frame in ALL_FRAMES:
-        for element in frame:
-            for atom in element:
-                print(atom.element + "	" + str(atom.location))
-        print()    
-    """
-    return number_atoms
-
-
-# This reads a custom data file.
-def DEF_atom_xyz_custom_datafile(path_datafile):
-
-    if path_datafile == "":
-        return False
-
-    path_datafile = bpy.path.abspath(path_datafile)
-
-    if os.path.isfile(path_datafile) == False:
-        return False
-
-    # The whole list gets deleted! We build it new.
-    ATOM_XYZ_ELEMENTS[:] = []
-
-    # Read the data file, which contains all data
-    # (atom name, radii, colors, etc.)
-    data_file_p = io.open(path_datafile, "r")
-
-    for line in data_file_p:
-
-        if "Atom" in line:
-
-            line = data_file_p.readline()
-            # Number
-            line = data_file_p.readline()
-            number = line[19:-1]
-            # Name
-            line = data_file_p.readline()
-            name = line[19:-1]
-            # Short name
-            line = data_file_p.readline()
-            short_name = line[19:-1]
-            # Color
-            line = data_file_p.readline()
-            color_value = line[19:-1].split(',')
-            color = [float(color_value[0]),
-                     float(color_value[1]),
-                     float(color_value[2])]
-            # Used radius
-            line = data_file_p.readline()
-            radius_used = float(line[19:-1])
-            # Atomic radius
-            line = data_file_p.readline()
-            radius_atomic = float(line[19:-1])
-            # Van der Waals radius
-            line = data_file_p.readline()
-            radius_vdW = float(line[19:-1])
-            radii = [radius_used,radius_atomic,radius_vdW]
-            radii_ionic = []
-
-            element = CLASS_atom_xyz_Elements(number,name,short_name,color,
-                                              radii, radii_ionic)
-
-            ATOM_XYZ_ELEMENTS.append(element)
-
-    data_file_p.close()
-
-    return True
-
-# -----------------------------------------------------------------------------
-#                                                            The main routine
-
-def DEF_atom_xyz_main(use_mesh,
-                      Ball_azimuth,
-                      Ball_zenith,
-                      Ball_radius_factor,
-                      radiustype,
-                      Ball_distance_factor,
-                      put_to_center, 
-                      use_camera,
-                      use_lamp,
-                      path_datafile):
-
-    # List of materials
-    atom_material_list = []
-
-    # ------------------------------------------------------------------------
-    # INITIALIZE THE ELEMENT LIST
-
-    DEF_atom_xyz_read_elements()
-
-    # ------------------------------------------------------------------------
-    # READING DATA OF ATOMS
-
-    Number_of_total_atoms = DEF_atom_xyz_read_xyz_file(ATOM_XYZ_FILEPATH, 
-                                                       radiustype)
-                                               
-    # We show the atoms of the first frame.
-    first_frame = ALL_FRAMES[0]
-
-    # ------------------------------------------------------------------------
-    # MATERIAL PROPERTIES FOR ATOMS
-
-    # Create first a new list of materials for each type of atom
-    # (e.g. hydrogen)
-    for atoms_of_one_type in first_frame:
-        # Take the first atom
-        atom = atoms_of_one_type[0]
-        material = bpy.data.materials.new(atom.name)
-        material.name = atom.name
-        material.diffuse_color = atom.color
-        atom_material_list.append(material)
-
-    # Now, we go through all atoms and give them a material. For all atoms ...
-    for atoms_of_one_type in first_frame:
-        for atom in atoms_of_one_type:
-            # ... and all materials ...
-            for material in atom_material_list:
-                # ... select the correct material for the current atom via
-                # comparison of names ...
-                if atom.name in material.name:
-                    # ... and give the atom its material properties.
-                    # However, before we check, if it is a vacancy
-                    # The vacancy is represented by a transparent cube.
-                    if atom.name == "Vacancy":
-                        material.transparency_method = 'Z_TRANSPARENCY'
-                        material.alpha = 1.3
-                        material.raytrace_transparency.fresnel = 1.6
-                        material.raytrace_transparency.fresnel_factor = 1.6
-                        material.use_transparency = True
-                    # The atom gets its properties.
-                    atom.material = material
-
-    # ------------------------------------------------------------------------
-    # TRANSLATION OF THE STRUCTURE TO THE ORIGIN
-
-    # It may happen that the structure in a XYZ file already has an offset
-    # If chosen, the structure is first put into the center of the scene
-    # (the offset is substracted).
-
-    if put_to_center == True:
-
-        sum_vec = Vector((0.0,0.0,0.0))
-
-        # Sum of all atom coordinates
-        for atoms_of_one_type in first_frame:
-            sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec)
-
-        # Then the average is taken
-        sum_vec = sum_vec / Number_of_total_atoms
-
-        # After, for each atom the center of gravity is substracted
-        for atoms_of_one_type in first_frame:
-            for atom in atoms_of_one_type:
-                atom.location -= sum_vec
-    
-    # ------------------------------------------------------------------------
-    # SCALING
-
-    # Take all atoms and adjust their radii and scale the distances.
-    for atoms_of_one_type in first_frame:
-        for atom in atoms_of_one_type:
-            atom.location *= Ball_distance_factor
-    
-    # ------------------------------------------------------------------------
-    # DETERMINATION OF SOME GEOMETRIC PROPERTIES
-
-    # In the following, some geometric properties of the whole object are
-    # determined: center, size, etc.
-    sum_vec = Vector((0.0,0.0,0.0))
-
-    # First the center is determined. All coordinates are summed up ...
-    for atoms_of_one_type in first_frame:
-        sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec)
-
-    # ... and the average is taken. This gives the center of the object.
-    object_center_vec = sum_vec / Number_of_total_atoms
-
-    # Now, we determine the size.The farest atom from the object center is
-    # taken as a measure. The size is used to place well the camera and light
-    # into the scene.
-
-    object_size_vec = []
-    for atoms_of_one_type in first_frame:
-        object_size_vec += [atom.location - object_center_vec for atom in atoms_of_one_type]
-
-    object_size = 0.0
-    object_size = max(object_size_vec).length
-
-    # ------------------------------------------------------------------------
-    # CAMERA AND LAMP
-    camera_factor = 15.0
-
-    # If chosen a camera is put into the scene.
-    if use_camera == True:
-
-        # Assume that the object is put into the global origin. Then, the
-        # camera is moved in x and z direction, not in y. The object has its
-        # size at distance math.sqrt(object_size) from the origin. So, move the
-        # camera by this distance times a factor of camera_factor in x and z.
-        # Then add x, y and z of the origin of the object.
-        object_camera_vec = Vector((math.sqrt(object_size) * camera_factor,
-                                    0.0,
-                                    math.sqrt(object_size) * camera_factor))
-        camera_xyz_vec = object_center_vec + object_camera_vec
-
-        # Create the camera
-        current_layers=bpy.context.scene.layers
-        bpy.ops.object.camera_add(view_align=False, enter_editmode=False,
-                               location=camera_xyz_vec,
-                               rotation=(0.0, 0.0, 0.0), layers=current_layers)
-        # Some properties of the camera are changed.
-        camera = bpy.context.scene.objects.active
-        camera.name = "A_camera"
-        camera.data.name = "A_camera"
-        camera.data.lens = 45
-        camera.data.clip_end = 500.0
-
-        # Here the camera is rotated such it looks towards the center of
-        # the object. The [0.0, 0.0, 1.0] vector along the z axis
-        z_axis_vec             = Vector((0.0, 0.0, 1.0))
-        # The angle between the last two vectors
-        angle                  = object_camera_vec.angle(z_axis_vec, 0)
-        # The cross-product of z_axis_vec and object_camera_vec
-        axis_vec               = z_axis_vec.cross(object_camera_vec)
-        # Rotate 'axis_vec' by 'angle' and convert this to euler parameters.
-        # 4 is the size of the matrix.
-        euler                  = Matrix.Rotation(angle, 4, axis_vec).to_euler()
-        camera.rotation_euler  = euler
-
-        # Rotate the camera around its axis by 90° such that we have a nice
-        # camera position and view onto the object.
-        bpy.ops.transform.rotate(value=(90.0*2*math.pi/360.0,),
-                                 axis=object_camera_vec,
-                                 constraint_axis=(False, False, False),
-                                 constraint_orientation='GLOBAL',
-                                 mirror=False, proportional='DISABLED',
-                                 proportional_edit_falloff='SMOOTH',
-                                 proportional_size=1, snap=False,
-                                 snap_target='CLOSEST', snap_point=(0, 0, 0),
-                                 snap_align=False, snap_normal=(0, 0, 0),
-                                 release_confirm=False)
-
-        # This does not work, I don't know why.
-        #
-        #for area in bpy.context.screen.areas:
-        #    if area.type == 'VIEW_3D':
-        #        area.spaces[0].region_3d.view_perspective = 'CAMERA'
-
-    # Here a lamp is put into the scene, if chosen.
-    if use_lamp == True:
-
-        # This is the distance from the object measured in terms of %
-        # of the camera distance. It is set onto 50% (1/2) distance.
-        lamp_dl = math.sqrt(object_size) * 15 * 0.5
-        # This is a factor to which extend the lamp shall go to the right
-        # (from the camera  point of view).
-        lamp_dy_right = lamp_dl * (3.0/4.0)
-
-        # Create x, y and z for the lamp.
-        object_lamp_vec = Vector((lamp_dl,lamp_dy_right,lamp_dl))
-        lamp_xyz_vec = object_center_vec + object_lamp_vec
-
-        # Create the lamp
-        current_layers=bpy.context.scene.layers
-        bpy.ops.object.lamp_add (type = 'POINT', view_align=False,
-                                 location=lamp_xyz_vec,
-                                 rotation=(0.0, 0.0, 0.0),
-                                 layers=current_layers)
-        # Some properties of the lamp are changed.
-        lamp = bpy.context.scene.objects.active
-        lamp.data.name = "A_lamp"
-        lamp.name = "A_lamp"
-        lamp.data.distance = 500.0
-        lamp.data.energy = 3.0
-        lamp.data.shadow_method = 'RAY_SHADOW'
-
-        bpy.context.scene.world.light_settings.use_ambient_occlusion = True
-        bpy.context.scene.world.light_settings.ao_factor = 0.2
-
-    # ------------------------------------------------------------------------
-    # SOME OUTPUT ON THE CONSOLE
-
-    print()
-    print()
-    print()
-    print(ATOM_XYZ_STRING)
-    print()
-    print("Total number of atoms       : " + str(Number_of_total_atoms))
-    print("Center of object (Angstrom) : ", object_center_vec)
-    print("Size of object (Angstrom)   : ", object_size)
-    print()
-
-    # ------------------------------------------------------------------------
-    # DRAWING THE ATOMS
-
-    bpy.ops.object.select_all(action='DESELECT')
-
-    # For each list of atoms of ONE type (e.g. Hydrogen)
-    for atoms_of_one_type in first_frame:
-
-        # Create first the vertices composed of the coordinates of all
-        # atoms of one type
-        atom_vertices = []
-        for atom in atoms_of_one_type:
-            # In fact, the object is created in the World's origin.
-            # This is why 'object_center_vec' is substracted. At the end
-            # the whole object is translated back to 'object_center_vec'.
-            atom_vertices.append( atom.location - object_center_vec )
-
-        # Build the mesh
-        atom_mesh = bpy.data.meshes.new("Mesh_"+atom.name)
-        atom_mesh.from_pydata(atom_vertices, [], [])
-        atom_mesh.update()
-        new_atom_mesh = bpy.data.objects.new(atom.name, atom_mesh)
-        bpy.context.scene.objects.link(new_atom_mesh)
-
-        # Now, build a representative sphere (atom)
-        current_layers=bpy.context.scene.layers
-
-        if atom.name == "Vacancy":
-            bpy.ops.mesh.primitive_cube_add(
-                            view_align=False, enter_editmode=False,
-                            location=(0.0, 0.0, 0.0),
-                            rotation=(0.0, 0.0, 0.0),
-                            layers=current_layers)
-        else:
-            # NURBS balls
-            if use_mesh == False:
-                bpy.ops.surface.primitive_nurbs_surface_sphere_add(
-                            view_align=False, enter_editmode=False,
-                            location=(0,0,0), rotation=(0.0, 0.0, 0.0),
-                            layers=current_layers)
-            # UV balls
-            else:
-                bpy.ops.mesh.primitive_uv_sphere_add(
-                            segments=Ball_azimuth, ring_count=Ball_zenith,
-                            size=1, view_align=False, enter_editmode=False,
-                            location=(0,0,0), rotation=(0, 0, 0),
-                            layers=current_layers)
-
-        ball = bpy.context.scene.objects.active
-        ball.scale  = (atom.radius*Ball_radius_factor,) * 3
-
-        if atom.name == "Vacancy":
-            ball.name = "Cube_"+atom.name
-        else:
-            ball.name = "Ball (NURBS)_"+atom.name
-        ball.active_material = atom.material
-        ball.parent = new_atom_mesh
-        new_atom_mesh.dupli_type = 'VERTS'
-        # The object is back translated to 'object_center_vec'.
-        new_atom_mesh.location = object_center_vec
-        STRUCTURE.append(new_atom_mesh)
-
-    print()
-
-    # ------------------------------------------------------------------------
-    # SELECT ALL LOADED OBJECTS
-    
-    bpy.ops.object.select_all(action='DESELECT')
-    obj = None
-    for obj in STRUCTURE:
-        obj.select = True
-    # activate the last selected object (perhaps another should be active?)
-    if obj:
-        bpy.context.scene.objects.active = obj
-    print("\n\nAll atoms (%d) have been drawn - finished.\n\n"
-           % (Number_of_total_atoms))
-
-    return Number_of_total_atoms
-    
-
-def DEF_atom_xyz_build_frames(frame_delta, frame_skip):
-
-    scn = bpy.context.scene
-    current_layers = scn.layers
-
-    # Introduce the basis for all elements that appear in the structure.     
-    for element in STRUCTURE:
-     
-        bpy.ops.object.select_all(action='DESELECT')   
-        bpy.context.scene.objects.active = element
-        element.select = True
-        bpy.ops.object.shape_key_add(None)
-        
-    frame_skip += 1    
-
-    # Introduce the keys and reference the atom positions for each key.     
-    i = 0
-    for j, frame in enumerate(ALL_FRAMES):        
-           
-        if j % frame_skip == 0:
-           
-            for elements_frame, elements_structure in zip(frame,STRUCTURE):
-             
-                key = elements_structure.shape_key_add()
-    
-                for atom_frame, atom_structure in zip(elements_frame, key.data):
-    
-                    atom_structure.co = (atom_frame.location 
-                                       - elements_structure.location)
-    
-                key.name = atom_frame.name + "_frame_" + str(i) 
-
-            i += 1
-
-    num_frames = i
-        
-    scn.frame_start = 0
-    scn.frame_end = frame_delta * num_frames
-
-    # Manage the values of the keys
-    for element in STRUCTURE:
- 
-        scn.frame_current = 0 
-
-        element.data.shape_keys.key_blocks[1].value = 1.0
-        element.data.shape_keys.key_blocks[2].value = 0.0
-        element.data.shape_keys.key_blocks[1].keyframe_insert("value")     
-        element.data.shape_keys.key_blocks[2].keyframe_insert("value")         
-
-        scn.frame_current += frame_delta
-    
-        for number in range(num_frames)[2:]:#-1]:
-    
-            element.data.shape_keys.key_blocks[number-1].value = 0.0
-            element.data.shape_keys.key_blocks[number].value = 1.0
-            element.data.shape_keys.key_blocks[number+1].value = 0.0
-            element.data.shape_keys.key_blocks[number-1].keyframe_insert("value")     
-            element.data.shape_keys.key_blocks[number].keyframe_insert("value")     
-            element.data.shape_keys.key_blocks[number+1].keyframe_insert("value")         
-                
-            scn.frame_current += frame_delta
-            
-        number += 1    
-            
-        element.data.shape_keys.key_blocks[number].value = 1.0
-        element.data.shape_keys.key_blocks[number-1].value = 0.0
-        element.data.shape_keys.key_blocks[number].keyframe_insert("value")     
-        element.data.shape_keys.key_blocks[number-1].keyframe_insert("value")    
-        
-
-
diff --git a/release/scripts/addons_contrib/io_points_pcd/__init__.py b/release/scripts/addons_contrib/io_points_pcd/__init__.py
deleted file mode 100644
index f81f5ad..0000000
--- a/release/scripts/addons_contrib/io_points_pcd/__init__.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "PCD",
-    "author": "Aurel Wildfellner",
-    "version": (0, 1),
-    "blender": (2, 5, 7),
-    "location": "File > Import-Export > Point Cloud Data",
-    "description": "Imports and Exports PCD (Point Cloud Data) files. PCD files are the default format used by  pcl (Point Cloud Library).",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "",
-#    "support": 'OFFICAL',
-    "category": "Import-Export"}
-
-
-if "bpy" in locals():
-    import imp
-    imp.reload(pcd_utils)
-else:
-    from . import pcd_utils
-
-import itertools
-import os
-
-
-import bpy
-from bpy.props import *
-from bpy_extras.io_utils import ExportHelper, ImportHelper
-
-
-class ImportPCD(bpy.types.Operator, ImportHelper):
-    '''Load PCD (Point Cloud Data) files'''
-    bl_idname = "import_points.stl"
-    bl_label = "Import PCD"
-
-    filename_ext = ".pcd"
-
-    filter_glob = StringProperty(default="*.pcd", options={'HIDDEN'})
-
-    files = CollectionProperty(name="File Path",
-                          description="File path used for importing "
-                                      "the PCD file",
-                          type=bpy.types.OperatorFileListElement)
-
-    directory = StringProperty(subtype='DIR_PATH')
-
-    def execute(self, context):
-        paths = [os.path.join(self.directory, name.name) for name in self.files]
-        if not paths:
-            paths.append(self.filepath)
-
-        for path in paths:
-            pcd_utils.import_pcd(path)
-
-        return {'FINISHED'}
-
-
-
-
-def menu_func_import(self, context):
-    self.layout.operator(ImportPCD.bl_idname, text="Point Cloud Data (.pcd)").filepath = "*.pcd"
-
-
-def menu_func_export(self, context):
-    #self.layout.operator(ExportPLY.bl_idname, text="Point Cloud Data (.pcd)")
-    pass
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_file_import.append(menu_func_import)
-    bpy.types.INFO_MT_file_export.append(menu_func_export)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_file_import.remove(menu_func_import)
-    bpy.types.INFO_MT_file_export.remove(menu_func_export)
-
-
-if __name__ == "__main__":
-    register()
-
diff --git a/release/scripts/addons_contrib/io_points_pcd/pcd_utils.py b/release/scripts/addons_contrib/io_points_pcd/pcd_utils.py
deleted file mode 100644
index 0c9e042..0000000
--- a/release/scripts/addons_contrib/io_points_pcd/pcd_utils.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-import bpy
-
-from . import pcdparser
-
-
-def create_and_link_mesh(name, points):
-    '''
-    Create a blender mesh and object called name from a list of
-    *points* and link it in the current scene.
-    '''
-
-    mesh = bpy.data.meshes.new(name)
-    mesh.from_pydata(points, [], [])
-
-    # update mesh to allow proper display
-    mesh.validate()
-    mesh.update()
-
-    scene = bpy.context.scene
-
-    obj = bpy.data.objects.new(name, mesh)
-    scene.objects.link(obj)
-    obj.select = True
-
-
-def import_pcd(filepath, name="new_pointcloud"):
-    parser = pcdparser.PCDParser.factory(filepath, pcdparser.PointXYZ)
-    parser.parseFile()
-    points = parser.getPoints()
-
-    blender_points = []
-    for point in points:
-        blender_points.append((point.x, point.y, point.z))
-
-    create_and_link_mesh(name, blender_points)
-  
-
diff --git a/release/scripts/addons_contrib/io_points_pcd/pcdparser.py b/release/scripts/addons_contrib/io_points_pcd/pcdparser.py
deleted file mode 100644
index 8c543c4..0000000
--- a/release/scripts/addons_contrib/io_points_pcd/pcdparser.py
+++ /dev/null
@@ -1,338 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#   
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-import struct
-
-
-def encodeASCIILine(line):
-    return line.decode(encoding='ASCII')
-
-
-
-class Point:
-
-    def __init__(self):
-        pass
-
-
-    def setField(self, fieldname, values):
-        pass
-
-
-
-
-class PointXYZ(Point):
-
-    x = 0
-    y = 0
-    z = 0
-
-    def __init__(self):
-        super().__init__()
-
-
-    def setField(self, fieldname, values):
-        value = values[0]
-        if fieldname == 'x':
-            self.x = value
-        elif fieldname == 'y':
-            self.y = value
-        elif fieldname == 'z':
-            self.z = value
-
-
-
-
-class PCDParser:
-
-    filepath = ''
-    file = None
-
-    points = []
-    PointClass = None
-
-    headerEnd = False
-
-
-    @staticmethod
-    def factory(filepath, PointClass):
-        version = 'NO_VERSION_NUMBER'
-        with open(filepath, 'rb') as f:
-            for b in f:
-                line = encodeASCIILine(b)
-                line_split = line.split()
-                if line_split[0] == 'VERSION' and len(line_split) > 1:
-                    version = line_split[1]
-                    break
-      
-        if version == ".7" or version == "0.7": 
-            return PCDParser_v0_7(filepath, PointClass)
-        else:
-            return None
-
-
-    def __init__(self, filepath, PointClass):
-        self.filepath = filepath
-        self.PointClass = PointClass
-
-        self.file = None
-        self.headerEnd = False
-        self.points = []
-
-
-    def parserWarning(self, msg):
-        print("[WARNING] ", msg)
-    
-
-    def rmComment(self, line):
-        return line[:line.find('#')] 
-
-
-    def parseFile(self):
-        with open(self.filepath, 'rb') as self.file:
-            self.parseHeader()
-            self.parsePoints()
-
-
-    def parseHeader(self):
-        for b in self.file:
-            line = encodeASCIILine(b)
-            line = self.rmComment(line)
-
-            split = line.split()
-            if len(split) > 0:
-                self.parseHeaderLine(split)
-
-            if self.headerEnd:
-                self.finalizeHeader()
-                break
-
-
-    def parseHeaderLine(self, split):
-        keyword = split[0]
-        self.parserWarning("Uknown header Keyword '" + keyword + "' gets ignored")
-
-    
-    def finalizeHeader(self):
-        pass
-
-
-    def parsePoints(self):
-        pass
-
-
-    def getPoints(self):
-        return self.points
-
-
-    def version(self):
-        return 'NO_VERSION_NUMBER'
-
-
-
-
-class PCDParser_v0_7(PCDParser):
-
-    fields = []
-
-    def __init__(self, filepath, PointClass):
-        super().__init__(filepath, PointClass)
-        self.fields = []
-
-
-    def version(self):
-        return '.7'
-
-
-    def parseHeaderLine(self, split):
-        keyword = split[0]
-        if keyword == 'VERSION':
-            self.parseVERSION(split[1:])
-        elif keyword == 'FIELDS':
-            self.parseFIELDS(split[1:])
-        elif keyword == 'SIZE':
-            self.parseSIZE(split[1:])
-        elif keyword == 'TYPE':
-            self.parseTYPE(split[1:])
-        elif keyword == 'COUNT':
-            self.parseCOUNT(split[1:])
-        elif keyword == 'WIDTH':
-            self.parseWIDTH(split[1:])
-        elif keyword == 'HEIGHT':
-            self.parseHEIGHT(split[1:])
-        elif keyword == 'POINTS':
-            self.parsePOINTS(split[1:])
-        elif keyword == 'DATA':
-            self.parseDATA(split[1:])
-        else:
-            super().parseHeaderLine(split)
-
-
-    def parseVERSION(self, split):
-        pass
-
-
-    def parseFIELDS(self, split):
-        print("SPLIT FIELDS:", split)
-        for field in split:
-            self.fields.append([field, None, None, None])
-        print("FIELDS, after parsing:", self.fields)
-
-
-    def parseSIZE(self, split):
-        for i, size in enumerate(split):
-            self.fields[i][1] = int(size)
-
-
-    def parseTYPE(self, split):
-        for i, type in enumerate(split):
-            self.fields[i][2] = type
-
-
-    def parseCOUNT(self, split):
-        for i, count in enumerate(split):
-            self.fields[i][3] = int(count)
-
-
-    def parseWIDTH(self, split):
-        self.width = int(split[0])
-
-
-    def parseHEIGHT(self, split):
-        self.height = int(split[0])
-
-
-    def parsePOINTS(self, split):
-        pass
-
-
-    def parseDATA(self, split):
-        if split[0] == "ascii":
-            self.datatype = 'ASCII'
-        elif split[0] == "binary":
-            self.datatype = 'BINARY'
-        self.headerEnd = True
-
-
-    def finalizeHeader(self):
-        self.numPoints = self.width * self.height
-        print("FIELDS - finalized", self.fields)
-
-
-    def parsePoints(self):
-        if self.datatype == 'ASCII':
-            self.parseASCII()
-        elif self.datatype == 'BINARY':
-            self.parseBINARY()
-
-
-    def parseASCII(self):
-        parsedPoints = 0
-        while parsedPoints < self.numPoints:
-           
-            try: 
-                b = self.file.readline()
-                line = encodeASCIILine(b)
-            except:
-                self.parserError("Unexpected end of data")
-                return
-            line = self.rmComment(line)
-            split = line.split()
-
-            if (len(split) == 0):
-                continue
-            else:
-                parsedPoints += 1
-
-            point = self.PointClass()
-
-            for field in self.fields:
-                fieldname = field[0]
-                fieldtype = field[2]
-                fieldcount = field[3]
-
-                values = []
-                for i in range(fieldcount):
-                    vs = split.pop(0)
-                    if fieldtype == 'F':
-                        values.append(float(vs))
-                    elif fieldtype in ['U', 'I']:
-                        values.append(int(vs))
-
-                point.setField(fieldname, values)
-
-            self.points.append(point)
-
-
-    def parseBINARY(self):
-        for pointi in range(self.numPoints):
-            point = self.PointClass()
-
-            for field in self.fields:
-                fieldname = field[0]
-                fieldsize = field[1]
-                fieldtype = field[2]
-                fieldcount = field[3]
-
-                values = []
-                for i in range(fieldcount):
-
-                    fs = None
-                    if fieldtype == 'F':
-                        if fieldsize == 4: #float
-                            fs = '<f'
-                        elif fieldsize == 8: #double
-                            fs = '<d'
-                    elif fieldtype == 'U':
-                        if fieldsize == 1: #unsinged char
-                            fs = '<B'
-                        elif fieldsize == 2: #unsinged short
-                            fs = '<H'
-                        elif fieldsize == 4: #unsinged int
-                            fs =  '<I'
-                    elif fieldtype == 'I':
-                        if fieldsize == 1: #char
-                            fs = '<c'
-                        elif fieldsize == 2: #short
-                            fs = '<h'
-                        elif fieldsize == 4: #signed int
-                            fs =  '<i'
-
-                    raw = self.file.read(fieldsize)
-                    if (fs):
-                        data = struct.unpack(fs, raw)
-                        values.append(data[0])
-
-                point.setField(fieldname, values)
-
-            self.points.append(point)
-
-
-
-
-def test():
-    parser = PCDParser.factory('test.pcd', PointXYZ)
-    if parser:
-        parser.parseFile()
-        points = parser.getPoints()
-        for point in points:
-            print(point.x, point.y, point.z)
-    else:
-        print("Can't create parser for this file")
-
diff --git a/release/scripts/addons_contrib/io_points_pcd/test.pcd b/release/scripts/addons_contrib/io_points_pcd/test.pcd
deleted file mode 100644
index 79ec41d..0000000
--- a/release/scripts/addons_contrib/io_points_pcd/test.pcd
+++ /dev/null
@@ -1,224 +0,0 @@
-# .PCD v.7 - Point Cloud Data file format
-VERSION .7
-FIELDS x y z rgb
-SIZE 4 4 4 4
-TYPE F F F F
-COUNT 1 1 1 1
-WIDTH 213
-HEIGHT 1
-VIEWPOINT 0 0 0 1 0 0 0
-POINTS 213
-DATA ascii
-0.93773 0.33763 0 4.2108e+06
-0.90805 0.35641 0 4.2108e+06
-0.81915 0.32 0 4.2108e+06
-0.97192 0.278 0 4.2108e+06
-0.944 0.29474 0 4.2108e+06
-0.98111 0.24247 0 4.2108e+06
-0.93655 0.26143 0 4.2108e+06
-0.91631 0.27442 0 4.2108e+06
-0.81921 0.29315 0 4.2108e+06
-0.90701 0.24109 0 4.2108e+06
-0.83239 0.23398 0 4.2108e+06
-0.99185 0.2116 0 4.2108e+06
-0.89264 0.21174 0 4.2108e+06
-0.85082 0.21212 0 4.2108e+06
-0.81044 0.32222 0 4.2108e+06
-0.74459 0.32192 0 4.2108e+06
-0.69927 0.32278 0 4.2108e+06
-0.8102 0.29315 0 4.2108e+06
-0.75504 0.29765 0 4.2108e+06
-0.8102 0.24399 0 4.2108e+06
-0.74995 0.24723 0 4.2108e+06
-0.68049 0.29768 0 4.2108e+06
-0.66509 0.29002 0 4.2108e+06
-0.69441 0.2526 0 4.2108e+06
-0.62807 0.22187 0 4.2108e+06
-0.58706 0.32199 0 4.2108e+06
-0.52125 0.31955 0 4.2108e+06
-0.49351 0.32282 0 4.2108e+06
-0.44313 0.32169 0 4.2108e+06
-0.58678 0.2929 0 4.2108e+06
-0.53436 0.29164 0 4.2108e+06
-0.59308 0.24134 0 4.2108e+06
-0.5357 0.2444 0 4.2108e+06
-0.50043 0.31235 0 4.2108e+06
-0.44107 0.29711 0 4.2108e+06
-0.50727 0.22193 0 4.2108e+06
-0.43957 0.23976 0 4.2108e+06
-0.8105 0.21112 0 4.2108e+06
-0.73555 0.2114 0 4.2108e+06
-0.69907 0.21082 0 4.2108e+06
-0.63327 0.21154 0 4.2108e+06
-0.59165 0.21201 0 4.2108e+06
-0.52477 0.21491 0 4.2108e+06
-0.49375 0.21006 0 4.2108e+06
-0.4384 0.19632 0 4.2108e+06
-0.43425 0.16052 0 4.2108e+06
-0.3787 0.32173 0 4.2108e+06
-0.33444 0.3216 0 4.2108e+06
-0.23815 0.32199 0 4.808e+06
-0.3788 0.29315 0 4.2108e+06
-0.33058 0.31073 0 4.2108e+06
-0.3788 0.24399 0 4.2108e+06
-0.30249 0.29189 0 4.2108e+06
-0.23492 0.29446 0 4.808e+06
-0.29465 0.24399 0 4.2108e+06
-0.23514 0.24172 0 4.808e+06
-0.18836 0.32277 0 4.808e+06
-0.15992 0.32176 0 4.808e+06
-0.08642 0.32181 0 4.808e+06
-0.039994 0.32283 0 4.808e+06
-0.20039 0.31211 0 4.808e+06
-0.1417 0.29506 0 4.808e+06
-0.20921 0.22332 0 4.808e+06
-0.13884 0.24227 0 4.808e+06
-0.085123 0.29441 0 4.808e+06
-0.048446 0.31279 0 4.808e+06
-0.086957 0.24399 0 4.808e+06
-0.3788 0.21189 0 4.2108e+06
-0.29465 0.19323 0 4.2108e+06
-0.23755 0.19348 0 4.808e+06
-0.29463 0.16054 0 4.2108e+06
-0.23776 0.16054 0 4.808e+06
-0.19016 0.21038 0 4.808e+06
-0.15704 0.21245 0 4.808e+06
-0.08678 0.21169 0 4.808e+06
-0.012746 0.32168 0 4.808e+06
--0.075715 0.32095 0 4.808e+06
--0.10622 0.32304 0 4.808e+06
--0.16391 0.32118 0 4.808e+06
-0.00088411 0.29487 0 4.808e+06
--0.057568 0.29457 0 4.808e+06
--0.0034333 0.24399 0 4.808e+06
--0.055185 0.24185 0 4.808e+06
--0.10983 0.31352 0 4.808e+06
--0.15082 0.29453 0 4.808e+06
--0.11534 0.22049 0 4.808e+06
--0.15155 0.24381 0 4.808e+06
--0.1912 0.32173 0 4.808e+06
--0.281 0.3185 0 4.808e+06
--0.30791 0.32307 0 4.808e+06
--0.33854 0.32148 0 4.808e+06
--0.21248 0.29805 0 4.808e+06
--0.26372 0.29905 0 4.808e+06
--0.22562 0.24399 0 4.808e+06
--0.25035 0.2371 0 4.808e+06
--0.29941 0.31191 0 4.808e+06
--0.35845 0.2954 0 4.808e+06
--0.29231 0.22236 0 4.808e+06
--0.36101 0.24172 0 4.808e+06
--0.0034393 0.21129 0 4.808e+06
--0.07306 0.21304 0 4.808e+06
--0.10579 0.2099 0 4.808e+06
--0.13642 0.21411 0 4.808e+06
--0.22562 0.19323 0 4.808e+06
--0.24439 0.19799 0 4.808e+06
--0.22591 0.16041 0 4.808e+06
--0.23466 0.16082 0 4.808e+06
--0.3077 0.20998 0 4.808e+06
--0.3413 0.21239 0 4.808e+06
--0.40551 0.32178 0 4.2108e+06
--0.50568 0.3218 0 4.2108e+06
--0.41732 0.30844 0 4.2108e+06
--0.44237 0.28859 0 4.2108e+06
--0.41591 0.22004 0 4.2108e+06
--0.44803 0.24236 0 4.2108e+06
--0.50623 0.29315 0 4.2108e+06
--0.50916 0.24296 0 4.2108e+06
--0.57019 0.22334 0 4.2108e+06
--0.59611 0.32199 0 4.2108e+06
--0.65104 0.32199 0 4.2108e+06
--0.72566 0.32129 0 4.2108e+06
--0.75538 0.32301 0 4.2108e+06
--0.59653 0.29315 0 4.2108e+06
--0.65063 0.29315 0 4.2108e+06
--0.59478 0.24245 0 4.2108e+06
--0.65063 0.24399 0 4.2108e+06
--0.70618 0.29525 0 4.2108e+06
--0.76203 0.31284 0 4.2108e+06
--0.70302 0.24183 0 4.2108e+06
--0.77062 0.22133 0 4.2108e+06
--0.41545 0.21099 0 4.2108e+06
--0.45004 0.19812 0 4.2108e+06
--0.4475 0.1673 0 4.2108e+06
--0.52031 0.21236 0 4.2108e+06
--0.55182 0.21045 0 4.2108e+06
--0.5965 0.21131 0 4.2108e+06
--0.65064 0.2113 0 4.2108e+06
--0.72216 0.21286 0 4.2108e+06
--0.7556 0.20987 0 4.2108e+06
--0.78343 0.31973 0 4.2108e+06
--0.87572 0.32111 0 4.2108e+06
--0.90519 0.32263 0 4.2108e+06
--0.95526 0.34127 0 4.2108e+06
--0.79774 0.29271 0 4.2108e+06
--0.85618 0.29497 0 4.2108e+06
--0.79975 0.24326 0 4.2108e+06
--0.8521 0.24246 0 4.2108e+06
--0.91157 0.31224 0 4.2108e+06
--0.95031 0.29572 0 4.2108e+06
--0.92223 0.2213 0 4.2108e+06
--0.94979 0.24354 0 4.2108e+06
--0.78641 0.21505 0 4.2108e+06
--0.87094 0.21237 0 4.2108e+06
--0.90637 0.20934 0 4.2108e+06
--0.93777 0.21481 0 4.2108e+06
-0.22244 -0.0296 0 4.808e+06
-0.2704 -0.078167 0 4.808e+06
-0.24416 -0.056883 0 4.808e+06
-0.27311 -0.10653 0 4.808e+06
-0.26172 -0.10653 0 4.808e+06
-0.2704 -0.1349 0 4.808e+06
-0.24428 -0.15599 0 4.808e+06
-0.19017 -0.025297 0 4.808e+06
-0.14248 -0.02428 0 4.808e+06
-0.19815 -0.037432 0 4.808e+06
-0.14248 -0.03515 0 4.808e+06
-0.093313 -0.02428 0 4.808e+06
-0.044144 -0.02428 0 4.808e+06
-0.093313 -0.03515 0 4.808e+06
-0.044144 -0.03515 0 4.808e+06
-0.21156 -0.17357 0 4.808e+06
-0.029114 -0.12594 0 4.2108e+06
-0.036583 -0.15619 0 4.2108e+06
-0.22446 -0.20514 0 4.808e+06
-0.2208 -0.2369 0 4.808e+06
-0.2129 -0.208 0 4.808e+06
-0.19316 -0.25672 0 4.808e+06
-0.14497 -0.27484 0 4.808e+06
-0.030167 -0.18748 0 4.2108e+06
-0.1021 -0.27453 0 4.808e+06
-0.1689 -0.2831 0 4.808e+06
-0.13875 -0.28647 0 4.808e+06
-0.086993 -0.29568 0 4.808e+06
-0.044924 -0.3154 0 4.808e+06
--0.0066125 -0.02428 0 4.808e+06
--0.057362 -0.02428 0 4.808e+06
--0.0066125 -0.03515 0 4.808e+06
--0.057362 -0.03515 0 4.808e+06
--0.10653 -0.02428 0 4.808e+06
--0.15266 -0.025282 0 4.808e+06
--0.10653 -0.03515 0 4.808e+06
--0.16036 -0.037257 0 4.808e+06
-0.0083286 -0.1259 0 4.2108e+06
-0.0007442 -0.15603 0 4.2108e+06
--0.1741 -0.17381 0 4.808e+06
--0.18502 -0.02954 0 4.808e+06
--0.20707 -0.056403 0 4.808e+06
--0.23348 -0.07764 0 4.808e+06
--0.2244 -0.10653 0 4.808e+06
--0.23604 -0.10652 0 4.808e+06
--0.20734 -0.15641 0 4.808e+06
--0.23348 -0.13542 0 4.808e+06
-0.0061083 -0.18729 0 4.2108e+06
--0.066235 -0.27472 0 4.808e+06
--0.17577 -0.20789 0 4.808e+06
--0.10861 -0.27494 0 4.808e+06
--0.15584 -0.25716 0 4.808e+06
--0.0075775 -0.31546 0 4.808e+06
--0.050817 -0.29595 0 4.808e+06
--0.10306 -0.28653 0 4.808e+06
--0.1319 -0.2831 0 4.808e+06
--0.18716 -0.20571 0 4.808e+06
--0.18369 -0.23729 0 4.808e+06
diff --git a/release/scripts/addons_contrib/io_scene_cod/__init__.py b/release/scripts/addons_contrib/io_scene_cod/__init__.py
deleted file mode 100644
index 00776ba..0000000
--- a/release/scripts/addons_contrib/io_scene_cod/__init__.py
+++ /dev/null
@@ -1,475 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Blender-CoD: Blender Add-On for Call of Duty modding
-Version: alpha 3
-
-Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
-
-http://code.google.com/p/blender-cod/
-
-TODO
-- UI for xmodel and xanim import (planned for alpha 4/5)
-
-"""
-
-bl_info = {
-    "name": "Blender-CoD - Add-On for Call of Duty modding (alpha 3)",
-    "author": "CoDEmanX, Flybynyt",
-    "version": (0, 3, 5),
-    "blender": (2, 62, 3),
-    "location": "File > Import  |  File > Export",
-    "description": "Export models to *.XMODEL_EXPORT and animations to *.XANIM_EXPORT",
-    "warning": "Alpha version, please report any bugs!",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/Call_of_Duty_IO",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=30482",
-    "support": "TESTING",
-    "category": "Import-Export"
-}
-
-# To support reload properly, try to access a package var, if it's there, reload everything
-if "bpy" in locals():
-    import imp
-    if "import_xmodel" in locals():
-        imp.reload(import_xmodel)
-    if "export_xmodel" in locals():
-        imp.reload(export_xmodel)
-    if "import_xanim" in locals():
-        imp.reload(import_xanim)
-    if "export_xanim" in locals():
-        imp.reload(export_xanim)
-
-import bpy
-from bpy.props import BoolProperty, IntProperty, FloatProperty, StringProperty, EnumProperty
-import bpy_extras.io_utils
-from bpy_extras.io_utils import ExportHelper, ImportHelper
-import time
-
-# Planned for alpha 4/5
-class ImportXmodel(bpy.types.Operator, ImportHelper):
-    """Load a CoD XMODEL_EXPORT File"""
-    bl_idname = "import_scene.xmodel"
-    bl_label = "Import XMODEL_EXPORT"
-    bl_options = {'PRESET'}
-
-    filename_ext = ".XMODEL_EXPORT"
-    filter_glob = StringProperty(default="*.XMODEL_EXPORT", options={'HIDDEN'})
-
-    #use_meshes = BoolProperty(name="Meshes", description="Import meshes", default=True)
-    #use_armature = BoolProperty(name="Armature", description="Import Armature", default=True)
-    #use_bind_armature = BoolProperty(name="Bind Meshes to Armature", description="Parent imported meshes to armature", default=True)
-
-    #use_split_objects = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default=True)
-    #use_split_groups = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default=True)
-
-    #use_image_search = BoolProperty(name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default=True)
-
-    def execute(self, context):
-        from . import import_xmodel
-        start_time = time.clock()
-        result = import_xmodel.load(self, context, **self.as_keywords(ignore=("filter_glob", "check_existing")))
-
-        if not result:
-            self.report({'INFO'}, "Import finished in %.4f sec." % (time.clock() - start_time))
-            return {'FINISHED'}
-        else:
-            self.report({'ERROR'}, result)
-            return {'CANCELLED'}
-
-    """
-    def draw(self, context):
-        layout = self.layout
-
-        col = layout.column()
-        col.prop(self, "use_meshes")
-        col.prop(self, "use_armature")
-
-        row = layout.row()
-        row.active = self.use_meshes and self.use_armature
-        row.prop(self, "use_bind_armature")
-    """
-
-    @classmethod
-    def poll(self, context):
-        return (context.scene is not None)
-
-class ImportXanim(bpy.types.Operator, ImportHelper):
-    """Load a CoD XANIM_EXPORT File"""
-    bl_idname = "import_scene.xanim"
-    bl_label = "Import XANIM_EXPORT"
-    bl_options = {'PRESET'}
-
-    filename_ext = ".XANIM_EXPORT"
-    filter_glob = StringProperty(default="*.XANIM_EXPORT;*.NT_EXPORT", options={'HIDDEN'})
-
-    def execute(self, context):
-        # print("Selected: " + context.active_object.name)
-        from . import import_xanim
-
-        return import_xanim.load(self, context, **self.as_keywords(ignore=("filter_glob",)))
-
-class ExportXmodel(bpy.types.Operator, ExportHelper):
-    """Save a CoD XMODEL_EXPORT File"""
-
-    bl_idname = "export_scene.xmodel"
-    bl_label = 'Export XMODEL_EXPORT'
-    bl_options = {'PRESET'}
-
-    filename_ext = ".XMODEL_EXPORT"
-    filter_glob = StringProperty(default="*.XMODEL_EXPORT", options={'HIDDEN'})
-
-    # List of operator properties, the attributes will be assigned
-    # to the class instance from the operator settings before calling.
-
-    use_version = EnumProperty(
-        name="Format Version",
-        description="XMODEL_EXPORT format version for export",
-        items=(('5', "Version 5", "vCoD, CoD:UO"),
-               ('6', "Version 6", "CoD2, CoD4, CoD5, CoD7")),
-        default='6',
-        )
-
-    use_selection = BoolProperty(
-        name="Selection only",
-        description="Export selected meshes only (object or weight paint mode)",
-        default=False
-        )
-
-    use_vertex_colors = BoolProperty(
-        name="Vertex colors",
-        description="Export vertex colors (if disabled, white color will be used)",
-        default=True
-        )
-
-    use_vertex_colors_alpha = BoolProperty(
-        name="As alpha",
-        description="Turn RGB vertex colors into grayscale (average value) and use it as alpha transparency. White is 1 (opaque), black 0 (invisible)",
-        default=False
-        )
-
-    use_apply_modifiers = BoolProperty(
-        name="Apply Modifiers",
-        description="Apply all mesh modifiers except Armature (preview resolution)",
-        default=True
-        )
-
-    use_armature = BoolProperty(
-        name="Armature",
-        description="Export bones (if disabled, only a 'tag_origin' bone will be written)",
-        default=True
-        )
-
-    use_vertex_cleanup = BoolProperty(
-        name="Clean up vertices",
-        description="Try this if you have problems converting to xmodel. Skips vertices which aren't used by any face and updates references.",
-        default=False
-        )
-
-    use_armature_pose = BoolProperty(
-        name="Pose animation to models",
-        description="Export meshes with Armature modifier applied as a series of XMODEL_EXPORT files",
-        default=False
-        )
-
-    use_frame_start = IntProperty(
-        name="Start",
-        description="First frame to export",
-        default=1,
-        min=0
-        )
-
-    use_frame_end = IntProperty(
-        name="End",
-        description="Last frame to export",
-        default=250,
-        min=0
-        )
-
-    use_weight_min = BoolProperty(
-        name="Minimum bone weight",
-        description="Try this if you get 'too small weight' errors when converting",
-        default=False,
-        )
-
-    use_weight_min_threshold = FloatProperty(
-        name="Threshold",
-        description="Smallest allowed weight (minimum value)",
-        default=0.010097,
-        min=0.0,
-        max=1.0,
-        precision=6
-        )
-
-    def execute(self, context):
-        from . import export_xmodel
-        start_time = time.clock()
-        result = export_xmodel.save(self, context, **self.as_keywords(ignore=("filter_glob", "check_existing")))
-
-        if not result:
-            self.report({'INFO'}, "Export finished in %.4f sec." % (time.clock() - start_time))
-            return {'FINISHED'}
-        else:
-            self.report({'ERROR'}, result)
-            return {'CANCELLED'}
-
-    # Extend ExportHelper invoke function to support dynamic default values
-    def invoke(self, context, event):
-
-        #self.use_frame_start = context.scene.frame_start
-        self.use_frame_start = context.scene.frame_current
-
-        #self.use_frame_end = context.scene.frame_end
-        self.use_frame_end = context.scene.frame_current
-
-        return super().invoke(context, event)
-
-    def draw(self, context):
-        layout = self.layout
-
-        row = layout.row(align=True)
-        row.prop(self, "use_version", expand=True)
-
-        # Calculate number of selected mesh objects
-        if context.mode in ('OBJECT', 'PAINT_WEIGHT'):
-            meshes_selected = len([m for m in bpy.data.objects if m.type == 'MESH' and m.select])
-        else:
-            meshes_selected = 0
-
-        col = layout.column(align=True)
-        col.prop(self, "use_selection", "Selection only (%i meshes)" % meshes_selected)
-        col.enabled = bool(meshes_selected)
-
-        col = layout.column(align=True)
-        col.prop(self, "use_apply_modifiers")
-
-        col = layout.column(align=True)
-        col.enabled = not self.use_armature_pose
-        if self.use_armature and self.use_armature_pose:
-            col.prop(self, "use_armature", "Armature  (disabled)")
-        else:
-            col.prop(self, "use_armature")
-
-        if self.use_version == '6':
-
-            row = layout.row(align=True)
-            row.prop(self, "use_vertex_colors")
-
-            sub = row.split()
-            sub.active = self.use_vertex_colors
-            sub.prop(self, "use_vertex_colors_alpha")
-
-        col = layout.column(align=True)
-        col.label("Advanced:")
-
-        col = layout.column(align=True)
-        col.prop(self, "use_vertex_cleanup")
-
-        box = layout.box()
-
-        col = box.column(align=True)
-        col.prop(self, "use_armature_pose")
-
-        sub = box.column()
-        sub.active = self.use_armature_pose
-        sub.label(text="Frame range: (%i frames)" % (abs(self.use_frame_end - self.use_frame_start) + 1))
-
-        row = sub.row(align=True)
-        row.prop(self, "use_frame_start")
-        row.prop(self, "use_frame_end")
-
-        box = layout.box()
-
-        col = box.column(align=True)
-        col.prop(self, "use_weight_min")
-
-        sub = box.column()
-        sub.enabled = self.use_weight_min
-        sub.prop(self, "use_weight_min_threshold")
-
-    @classmethod
-    def poll(self, context):
-        return (context.scene is not None)
-
-class ExportXanim(bpy.types.Operator, ExportHelper):
-    """Save a XMODEL_XANIM File"""
-
-    bl_idname = "export_scene.xanim"
-    bl_label = 'Export XANIM_EXPORT'
-    bl_options = {'PRESET'}
-
-    filename_ext = ".XANIM_EXPORT"
-    filter_glob = StringProperty(default="*.XANIM_EXPORT", options={'HIDDEN'})
-
-    # List of operator properties, the attributes will be assigned
-    # to the class instance from the operator settings before calling.
-
-    use_selection = BoolProperty(
-        name="Selection only",
-        description="Export selected bones only (pose mode)",
-        default=False
-        )
-
-    use_framerate = IntProperty(
-        name="Framerate",
-        description="Set frames per second for export, 30 fps is commonly used.",
-        default=24,
-        min=1,
-        max=100
-        )
-
-    use_frame_start = IntProperty(
-        name="Start",
-        description="First frame to export",
-        default=1,
-        min=0
-        )
-
-    use_frame_end = IntProperty(
-        name="End",
-        description="Last frame to export",
-        default=250,
-        min=0
-        )
-
-    use_notetrack = BoolProperty(
-        name="Notetrack",
-        description="Export timeline markers as notetrack nodes",
-        default=True
-        )
-
-    use_notetrack_format = EnumProperty(
-        name="Notetrack format",
-        description="Notetrack format to use. Always set 'CoD 7' for Black Ops, even if not using notetrack!",
-        items=(('5', "CoD 5", "Separate NT_EXPORT notetrack file for 'World at War'"),
-               ('7', "CoD 7", "Separate NT_EXPORT notetrack file for 'Black Ops'"),
-               ('1', "all other", "Inline notetrack data for all CoD versions except WaW and BO")),
-        default='1',
-        )
-
-    def execute(self, context):
-        from . import export_xanim
-        start_time = time.clock()
-        result = export_xanim.save(self, context, **self.as_keywords(ignore=("filter_glob", "check_existing")))
-
-        if not result:
-            self.report({'INFO'}, "Export finished in %.4f sec." % (time.clock() - start_time))
-            return {'FINISHED'}
-        else:
-            self.report({'ERROR'}, result)
-            return {'CANCELLED'}
-
-    # Extend ExportHelper invoke function to support dynamic default values
-    def invoke(self, context, event):
-
-        self.use_frame_start = context.scene.frame_start
-        self.use_frame_end = context.scene.frame_end
-        self.use_framerate = round(context.scene.render.fps / context.scene.render.fps_base)
-
-        return super().invoke(context, event)
-
-    def draw(self, context):
-
-        layout = self.layout
-
-        bones_selected = 0
-        armature = None
-
-        # Take the first armature
-        for ob in bpy.data.objects:
-            if ob.type == 'ARMATURE' and len(ob.data.bones) > 0:
-                armature = ob.data
-
-                # Calculate number of selected bones if in pose-mode
-                if context.mode == 'POSE':
-                    bones_selected = len([b for b in armature.bones if b.select])
-
-                # Prepare info string
-                armature_info = "%s (%i bones)" % (ob.name, len(armature.bones))
-                break
-        else:
-            armature_info = "Not found!"
-
-        if armature:
-            icon = 'NONE'
-        else:
-            icon = 'ERROR'
-
-        col = layout.column(align=True)
-        col.label("Armature: %s" % armature_info, icon)
-
-        col = layout.column(align=True)
-        col.prop(self, "use_selection", "Selection only (%i bones)" % bones_selected)
-        col.enabled = bool(bones_selected)
-
-        layout.label(text="Frame range: (%i frames)" % (abs(self.use_frame_end - self.use_frame_start) + 1))
-
-        row = layout.row(align=True)
-        row.prop(self, "use_frame_start")
-        row.prop(self, "use_frame_end")
-
-        col = layout.column(align=True)
-        col.prop(self, "use_framerate")
-
-        # Calculate number of markers in export range
-        frame_min = min(self.use_frame_start, self.use_frame_end)
-        frame_max = max(self.use_frame_start, self.use_frame_end)
-        num_markers = len([m for m in context.scene.timeline_markers if frame_max >= m.frame >= frame_min])
-
-        col = layout.column(align=True)
-        col.prop(self, "use_notetrack", text="Notetrack (%i nodes)" % num_markers)
-
-        col = layout.column(align=True)
-        col.prop(self, "use_notetrack_format", expand=True)
-
-    @classmethod
-    def poll(self, context):
-        return (context.scene is not None)
-
-def menu_func_xmodel_import(self, context):
-    self.layout.operator(ImportXmodel.bl_idname, text="CoD Xmodel (.XMODEL_EXPORT)")
-"""
-def menu_func_xanim_import(self, context):
-    self.layout.operator(ImportXanim.bl_idname, text="CoD Xanim (.XANIM_EXPORT)")
-"""
-def menu_func_xmodel_export(self, context):
-    self.layout.operator(ExportXmodel.bl_idname, text="CoD Xmodel (.XMODEL_EXPORT)")
-
-def menu_func_xanim_export(self, context):
-    self.layout.operator(ExportXanim.bl_idname, text="CoD Xanim (.XANIM_EXPORT)")
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_file_import.append(menu_func_xmodel_import)
-    #bpy.types.INFO_MT_file_import.append(menu_func_xanim_import)
-    bpy.types.INFO_MT_file_export.append(menu_func_xmodel_export)
-    bpy.types.INFO_MT_file_export.append(menu_func_xanim_export)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_file_import.remove(menu_func_xmodel_import)
-    #bpy.types.INFO_MT_file_import.remove(menu_func_xanim_import)
-    bpy.types.INFO_MT_file_export.remove(menu_func_xmodel_export)
-    bpy.types.INFO_MT_file_export.remove(menu_func_xanim_export)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/io_scene_cod/export_xanim.py b/release/scripts/addons_contrib/io_scene_cod/export_xanim.py
deleted file mode 100644
index 4cfd505..0000000
--- a/release/scripts/addons_contrib/io_scene_cod/export_xanim.py
+++ /dev/null
@@ -1,231 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Blender-CoD: Blender Add-On for Call of Duty modding
-Version: alpha 3
-
-Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
-
-http://code.google.com/p/blender-cod/
-
-TODO
-- Test pose matrix exports, global or local?
-
-"""
-
-import bpy
-from datetime import datetime
-
-def save(self, context, filepath="",
-         use_selection=False,
-         use_framerate=24,
-         use_frame_start=1,
-         use_frame_end=250,
-         use_notetrack=True,
-         use_notetrack_format='1'):
-
-    armature = None
-    last_frame_current = context.scene.frame_current
-
-    # There's no context object right after object deletion, need to set one
-    if context.object:
-        last_mode = context.object.mode
-    else:
-        last_mode = 'OBJECT'
-
-        if bpy.data.objects:
-            context.scene.objects.active = bpy.data.objects[0]
-        else:
-            return "Nothing to export."
-
-    # HACK: Force an update, so that bone tree is properly sorted for hierarchy table export
-    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-
-    # Check input objects, don't move this above hack!
-    for ob in bpy.data.objects:
-
-        # Take the first armature
-        if ob.type == 'ARMATURE' and len(ob.data.bones) > 0:
-            armature = ob
-            break
-    else:
-        return "No armature to export."
-
-    # Get the wanted bones
-    if use_selection:
-        bones = [b for b in armature.data.bones if b.select]
-    else:
-        bones = armature.data.bones
-
-    # Get armature matrix once for later global coords/matrices calculation per frame
-    a_matrix = armature.matrix_world
-
-    # There's valid data for export, create output file
-    try:
-        file = open(filepath, "w")
-    except IOError:
-        return "Could not open file for writing:\n%s" % filepath
-
-     # write the header
-    file.write("// XANIM_EXPORT file in CoD animation v3 format created with Blender v%s\n" \
-               % bpy.app.version_string)
-    file.write("// Source file: %s\n" % filepath)
-    file.write("// Export time: %s\n\n" % datetime.now().strftime("%d-%b-%Y %H:%M:%S"))
-    file.write("ANIMATION\n")
-    file.write("VERSION 3\n\n")
-
-    file.write("NUMPARTS %i\n" % len(bones))
-
-    # Write bone table
-    for i_bone, bone in enumerate(bones):
-        file.write("PART %i \"%s\"\n" % (i_bone, bone.name))
-
-    # Exporter shall use Blender's framerate (render settings, used as playback speed)
-    # Note: Time remapping not taken into account
-    file.write("\nFRAMERATE %i\n" % use_framerate)
-
-    file.write("NUMFRAMES %i\n\n" % (abs(use_frame_start - use_frame_end) + 1))
-
-    # If start frame greater than end frame, export animation reversed
-    if use_frame_start < use_frame_end:
-        frame_order = 1
-        frame_min = use_frame_start
-        frame_max = use_frame_end
-    else:
-        frame_order = -1
-        frame_min = use_frame_end
-        frame_max = use_frame_start
-
-    for i_frame, frame in enumerate(range(use_frame_start,
-                                          use_frame_end + frame_order,
-                                          frame_order),
-                                    frame_min):
-
-        file.write("FRAME %i\n" % i_frame)
-
-        # Set frame directly
-        context.scene.frame_set(frame)
-
-        # Get PoseBones for that frame
-        if use_selection:
-            bones = [b for b in armature.pose.bones if b.bone.select]
-        else:
-            bones = armature.pose.bones
-
-        # Write bone orientations
-        for i_bone, bone in enumerate(bones):
-
-            # Skip bone if 'Selection only' is enabled and bone not selected
-            if use_selection and not bone.bone.select: # It's actually posebone.bone!
-                continue
-
-            file.write("PART %i\n" % i_bone)
-
-
-            """ Doesn't seem to be right... or maybe it is? root can't have rotation, it rather sets the global orientation
-            if bone.parent is None:
-                file.write("OFFSET 0.000000 0.000000 0.000000\n")
-                file.write("SCALE 1.000000 1.000000 1.000000\n")
-                file.write("X 1.000000, 0.000000, 0.000000\n")
-                file.write("Y 0.000000, 1.000000, 0.000000\n")
-                file.write("Z 0.000000, 0.000000, 1.000000\n\n")
-            else:
-            """
-
-            b_tail = a_matrix * bone.tail
-            file.write("OFFSET %.6f %.6f %.6f\n" % (b_tail[0], b_tail[1], b_tail[2]))
-            file.write("SCALE 1.000000 1.000000 1.000000\n") # Is this even supported by CoD?
-            
-            file.write("X %.6f %.6f %.6f\n" % (bone.matrix[0][0], bone.matrix[1][0], bone.matrix[2][0]))
-            file.write("Y %.6f %.6f %.6f\n" % (bone.matrix[0][1], bone.matrix[1][1], bone.matrix[2][1]))
-            file.write("Z %.6f %.6f %.6f\n\n" % (bone.matrix[0][2], bone.matrix[1][2], bone.matrix[2][2]))
-
-            """
-            # Is a local matrix used (above) or a global?
-            # Rest pose bone roll shouldn't matter if local is used... o_O
-            # Note: Converting to xanim delta doesn't allow bone moves (only root?)
-            b_matrix = a_matrix * bone.matrix
-            file.write("X %.6f %.6f %.6f\n" % (b_matrix[0][0], b_matrix[1][0], b_matrix[2][0]))
-            file.write("Y %.6f %.6f %.6f\n" % (b_matrix[0][1], b_matrix[1][1], b_matrix[2][1]))
-            file.write("Z %.6f %.6f %.6f\n" % (b_matrix[0][2], b_matrix[1][2], b_matrix[2][2]))
-            """
-
-    # Blender timeline markers to notetrack nodes
-    markers = []
-    for m in context.scene.timeline_markers:
-        if frame_max >= m.frame >= frame_min:
-            markers.append([m.frame, m.name])
-    markers = sorted(markers)
-
-    # Cache marker string
-    marker_string = "NUMKEYS %i\n" % len(markers)
-
-    for m in markers:
-        marker_string += "FRAME %i \"%s\"\n" % (m[0], m[1])
-
-    # Write notetrack data
-    if use_notetrack_format == '7':
-        # Always 0 for CoD7, no matter if there are markers or not!
-        file.write("NUMKEYS 0\n")
-    else:
-        file.write("NOTETRACKS\n\n")
-
-        for i_bone, bone in enumerate(bones):
-
-            file.write("PART %i\n" % (i_bone))
-
-            if i_bone == 0 and use_notetrack and use_notetrack_format == '1' and len(markers) > 0:
-
-                file.write("NUMTRACKS 1\n\n")
-                file.write("NOTETRACK 0\n")
-                file.write(marker_string)
-                file.write("\n")
-
-            else:
-                file.write("NUMTRACKS 0\n\n")
-
-    # Close to flush buffers!
-    file.close()
-
-    if use_notetrack and use_notetrack_format in ('5', '7'):
-
-        import os.path
-        filepath = os.path.splitext(filepath)[0] + ".NT_EXPORT"
-
-        try:
-            file = open(filepath, "w")
-        except IOError:
-            return "Could not open file for writing:\n%s" % filepath
-
-        if use_notetrack_format == '7':
-            file.write("FIRSTFRAME %i\n" % use_frame_start)
-            file.write("NUMFRAMES %i\n" % (abs(use_frame_end - use_frame_start) + 1))
-        file.write(marker_string)
-
-        file.close()
-
-    # Set frame_current and mode back
-    context.scene.frame_set(last_frame_current)
-    bpy.ops.object.mode_set(mode=last_mode, toggle=False)
-
-    # Quit with no errors
-    return
diff --git a/release/scripts/addons_contrib/io_scene_cod/export_xmodel.py b/release/scripts/addons_contrib/io_scene_cod/export_xmodel.py
deleted file mode 100644
index 72874c2..0000000
--- a/release/scripts/addons_contrib/io_scene_cod/export_xmodel.py
+++ /dev/null
@@ -1,732 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Blender-CoD: Blender Add-On for Call of Duty modding
-Version: alpha 3
-
-Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
-
-http://code.google.com/p/blender-cod/
-
-"""
-
-import bpy
-import os
-from datetime import datetime
-
-def save(self, context, filepath="",
-         use_version='6',
-         use_selection=False,
-         use_apply_modifiers=True,
-         use_armature=True,
-         use_vertex_colors=True,
-         use_vertex_colors_alpha=False,
-         use_vertex_cleanup=False,
-         use_armature_pose=False,
-         use_frame_start=1,
-         use_frame_end=250,
-         use_weight_min=False,
-         use_weight_min_threshold=0.010097):
-
-    # There's no context object right after object deletion, need to set one
-    if context.object:
-        last_mode = context.object.mode
-    else:
-        last_mode = 'OBJECT'
-
-        for ob in bpy.data.objects:
-            if ob.type == 'MESH':
-                context.scene.objects.active = ob
-                break
-        else:
-            return "No mesh to export."
-
-    # HACK: Force an update, so that bone tree is properly sorted for hierarchy table export
-    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-
-    # Remember frame to set it back after export
-    last_frame_current = context.scene.frame_current
-
-    # Disable Armature for Pose animation export, bone.tail_local not available for PoseBones
-    if use_armature and use_armature_pose:
-        use_armature = False
-
-    # Don't iterate for a single frame
-    if not use_armature_pose or (use_armature_pose and use_frame_start == use_frame_end):
-        context.scene.frame_set(use_frame_start)
-
-        result = _write(self, context, filepath,
-                        use_version,
-                        use_selection,
-                        use_apply_modifiers,
-                        use_armature,
-                        use_vertex_colors,
-                        use_vertex_colors_alpha,
-                        use_vertex_cleanup,
-                        use_armature_pose,
-                        use_weight_min,
-                        use_weight_min_threshold)
-    else:
-
-        if use_frame_start < use_frame_end:
-            frame_order = 1
-            frame_min = use_frame_start
-            frame_max = use_frame_end
-        else:
-            frame_order = -1
-            frame_min = use_frame_end
-            frame_max = use_frame_start
-
-        # String length of highest frame number for filename padding
-        frame_strlen = len(str(frame_max))
-
-        filepath_split = os.path.splitext(filepath)
-
-        for i_frame, frame in enumerate(range(use_frame_start,
-                                              use_frame_end + frame_order,
-                                              frame_order
-                                              ),
-                                        frame_min):
-
-            # Set frame for export
-            # Don't do it directly to frame_current, as to_mesh() won't use updated frame!
-            context.scene.frame_set(frame)
-
-            # Generate filename including padded frame number
-            filepath_frame = "%s_%.*i%s" % (filepath_split[0], frame_strlen, i_frame, filepath_split[1])
-
-            result = _write(self, context, filepath_frame,
-                            use_version,
-                            use_selection,
-                            use_apply_modifiers,
-                            use_armature,
-                            use_vertex_colors,
-                            use_vertex_colors_alpha,
-                            use_vertex_cleanup,
-                            use_armature_pose,
-                            use_weight_min,
-                            use_weight_min_threshold
-                            )
-
-            # Quit iteration on error
-            if result:
-                context.scene.frame_set(last_frame_current)
-                return result
-
-    # Set frame back
-    context.scene.frame_set(last_frame_current)
-
-    # Set mode back
-    bpy.ops.object.mode_set(mode=last_mode, toggle=False)
-
-    # Handle possible error result of single frame export
-    return result
-
-def _write(self, context, filepath,
-           use_version,
-           use_selection,
-           use_apply_modifiers,
-           use_armature,
-           use_vertex_colors,
-           use_vertex_colors_alpha,
-           use_vertex_cleanup,
-           use_armature_pose,
-           use_weight_min,
-           use_weight_min_threshold):
-
-    num_verts = 0
-    num_verts_unique = 0
-    verts_unique = []
-    num_faces = 0
-    meshes = []
-    meshes_matrix = []
-    meshes_vgroup = []
-    objects = []
-    armature = None
-    bone_mapping = {}
-    materials = []
-
-    ob_count = 0
-    v_count = 0
-
-    # Check input objects, count them and convert mesh objects
-    for ob in bpy.data.objects:
-
-        # Take the first armature
-        if ob.type == 'ARMATURE' and use_armature and armature is None and len(ob.data.bones) > 0:
-            armature = ob
-            continue
-
-        if ob.type != 'MESH':
-            continue
-
-        # Skip meshes, which are unselected
-        if use_selection and not ob.select:
-            continue
-
-        # Set up modifiers whether to apply deformation or not
-        mod_states = []
-        for mod in ob.modifiers:
-            mod_states.append(mod.show_viewport)
-            if mod.type == 'ARMATURE':
-                mod.show_viewport = mod.show_viewport and use_armature_pose
-            else:
-                mod.show_viewport = mod.show_viewport and use_apply_modifiers
-
-        # to_mesh() applies enabled modifiers only
-        mesh = ob.to_mesh(scene=context.scene, apply_modifiers=True, settings='PREVIEW')
-
-        # Restore modifier settings
-        for i, mod in enumerate(ob.modifiers):
-            mod.show_viewport = mod_states[i]
-
-        # Skip invalid meshes
-        if len(mesh.vertices) < 3:
-            _skip_notice(ob.name, mesh.name, "Less than 3 vertices")
-            continue
-        if len(mesh.tessfaces) < 1:
-            _skip_notice(ob.name, mesh.name, "No faces")
-            continue
-        if len(ob.material_slots) < 1:
-            _skip_notice(ob.name, mesh.name, "No material")
-            continue
-        if not mesh.tessface_uv_textures:
-            _skip_notice(ob.name, mesh.name, "No UV texture, not unwrapped?")
-            continue
-
-        meshes.append(mesh)
-        meshes_matrix.append(ob.matrix_world)
-
-        if ob.vertex_groups:
-            meshes_vgroup.append(ob.vertex_groups)
-        else:
-            meshes_vgroup.append(None)
-
-        if use_vertex_cleanup:
-
-            # Retrieve verts which belong to a face
-            verts = []
-            for f in mesh.tessfaces:
-                for v in f.vertices:
-                    verts.append(v)
-
-            # Uniquify & sort
-            keys = {}
-            for e in verts:
-                keys[e] = 1
-            verts = list(keys.keys())
-
-        else:
-            verts = [v.index for v in mesh.vertices]
-
-        # Store vert sets, aligned to mesh objects
-        verts_unique.append(verts)
-
-        # As len(mesh.vertices) doesn't take unused verts into account, already count here
-        num_verts_unique += len(verts)
-
-        # Take quads into account!
-        for f in mesh.tessfaces:
-            if len(f.vertices) == 3:
-                num_faces += 1
-            else:
-                num_faces += 2
-
-        objects.append(ob.name)
-
-    if (num_verts or num_faces or len(objects)) == 0:
-        return "Nothing to export.\n" \
-               "Meshes must have at least:\n" \
-               "    3 vertices\n" \
-               "    1 face\n" \
-               "    1 material\n" \
-               "    UV mapping"
-
-    # There's valid data for export, create output file
-    try:
-        file = open(filepath, "w")
-    except IOError:
-        return "Could not open file for writing:\n%s" % filepath
-
-    # Write header
-    file.write("// XMODEL_EXPORT file in CoD model v%i format created with Blender v%s\n" \
-               % (int(use_version), bpy.app.version_string))
-
-    file.write("// Source file: %s\n" % bpy.data.filepath)
-    file.write("// Export time: %s\n\n" % datetime.now().strftime("%d-%b-%Y %H:%M:%S"))
-
-    if use_armature_pose:
-        file.write("// Posed model of frame %i\n\n" % bpy.context.scene.frame_current)
-
-    if use_weight_min:
-        file.write("// Minimum bone weight: %f\n\n" % use_weight_min_threshold)
-
-    file.write("MODEL\n")
-    file.write("VERSION %i\n" % int(use_version))
-
-    # Write armature data
-    if armature is None:
-
-        # Default rig
-        file.write("\nNUMBONES 1\n")
-        file.write("BONE 0 -1 \"tag_origin\"\n")
-
-        file.write("\nBONE 0\n")
-
-        if use_version == '5':
-            file.write("OFFSET 0.000000 0.000000 0.000000\n")
-            file.write("SCALE 1.000000 1.000000 1.000000\n")
-            file.write("X 1.000000 0.000000 0.000000\n")
-            file.write("Y 0.000000 1.000000 0.000000\n")
-            file.write("Z 0.000000 0.000000 1.000000\n")
-        else:
-            # Model format v6 has commas
-            file.write("OFFSET 0.000000, 0.000000, 0.000000\n")
-            file.write("SCALE 1.000000, 1.000000, 1.000000\n")
-            file.write("X 1.000000, 0.000000, 0.000000\n")
-            file.write("Y 0.000000, 1.000000, 0.000000\n")
-            file.write("Z 0.000000, 0.000000, 1.000000\n")
-
-    else:
-
-        # Either use posed armature bones for animation to model sequence export
-        if use_armature_pose:
-            bones = armature.pose.bones
-        # Or armature bones in rest pose for regular rigged models
-        else:
-            bones = armature.data.bones
-
-        file.write("\nNUMBONES %i\n" % len(bones))
-
-        # Get the armature object's orientation
-        a_matrix = armature.matrix_world
-
-        # Check for multiple roots, armature should have exactly one
-        roots = 0
-        for bone in bones:
-            if not bone.parent:
-                roots += 1
-        if roots != 1:
-            warning_string = "Warning: %i root bones found in armature object '%s'\n" \
-                             % (roots, armature.name)
-            print(warning_string)
-            file.write("// %s" % warning_string)
-
-        # Look up table for bone indices
-        bone_table = [b.name for b in bones]
-
-        # Write bone hierarchy table and create bone_mapping array for later use (vertex weights)
-        for i, bone in enumerate(bones):
-
-            if bone.parent:
-                try:
-                    bone_parent_index = bone_table.index(bone.parent.name)
-                except (ValueError):
-                    bone_parent_index = 0
-                    file.write("// Warning: \"%s\" not found in bone table, binding to root...\n"
-                               % bone.parent.name)
-            else:
-                bone_parent_index = -1
-
-            file.write("BONE %i %i \"%s\"\n" % (i, bone_parent_index, bone.name))
-            bone_mapping[bone.name] = i
-
-        # Write bone orientations
-        for i, bone in enumerate(bones):
-            file.write("\nBONE %i\n" % i)
-
-            # Using local tail for proper coordinates
-            b_tail = a_matrix * bone.tail_local
-
-            # TODO: Fix calculation/error: pose animation will use posebones, but they don't have tail_local!
-
-            # TODO: Fix rotation matrix calculation, calculation seems to be wrong...
-            #b_matrix = bone.matrix_local * a_matrix
-            #b_matrix = bone.matrix * a_matrix * bones[0].matrix.inverted()
-            #from mathutils import Matrix
-
-            # Is this the way to go? Or will it fix the root only, but mess up all other roll angles?
-            if i == 0:
-                b_matrix = ((1,0,0),(0,1,0),(0,0,1))
-            else:
-                b_matrix = a_matrix * bone.matrix_local
-                #from mathutils import Matrix
-                #b_matrix = bone.matrix_local * a_matrix * Matrix(((1,-0,0),(0,0,-1),(-0,1,0)))
-                
-            if use_version == '5':
-                file.write("OFFSET %.6f %.6f %.6f\n" % (b_tail[0], b_tail[1], b_tail[2]))
-                file.write("SCALE 1.000000 1.000000 1.000000\n") # Is this even supported by CoD?
-                file.write("X %.6f %.6f %.6f\n" % (b_matrix[0][0], b_matrix[1][0], b_matrix[2][0]))
-                file.write("Y %.6f %.6f %.6f\n" % (b_matrix[0][1], b_matrix[1][1], b_matrix[2][1]))
-                file.write("Z %.6f %.6f %.6f\n" % (b_matrix[0][2], b_matrix[1][2], b_matrix[2][2]))
-            else:
-                file.write("OFFSET %.6f, %.6f, %.6f\n" % (b_tail[0], b_tail[1], b_tail[2]))
-                file.write("SCALE 1.000000, 1.000000, 1.000000\n")
-                file.write("X %.6f, %.6f, %.6f\n" % (b_matrix[0][0], b_matrix[1][0], b_matrix[2][0]))
-                file.write("Y %.6f, %.6f, %.6f\n" % (b_matrix[0][1], b_matrix[1][1], b_matrix[2][1]))
-                file.write("Z %.6f, %.6f, %.6f\n" % (b_matrix[0][2], b_matrix[1][2], b_matrix[2][2]))
-
-    # Write vertex data
-    file.write("\nNUMVERTS %i\n" % num_verts_unique)
-
-    for i, me in enumerate(meshes):
-
-        # Get the right object matrix for mesh
-        mesh_matrix = meshes_matrix[i]
-
-        # Get bone influences per vertex
-        if armature is not None and meshes_vgroup[i] is not None:
-
-            groupNames, vWeightList = meshNormalizedWeights(meshes_vgroup[i],
-                                                            me,
-                                                            use_weight_min,
-                                                            use_weight_min_threshold
-                                                            )
-            # Get bones by vertex_group names, bind to root if can't find one 
-            groupIndices = [bone_mapping.get(g, -1) for g in groupNames]
-
-            weight_group_list = []
-            for weights in vWeightList:
-                weight_group_list.append(sorted(zip(weights, groupIndices), reverse=True))
-
-        # Use uniquified vert sets and count the verts
-        for i_vert, vert in enumerate(verts_unique[i]):
-            v = me.vertices[vert]
-
-            # Calculate global coords
-            x = mesh_matrix[0][0] * v.co[0] + \
-                mesh_matrix[0][1] * v.co[1] + \
-                mesh_matrix[0][2] * v.co[2] + \
-                mesh_matrix[0][3]
-
-            y = mesh_matrix[1][0] * v.co[0] + \
-                mesh_matrix[1][1] * v.co[1] + \
-                mesh_matrix[1][2] * v.co[2] + \
-                mesh_matrix[1][3]
-
-            z = mesh_matrix[2][0] * v.co[0] + \
-                mesh_matrix[2][1] * v.co[1] + \
-                mesh_matrix[2][2] * v.co[2] + \
-                mesh_matrix[2][3]
-                
-            #print("%.6f %.6f %.6f single calced xyz\n%.6f %.6f %.6f mat mult" % (x, y, z, ))
-
-            file.write("VERT %i\n" % (i_vert + v_count))
-
-            if use_version == '5':
-                file.write("OFFSET %.6f %.6f %.6f\n" % (x, y, z))
-            else:
-                file.write("OFFSET %.6f, %.6f, %.6f\n" % (x, y, z))
-
-            # Write bone influences
-            if armature is None or meshes_vgroup[i] is None:
-                file.write("BONES 1\n")
-                file.write("BONE 0 1.000000\n\n")
-            else:
-                cache = ""
-                c_bones = 0
-
-                for weight, bone_index in weight_group_list[v.index]:
-                    if (use_weight_min and round(weight, 6) < use_weight_min_threshold) or \
-                       (not use_weight_min and round(weight, 6) == 0):
-                        # No (more) bones with enough weight, totalweight of 0 would lead to error
-                        break
-                    cache += "BONE %i %.6f\n" % (bone_index, weight)
-                    c_bones += 1
-
-                if c_bones == 0:
-                    warning_string = "Warning: No bone influence found for vertex %i, binding to bone %i\n" \
-                                     % (v.index, bone_index)
-                    print(warning_string)
-                    file.write("// %s" % warning_string)
-                    file.write("BONES 1\n")
-                    file.write("BONE %i 0.000001\n\n" % bone_index) # HACK: Is a minimum weight a good idea?
-                else:
-                    file.write("BONES %i\n%s\n" % (c_bones, cache))
-
-        v_count += len(verts_unique[i]);
-
-    # TODO: Find a better way to keep track of the vertex index?
-    v_count = 0
-
-    # Prepare material array
-    for me in meshes:
-        for f in me.tessfaces:
-            try:
-                mat = me.materials[f.material_index]
-            except (IndexError):
-                # Mesh has no material with this index
-                # Note: material_index is never None (will be 0 instead)
-                continue
-            else:
-                if mat not in materials:
-                    materials.append(mat)
-
-    # Write face data
-    file.write("\nNUMFACES %i\n" % num_faces)
-
-    for i_me, me in enumerate(meshes):
-
-        #file.write("// Verts:\n%s\n" % list(enumerate(verts_unique[i_me])))
-
-        for f in me.tessfaces:
-
-            try:
-                mat = me.materials[f.material_index]
-
-            except (IndexError):
-                mat_index = 0
-
-                warning_string = "Warning: Assigned material with index %i not found, falling back to first\n" \
-                                  % f.material_index
-                print(warning_string)
-                file.write("// %s" % warning_string)
-
-            else:
-                try:
-                    mat_index = materials.index(mat)
-
-                except (ValueError):
-                    mat_index = 0
-
-                    warning_string = "Warning: Material \"%s\" not mapped, falling back to first\n" \
-                                      % mat.name
-                    print(warning_string)
-                    file.write("// %s" % warning_string)
-
-            # Support for vertex colors
-            if me.tessface_vertex_colors:
-                col = me.tessface_vertex_colors.active.data[f.index]
-
-            # Automatic triangulation support
-            f_v_orig = [v for v in enumerate(f.vertices)]
-
-            if len(f_v_orig) == 3:
-                f_v_iter = (f_v_orig[2], f_v_orig[1], f_v_orig[0]), # HACK: trailing comma to force a tuple
-            else:
-                f_v_iter = (f_v_orig[2], f_v_orig[1], f_v_orig[0]), (f_v_orig[3], f_v_orig[2], f_v_orig[0])
-
-            for iter in f_v_iter:
-
-                # TODO: Test material# export (v5 correct?)
-                if use_version == '5':
-                    file.write("TRI %i %i 0 1\n" % (ob_count, mat_index))
-                else:
-                    file.write("TRI %i %i 0 0\n" % (ob_count, mat_index))
-
-                for vi, v in iter:
-
-                    no = me.vertices[v].normal # Invert? Orientation seems to have no effect...
-
-                    uv = me.tessface_uv_textures.active
-                    uv1 = uv.data[f.index].uv[vi][0]
-                    uv2 = 1 - uv.data[f.index].uv[vi][1] # Flip!
-
-                    #if 0 > uv1 > 1 
-                    # TODO: Warn if accidentally tiling ( uv <0 or >1 )
-
-                    # Remap vert indices used by face
-                    if use_vertex_cleanup:
-                        vert_new = verts_unique[i_me].index(v) + v_count
-                        #file.write("// %i (%i) --> %i\n" % (v+v_count, v, vert_new))
-                    else:
-                        vert_new = v + v_count
-
-                    if use_version == '5':
-                        file.write("VERT %i %.6f %.6f %.6f %.6f %.6f\n" \
-                                   % (vert_new, uv1, uv2, no[0], no[1], no[2]))
-                    else:
-                        file.write("VERT %i\n" % vert_new)
-                        file.write("NORMAL %.6f %.6f %.6f\n" % (no[0], no[1], no[2]))
-
-                        if me.tessface_vertex_colors and use_vertex_colors:
-
-                            if vi == 0:
-                                c = col.color1
-                            elif vi == 1:
-                                c = col.color2
-                            elif vi == 2:
-                                c = col.color3
-                            else:
-                                c = col.color4
-
-                            if use_vertex_colors_alpha:
-
-                                # Turn RGB into grayscale (luminance conversion)
-                                c_lum = c[0] * 0.3 + c[1] * 0.59 + c[2] * 0.11
-                                file.write("COLOR 1.000000 1.000000 1.000000 %.6f\n" % c_lum)
-                            else:
-                                file.write("COLOR %.6f %.6f %.6f 1.000000\n" % (c[0], c[1], c[2]))
-
-                        else:
-                            file.write("COLOR 1.000000 1.000000 1.000000 1.000000\n")
-
-                        file.write("UV 1 %.6f %.6f\n" % (uv1, uv2))
-
-        # Note: Face types (tris/quads) have nothing to do with vert indices!
-        if use_vertex_cleanup:
-            v_count += len(verts_unique[i_me])
-        else:
-            v_count += len(me.vertices)
-
-        ob_count += 1
-
-    # Write object data
-    file.write("\nNUMOBJECTS %i\n" % len(objects))
-
-    for i_ob, ob in enumerate(objects):
-        file.write("OBJECT %i \"%s\"\n" % (i_ob, ob))
-
-    # Static material string
-    material_string = ("COLOR 0.000000 0.000000 0.000000 1.000000\n"
-                       "TRANSPARENCY 0.000000 0.000000 0.000000 1.000000\n"
-                       "AMBIENTCOLOR 0.000000 0.000000 0.000000 1.000000\n"
-                       "INCANDESCENCE 0.000000 0.000000 0.000000 1.000000\n"
-                       "COEFFS 0.800000 0.000000\n"
-                       "GLOW 0.000000 0\n"
-                       "REFRACTIVE 6 1.000000\n"
-                       "SPECULARCOLOR -1.000000 -1.000000 -1.000000 1.000000\n"
-                       "REFLECTIVECOLOR -1.000000 -1.000000 -1.000000 1.000000\n"
-                       "REFLECTIVE -1 -1.000000\n"
-                       "BLINN -1.000000 -1.000000\n"
-                       "PHONG -1.000000\n\n"
-                       )
-
-    if len(materials) > 0:
-        file.write("\nNUMMATERIALS %i\n" % len(materials))
-
-        for i_mat, mat in enumerate(materials):
-
-            try:
-                for i_ts, ts in enumerate(mat.texture_slots):
-
-                    # Skip empty slots and disabled textures
-                    if not ts or not mat.use_textures[i_ts]:
-                        continue
-
-                    # Image type and Color map? If yes, add to material array and index
-                    if ts.texture.type == 'IMAGE' and ts.use_map_color_diffuse:
-
-                        # Pick filename of the first color map
-                        imagepath = ts.texture.image.filepath
-                        imagename = os.path.split(imagepath)[1]
-                        if len(imagename) == 0:
-                            imagename = "untitled"
-                        break
-                else:
-                    raise(ValueError)
-
-            except:
-                imagename = "no color diffuse map found"
-
-            # Material can be assigned and None
-            if mat:
-                mat_name = mat.name
-                mat_shader = mat.diffuse_shader.capitalize()
-            else:
-                mat_name = "None"
-                mat_shader = "Lambert"
-
-            if use_version == '5':
-                file.write("MATERIAL %i \"%s\"\n" % (i_mat, imagename))
-                # or is it mat.name at filename?
-            else:
-                file.write("MATERIAL %i \"%s\" \"%s\" \"%s\"\n" % (
-                           i_mat,
-                           mat_name,
-                           mat_shader,
-                           imagename
-                           ))
-                file.write(material_string)
-    else:
-        # Write a default material
-        # Should never happen, nothing to export / mesh without material exceptions already caught
-        file.write("\nNUMMATERIALS 1\n")
-        if use_version == '5':
-            file.write("MATERIAL 0 \"default.tga\"\n")
-        else:
-            file.write("MATERIAL 0 \"$default\" \"Lambert\" \"untitled\"\n")
-            file.write(material_string)
-
-    # Close to flush buffers!
-    file.close()
-
-    # Remove meshes, which were made by to_mesh()
-    for mesh in meshes:
-        mesh.user_clear()
-        bpy.data.meshes.remove(mesh)    
-
-    # Quit with no errors
-    return
-
-# Taken from export_fbx.py by Campbell Barton
-# Modified to accept vertex_groups directly instead of mesh object
-def BPyMesh_meshWeight2List(vgroup, me):
-
-    """ Takes a mesh and return its group names and a list of lists, one list per vertex.
-    aligning the each vert list with the group names, each list contains float value for the weight.
-    These 2 lists can be modified and then used with list2MeshWeight to apply the changes.
-    """
-
-    # Clear the vert group.
-    groupNames = [g.name for g in vgroup]
-    len_groupNames = len(groupNames)
-
-    if not len_groupNames:
-        # no verts? return a vert aligned empty list
-        #return [[] for i in range(len(me.vertices))], []
-        return [], []
-
-    else:
-        vWeightList = [[0.0] * len_groupNames for i in range(len(me.vertices))]
-
-    for i, v in enumerate(me.vertices):
-        for g in v.groups:
-            # possible weights are out of range
-            index = g.group
-            if index < len_groupNames:
-                vWeightList[i][index] = g.weight
-
-    return groupNames, vWeightList
-
-def meshNormalizedWeights(vgroup, me, weight_min, weight_min_threshold):
-
-    groupNames, vWeightList = BPyMesh_meshWeight2List(vgroup, me)
-
-    if not groupNames:
-        return [], []
-
-    for vWeights in vWeightList:
-        tot = 0.0
-        for w in vWeights:
-            if weight_min and w < weight_min_threshold:
-                w = 0.0
-            tot += w
-
-        if tot:
-            for j, w in enumerate(vWeights):
-                vWeights[j] = w / tot
-
-    return groupNames, vWeightList
-
-def _skip_notice(ob_name, mesh_name, notice):
-    print("\nSkipped object \"%s\" (mesh \"%s\"): %s" % (ob_name, mesh_name, notice))
diff --git a/release/scripts/addons_contrib/io_scene_cod/import_xanim.py b/release/scripts/addons_contrib/io_scene_cod/import_xanim.py
deleted file mode 100644
index 4d79034..0000000
--- a/release/scripts/addons_contrib/io_scene_cod/import_xanim.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Blender-CoD: Blender Add-On for Call of Duty modding
-Version: alpha 3
-
-Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
-
-http://code.google.com/p/blender-cod/
-
-TODO
-- Implement xanim import (apply anim data to the armature of a loaded model)
-
-"""
-
-def load(self, context, **keywords):
-
-    #filepath = os.fsencode(filepath)
-
-    return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/io_scene_cod/import_xmodel.py b/release/scripts/addons_contrib/io_scene_cod/import_xmodel.py
deleted file mode 100644
index 6f862e0..0000000
--- a/release/scripts/addons_contrib/io_scene_cod/import_xmodel.py
+++ /dev/null
@@ -1,392 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Blender-CoD: Blender Add-On for Call of Duty modding
-Version: alpha 3
-
-Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
-
-http://code.google.com/p/blender-cod/
-
-NOTES
-- Code is in early state of development and work in progress!
-- Importing rigs from XMODEL_EXPORT v6 works, but the code is really messy.
-
-TODO
-- Implement full xmodel import
-
-"""
-
-import os
-import bpy
-from mathutils import *
-import math
-#from mathutils.geometry import tesselate_polygon
-#from io_utils import load_image, unpack_list, unpack_face_list
-
-def round_matrix_3x3(mat, precision=6):
-    return Matrix(((round(mat[0][0],precision), round(mat[0][1],precision), round(mat[0][2],precision)),
-                (round(mat[1][0],precision), round(mat[1][1],precision), round(mat[1][2],precision)),
-                (round(mat[2][0],precision), round(mat[2][1],precision), round(mat[2][2],precision))))
-
-def load(self, context, filepath=""):
-
-    filepath = os.fsencode(filepath)
-
-    test_0 = []
-    test_1 = []
-    test_2 = []
-    test_3 = []
-
-    state = 0
-
-    # placeholders
-    vec0 = Vector((0.0, 0.0, 0.0))
-    mat0 = Matrix(((0.0, 0.0, 0.0),(0.0, 0.0, 0.0),(0.0, 0.0, 0.0)))
-
-    numbones = 0
-    numbones_i = 0
-    bone_i = 0
-    bone_table = []
-    numverts = 0
-    vert_i = 0
-    vert_table = [] # allocate table? [0]*numverts
-    face_i = 0
-    face_tmp = []
-    face_table = []
-    bones_influencing_num = 0
-    bones_influencing_i = 0
-    numfaces = 0
-
-    print("\nImporting %s" % filepath)
-
-    try:
-        file = open(filepath, "r")
-    except IOError:
-        return "Could not open file for reading:\n%s" % filepath
-
-    for line in file:
-        line = line.strip()
-        line_split = line.split()
-
-        # Skip empty and comment lines
-        if not line or line[0] == "/":
-            continue
-
-        elif state == 0 and line_split[0] == "MODEL":
-            state = 1
-
-        elif state == 1 and line_split[0] == "VERSION":
-            if line_split[1] != "6":
-                error_string = "Unsupported version: %s" % line_split[1]
-                print("\n%s" % error_string)
-                return error_string
-            state = 2
-
-        elif state == 2 and line_split[0] == "NUMBONES":
-            numbones = int(line_split[1])
-            state = 3
-
-        elif state == 3 and line_split[0] == "BONE":
-            if numbones_i != int(line_split[1]):
-                error_string = "Unexpected bone number: %s (expected %i)" % (line_split[1], numbones_i)
-                print("\n%s" % error_string)
-                return error_string
-            bone_table.append((line_split[3][1:-1], int(line_split[2]), vec0, mat0))
-            test_0.append(line_split[3][1:-1])
-            test_1.append(int(line_split[2]))
-            if numbones_i >= numbones-1:
-                state = 4
-            else:
-                numbones_i += 1
-
-        elif state == 4 and line_split[0] == "BONE":
-            bone_num = int(line_split[1])
-            if bone_i != bone_num:
-                error_string = "Unexpected bone number: %s (expected %i)" % (line_split[1], bone_i)
-                print("\n%s" % error_string)
-                return error_string
-            state = 5
-
-        elif state == 5 and line_split[0] == "OFFSET":
-            # remove commas - line_split[#][:-1] would also work, but isn't as save
-            line_split = line.replace(",", "").split()
-
-            # should we check for len(line_split) to ensure we got enough elements?
-            # Note: we can't assign a new vector to tuple object, we need to change each value
-
-            bone_table[bone_i][2].xyz = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-            #print("\nPROBLEMATIC: %s" % bone_table[bone_i][2])
-            #NO ERROR HERE, but for some reason the whole table will contain the same vectors
-            #bone_table[bone_i][2][0] = float(line_split[1])
-            #bone_table[bone_i][2][1] = float(line_split[2])
-            #bone_table[bone_i][2][2] = float(line_split[3])
-            test_2.append(Vector((float(line_split[1]),float(line_split[2]),float(line_split[3]))))
-
-            state = 6
-
-        elif state == 6 and line_split[0] == "SCALE":
-            # always 1.000000?! no processing so far...
-            state = 7
-
-        elif state == 7 and line_split[0] == "X":
-            line_split = line.replace(",", "").split()
-            bone_table[bone_i][3][0] = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-
-            """ Use something like this:
-            bone.align_roll(targetmatrix[2])
-            roll = roll%360 #nicer to have it 0-359.99...
-            """
-            m_col = []
-            m_col.append((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-            
-            state = 8
-
-        elif state == 8 and line_split[0] == "Y":
-            line_split = line.replace(",", "").split()
-            bone_table[bone_i][3][1] = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-            
-            m_col.append((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-
-            state = 9
-
-        elif state == 9 and line_split[0] == "Z":
-            line_split = line.replace(",", "").split()
-            vec_roll = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-            ##bone_table[bone_i][3][2] = vec_roll
-            #print("bone_table: %s" % bone_table[bone_i][3][2])
-            
-            m_col.append((float(line_split[1]), float(line_split[2]), float(line_split[3])))
-
-            #test_3.append(Vector(vec_roll))
-            
-            test_3.append(m_col)
-            #print("test_3: %s\n\n" % test_3[:])
-
-            if bone_i >= numbones-1:
-                state = 10
-            else:
-                #print("\n---> Increasing bone: %3i" % bone_i)
-                #print("\t" + str(bone_table[bone_i][3]))
-                #print("\t" + str(bone_table[bone_i][0]))
-                bone_i += 1
-                state = 4
-
-        elif state == 10 and line_split[0] == "NUMVERTS":
-            numverts = int(line_split[1])
-            state = 11
-
-        elif state == 11 and line_split[0] == "VERT":
-            vert_num = int(line_split[1])
-            if vert_i != vert_num:
-                error_string = "Unexpected vertex number: %s (expected %i)" % (line_split[1], vert_i)
-                print("\n%s" % error_string)
-                return error_string
-            vert_i += 1
-            state = 12
-
-        elif state == 12 and line_split[0] == "OFFSET":
-            line_split = line.replace(",", "").split()
-            vert_table.append(Vector((float(line_split[1]), float(line_split[2]), float(line_split[3]))))
-            state = 13
-
-        elif state == 13 and line_split[0] == "BONES":
-            # TODO: process
-            bones_influencing_num = int(line_split[1])
-            state= 14
-
-        elif state == 14 and line_split[0] == "BONE":
-            # TODO: add bones to vert_table
-            if bones_influencing_i >= bones_influencing_num-1:
-                if vert_i >= numverts:
-                    state = 15
-                else:
-                    state = 11
-            else:
-                bones_influencing_i += 1
-                #state = 14
-
-        elif state == 15 and line_split[0] == "NUMFACES":
-            numfaces = int(line_split[1])
-            state = 16
-            
-        elif state == 16: #and line_split[0] == "TRI":
-            #face_i += 1
-            face_tmp = []
-            state = 17
-            
-        elif (state == 17 or state == 21 or state == 25) and line_split[0] == "VERT":
-            #print("face_tmp length: %i" % len(face_tmp))
-            face_tmp.append(int(line_split[1]))
-            state += 1
-        
-        elif (state == 18 or state == 22 or state == 26) and line_split[0] == "NORMAL":
-            state += 1
-            
-        elif (state == 19 or state == 23 or state == 27) and line_split[0] == "COLOR":
-            state += 1
-            
-        elif (state == 20 or state == 24 or state == 28) and line_split[0] == "UV":
-            state += 1
-        
-        elif state == 29:
-
-            #print("Adding face: %s\n%i faces so far (of %i)\n" % (str(face_tmp), face_i, numfaces))
-            face_table.append(face_tmp)
-            if (face_i >= numfaces - 1):
-                state = 30
-            else:
-                face_i += 1
-                face_tmp = []
-                state = 17
-                
-        elif state > 15 and state < 30 and line_split[0] == "NUMOBJECTS":
-            print("Bad numfaces, terminated loop\n")
-            state = 30
-            
-        elif state == 30:
-            print("Adding mesh!")
-            me = bpy.data.meshes.new("pymesh")
-            me.from_pydata(vert_table, [], face_table)
-            me.update()
-            ob = bpy.data.objects.new("Py-Mesh", me)
-            bpy.context.scene.objects.link(ob)
-            
-            state = 31
-
-        else: #elif state == 16:
-            #UNDONE
-            print("eh? state is %i line: %s" % (state, line))
-            pass
-
-        #print("\nCurrent state=" + str(state) + "\nLine:" + line)
-
-    #print("\n" + str(list(bone_table)) + "\n\n" + str(list(vert_table)))
-
-    #createRig(context, "Armature", Vector((0,0,0)), bone_table)
-
-    name = "Armature"
-    origin = Vector((0,0,0))
-    boneTable = bone_table
-
-    # If no context object, an object was deleted and mode is 'OBJECT' for sure
-    if context.object: #and context.mode is not 'OBJECT':
-
-        # Change mode, 'cause modes like POSE will lead to incorrect context poll
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-    # Create armature and object
-    bpy.ops.object.add(
-        type='ARMATURE', 
-        enter_editmode=True,
-        location=origin)
-    ob = bpy.context.object
-    ob.show_x_ray = True
-    ob.name = name
-    amt = ob.data
-    amt.name = name + "Amt"
-    #amt.show_axes = True
-
-    # Create bones
-    bpy.ops.object.mode_set(mode='EDIT')
-    #for (bname, pname, vector, matrix) in boneTable:
-    #i = 0
-    for (t0, t1, t2, t3) in zip(test_0, test_1, test_2, test_3):
-
-        t3 = Matrix(t3)
-
-        bone = amt.edit_bones.new(t0)
-        if t1 != -1:
-            parent = amt.edit_bones[t1]
-            bone.parent = parent
-            bone.head = parent.tail
-
-            bone.align_roll((parent.matrix.to_3x3()*t3)[2])
-            #local_mat = parent.matrix.to_3x3() * t3()
-            #bone.align_roll(local_mat[2])
-            from math import degrees
-            print("t3[2]: %s\nroll: %f\n---------" % (t3.col[2], degrees(bone.roll)))
-            #bone.roll = math.radians(180 - math.degrees(bone.roll))
-            #print("###\nalign_roll: %s\nroll: %.2f\ntest_3:%s" % (t3, math.degrees(bone.roll), list(test_3)))
-            bone.use_connect = True
-        else:
-            bone.head = (0,0,0)
-            rot = Matrix.Translation((0,0,0))	# identity matrix
-            bone.align_roll(t3[2])
-            bone.use_connect = False
-        bone.tail = t2
-
-    file.close()
-
-"""
-def createRig(context, name, origin, boneTable):
-
-    # If no context object, an object was deleted and mode is 'OBJECT' for sure
-    if context.object: #and context.mode is not 'OBJECT':
-
-        # Change mode, 'cause modes like POSE will lead to incorrect context poll
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-    # Create armature and object
-    bpy.ops.object.add(
-        type='ARMATURE', 
-        enter_editmode=True,
-        location=origin)
-    ob = bpy.context.object
-    ob.show_x_ray = True
-    ob.name = name
-    amt = ob.data
-    amt.name = name + "Amt"
-    #amt.show_axes = True
-
-    # Create bones
-    bpy.ops.object.mode_set(mode='EDIT')
-    #for (bname, pname, vector, matrix) in boneTable:
-    #i = 0
-    for i in range(len(test_0)):
-        t0 = test_0[i]
-        t1 = test_1[i]
-        t2 = test_2[i]
-        t3 = test_3[i]
-
-        bone = amt.edit_bones.new(t0)
-        if t1 != -1:
-            parent = amt.edit_bones[t1]
-            bone.parent = parent
-            bone.head = parent.tail
-            bone.use_connect = True
-            bone.align_roll(t3)
-            #print("align_roll: %s\nroll: %.2f" % (t3, math.degrees(bone.roll)))
-            #(trans, rot, scale) = parent.matrix.decompose()
-        else:
-            bone.head = (0,0,0)
-            rot = Matrix.Translation((0,0,0))	# identity matrix
-            bone.use_connect = False
-        #bone.tail = Vector(vector) * rot + bone.head
-        bone.tail = t2
-        #bone.tail = boneTable[i][2] #passing boneTable as parameter seems to break it :(
-        #i += 1
-
-    #outfile.write("\n%s" % str(boneTable))
-
-    bpy.ops.object.mode_set(mode='OBJECT')
-    return ob
-"""
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt b/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt
deleted file mode 100644
index 115ae25..0000000
--- a/release/scripts/addons_contrib/io_scene_ms3d/__README__.txt
+++ /dev/null
@@ -1,199 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-
-
-# ##### BEGIN COPYRIGHT BLOCK #####
-#
-# initial script copyright (c)2011 Alexander Nussbaumer
-#
-# ##### END COPYRIGHT BLOCK #####
-
-
-files:
-__README__.txt
-__init__.py
-ms3d_export.py
-ms3d_import.py
-ms3d_spec.py
-ms3d_utils.py
-
-
-description:
-__README__.txt      : this file
-                    § Blender maintenance
-
-__init__.py         : entry point for blender plugins
-                      initialize and registers/unregisters plugin functions
-                    § Blender maintenance
-
-ms3d_export.py      : entry point for exporter
-                      functions to bring Blender content in a correct way to MilkShape
-                    § Blender maintenance
-                    § Blender -> MilkShape3D maintenance
-
-ms3d_import.py      : entry point for importer
-                      functions to bring MilkShape content in a correct way to Blender
-                    § Blender maintenance
-                    § MilkShape3D -> Blender maintenance
-
-ms3d_spec.py        : objects and structures that specified a MilkShape3D file
-                      base functions to write/read its objects itself
-                    § MilkShape maintenance
-
-ms3d_utils.py       : most of the strings used in the addon to have a central point for optional internationalization
-                      functions that are used by importer and exporter
-                    § Blender maintenance
-                    § Blender -> MilkShape3D maintenance
-                    § MilkShape3D -> Blender maintenance
-
-
-known issues:
-  importer issues:
-    - does not import keyframes
-
-  exporter issues:
-    - does only export the first existing material, if more than one material is used per mesh
-    - does only export the first existing UV texture coordinates, if more than one UV texture is used per mesh
-    - does not export bones
-    - does not export joints
-    - does not export keyframes
-    - does not export comments (will never be supported - blender doesn't have similar stuff)
-
-
-todo:
-- change internal data structure for more performance on searching vertex indices and double vertices
-- add support for bones and joints in exporter
-- add support for keyframes
-
-
-
-changelog:
-changed: (0, 3, 8),
-mod: changed matrix handling, in account to matrix changes since blender rev.42816; for a while with side-by-side implementation by checking 'bpy.app.build_revision'
-del: removed unused option for export FuturePinball animation script (i will make an extra addon future_pinball_tool collection)
-
-changed: (0, 3, 6, "beta (2011-12-13 00:00)"),
-mod: exporter use an other logic to reduces the total number of smooth groups
-mod: correct "version" and "blender" in __init__.py
-fix: division by zero in importer
-mod: import armature bones (head-tail to tail-head + additional post process to connect for better auto IK handling)
-add: import bones and joints with armature modifier
-mod: changed mesh generation (take only used vertices, instead of take all vertices and delete deserted in an extra pass)
-
-changed: (0, 3, 4, "beta (2011-12-09 00:00)"),
-fix: exporter forgot to change changed vertex_ex handling in ms3d_exporter.py
-add: importer adds ms3d_flags custom properties for some objects
-fix: importer corrects the roll of blender bones
-add: importer adds ms3d_comment custom properties for modelComment (to a blender empty), groupComments (to its blender meshes), materialComments (to its blender materials) and jointComments (to its blender bones)
-add: importer adds raw data ms3d_ambient and ms3d_emissive custom properties to material, because blender does not have an exact similar color definition
-fix: ms3d_spec, modelComment, only one comment is allowed and a modelComment does not have an index value
-mod: droped most of DEBUG_... code
-mod: class __init__(self, ...) default parameter handling
-mod: droped some tuple constructions: replaced with regular expression "tuple[(].*[[](.*)[]].*[)]" with "(\1)"
-
-changed: (0, 3, 3, "beta (2011-12-02 00:00)")
-add: importer adds additionally smoothingGroups as vertex_groups "ms3d_smoothingGroup{1...32}"
-fix: export smoothingGroups start index to 1
-mod: some blender like modifications ('ENUM' instead "ENUM" on enum values)
-mod: some pep8 like modifications (lay-out)
-mod: some pep8 like modifications (moved import in the right order)
-mod: some pep8 like modifications ("foo(arg, value = 0)" to "foo(arg, value=0)")
-mod: some pep8 like modifications (drop "if (sequence) and (len(sequence) > 0):..." to "if (sequence):...")
-mod: bit more specific exception blocks
-
-
-changed: (0, 3, 3, "beta (2011-12-01 00:00)")
-mod: if "name" in somedict: result = somedict["name"]  to  result = somedict.get("name") if result is not None: (comment by campbellbarton)
-mod: "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=29404"
-
-
-changed: (0, 3, 3, "beta (2011-11-29 00:00)")
-mod: reuse existing data (now optional)
-fix: reuse existing data (now ignores data if library is not none)
-add: import process adds custom_properties with raw data (naming and some others, if expecting lost in translation)
-
-
-changed: (0, 3, 2, "beta (2011-11-27 00:00)")
-mod: mered ms3d_base.py to ms3d_utils.py (and droped ms3d_base.py)
-mod: moved exclusive importer stuff to ms3d_import.py (renamed BlenderFromMs3d... to ...)
-mod: moved exclusive exporter stuff to ms3d_export.py (renamed Ms3dFromBlender... to ...)
-fix: import object namings (keep track possible name collisions of ms3d and blender objects on non empty blender scenes - may have same names, but different content)
-add: import to group option
-
-changed: (0, 3, 1, "beta (2011-11-25 00:00)")
-dev: import bones (not finished yet)
-fix: import a material only once, if it is used many times
-fix: export materials (all meshes got the same material)
-fix: exception in verbose mode (on older ms3d versions with no extended datablocks)
-
-changed: (0, 3, 0, "beta 3b (2011-11-19 00:00)").
-mod: exception raise to pass the exception to the GUI
-fix: exception if mesh has no material
-add: import diffuse / alpha texture file to material (to material and uv texture)
-add: export diffuse / alpha texture file name from material (or diffuse from uv texture, if material does not have one)
-mod: metric setup on import (bigger clip end value)
-
-changed: (0, 2, 3, "beta_2a (2011-11-15 00:00)").
-add: viewport adjustment for import to metric
-mod: import / export scale; (reported by AtmanActive, Sun Nov 13, 2011 9:41 pm)
-fix: layer handling; bug (reported by AtmanActive, Sun Nov 13, 2011 9:41 pm)
-fix: all faces/vertices are now selected again after import
-
-changed: (0, 2, 201111112130, "beta_2").
-add: export smoothing groups (from linked faces)
-add: import smoothing groups (as linked faces)
-add: import groups (as meshes)
-fix: export ms3d_triangle_t.groupIndex
-add: mark optional part if not available (all value to "None")
-add: draw() for option makeup
-
-20111101
-changed: (0, 1, 201111011600).
-
-
-installation instruction:
-  - copy the "io_ms3d" folder to <Blender>/2.60/scripts/addons
-  - open blender
-  - File | User Preferences | Addons | Import-Export
-  - enable "Import-Export: MilkShape3D MS3D format (.ms3d)"
-
-# To support reload properly, try to access a package var, if it's there, reload everything
-if ("bpy" in locals()):
-    import imp
-    #if "ms3d_export" in locals():
-    #    imp.reload(ms3d_export)
-    #if "ms3d_import" in locals():
-    #    imp.reload(ms3d_import)
-    #if "ms3d_spec" in locals():
-    #    imp.reload(ms3d_spec)
-    #if "ms3d_utils" in locals():
-    #    imp.reload(ms3d_utils)
-    pass
-
-else:
-    #from . import ms3d_export
-    #from . import ms3d_import
-    #from . import ms3d_spec
-    #from . import ms3d_utils
-    pass
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/__init__.py b/release/scripts/addons_contrib/io_scene_ms3d/__init__.py
deleted file mode 100644
index c9763d6..0000000
--- a/release/scripts/addons_contrib/io_scene_ms3d/__init__.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-        "name": "MilkShape3D MS3D format (.ms3d)",
-        "description": "Import / Export MilkShape3D MS3D files"
-                " (conform with v1.8.4)",
-        "author": "Alexander Nussbaumer",
-        "version": (0, 3, 8),
-        "blender": (2, 60, 0),
-        "location": "File > Import-Export",
-        "warning": "[2012-01-17] side-by-side implementation for Matrix handling around rev.42816",
-        "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
-                "Scripts/Import-Export/MilkShape3D_MS3D",
-        "tracker_url": "http://projects.blender.org/tracker/index.php"\
-                "?func=detail&aid=29404",
-        "category": 'Import-Export',
-        }
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-
-
-# ##### BEGIN COPYRIGHT BLOCK #####
-#
-# initial script copyright (c)2011 Alexander Nussbaumer
-#
-# ##### END COPYRIGHT BLOCK #####
-
-
-# To support reload properly, try to access a package var,
-# if it's there, reload everything
-if ("bpy" in locals()):
-    import imp
-    if "ms3d_utils" in locals():
-        imp.reload(ms3d_utils)
-    if "ms3d_export" in locals():
-        imp.reload(ms3d_export)
-    if "ms3d_import" in locals():
-        imp.reload(ms3d_import)
-    pass
-
-else:
-    from . import ms3d_utils
-    from . import ms3d_export
-    from . import ms3d_import
-    pass
-
-
-#import blender stuff
-import bpy
-import bpy_extras
-
-
-###############################################################################
-# registration
-def menu_func_import(self, context):
-    self.layout.operator(
-            ms3d_import.ImportMS3D.bl_idname,
-            text=ms3d_utils.TEXT_OPERATOR
-            )
-
-
-def menu_func_export(self, context):
-    self.layout.operator(
-            ms3d_export.ExportMS3D.bl_idname,
-            text=ms3d_utils.TEXT_OPERATOR
-            )
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_file_export.append(menu_func_export)
-    bpy.types.INFO_MT_file_import.append(menu_func_import)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_file_export.remove(menu_func_export)
-    bpy.types.INFO_MT_file_import.remove(menu_func_import)
-
-
-###############################################################################
-# global entry point
-if (__name__ == "__main__"):
-    register()
-
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py
deleted file mode 100644
index 5efa57f..0000000
--- a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py
+++ /dev/null
@@ -1,732 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-
-
-# ##### BEGIN COPYRIGHT BLOCK #####
-#
-# initial script copyright (c)2011 Alexander Nussbaumer
-#
-# ##### END COPYRIGHT BLOCK #####
-
-
-#import python stuff
-import io
-import math
-import mathutils
-import os
-import sys
-import time
-
-
-# To support reload properly, try to access a package var,
-# if it's there, reload everything
-if ("bpy" in locals()):
-    import imp
-    if "ms3d_spec" in locals():
-        imp.reload(ms3d_spec)
-    if "ms3d_utils" in locals():
-        imp.reload(ms3d_utils)
-    pass
-
-else:
-    from . import ms3d_spec
-    from . import ms3d_utils
-    pass
-
-
-#import blender stuff
-import bpy
-import bpy_extras.io_utils
-
-from bpy.props import (
-        BoolProperty,
-        EnumProperty,
-        FloatProperty,
-        StringProperty,
-        )
-
-
-# registered entry point export
-class ExportMS3D(
-        bpy.types.Operator,
-        bpy_extras.io_utils.ExportHelper
-        ):
-    """Save a MilkShape3D MS3D File"""
-
-    bl_idname = "io_scene_ms3d.ms3d_export"
-    bl_label = "Export MS3D"
-    bl_description = "Export to a MS3D file format (.ms3d)"
-    bl_options = {'PRESET'}
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-
-    filename_ext = ms3d_utils.FILE_EXT
-    filter_glob = StringProperty(
-            default=ms3d_utils.FILE_FILTER,
-            options={'HIDDEN'}
-            )
-
-    filepath = StringProperty(subtype='FILE_PATH')
-
-    prop_verbose = BoolProperty(
-            name=ms3d_utils.PROP_NAME_VERBOSE,
-            description=ms3d_utils.PROP_DESC_VERBOSE,
-            default=ms3d_utils.PROP_DEFAULT_VERBOSE,
-            options=ms3d_utils.PROP_OPT_VERBOSE,
-            )
-
-    prop_coordinate_system = EnumProperty(
-            name=ms3d_utils.PROP_NAME_COORDINATESYSTEM,
-            description=ms3d_utils.PROP_DESC_COORDINATESYSTEM,
-            items=ms3d_utils.PROP_ITEMS_COORDINATESYSTEM,
-            default=ms3d_utils.PROP_DEFAULT_COORDINATESYSTEM_EXP,
-            options=ms3d_utils.PROP_OPT_COORDINATESYSTEM,
-            )
-
-    prop_scale = FloatProperty(
-            name=ms3d_utils.PROP_NAME_SCALE,
-            description=ms3d_utils.PROP_DESC_SCALE,
-            default=1.0 / ms3d_utils.PROP_DEFAULT_SCALE,
-            min=ms3d_utils.PROP_MIN_SCALE,
-            max=ms3d_utils.PROP_MAX_SCALE,
-            soft_min=ms3d_utils.PROP_SMIN_SCALE,
-            soft_max=ms3d_utils.PROP_SMAX_SCALE,
-            options=ms3d_utils.PROP_OPT_SCALE,
-            )
-
-    prop_objects = EnumProperty(
-            name=ms3d_utils.PROP_NAME_OBJECTS_EXP,
-            description=ms3d_utils.PROP_DESC_OBJECTS_EXP,
-            items=ms3d_utils.PROP_ITEMS_OBJECTS_EXP,
-            default=ms3d_utils.PROP_DEFAULT_OBJECTS_EXP,
-            options=ms3d_utils.PROP_OPT_OBJECTS_EXP,
-            )
-
-    prop_selected = BoolProperty(
-            name=ms3d_utils.PROP_NAME_SELECTED,
-            description=ms3d_utils.PROP_DESC_SELECTED,
-            default=ms3d_utils.PROP_DEFAULT_SELECTED,
-            options=ms3d_utils.PROP_OPT_SELECTED,
-            )
-
-    prop_animation = BoolProperty(
-            name=ms3d_utils.PROP_NAME_ANIMATION,
-            description=ms3d_utils.PROP_DESC_ANIMATION,
-            default=ms3d_utils.PROP_DEFAULT_ANIMATION,
-            options=ms3d_utils.PROP_OPT_ANIMATION,
-            )
-
-
-    # draw the option panel
-    def draw(self, context):
-        layout = self.layout
-        ms3d_utils.SetupMenuExport(self, layout)
-
-    # entrypoint for blender -> MS3D
-    def execute(self, blenderContext):
-        """start executing"""
-        return self.WriteMs3d(blenderContext)
-
-    #
-    def invoke(self, blenderContext, event):
-        blenderContext.window_manager.fileselect_add(self)
-        return {"RUNNING_MODAL"}
-
-    # create a empty ms3d ms3dTemplate
-    # fill ms3dTemplate with blender content
-    # writer ms3d file
-    def WriteMs3d(self, blenderContext):
-        """convert bender content to ms3d content and write it to file"""
-
-        t1 = time.time()
-        t2 = None
-
-        try:
-            # setup environment
-            ms3d_utils.PreSetupEnvironment(self)
-
-            # create an empty ms3d template
-            ms3dTemplate = ms3d_spec.ms3d_file_t()
-
-            # inject blender data to ms3d file
-            self.Ms3dFromBlender(blenderContext, ms3dTemplate)
-
-            t2 = time.time()
-
-            # write ms3d file to disk
-            self.file = io.FileIO(self.filepath, "w")
-
-            ms3dTemplate.write(self.file)
-
-            self.file.flush()
-            self.file.close()
-
-            # finalize/restore environment
-            ms3d_utils.PostSetupEnvironment(self, False)
-
-        except Exception:
-            type, value, traceback = sys.exc_info()
-            print("WriteMs3d - exception in try block\n  type: '{0}'\n"
-                    "  value: '{1}'".format(type, value, traceback))
-
-            if t2 is None:
-                t2 = time.time()
-
-            raise
-
-        else:
-            pass
-
-        t3 = time.time()
-        print("elapsed time: {0:.4}s (converter: ~{1:.4}s, disk io:"
-                " ~{2:.4}s)".format((t3 - t1), (t2 - t1), (t3 - t2)))
-
-        return {"FINISHED"}
-
-
-    ###########################################################################
-    def Ms3dFromBlender(self, blenderContext, ms3dTemplate):
-        """ known limitations:
-            - bones unsupported yet
-            - joints unsupported yet
-            - very bad performance
-
-        notes:
-            - interpreating a blender-mesh-objects as ms3d-group
-            - only one material allowed per group in ms3d,
-              maybe sub-split a mesh in to material groups???"""
-
-        blender = blenderContext.blend_data
-
-        # todo: use an optimized collection for quick search vertices;
-        # with ~(o log n); currently its (o**n)
-        ms3dVertices = []
-
-        ms3dTriangles = []
-        ms3dMaterials = []
-        ms3dGroups = []
-
-        flagHandleMaterials = \
-                (ms3d_utils.PROP_ITEM_OBJECT_MATERIAL in self.prop_objects)
-
-        # handle blender-materials (without mesh's uv texture image)
-        if (flagHandleMaterials):
-            for blenderMaterial in blender.materials:
-                if (blenderMaterial.users <= 0):
-                    continue
-
-                ms3dMaterial = self.CreateMaterial(blenderMaterial, None)
-                if ms3dMaterial and (ms3dMaterial not in ms3dMaterials):
-                    ms3dMaterials.append(ms3dMaterial)
-
-        nLayers = len(blenderContext.scene.layers)
-        # handle blender-objects
-        for blenderObject in blender.objects:
-
-            # do not handle non-mesh objects or unused objects
-            if (blenderObject.type != 'MESH') or (blenderObject.users <= 0):
-                continue
-
-            # skip unselected objects in "only selected"-mode
-            if (self.prop_selected) and (not blenderObject.select):
-                continue
-
-            # skip meshes of invisible layers
-            skip = True
-            for iLayer in range(nLayers):
-                if ((blenderObject.layers[iLayer]
-                        and blenderContext.scene.layers[iLayer])):
-                    skip = False
-                    break
-            if (skip):
-                continue
-
-            # make new object as active and only selected object
-            bpy.context.scene.objects.active = blenderObject
-
-            matrixObject = blenderObject.matrix_basis
-
-            blenderMesh = blenderObject.data
-
-            ms3dGroup = ms3d_spec.ms3d_group_t()
-            ms3dGroup.name = blenderObject.name
-
-            # handle blender-vertices
-            for blenderVertex in blenderMesh.vertices:
-                ms3dVertex = self.CreateVertex(matrixObject, blenderVertex)
-
-                # handle referenceCount and/or
-                # put vertex without duplicates
-                if (ms3dVertex in ms3dVertices):
-                    ms3dVertices[ms3dVertices.index(ms3dVertex)]\
-                            .referenceCount += 1
-                else:
-                    ms3dVertex.referenceCount = 1
-                    ms3dVertices.append(ms3dVertex)
-
-            # handle smoothing groups
-            smoothGroupFaces = self.GenerateSmoothGroups(
-                    blenderContext, ms3dTemplate, blenderMesh.faces)
-
-            # handle blender-faces
-            groupIndex = len(ms3dGroups)
-            for iFace, blenderFace in enumerate(blenderMesh.faces):
-                if (smoothGroupFaces) and (iFace in smoothGroupFaces):
-                    smoothingGroup = smoothGroupFaces[iFace]
-                else:
-                    smoothingGroup = 0
-
-                if (len(blenderFace.vertices) == 4):
-                    # 1'st tri of quad
-                    ms3dTriangle = self.CreateTriangle(matrixObject,
-                            ms3dVertices, blenderMesh, blenderFace,
-                            groupIndex, smoothingGroup, 0)
-                    # put triangle
-                    ms3dTriangles.append(ms3dTriangle)
-                    # put triangle index
-                    ms3dGroup.triangleIndices.append(
-                            ms3dTriangles.index(ms3dTriangle))
-
-                    # 2'nd tri of quad
-                    ms3dTriangle = self.CreateTriangle(matrixObject,
-                            ms3dVertices, blenderMesh, blenderFace,
-                            groupIndex, smoothingGroup, 1)
-
-                else:
-                    ms3dTriangle = self.CreateTriangle(matrixObject,
-                            ms3dVertices, blenderMesh, blenderFace,
-                            groupIndex, smoothingGroup)
-
-                # put triangle
-                ms3dTriangles.append(ms3dTriangle)
-                # put triangle index
-                ms3dGroup.triangleIndices.append(
-                        ms3dTriangles.index(ms3dTriangle))
-
-            # handle material (take the first one)
-            if (flagHandleMaterials) and (blenderMesh.materials):
-                if (blenderMesh.uv_textures):
-                    tmpMaterial1 = self.CreateMaterial(
-                            blenderMesh.materials[0],
-                            blenderMesh.uv_textures[0])
-                else:
-                    tmpMaterial1 = self.CreateMaterial(
-                            blenderMesh.materials[0],
-                            None)
-
-                if tmpMaterial1:
-                    ms3dGroup.materialIndex = ms3dMaterials.index(tmpMaterial1)
-
-                    # upgrade poor material.texture with rich material.texture
-                    tmpMaterial2 = ms3dMaterials[ms3dGroup.materialIndex]
-                    if (tmpMaterial1.texture) and (not tmpMaterial2.texture):
-                        tmpMaterial2.texture = tmpMaterial1.texture
-
-            # put group
-            ms3dGroups.append(ms3dGroup)
-
-        # injecting common data
-        ms3dTemplate._vertices = ms3dVertices
-        ms3dTemplate._triangles = ms3dTriangles
-        ms3dTemplate._groups = ms3dGroups
-        ms3dTemplate._materials = ms3dMaterials
-
-        # inject currently unsupported data
-        ms3dTemplate._vertex_ex = []
-        if (ms3dTemplate.subVersionVertexExtra == 1):
-            for i in range(ms3dTemplate.nNumVertices):
-                ms3dTemplate.vertex_ex.append(ms3d_spec.ms3d_vertex_ex1_t())
-        elif (ms3dTemplate.subVersionVertexExtra == 2):
-            for i in range(ms3dTemplate.nNumVertices):
-                ms3dTemplate.vertex_ex.append(ms3d_spec.ms3d_vertex_ex2_t())
-        elif (ms3dTemplate.subVersionVertexExtra == 3):
-            for i in range(ms3dTemplate.nNumVertices):
-                ms3dTemplate.vertex_ex.append(ms3d_spec.ms3d_vertex_ex3_t())
-        else:
-            pass
-
-        if (self.prop_verbose):
-            ms3dTemplate.print_internal()
-
-        isValid, statistics = ms3dTemplate.isValid()
-        print()
-        print("##############################################################")
-        print("Blender -> MS3D : [{0}]".format(self.filepath_splitted[1]))
-        print(statistics)
-        print("##############################################################")
-
-
-    ###########################################################################
-    def CreateMaterial(self, blenderMaterial, blenderUvLayer):
-        if (not blenderMaterial):
-            return None
-
-        ms3dMaterial = ms3d_spec.ms3d_material_t()
-
-        ms3dMaterial.name = blenderMaterial.name
-
-        ms3dMaterial._ambient = (
-                blenderMaterial.diffuse_color[0],
-                blenderMaterial.diffuse_color[1],
-                blenderMaterial.diffuse_color[2],
-                blenderMaterial.ambient
-                )
-
-        ms3dMaterial._diffuse = (
-                blenderMaterial.diffuse_color[0],
-                blenderMaterial.diffuse_color[1],
-                blenderMaterial.diffuse_color[2],
-                blenderMaterial.diffuse_intensity
-                )
-
-        ms3dMaterial._specular = (
-                blenderMaterial.specular_color[0],
-                blenderMaterial.specular_color[1],
-                blenderMaterial.specular_color[2],
-                blenderMaterial.specular_intensity
-                )
-
-        ms3dMaterial._emissive = (
-                blenderMaterial.diffuse_color[0],
-                blenderMaterial.diffuse_color[1],
-                blenderMaterial.diffuse_color[2],
-                blenderMaterial.emit
-                )
-
-        ms3dMaterial.shininess = blenderMaterial.specular_hardness / 2.0
-        if ms3dMaterial.shininess > 128:
-            ms3dMaterial.shininess = 128
-        if ms3dMaterial.shininess < 1:
-            ms3dMaterial.shininess = 1
-
-        if (blenderMaterial.use_transparency):
-            ms3dMaterial.transparency = blenderMaterial.alpha
-
-        if (blenderMaterial.texture_slots):
-            imageDiffuse = None
-            imageAlpha = None
-
-            for blenderTextureSlot in blenderMaterial.texture_slots:
-                if ((not blenderTextureSlot)
-                        or (not blenderTextureSlot.texture)
-                        or (blenderTextureSlot.texture_coords != 'UV')
-                        or (blenderTextureSlot.texture.type != 'IMAGE')
-                        ):
-                    continue
-
-                if ((not imageDiffuse)
-                        and (blenderTextureSlot.use_map_color_diffuse)):
-                    if ((blenderTextureSlot.texture.image)
-                            and (blenderTextureSlot.texture.image.filepath)):
-                        imageDiffuse = os.path.split(
-                                blenderTextureSlot.texture.image.filepath)[1]
-                    elif (not blenderTextureSlot.texture.image):
-                        # case it image was not loaded
-                        imageDiffuse = os.path.split(
-                                blenderTextureSlot.texture.name)[1]
-
-                elif ((not imageAlpha)
-                        and (blenderTextureSlot.use_map_color_alpha)):
-                    if ((blenderTextureSlot.texture.image)
-                            and (blenderTextureSlot.texture.image.filepath)):
-                        imageAlpha = os.path.split(
-                                blenderTextureSlot.texture.image.filepath)[1]
-                    elif (not blenderTextureSlot.texture.image):
-                        # case it image was not loaded
-                        imageAlpha = os.path.split(
-                                blenderTextureSlot.texture.name)[1]
-
-            # if no diffuse image was found, try to find a uv texture image
-            if (not imageDiffuse) and (blenderUvLayer):
-                for blenderTextureFace in blenderUvLayer.data:
-                    if ((blenderTextureFace) and (blenderTextureFace.image)
-                            and (blenderTextureFace.image.filepath)):
-                        imageDiffuse = os.path.split(
-                                blenderTextureFace.image.filepath)[1]
-                        break
-
-            if (imageDiffuse):
-                ms3dMaterial.texture = imageDiffuse
-
-            if (imageAlpha):
-                ms3dMaterial.alphamap = imageDiffuse
-
-        return ms3dMaterial
-
-
-    ###########################################################################
-    def CreateNormal(self,  matrixObject, blenderVertex):
-        mathVector = mathutils.Vector(blenderVertex.normal)
-
-        # apply its object matrix (translation, rotation, scale)
-        mathVector = (matrixObject * mathVector)
-
-        # apply export swap axis matrix
-        mathVector = mathVector * self.matrixSwapAxis
-
-        ms3dNormal = tuple(mathVector)
-
-        return ms3dNormal
-
-
-    ###########################################################################
-    def CreateTriangle(self, matrixObject, ms3dVertices,
-            blenderMesh, blenderFace,
-            groupIndex=0, smoothingGroup=None, subIndex=0):
-        """
-        known limitations:
-            - it will take only the first uv_texture-data,
-              if one or more are present
-        """
-        ms3dTriangle = ms3d_spec.ms3d_triangle_t()
-
-        ms3dTriangle.groupIndex = groupIndex
-
-        if (smoothingGroup) and (smoothingGroup > 0):
-            ms3dTriangle.smoothingGroup = \
-                    (smoothingGroup % ms3d_spec.MAX_GROUPS) + 1
-
-        if (blenderFace.select):
-            ms3dTriangle.flags |= ms3d_spec.FLAG_SELECTED
-
-        if (blenderFace.hide):
-            ms3dTriangle.flags |= ms3d_spec.FLAG_HIDDEN
-
-        tx = None
-        l = len(blenderFace.vertices)
-
-        if (l == 3):
-            # it is already a triangle geometry
-            if (subIndex != 0):
-                return None
-
-            # no order-translation needed
-            tx = (0, 1, 2)
-
-        elif (l == 4):
-            # it is a quad geometry
-            if (subIndex > 1) or (subIndex < 0):
-                return None
-
-            if (subIndex == 0):
-                # order-translation for 1'st triangle
-                tx = (0, 1, 3)
-            else:
-                # order-translation for 2'nd triangle
-                tx = (3, 1, 2)
-
-        else:
-            # it is any unhandled geometry
-            return None
-
-        # take blender-vertex from blender-mesh
-        # to get its vertex and normal coordinates
-        v = blenderMesh.vertices[blenderFace.vertices_raw[tx[0]]]
-        v0 = self.CreateVertex(matrixObject, v)
-        n0 = self.CreateNormal(matrixObject, v)
-
-        # take blender-vertex from blender-mesh
-        # to get its vertex and normal coordinates
-        v = blenderMesh.vertices[blenderFace.vertices_raw[tx[1]]]
-        v1 = self.CreateVertex(matrixObject, v)
-        n1 = self.CreateNormal(matrixObject, v)
-
-        # take blender-vertex from blender-mesh
-        # to get its vertex and normal coordinates
-        v = blenderMesh.vertices[blenderFace.vertices_raw[tx[2]]]
-        v2 = self.CreateVertex(matrixObject, v)
-        n2 = self.CreateNormal(matrixObject, v)
-
-        # put the indices of ms3d-vertices!
-        ms3dTriangle._vertexIndices = (
-                ms3dVertices.index(v0),
-                ms3dVertices.index(v1),
-                ms3dVertices.index(v2)
-                )
-
-        # put the normales
-        ms3dTriangle._vertexNormals = (n0, n1, n2)
-
-        # if uv's present
-        if (blenderMesh.uv_textures):
-            # take 1'st uv_texture-data
-            blenderUv = \
-                    blenderMesh.uv_textures[0].data[blenderFace.index].uv_raw
-
-            # translate uv to st
-            #
-            # blender uw
-            # y(v)
-            # |(0,1)  (1,1)
-            # |
-            # |
-            # |(0,0)  (1,0)
-            # +--------x(u)
-            #
-            # ms3d st
-            # +--------x(s)
-            # |(0,0)  (1,0)
-            # |
-            # |
-            # |(0,1)  (1,1)
-            # y(t)
-            s0, t0 = blenderUv[tx[0] << 1], 1.0 - blenderUv[(tx[0] << 1) + 1]
-            s1, t1 = blenderUv[tx[1] << 1], 1.0 - blenderUv[(tx[1] << 1) + 1]
-            s2, t2 = blenderUv[tx[2] << 1], 1.0 - blenderUv[(tx[2] << 1) + 1]
-
-            # put the uv-coordinates
-            ms3dTriangle._s = (s0, s1, s2)
-            ms3dTriangle._t = (t0, t1, t2)
-
-        return ms3dTriangle
-
-
-    ###########################################################################
-    def CreateVertex(self,  matrixObject, blenderVertex):
-        """ known limitations:
-            - boneId not supported """
-        ms3dVertex = ms3d_spec.ms3d_vertex_t()
-
-        if (blenderVertex.select):
-            ms3dVertex.flags |= ms3d_spec.FLAG_SELECTED
-
-        if (blenderVertex.hide):
-            ms3dVertex.flags |= ms3d_spec.FLAG_HIDDEN
-
-        mathVector = mathutils.Vector(blenderVertex.co)
-
-        # apply its object matrix (translation, rotation, scale)
-        mathVector = (matrixObject * mathVector)
-
-        # apply export viewport matrix
-        mathVector = mathVector * self.matrixViewport
-
-        ms3dVertex._vertex = tuple(mathVector)
-
-        return ms3dVertex
-
-
-    ###########################################################################
-    def GenerateSmoothGroups(self, blenderContext, ms3dTemplate, blenderFaces):
-        ms3d_utils.EnableEditMode(True)
-
-        # enable face-selection-mode
-        bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-
-        # deselect all "faces"
-        ms3d_utils.SelectAll(False) # mesh
-
-        # enable object-mode (important for face.select = value)
-        ms3d_utils.EnableEditMode(False)
-
-        handledFacesSet = set()
-        smoothGroupVertices = {}
-
-        blenderVertices = blenderContext.active_object.data.vertices
-
-        # run throug the faces
-        # mark linked faces and set its smoothGroup value
-        nFaces = len(blenderFaces)
-
-        for iFace in range(nFaces):
-            if (blenderFaces[iFace].select) or (iFace in handledFacesSet):
-                continue
-
-            # a new unhandled face found
-            blenderFaces[iFace].select = True
-
-            ms3d_utils.EnableEditMode(True)
-
-            if bpy.ops.mesh.select_linked.poll():
-                bpy.ops.mesh.select_linked()
-
-            ms3d_utils.EnableEditMode(False)
-
-            # build a set of vertices hashes
-            currentFaceSet = set()
-            currentVertexSet = set()
-            for iiFace in range(nFaces):
-                if ((blenderFaces[iiFace].select)
-                        and (iiFace not in handledFacesSet)):
-                    handledFacesSet.add(iiFace)
-                    currentFaceSet.add(iiFace)
-
-                    iVertex = blenderFaces[iiFace].vertices[0]
-                    mathVector = blenderVertices[iVertex].co
-                    currentVertexSet.add(
-                            hash(mathVector[0])
-                            ^ hash(mathVector[1])
-                            ^ hash(mathVector[2]))
-
-                    iVertex = blenderFaces[iiFace].vertices[1]
-                    mathVector = blenderVertices[iVertex].co
-                    currentVertexSet.add(
-                            hash(mathVector[0])
-                            ^ hash(mathVector[1])
-                            ^ hash(mathVector[2]))
-
-                    iVertex = blenderFaces[iiFace].vertices[2]
-                    mathVector = blenderVertices[iVertex].co
-                    currentVertexSet.add(
-                            hash(mathVector[0])
-                            ^ hash(mathVector[1])
-                            ^ hash(mathVector[2]))
-
-                    if(len(blenderFaces[iiFace].vertices) == 4):
-                        iVertex = blenderFaces[iiFace].vertices[3]
-                        mathVector = blenderVertices[iVertex].co
-                        currentVertexSet.add(
-                                hash(mathVector[0])
-                                ^ hash(mathVector[1])
-                                ^ hash(mathVector[2]))
-
-            # search for collision set
-            reused_smoothgroup = False
-            for iSmoothGroup in smoothGroupVertices:
-                smoothVertexSet = smoothGroupVertices[iSmoothGroup][1]
-                intersectionVertexSet = currentVertexSet & smoothVertexSet
-                if(len(intersectionVertexSet) == 0):
-                    # no shared vertices, you can use that smoothgroup without collision
-                    item = smoothGroupVertices[iSmoothGroup]
-                    item[0] |= currentFaceSet
-                    item[1] |= currentVertexSet
-                    reused_smoothgroup = True
-                    break
-
-            if not reused_smoothgroup:
-                smoothGroupVertices[len(smoothGroupVertices)] = [currentFaceSet, currentVertexSet]
-
-        # put result to a smoothGroupFaces dictionary
-        smoothGroupFaces = {}
-        for iSmoothGroup in smoothGroupVertices:
-            for iFace in smoothGroupVertices[iSmoothGroup][0]:
-                smoothGroupFaces[iFace] = iSmoothGroup
-
-        return smoothGroupFaces
-
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py
deleted file mode 100644
index 9994268..0000000
--- a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py
+++ /dev/null
@@ -1,1250 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-
-
-# ##### BEGIN COPYRIGHT BLOCK #####
-#
-# initial script copyright (c)2011 Alexander Nussbaumer
-#
-# ##### END COPYRIGHT BLOCK #####
-
-
-#import python stuff
-import io
-import math
-import mathutils
-import os
-import sys
-import time
-
-
-# To support reload properly, try to access a package var,
-# if it's there, reload everything
-if ("bpy" in locals()):
-    import imp
-    if "ms3d_spec" in locals():
-        imp.reload(ms3d_spec)
-    if "ms3d_utils" in locals():
-        imp.reload(ms3d_utils)
-    pass
-
-else:
-    from . import ms3d_spec
-    from . import ms3d_utils
-    pass
-
-
-#import blender stuff
-import bpy
-import bpy_extras.io_utils
-
-from bpy_extras.image_utils import load_image
-from bpy.props import (
-        BoolProperty,
-        EnumProperty,
-        FloatProperty,
-        StringProperty,
-        )
-
-
-###############################################################################
-def prop(name):
-    return "ms3d_{0}".format(name)
-
-
-###############################################################################
-def hashStr(obj):
-    return str(hash(obj))
-
-
-PROP_NAME_HASH = "import_hash"
-PROP_NAME_SMOOTH_GROUP = "smoothingGroup{0}"
-
-
-###############################################################################
-_idb_ms3d = 0
-_idb_blender = 1
-_idb_roll = 2
-
-_bone_dummy = 1.0
-_bone_distort = 0.00001 # sys.float_info.epsilon
-
-
-###############################################################################
-# registered entry point import
-class ImportMS3D(
-        bpy.types.Operator,
-        bpy_extras.io_utils.ImportHelper
-        ):
-    """ Load a MilkShape3D MS3D File """
-
-    bl_idname = "io_scene_ms3d.ms3d_import"
-    bl_label = "Import MS3D"
-    bl_description = "Import from a MS3D file format (.ms3d)"
-    bl_options = {'PRESET'}
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-
-    filename_ext = ms3d_utils.FILE_EXT
-    filter_glob = StringProperty(
-            default=ms3d_utils.FILE_FILTER,
-            options={'HIDDEN'}
-            )
-
-    filepath = StringProperty(subtype='FILE_PATH')
-
-    prop_verbose = BoolProperty(
-            name=ms3d_utils.PROP_NAME_VERBOSE,
-            description=ms3d_utils.PROP_DESC_VERBOSE,
-            default=ms3d_utils.PROP_DEFAULT_VERBOSE,
-            options=ms3d_utils.PROP_OPT_VERBOSE,
-            )
-
-    prop_coordinate_system = EnumProperty(
-            name=ms3d_utils.PROP_NAME_COORDINATESYSTEM,
-            description=ms3d_utils.PROP_DESC_COORDINATESYSTEM,
-            items=ms3d_utils.PROP_ITEMS_COORDINATESYSTEM,
-            default=ms3d_utils.PROP_DEFAULT_COORDINATESYSTEM_IMP,
-            options=ms3d_utils.PROP_OPT_COORDINATESYSTEM,
-            )
-
-    prop_scale = FloatProperty(
-            name=ms3d_utils.PROP_NAME_SCALE,
-            description=ms3d_utils.PROP_DESC_SCALE,
-            default=ms3d_utils.PROP_DEFAULT_SCALE,
-            min=ms3d_utils.PROP_MIN_SCALE,
-            max=ms3d_utils.PROP_MAX_SCALE,
-            soft_min=ms3d_utils.PROP_SMIN_SCALE,
-            soft_max=ms3d_utils.PROP_SMAX_SCALE,
-            options=ms3d_utils.PROP_OPT_SCALE,
-            )
-
-    prop_unit_mm = BoolProperty(
-            name=ms3d_utils.PROP_NAME_UNIT_MM,
-            description=ms3d_utils.PROP_DESC_UNIT_MM,
-            default=ms3d_utils.PROP_DEFAULT_UNIT_MM,
-            options=ms3d_utils.PROP_OPT_UNIT_MM,
-            )
-
-    prop_objects = EnumProperty(
-            name=ms3d_utils.PROP_NAME_OBJECTS_IMP,
-            description=ms3d_utils.PROP_DESC_OBJECTS_IMP,
-            items=ms3d_utils.PROP_ITEMS_OBJECTS_IMP,
-            default=ms3d_utils.PROP_DEFAULT_OBJECTS_IMP,
-            options=ms3d_utils.PROP_OPT_OBJECTS_IMP,
-            )
-
-    prop_animation = BoolProperty(
-            name=ms3d_utils.PROP_NAME_ANIMATION,
-            description=ms3d_utils.PROP_DESC_ANIMATION,
-            default=ms3d_utils.PROP_DEFAULT_ANIMATION,
-            options=ms3d_utils.PROP_OPT_ANIMATION,
-            )
-
-    prop_reuse = EnumProperty(
-            name=ms3d_utils.PROP_NAME_REUSE,
-            description=ms3d_utils.PROP_DESC_REUSE,
-            items=ms3d_utils.PROP_ITEMS_REUSE,
-            default=ms3d_utils.PROP_DEFAULT_REUSE,
-            options=ms3d_utils.PROP_OPT_REUSE,
-            )
-
-
-    # draw the option panel
-    def draw(self, context):
-        layout = self.layout
-        ms3d_utils.SetupMenuImport(self, layout)
-
-    # entrypoint for MS3D -> blender
-    def execute(self, blenderContext):
-        """ start executing """
-        return self.ReadMs3d(blenderContext)
-
-    def invoke(self, blenderContext, event):
-        blenderContext.window_manager.fileselect_add(self)
-        return {"RUNNING_MODAL"}
-
-    # create empty blender ms3dTemplate
-    # read ms3d file
-    # fill blender with ms3dTemplate content
-    def ReadMs3d(self, blenderContext):
-        """ read ms3d file and convert ms3d content to bender content """
-
-        t1 = time.time()
-        t2 = None
-
-        try:
-            # setup environment
-            ms3d_utils.PreSetupEnvironment(self)
-
-            # create an empty ms3d template
-            ms3dTemplate = ms3d_spec.ms3d_file_t(self.filepath_splitted[1])
-
-            # open ms3d file
-            self.file = io.FileIO(self.properties.filepath, "r")
-
-            # read and inject ms3d data disk to blender
-            ms3dTemplate.read(self.file)
-
-            # close ms3d file
-            self.file.close()
-
-            t2 = time.time()
-
-            # inject dictionaries
-            # handle internal ms3d names to external blender names
-            # to prevent potential name collisions on multiple imports
-            # with same names but different content
-            self.dict_actions = {}
-            self.dict_armatures = {}
-            self.dict_armature_objects = {}
-            self.dict_groups = {}
-            self.dict_images = {}
-            self.dict_materials = {}
-            self.dict_meshes = {}
-            self.dict_mesh_objects = {}
-            self.dict_textures = {}
-            self.dict_comment_objects = {}
-
-            # inject ms3d data to blender
-            self.BlenderFromMs3d(blenderContext, ms3dTemplate)
-
-            # finalize/restore environment
-            ms3d_utils.PostSetupEnvironment(self, self.prop_unit_mm)
-
-        except Exception:
-            type, value, traceback = sys.exc_info()
-            print("ReadMs3d - exception in try block\n  type: '{0}'\n"
-                    "  value: '{1}'".format(type, value, traceback))
-
-            if t2 is None:
-                t2 = time.time()
-
-            raise
-
-        else:
-            pass
-
-        t3 = time.time()
-        print("elapsed time: {0:.4}s (disk io: ~{1:.4}s, converter:"
-                " ~{2:.4}s)".format((t3 - t1), (t2 - t1), (t3 - t2)))
-
-        return {"FINISHED"}
-
-
-    ###########################################################################
-    def BlenderFromMs3d(self, blenderContext, ms3dTemplate):
-        isValid, statistics = ms3dTemplate.isValid()
-
-        if (self.prop_verbose):
-            ms3dTemplate.print_internal()
-
-        if (isValid):
-            if ms3dTemplate.modelComment is not None:
-                blenderEmpty, setupEmpty = self.GetCommentObject(ms3dTemplate)
-                blenderContext.scene.objects.link(blenderEmpty)
-                if setupEmpty:
-                    blenderEmpty[prop(ms3d_spec.PROP_NAME_COMMENT)] = \
-                            ms3dTemplate.modelComment.comment
-
-            if (ms3d_utils.PROP_ITEM_OBJECT_JOINT in self.prop_objects):
-                dict_bones, blenderArmatureObject = self.CreateArmature(
-                        blenderContext, ms3dTemplate)
-
-                if self.prop_animation:
-                    self.CreateAnimation(blenderContext, ms3dTemplate,
-                            dict_bones, blenderArmatureObject)
-                    pass
-
-            for ms3dGroupIndex, ms3dGroup in enumerate(ms3dTemplate.groups):
-                blenderMesh = self.CreateMesh(blenderContext, ms3dTemplate,
-                        ms3dGroup, ms3dGroupIndex)
-
-                # apply material if available
-                if ((ms3d_utils.PROP_ITEM_OBJECT_MATERIAL in self.prop_objects)
-                        and (ms3dGroup.materialIndex >= 0)):
-                    blenderMaterial = self.CreateMaterial(blenderContext,
-                            ms3dTemplate, ms3dGroup.materialIndex,
-                            blenderMesh.uv_textures[0])
-                    blenderMesh.materials.append(blenderMaterial)
-
-                # apply smoothing groups
-                if (ms3d_utils.PROP_ITEM_OBJECT_SMOOTHGROUPS in
-                        self.prop_objects):
-                    self.GenerateSmoothGroups(blenderContext, ms3dTemplate,
-                            ms3dGroup, blenderMesh.faces)
-
-                # apply tris to quads
-                if (ms3d_utils.PROP_ITEM_OBJECT_TRI_TO_QUAD in
-                        self.prop_objects):
-                    ms3d_utils.EnableEditMode(True)
-
-                    # remove double vertices
-                    ms3d_utils.SelectAll(True) # mesh
-
-                    # convert tris to quads
-                    if bpy.ops.mesh.tris_convert_to_quads.poll():
-                        bpy.ops.mesh.tris_convert_to_quads()
-
-                    ms3d_utils.EnableEditMode(False)
-
-                self.PostSetupMesh()
-
-            # put all objects to group
-            if (ms3d_utils.PROP_ITEM_OBJECT_GROUP in self.prop_objects):
-                blenderGroup, setupGroup = self.GetGroup(ms3dTemplate)
-                if setupGroup:
-                    for item in self.dict_mesh_objects.values():
-                        blenderGroup.objects.link(item)
-                        item.select = True
-                    for item in self.dict_armature_objects.values():
-                        blenderGroup.objects.link(item)
-                        item.select = True
-                    for item in self.dict_comment_objects.values():
-                        blenderGroup.objects.link(item)
-                        item.select = True
-
-            print()
-            print("##########################################################")
-            print("MS3D -> Blender : [{0}]".format(self.filepath_splitted[1]))
-            print(statistics)
-            print("##########################################################")
-
-
-    ###########################################################################
-    def CreateArmature(self, blenderContext, ms3dTemplate):
-        if (ms3dTemplate.nNumJoints <= 0):
-            return None, None
-
-        blenderScene = blenderContext.scene
-
-        blenderArmature, setupArmature = self.GetArmature(ms3dTemplate)
-        if setupArmature:
-            blenderArmature.draw_type = 'STICK'
-            blenderArmature.show_axes = True
-            blenderArmature.use_auto_ik = True
-
-        blenderObject, setupObject = self.GetArmatureObject(ms3dTemplate,
-                blenderArmature)
-        if setupObject:
-            blenderObject.location = blenderContext.scene.cursor_location
-            blenderObject.show_x_ray = True
-            blenderScene.objects.link(blenderObject)
-
-        blenderScene.objects.active = blenderObject
-
-        ms3d_utils.EnableEditMode(True)
-
-        dict_bones = {}
-        for iBone, ms3dJoint in enumerate(ms3dTemplate.joints):
-            blenderBone = blenderArmature.edit_bones.new(ms3dJoint.name)
-            blenderBone[prop(ms3d_spec.PROP_NAME_NAME)] = ms3dJoint.name
-            blenderBone[prop(ms3d_spec.PROP_NAME_FLAGS)] = ms3dJoint.flags
-
-            ms3dComment = ms3dTemplate.get_joint_comment_by_key(iBone)
-            if ms3dComment is not None:
-                blenderBone[prop(ms3d_spec.PROP_NAME_COMMENT)] = \
-                        ms3dComment.comment
-
-            ms3dJointEx = ms3dTemplate.get_joint_ex_by_key(iBone)
-            if ms3dJointEx is not None:
-                blenderBone[prop(ms3d_spec.PROP_NAME_COLOR)] = \
-                        ms3dJointEx.color
-
-            blenderBone.select = True
-            blenderArmature.edit_bones.active = blenderBone
-
-            # [ms3d bone, number of references, blender bone, roll vector]
-            dict_bones[ms3dJoint.name] = [ms3dJoint, blenderBone, None]
-
-            mathVector = mathutils.Vector(ms3dJoint.position)
-            mathVector = mathVector * self.matrixViewport
-
-            if (not ms3dJoint.parentName):
-                blenderBone.head = mathVector
-                matrixRotation = None
-
-                #dummy tail
-                blenderBone.tail = blenderBone.head + mathutils.Vector(
-                        (_bone_dummy, 0.0, 0.0))
-
-            else:
-                boneItem = dict_bones[ms3dJoint.parentName]
-                blenderBoneParent = boneItem[_idb_blender]
-
-                blenderBone.parent = blenderBoneParent
-                if self.prop_animation:
-                    blenderBone.use_inherit_rotation = False
-                    blenderBone.use_inherit_scale = False
-
-                matrixRotation = mathutils.Matrix()
-                for blenderBoneParent in blenderBone.parent_recursive:
-                    key = blenderBoneParent.name
-
-                    # correct rotaion axis
-                    rotationAxis = mathutils.Vector((
-                            -dict_bones[key][_idb_ms3d].rotation[0],
-                            -dict_bones[key][_idb_ms3d].rotation[1],
-                            -dict_bones[key][_idb_ms3d].rotation[2]))
-                    rotationAxis = rotationAxis * self.matrixSwapAxis
-
-                    mathRotation = mathutils.Euler(rotationAxis, 'XZY')
-                    matrixRotation = matrixRotation * mathRotation.to_matrix(
-                            ).to_4x4()
-
-                mathVector = blenderBone.parent.head + (mathVector
-                        * matrixRotation)
-
-                # at some very rare models, bones share the same place.
-                # but blender removes bones that share the same space,
-                # so distort the location a little bit
-                if mathVector ==  blenderBone.parent.head:
-                    mathVector -= mathutils.Vector((_bone_distort, 0.0, 0.0))
-                    print("Info: distort bone in blender: '{0}'".format(blenderBone.name))
-
-                blenderBone.head = mathVector
-
-                # dummy tail
-                blenderBone.tail = blenderBone.head + (
-                        mathutils.Vector((_bone_dummy, 0.0, 0.0))
-                        * self.matrixSwapAxis
-                        * matrixRotation)
-
-            if matrixRotation is not None:
-                mathRollVector = (mathutils.Vector((0.0, 0.0, 1.0))
-                        * matrixRotation)
-                boneItem[_idb_roll] = mathRollVector
-
-        # an adjustment pass
-        # to adjust connection and tails of bones
-        for blenderBone in blenderArmature.edit_bones:
-            # skip if it has no parent
-            if blenderBone.parent is None:
-                continue
-
-            # make nice blunt ending
-            if not blenderBone.children:
-                blenderBone.tail = blenderBone.parent.head
-
-            # skip if parent has more than one children
-            numberChildren = len(blenderBone.children)
-            if (numberChildren == 1):
-                blenderBone.tail = blenderBone.children[0].head
-                blenderBone.children[0].use_connect = True
-
-        # an extra additional adjustment pass
-        # to re-correct possible modified bonerolls
-        for key in dict_bones:
-            boneItem = dict_bones[key]
-            blenderBone = boneItem[_idb_blender]
-            mathRollVector = boneItem[_idb_roll]
-            if mathRollVector is not None:
-                blenderBone.align_roll(mathRollVector)
-
-            # make dict lightweight
-            boneItem[_idb_blender] = boneItem[_idb_blender].name
-            #boneItem[_idb_ms3d] = boneItem[_idb_ms3d]
-            boneItem[_idb_roll] = None
-
-        ms3d_utils.EnableEditMode(False)
-
-        return dict_bones, blenderObject
-
-
-    ###########################################################################
-    def CreateAnimation(self, blenderContext, ms3dTemplate, dict_bones, blenderObject):
-        if (ms3dTemplate.nNumJoints <= 0):
-            return None
-
-        blenderScene = blenderContext.scene
-
-        blenderScene.render.fps = ms3dTemplate.fAnimationFPS
-        if ms3dTemplate.fAnimationFPS:
-            blenderScene.render.fps_base = (blenderScene.render.fps /
-                    ms3dTemplate.fAnimationFPS)
-        blenderScene.frame_start = 1
-        blenderScene.frame_end = (ms3dTemplate.iTotalFrames
-                + blenderScene.frame_start) - 1
-        blenderScene.frame_current = (ms3dTemplate.fCurrentTime
-                * blenderScene.render.fps
-                / blenderScene.render.fps_base)
-
-        blenderAction, setupAction = self.GetAction(ms3dTemplate)
-        if blenderObject.animation_data is None:
-            blenderObject.animation_data_create()
-        blenderObject.animation_data.action = blenderAction
-
-        for boneName in dict_bones:
-            item = dict_bones[boneName]
-            blenderBoneName = item[_idb_blender]
-            ms3dJoint =  item[_idb_ms3d]
-
-            blenderBoneObject = blenderObject.pose.bones.get(blenderBoneName)
-            if blenderBoneObject is None:
-                # no idea why at some models are
-                # bones are missing in blender, but are present in dict
-                print("Info: missing bone in blender: '{0}'".format(blenderBoneName))
-                continue
-
-            blenderBone = blenderObject.data.bones.get(blenderBoneName)
-
-            data_path = blenderBoneObject.path_from_id("location")
-            fcurveTransX = blenderAction.fcurves.new(data_path, index=0)
-            fcurveTransY = blenderAction.fcurves.new(data_path, index=1)
-            fcurveTransZ = blenderAction.fcurves.new(data_path, index=2)
-            for keyFramesTrans in ms3dJoint.keyFramesTrans:
-                frame = (keyFramesTrans.time
-                        * blenderScene.render.fps
-                        / blenderScene.render.fps_base)
-                translationAxis = mathutils.Vector((
-                        keyFramesTrans.position[0],
-                        keyFramesTrans.position[1],
-                        keyFramesTrans.position[2]))
-                translationAxis = translationAxis * self.matrixSwapAxis
-                fcurveTransX.keyframe_points.insert(frame, translationAxis[0])
-                fcurveTransY.keyframe_points.insert(frame, translationAxis[1])
-                fcurveTransZ.keyframe_points.insert(frame, translationAxis[2])
-
-            data_path = blenderBoneObject.path_from_id("rotation_euler")
-            blenderBoneObject.rotation_mode = 'XZY'
-            #data_path = blenderBoneObject.path_from_id("rotation_quaternion")
-            #fcurveRotW = blenderAction.fcurves.new(data_path, index=0)
-            fcurveRotX = blenderAction.fcurves.new(data_path, index=0)
-            fcurveRotY = blenderAction.fcurves.new(data_path, index=1)
-            fcurveRotZ = blenderAction.fcurves.new(data_path, index=2)
-            for keyFramesRot in ms3dJoint.keyFramesRot:
-                frame = (keyFramesRot.time
-                        * blenderScene.render.fps
-                        / blenderScene.render.fps_base)
-                rotationAxis = mathutils.Vector((
-                        -keyFramesRot.rotation[0],
-                        -keyFramesRot.rotation[1],
-                        -keyFramesRot.rotation[2]))
-                rotationAxis = rotationAxis * self.matrixSwapAxis
-                mathRotEuler = mathutils.Euler(rotationAxis, 'XZY')
-
-                fcurveRotX.keyframe_points.insert(frame, mathRotEuler.x)
-                fcurveRotY.keyframe_points.insert(frame, mathRotEuler.y)
-                fcurveRotZ.keyframe_points.insert(frame, mathRotEuler.z)
-
-                #mathRotQuaternion = mathRotEuler.to_quaternion()
-                #fcurveRotW.keyframe_points.insert(frame, mathRotQuaternion.w)
-                #fcurveRotX.keyframe_points.insert(frame, mathRotQuaternion.x)
-                #fcurveRotY.keyframe_points.insert(frame, mathRotQuaternion.y)
-                #fcurveRotZ.keyframe_points.insert(frame, mathRotQuaternion.z)
-
-
-    ###########################################################################
-    def CreateImageTexture(self, ms3dMaterial, alphamap, allow_create=True):
-        blenderImage, setupImage = self.GetImage(ms3dMaterial, alphamap,
-                allow_create=allow_create)
-        if setupImage:
-            pass
-
-        blenderTexture, setupTexture = self.GetTexture(ms3dMaterial, alphamap,
-                blenderImage, allow_create=allow_create)
-        if setupTexture:
-            blenderTexture.image = blenderImage
-
-            if (alphamap):
-                blenderTexture.use_preview_alpha = True
-
-        return blenderTexture
-
-
-    ###########################################################################
-    def CreateMaterial(self, blenderContext, ms3dTemplate, ms3dMaterialIndex,
-            blenderUvLayer):
-        ms3dMaterial = ms3dTemplate.materials[ms3dMaterialIndex]
-
-        blenderMaterial, setupMaterial = self.GetMaterial(ms3dMaterial)
-        if setupMaterial:
-            blenderMaterial[prop(PROP_NAME_HASH)] = hashStr(ms3dMaterial)
-            blenderMaterial[prop(ms3d_spec.PROP_NAME_MODE)] = ms3dMaterial.mode
-            blenderMaterial[prop(ms3d_spec.PROP_NAME_AMBIENT)] = \
-                    ms3dMaterial.ambient
-            blenderMaterial[prop(ms3d_spec.PROP_NAME_EMISSIVE)] = \
-                    ms3dMaterial.emissive
-
-            ms3dComment = \
-                    ms3dTemplate.get_material_comment_by_key(ms3dMaterialIndex)
-            if ms3dComment is not None:
-                blenderMaterial[prop(ms3d_spec.PROP_NAME_COMMENT)] = \
-                        ms3dComment.comment
-
-            blenderMaterial.ambient = ((
-                    (ms3dMaterial.ambient[0]
-                    + ms3dMaterial.ambient[1]
-                    + ms3dMaterial.ambient[2]) / 3.0)
-                    * ms3dMaterial.ambient[3])
-
-            blenderMaterial.diffuse_color[0] = ms3dMaterial.diffuse[0]
-            blenderMaterial.diffuse_color[1] = ms3dMaterial.diffuse[1]
-            blenderMaterial.diffuse_color[2] = ms3dMaterial.diffuse[2]
-            blenderMaterial.diffuse_intensity = ms3dMaterial.diffuse[3]
-
-            blenderMaterial.specular_color[0] = ms3dMaterial.specular[0]
-            blenderMaterial.specular_color[1] = ms3dMaterial.specular[1]
-            blenderMaterial.specular_color[2] = ms3dMaterial.specular[2]
-            blenderMaterial.specular_intensity = ms3dMaterial.specular[3]
-
-            blenderMaterial.emit = ((
-                    (ms3dMaterial.emissive[0]
-                    + ms3dMaterial.emissive[1]
-                    + ms3dMaterial.emissive[2]) / 3.0)
-                    * ms3dMaterial.emissive[3])
-
-            blenderMaterial.specular_hardness = ms3dMaterial.shininess * 2.0
-
-            if (ms3dMaterial.transparency):
-                blenderMaterial.use_transparency = True
-                blenderMaterial.alpha = ms3dMaterial.transparency
-                blenderMaterial.specular_alpha = blenderMaterial.alpha
-
-            if (blenderMaterial.game_settings):
-                blenderMaterial.game_settings.use_backface_culling = False
-                blenderMaterial.game_settings.alpha_blend = 'ALPHA'
-
-            # diffuse texture
-            if (ms3dMaterial.texture):
-                blenderMaterial[prop(ms3d_spec.PROP_NAME_TEXTURE)] = \
-                        ms3dMaterial.texture
-                blenderTexture = self.CreateImageTexture(ms3dMaterial, False)
-
-                blenderTextureSlot = blenderMaterial.texture_slots.add()
-                blenderTextureSlot.texture = blenderTexture
-                blenderTextureSlot.texture_coords = 'UV'
-                blenderTextureSlot.uv_layer = blenderUvLayer.name
-                blenderTextureSlot.use_map_color_diffuse = True
-                blenderTextureSlot.use_map_alpha = False
-
-                # apply image also to uv's
-                for blenderTextureFace in blenderUvLayer.data:
-                    blenderTextureFace.image = blenderTexture.image
-
-            # alpha texture
-            if (ms3dMaterial.alphamap):
-                blenderMaterial[prop(ms3d_spec.PROP_NAME_ALPHAMAP)] = \
-                        ms3dMaterial.alphamap
-                blenderMaterial.alpha = 0
-                blenderMaterial.specular_alpha = 0
-
-                blenderTexture = self.CreateImageTexture(ms3dMaterial, True)
-
-                blenderTextureSlot = blenderMaterial.texture_slots.add()
-                blenderTextureSlot.texture = blenderTexture
-                blenderTextureSlot.texture_coords = 'UV'
-                blenderTextureSlot.uv_layer = blenderUvLayer.name
-                blenderTextureSlot.use_map_color_diffuse = False
-                blenderTextureSlot.use_map_alpha = True
-                blenderTextureSlot.use_rgb_to_intensity = True
-
-        else:
-            if (ms3dMaterial.texture):
-                blenderTexture = self.CreateImageTexture(ms3dMaterial, False,
-                        allow_create=False)
-
-                # apply image also to uv's
-                if blenderTexture:
-                    for blenderTextureFace in blenderUvLayer.data:
-                        blenderTextureFace.image = blenderTexture.image
-
-        return blenderMaterial
-
-
-    ###########################################################################
-    def CreateMesh(self, blenderContext, ms3dTemplate, ms3dGroup,
-            ms3dGroupIndex):
-        vertices = []
-        edges = []
-        faces = []
-
-        boneIds = {}
-        dict_vertices = {}
-
-        for iTriangle in ms3dGroup.triangleIndices:
-            face = []
-            for iVertex in ms3dTemplate.triangles[iTriangle].vertexIndices:
-                iiVertex = dict_vertices.get(iVertex)
-                if iiVertex is None:
-                    # add to ms3d to blender translation dictionary
-                    dict_vertices[iVertex] = iiVertex = len(vertices)
-
-                    # prepare vertices of mesh
-                    ms3dVertex = ms3dTemplate.vertices[iVertex]
-                    mathVector = mathutils.Vector(ms3dVertex.vertex)
-                    mathVector = mathVector * self.matrixViewport
-                    vertices.append(mathVector)
-
-                    # prepare boneId dictionary for later use
-                    iBone = boneIds.get(ms3dVertex.boneId)
-                    if iBone is not None:
-                        iBone.append(iiVertex)
-                    else:
-                        boneIds[ms3dVertex.boneId] = [iiVertex, ]
-
-                face.append(iiVertex)
-            faces.append(face)
-
-        blenderScene = blenderContext.scene
-
-        blenderMesh, setupMesh = self.GetMesh(ms3dGroup)
-
-        blenderObject, setupObject = self.GetMeshObject(ms3dGroup, blenderMesh)
-        blenderObject.location = blenderScene.cursor_location
-        blenderScene.objects.link(blenderObject)
-        if setupObject:
-            blenderObject[prop(ms3d_spec.PROP_NAME_FLAGS)] = ms3dGroup.flags
-            ms3dComment = ms3dTemplate.get_group_comment_by_key(ms3dGroupIndex)
-            if ms3dComment is not None:
-                blenderObject[prop(ms3d_spec.PROP_NAME_COMMENT)] = \
-                        ms3dComment.comment
-
-        # setup mesh
-        blenderMesh.from_pydata(vertices, edges, faces)
-        if (not edges):
-            blenderMesh.update(calc_edges=True)
-
-        # make new object as active and only selected object
-        ms3d_utils.SelectAll(False) # object
-        blenderObject.select = True
-        bpy.context.scene.objects.active = blenderObject
-
-        # create vertex groups for boneIds
-        for boneId, vertexIndices in boneIds.items():
-            if boneId < 0:
-                continue
-
-            # put selected to vertex_group
-            #n = ms3dTemplate.get_joint_by_key(boneId)
-            n = ms3dTemplate.joints[boneId]
-            blenderBoneIdKey = n.name
-            blenderVertexGroup = \
-                bpy.context.active_object.vertex_groups.new(blenderBoneIdKey)
-
-            for iiVertex in vertexIndices:
-                blenderVertexGroup.add([iiVertex], 1.0, 'REPLACE')
-
-            # add group to armature modifier
-            if (ms3d_utils.PROP_ITEM_OBJECT_JOINT in self.prop_objects):
-                blenderArmatureObject = self.GetArmatureObject(
-                        ms3dTemplate, None)
-                if blenderArmatureObject[0] is not None:
-                    name = ms3dTemplate.get_joint_by_key(boneId).name
-                    blenderBone = blenderArmatureObject[0].data.bones.get(name)
-                    if blenderBone is not None:
-                        blenderModifier = blenderObject.modifiers.new(
-                                name, type='ARMATURE')
-                        blenderModifier.object = blenderArmatureObject[0]
-                        blenderModifier.vertex_group = blenderVertexGroup.name
-
-        # handle UVs
-        # add UVs
-        if ((not blenderMesh.uv_textures)
-                and bpy.ops.mesh.uv_texture_add.poll()):
-            bpy.ops.mesh.uv_texture_add()
-
-        # convert ms3d-ST to blender-UV
-        for i, blenderUv in enumerate(blenderMesh.uv_textures[0].data):
-            blenderUv.uv1[0], blenderUv.uv1[1] = ms3dTemplate.triangles[
-                    ms3dGroup.triangleIndices[i]].s[0], (1.0 -
-                    ms3dTemplate.triangles[ms3dGroup.triangleIndices[i]].t[0])
-            blenderUv.uv2[0], blenderUv.uv2[1] = ms3dTemplate.triangles[
-                    ms3dGroup.triangleIndices[i]].s[1], (1.0 -
-                    ms3dTemplate.triangles[ms3dGroup.triangleIndices[i]].t[1])
-            blenderUv.uv3[0], blenderUv.uv3[1] = ms3dTemplate.triangles[
-                    ms3dGroup.triangleIndices[i]].s[2], (1.0 -
-                    ms3dTemplate.triangles[ms3dGroup.triangleIndices[i]].t[2])
-
-        ms3d_utils.EnableEditMode(False)
-
-        return blenderMesh
-
-
-    ###########################################################################
-    def GenerateSmoothGroups(self, blenderContext, ms3dTemplate, ms3dGroup,
-            blenderFaces):
-        """ split faces of a smoothingGroup.
-            it will preserve the UVs and materials.
-
-            SIDE-EFFECT: it will change the order of faces! """
-
-        # smooth mesh to see its smoothed region
-        if bpy.ops.object.shade_smooth.poll():
-            bpy.ops.object.shade_smooth()
-
-        nFaces = len(blenderFaces)
-
-        # collect smoothgroups and its faces
-        smoothGroupFaceIndices = {}
-        for iTriangle, ms3dTriangleIndex in \
-                enumerate(ms3dGroup.triangleIndices):
-            smoothGroupKey = \
-                    ms3dTemplate.triangles[ms3dTriangleIndex].smoothingGroup
-
-            if (smoothGroupKey == 0):
-                continue
-
-            if (smoothGroupKey not in smoothGroupFaceIndices):
-                smoothGroupFaceIndices[smoothGroupKey] = []
-
-            smoothGroupFaceIndices[smoothGroupKey].append(iTriangle)
-
-        nKeys = len(smoothGroupFaceIndices)
-
-        # handle smoothgroups, if more than one is available
-        if (nKeys <= 1):
-            return
-
-        # enable edit-mode
-        ms3d_utils.EnableEditMode(True)
-
-        for smoothGroupKey in smoothGroupFaceIndices:
-            # deselect all "faces"
-            ms3d_utils.SelectAll(False) # mesh
-
-            # enable object-mode (important for face.select = value)
-            ms3d_utils.EnableEditMode(False)
-
-            # select faces of current smoothgroup
-            for faceIndex in smoothGroupFaceIndices[smoothGroupKey]:
-                blenderFaces[faceIndex].select = True
-
-            # enable edit-mode again
-            ms3d_utils.EnableEditMode(True)
-
-            ## split selected faces
-            ## WARNING: it will reorder the faces!
-            ## after that, with that logic, it is impossible to use the
-            ## dictionary for the next outstanding smoothgroups anymore
-            # if bpy.ops.mesh.split.poll():
-            #     bpy.ops.mesh.split()
-
-            # SPLIT WORKAROUND part 1
-            # duplicate selected faces
-            if bpy.ops.mesh.duplicate.poll():
-                bpy.ops.mesh.duplicate()
-
-            # put selected to vertex_group
-            blenderVertexGroup = bpy.context.active_object.vertex_groups.new(
-                    prop(PROP_NAME_SMOOTH_GROUP).format(smoothGroupKey))
-            bpy.context.active_object.vertex_groups.active = blenderVertexGroup
-            if bpy.ops.object.vertex_group_assign.poll():
-                bpy.ops.object.vertex_group_assign()
-
-        ## SPLIT WORKAROUND START part 2
-        # cleanup old faces
-        #
-        ms3d_utils.SelectAll(False) # mesh
-
-        # enable object-mode (important for face.select = value)
-        ms3d_utils.EnableEditMode(False)
-
-        # select all old faces
-        for faceIndex in range(nFaces):
-            blenderFaces[faceIndex].select = True
-            pass
-
-        # enable edit-mode again
-        ms3d_utils.EnableEditMode(True)
-
-        # delete old faces and its vertices
-        if bpy.ops.mesh.delete.poll():
-            bpy.ops.mesh.delete(type='VERT')
-        #
-        ## SPLIT WORKAROUND END part 2
-
-
-        # enable object-mode
-        ms3d_utils.EnableEditMode(False)
-
-        pass
-
-
-    ###########################################################################
-    def PostSetupMesh(self):
-        ms3d_utils.EnableEditMode(True)
-        ms3d_utils.SelectAll(True) # mesh
-        ms3d_utils.EnableEditMode(False)
-
-
-    ###########################################################################
-    def GetAction(self, ms3dObject):
-        nameAction = ms3dObject.name
-
-        # already available
-        blenderAction = self.dict_actions.get(nameAction)
-        if blenderAction is not None:
-            return blenderAction, False
-
-        # create new
-        blenderAction = bpy.data.actions.new(nameAction)
-        self.dict_actions[nameAction] = blenderAction
-        if blenderAction is not None:
-            blenderAction[prop(ms3d_spec.PROP_NAME_NAME)] = nameAction
-        return blenderAction, True
-
-
-    ###########################################################################
-    def GetArmature(self, ms3dObject):
-        nameArmature = ms3dObject.name
-
-        # already available
-        blenderArmature = self.dict_armatures.get(nameArmature)
-        if blenderArmature is not None:
-            return blenderArmature, False
-
-        # create new
-        blenderArmature = bpy.data.armatures.new(nameArmature)
-        self.dict_armatures[nameArmature] = blenderArmature
-        if blenderArmature is not None:
-            blenderArmature[prop(ms3d_spec.PROP_NAME_NAME)] = nameArmature
-        return blenderArmature, True
-
-
-    ###########################################################################
-    def GetArmatureObject(self, ms3dObject, objectData):
-        nameObject = ms3dObject.name
-
-        # already available
-        blenderObject = self.dict_armature_objects.get(nameObject)
-        if blenderObject is not None:
-            return blenderObject, False
-
-        # create new
-        blenderObject = bpy.data.objects.new(nameObject, objectData)
-        self.dict_armature_objects[nameObject] = blenderObject
-        if blenderObject is not None:
-            blenderObject[prop(ms3d_spec.PROP_NAME_NAME)] = nameObject
-        return blenderObject, True
-
-
-    ###########################################################################
-    def GetGroup(self, ms3dObject):
-        nameGroup = ms3dObject.name
-
-        # already available
-        blenderGroup = self.dict_groups.get(nameGroup)
-        if blenderGroup is not None:
-            return blenderGroup, False
-
-        # create new
-        blenderGroup = bpy.data.groups.new(nameGroup)
-        self.dict_groups[nameGroup] = blenderGroup
-        if blenderGroup is not None:
-            blenderGroup[prop(ms3d_spec.PROP_NAME_NAME)] = nameGroup
-        return blenderGroup, True
-
-
-    ###########################################################################
-    def GetImage(self, ms3dMaterial, alphamap, allow_create=True):
-        if alphamap:
-            nameImageRaw = ms3dMaterial.alphamap
-            propName = ms3d_spec.PROP_NAME_ALPHAMAP
-        else:
-            nameImageRaw = ms3dMaterial.texture
-            propName = ms3d_spec.PROP_NAME_TEXTURE
-
-        nameImage = os.path.split(nameImageRaw)[1]
-        nameDirectory = self.filepath_splitted[0]
-
-        # already available
-        blenderImage = self.dict_images.get(nameImage)
-        if blenderImage is not None:
-            return blenderImage, False
-
-        # OPTIONAL: try to find an existing one, that fits
-        if (self.prop_reuse == ms3d_utils.PROP_ITEM_REUSE_MATCH_VALUES):
-            testBlenderImage = bpy.data.images.get(nameImage, None)
-            if (testBlenderImage):
-                # take a closer look to its content
-                if ((not testBlenderImage.library)
-                        and (os.path.split(
-                        testBlenderImage.filepath)[1] == nameImage)):
-                    return testBlenderImage, False
-
-        # elif (self.prop_reuse == ms3d_utils.PROP_ITEM_REUSE_MATCH_HASH):
-        #     # irrespecting its real content
-        #     # take materials, that have the same "ms3d_import_hash"
-        #     # custom property (of an previous import)
-        #     propKey = prop(PROP_NAME_HASH)
-        #     hexHash = hex(hash(nameImage))
-        #     for testBlenderImage in bpy.data.images:
-        #         if ((testBlenderImage) and (not testBlenderImage.library)
-        #                 and (propKey in testBlenderImage)
-        #                 and (testBlenderImage[propKey] == hexHash)):
-        #             return testBlenderImage, False
-
-        if not allow_create:
-            return None, False
-
-        # create new
-        blenderImage = load_image(nameImage, nameDirectory)
-        self.dict_images[nameImage] = blenderImage
-        if blenderImage is not None:
-            blenderImage[prop(ms3d_spec.PROP_NAME_NAME)] = ms3dMaterial.name
-            blenderImage[prop(propName)] = nameImageRaw
-        return blenderImage, True
-
-
-    ###########################################################################
-    def GetTexture(self, ms3dMaterial, alphamap, blenderImage,
-            allow_create=True):
-        if alphamap:
-            nameTextureRaw = ms3dMaterial.alphamap
-            propName = ms3d_spec.PROP_NAME_ALPHAMAP
-        else:
-            nameTextureRaw = ms3dMaterial.texture
-            propName = ms3d_spec.PROP_NAME_TEXTURE
-
-        nameTexture = os.path.split(nameTextureRaw)[1]
-
-        # already available
-        blenderTexture = self.dict_textures.get(nameTexture)
-        if blenderTexture is not None:
-            return blenderTexture, False
-
-        # OPTIONAL: try to find an existing one, that fits
-        if self.prop_reuse == ms3d_utils.PROP_ITEM_REUSE_MATCH_VALUES:
-            testBlenderTexture = bpy.data.textures.get(nameTexture, None)
-            if (testBlenderTexture):
-                # take a closer look to its content
-                if ((not testBlenderTexture.library)
-                        and (testBlenderTexture.type == 'IMAGE')
-                        and (testBlenderTexture.image)
-                        and (blenderImage)
-                        and (testBlenderTexture.image.filepath
-                        == blenderImage.filepath)
-                        ):
-                    return testBlenderTexture, False
-
-        #elif self.prop_reuse == ms3d_utils.PROP_ITEM_REUSE_MATCH_HASH:
-        #    # irrespecting its real content
-        #    # take materials, that have the same "ms3d_import_hash"
-        #    # custom property (of an previous import)
-        #    propKey = prop(PROP_NAME_HASH)
-        #    hexHash = hex(hash(nameTexture))
-        #    for testBlenderTexture in bpy.data.textures:
-        #        if ((testBlenderTexture) and (not testBlenderTexture.library)
-        #                 and (propKey in testBlenderTexture)
-        #                 and (testBlenderTexture[propKey] == hexHash)):
-        #            return testBlenderTexture, False
-
-        if not allow_create:
-            return None, False
-
-        # create new
-        blenderTexture = bpy.data.textures.new(name=nameTexture, type='IMAGE')
-        self.dict_textures[nameTexture] = blenderTexture
-        if blenderTexture is not None:
-            blenderTexture[prop(ms3d_spec.PROP_NAME_NAME)] = ms3dMaterial.name
-            blenderTexture[prop(propName)] = nameTextureRaw
-        return blenderTexture, True
-
-
-    ###########################################################################
-    def GetMaterial(self, ms3dMaterial):
-        nameMaterial = ms3dMaterial.name
-
-        # already available
-        blenderMaterial = self.dict_materials.get(nameMaterial)
-        if blenderMaterial is not None:
-            return blenderMaterial, False
-
-        # OPTIONAL: try to find an existing one, that fits
-        if self.prop_reuse == ms3d_utils.PROP_ITEM_REUSE_MATCH_VALUES:
-            # irrespecting non tested real content
-            # take materials, that have similar values
-            epsilon = 0.00001
-            for testBlenderMaterial in bpy.data.materials:
-                # take a closer look to its content
-                if ((testBlenderMaterial)
-                        and (not testBlenderMaterial.library)
-                        and (epsilon > abs(testBlenderMaterial.ambient - ((
-                            ms3dMaterial.ambient[0] + ms3dMaterial.ambient[1]
-                            + ms3dMaterial.ambient[2]) / 3.0)
-                            * ms3dMaterial.ambient[3]))
-                        and (epsilon > abs(testBlenderMaterial.diffuse_color[0]
-                            - ms3dMaterial.diffuse[0]))
-                        and (epsilon > abs(testBlenderMaterial.diffuse_color[1]
-                            - ms3dMaterial.diffuse[1]))
-                        and (epsilon > abs(testBlenderMaterial.diffuse_color[2]
-                            - ms3dMaterial.diffuse[2]))
-                        and (epsilon > abs(
-                            testBlenderMaterial.diffuse_intensity
-                            - ms3dMaterial.diffuse[3]))
-                        and (epsilon > abs(
-                            testBlenderMaterial.specular_color[0]
-                            - ms3dMaterial.specular[0]))
-                        and (epsilon > abs(
-                            testBlenderMaterial.specular_color[1]
-                            - ms3dMaterial.specular[1]))
-                        and (epsilon > abs(
-                            testBlenderMaterial.specular_color[2]
-                            - ms3dMaterial.specular[2]))
-                        and (epsilon > abs(
-                            testBlenderMaterial.specular_intensity
-                            - ms3dMaterial.specular[3]))
-                        and (epsilon > abs(testBlenderMaterial.emit - ((
-                            ms3dMaterial.emissive[0] + ms3dMaterial.emissive[1]
-                            + ms3dMaterial.emissive[2]) / 3.0)
-                            * ms3dMaterial.emissive[3]))
-                        and (epsilon > abs(
-                            testBlenderMaterial.specular_hardness
-                            - (ms3dMaterial.shininess * 2.0)))
-                        ):
-
-                    # diffuse texture
-                    fitTexture = False
-                    testTexture = False
-                    if (ms3dMaterial.texture):
-                        testTexture = True
-
-                        if (testBlenderMaterial.texture_slots):
-                            nameTexture = os.path.split(ms3dMaterial.texture)[1]
-
-                            for blenderTextureSlot in testBlenderMaterial.texture_slots:
-                                if ((blenderTextureSlot)
-                                        and (blenderTextureSlot.use_map_color_diffuse)
-                                        and (blenderTextureSlot.texture)
-                                        and (blenderTextureSlot.texture.type == 'IMAGE')
-                                        and (
-                                            ((blenderTextureSlot.texture.image)
-                                                and (blenderTextureSlot.texture.image.filepath)
-                                                and (os.path.split(blenderTextureSlot.texture.image.filepath)[1] == nameTexture)
-                                            )
-                                            or
-                                            ((not blenderTextureSlot.texture.image)
-                                                and (blenderTextureSlot.texture.name == nameTexture)
-                                            )
-                                        )):
-                                    fitTexture = True
-                                    break;
-
-                    fitAlpha = False
-                    testAlpha = False
-                    # alpha texture
-                    if (ms3dMaterial.alphamap):
-                        testAlpha = True
-
-                        if (testBlenderMaterial.texture_slots):
-                            nameAlpha = os.path.split(ms3dMaterial.alphamap)[1]
-
-                            for blenderTextureSlot in testBlenderMaterial.texture_slots:
-                                if ((blenderTextureSlot)
-                                        and (blenderTextureSlot.use_map_alpha)
-                                        and (blenderTextureSlot.texture)
-                                        and (blenderTextureSlot.texture.type == 'IMAGE')
-                                        and (
-                                            ((blenderTextureSlot.texture.image)
-                                                and (blenderTextureSlot.texture.image.filepath)
-                                                and (os.path.split(blenderTextureSlot.texture.image.filepath)[1] == nameAlpha)
-                                            )
-                                            or
-                                            ((not blenderTextureSlot.texture.image)
-                                                and (blenderTextureSlot.texture.name == nameAlpha)
-                                                )
-                                        )):
-                                    fitAlpha = True
-                                    break;
-
-                    if (((not testTexture) or (testTexture and fitTexture))
-                            and ((not testAlpha) or (testAlpha and fitAlpha))):
-                        return testBlenderMaterial, False
-
-        # elif self.prop_reuse == ms3d_utils.PROP_ITEM_REUSE_MATCH_HASH:
-        #    # irrespecting its real content
-        #    # take materials, that have the same "ms3d_import_hash"
-        #    # custom property (of an previous import)
-        #    propKey = prop(PROP_NAME_HASH)
-        #    hexHash = hex(hash(ms3dMaterial))
-        #    for testBlenderMaterial in bpy.data.materials:
-        #        if ((testBlenderMaterial) and (not testBlenderMaterial.library)
-        #                and (propKey in testBlenderMaterial)
-        #                and (testBlenderMaterial[propKey] == hexHash)):
-        #            return testBlenderMaterial, False
-
-        # create new
-        blenderMaterial = bpy.data.materials.new(nameMaterial)
-        self.dict_materials[nameMaterial] = blenderMaterial
-        if blenderMaterial is not None:
-            blenderMaterial[prop(ms3d_spec.PROP_NAME_NAME)] = nameMaterial
-        return blenderMaterial, True
-
-
-    ###########################################################################
-    def GetMesh(self, ms3dGroup):
-        nameMesh = ms3dGroup.name
-
-        # already available
-        blenderMesh = self.dict_meshes.get(nameMesh)
-        if blenderMesh is not None:
-            return blenderMesh, False
-
-        # create new
-        blenderMesh = bpy.data.meshes.new(nameMesh)
-        self.dict_meshes[nameMesh] = blenderMesh
-        if blenderMesh is not None:
-            blenderMesh[prop(ms3d_spec.PROP_NAME_NAME)] = nameMesh
-        return blenderMesh, True
-
-
-    ###########################################################################
-    def GetMeshObject(self, ms3dObject, objectData):
-        nameObject = ms3dObject.name
-
-        # already available
-        blenderObject = self.dict_mesh_objects.get(nameObject)
-        if blenderObject is not None:
-            return blenderObject, False
-
-        # create new
-        blenderObject = bpy.data.objects.new(nameObject, objectData)
-        self.dict_mesh_objects[nameObject] = blenderObject
-        if blenderObject is not None:
-            blenderObject[prop(ms3d_spec.PROP_NAME_NAME)] = nameObject
-        return blenderObject, True
-
-
-    ###########################################################################
-    def GetCommentObject(self, ms3dObject):
-        nameObject = ms3dObject.name
-
-        # already available
-        blenderObject = self.dict_comment_objects.get(nameObject)
-        if blenderObject is not None:
-            return blenderObject, False
-
-        # create new
-        blenderObject = bpy.data.objects.new(nameObject, None)
-        self.dict_comment_objects[nameObject] = blenderObject
-        if blenderObject is not None:
-            blenderObject[prop(ms3d_spec.PROP_NAME_NAME)] = nameObject
-        return blenderObject, True
-
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py
deleted file mode 100644
index 895d4d9..0000000
--- a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py
+++ /dev/null
@@ -1,2270 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-
-
-# ##### BEGIN COPYRIGHT BLOCK #####
-#
-# initial script copyright (c)2011 Alexander Nussbaumer
-#
-# ##### END COPYRIGHT BLOCK #####
-
-
-#import python stuff
-import collections
-import io
-import struct
-import sys
-
-
-#import blender stuff
-import bpy_extras.io_utils
-
-
-PROP_NAME_NAME = "name"
-PROP_NAME_MODE = "mode"
-PROP_NAME_TEXTURE = "texture"
-PROP_NAME_ALPHAMAP = "alphamap"
-PROP_NAME_FLAGS = "flags"
-PROP_NAME_PARENTNAME = "parentName"
-PROP_NAME_EXTRA = "extra"
-PROP_NAME_COMMENT = "comment"
-PROP_NAME_AMBIENT = "ambient"
-PROP_NAME_EMISSIVE = "emissive"
-PROP_NAME_COLOR = "color"
-
-#
-#
-#
-# MilkShape 3D 1.8.5 File Format Specification
-#
-#
-# This specifcation is written in Python 3.1 style. (C was original)
-#
-#
-# The data structures are defined in the order as they appear
-# in the .ms3d file.
-#
-#
-#
-#
-#
-
-
-###############################################################################
-#
-# max values
-#
-MAX_VERTICES = 65534 # 0..65533; note: (65534???, 65535???)
-MAX_TRIANGLES = 65534 # 0..65533; note: (65534???, 65535???)
-MAX_GROUPS = 255 # 1..255; note: (0 default group)
-MAX_MATERIALS = 128 # 0..127; note: (-1 no material)
-MAX_JOINTS = 128 # 0..127; note: (-1 no joint)
-MAX_SMOOTH_GROUP = 32 # 0..32; note: (0 no smoothing group)
-
-
-###############################################################################
-#
-# flags
-#
-FLAG_NONE = 0
-FLAG_SELECTED = 1
-FLAG_HIDDEN = 2
-FLAG_SELECTED2 = 4
-FLAG_DIRTY = 8
-
-
-###############################################################################
-#
-# values
-#
-HEADER = "MS3D000000"
-
-###############################################################################
-#
-# sizes
-#
-SIZE_BYTE = 1
-SIZE_CHAR = 1
-SIZE_WORD = 2
-SIZE_DWORD = 4
-SIZE_FLOAT = 4
-
-
-LENGTH_ID = 10
-LENGTH_NAME = 32
-LENGTH_FILENAME = 128
-
-
-###############################################################################
-def read_byte(file):
-    """ read a single byte from file """
-    value = struct.unpack("<B", file.read(SIZE_BYTE))[0]
-    return value
-
-def write_byte(file, value):
-    """ write a single byte to file """
-    file.write(struct.pack("<B", value))
-
-###############################################################################
-def read_char(file):
-    """ read a single char (signed byte) from file """
-    value = struct.unpack("<b", file.read(SIZE_CHAR))[0]
-    return value
-
-def write_char(file, value):
-    """ write a single char (signed byte) to file """
-    file.write(struct.pack("<b", value))
-
-###############################################################################
-def read_word(file):
-    """ read a single word from file """
-    value = struct.unpack("<H", file.read(SIZE_WORD))[0]
-    return value
-
-def write_word(file, value):
-    """ write a single word to file """
-    file.write(struct.pack("<H", value))
-
-###############################################################################
-def read_dword(file):
-    """ read a single double word from file """
-    value = struct.unpack("<I", file.read(SIZE_DWORD))[0]
-    return value
-
-def write_dword(file, value):
-    """ write a single double word to file """
-    file.write(struct.pack("<I", value))
-
-###############################################################################
-def read_float(file):
-    """ read a single float from file """
-    value = struct.unpack("<f", file.read(SIZE_FLOAT))[0]
-    return value
-
-def write_float(file, value):
-    """ write a single float to file """
-    file.write(struct.pack("<f", value))
-
-###############################################################################
-def read_array(file, itemReader, count):
-    """ read an array[count] of objects from file, by using a itemReader """
-    value = []
-    for i in range(count):
-        itemValue = itemReader(file)
-        value.append(itemValue)
-    return tuple(value)
-
-###############################################################################
-def write_array(file, itemWriter, count, value):
-    """ write an array[count] of objects to file, by using a itemWriter """
-    for i in range(count):
-        itemValue = value[i]
-        itemWriter(file, itemValue)
-
-###############################################################################
-def read_array2(file, itemReader, count, count2):
-    """ read an array[count][count2] of objects from file,
-        by using a itemReader """
-    value = []
-    for i in range(count):
-        itemValue = read_array(file, itemReader, count2)
-        value.append(tuple(itemValue))
-    return value #tuple(value)
-
-###############################################################################
-def write_array2(file, itemWriter, count, count2, value):
-    """ write an array[count][count2] of objects to file,
-        by using a itemWriter """
-    for i in range(count):
-        itemValue = value[i]
-        write_array(file, itemWriter, count2, itemValue)
-
-###############################################################################
-def read_string(file, length):
-    """ read a string of a specific length from file """
-    value = []
-    skip = False
-    for i in range(length):
-        raw = struct.unpack("<b", file.read(SIZE_CHAR))[0]
-        if (raw >= 32) & (raw <= 255):
-            pass
-        else:
-            if (raw == 0):
-                raw = 0
-                skip = True
-            else:
-                raw = 32
-
-        c = chr(raw)
-
-        if (not skip):
-            value.append(c)
-
-    finalValue = "".join(value)
-    return finalValue
-
-###############################################################################
-def write_string(file, length, value):
-    """ write a string of a specific length to file """
-    l = len(value)
-    for i in range(length):
-        if(i < l):
-            c = value[i]
-
-            if (isinstance(c, str)):
-                c = c[0]
-                raw = ord(c)
-            elif (isinstance(c, int)):
-                raw = c
-            else:
-                pass
-        else:
-            raw = 0
-
-        file.write(struct.pack("<b", raw % 255))
-
-
-###############################################################################
-#
-# multi complex types
-#
-###############################################################################
-class ms3d_header_t:
-    """
-    ms3d_header_t
-    """
-    #char id[LENGTH_ID]; // always "MS3D000000"
-    #int version; // 4
-    __slots__ = (
-            "id",
-            "version"
-            )
-
-    def __init__(
-            self,
-            defaultId=HEADER,
-            defaultVersion=4
-            ):
-        """
-        initialize
-
-        :arg id: magic number of file
-        :type id: :class:`string`
-        :arg version: version number of file
-        :type version: :class:`dword`
-        """
-
-        self.id = defaultId
-        self.version = defaultVersion
-
-    def __repr__(self):
-        return "\n<id='{0}', version={1}>".format(
-            self.id,
-            self.version
-            )
-
-    def __hash__(self):
-        return hash(self.id) ^ hash(self.version)
-
-    def __eq__(self, other):
-        return ((self is not None) and (other is not None)
-                and (self.id == other.id)
-                and (self.version == other.version))
-
-    def read(self, file):
-        self.id = read_string(file, LENGTH_ID)
-        self.version = read_dword(file)
-        return self
-
-    def write(self, file):
-        write_string(file, LENGTH_ID, self.id)
-        write_dword(file, self.version)
-
-
-###############################################################################
-class ms3d_vertex_t:
-    """
-    ms3d_vertex_t
-    """
-    #byte flags; // FLAG_NONE | FLAG_SELECTED | FLAG_SELECTED2 | FLAG_HIDDEN
-    #float vertex[3];
-    #char boneId; // -1 = no bone
-    #byte referenceCount;
-    __slots__ = (
-            PROP_NAME_FLAGS,
-            "_vertex",
-            "boneId",
-            "referenceCount",
-            )
-
-    def __init__(
-            self,
-            defaultFlags=FLAG_NONE,
-            defaultVertex=(0.0 ,0.0 ,0.0),
-            defaultBoneId=-1,
-            defaultReferenceCount=0
-            ):
-        """
-        initialize
-
-        :arg flags: selection flag
-        :type flags: :class:`byte`
-        :arg vertex: vertex
-        :type vertex: :class:`float[3]`
-        :arg boneId: bone id
-        :type boneId: :class:`char`
-        :arg referenceCount: reference count
-        :type referenceCount: :class:`byte`
-        """
-
-        self.flags = defaultFlags
-        self._vertex = defaultVertex
-        self.boneId = defaultBoneId
-        self.referenceCount = defaultReferenceCount
-        __hash_cash = None
-
-    def __repr__(self):
-        return "\n<flags={0}, vertex={1}, boneId={2},"\
-                " referenceCount={3}>".format(
-                self.flags,
-                self._vertex,
-                self.boneId,
-                self.referenceCount
-                )
-
-    def __hash__(self):
-        return (hash(self.vertex)
-                #^ hash(self.flags)
-                #^ hash(self.boneId)
-                #^ hash(self.referenceCount)
-                )
-
-    def __eq__(self, other):
-        return ((self.vertex == other.vertex)
-                #and (self.flags == other.flags)
-                #and (self.boneId == other.boneId)
-                #and (self.referenceCount == other.referenceCount)
-                )
-
-
-    @property
-    def vertex(self):
-        return self._vertex
-
-
-    def read(self, file):
-        self.flags = read_byte(file)
-        self._vertex = read_array(file, read_float, 3)
-        self.boneId = read_char(file)
-        self.referenceCount = read_byte(file)
-        return self
-
-    def write(self, file):
-        write_byte(file, self.flags)
-        write_array(file, write_float, 3, self.vertex)
-        write_char(file, self.boneId)
-        write_byte(file, self.referenceCount)
-
-
-###############################################################################
-class ms3d_triangle_t:
-    """
-    ms3d_triangle_t
-    """
-    #word flags; // FLAG_NONE | FLAG_SELECTED | FLAG_SELECTED2 | FLAG_HIDDEN
-    #word vertexIndices[3];
-    #float vertexNormals[3][3];
-    #float s[3];
-    #float t[3];
-    #byte smoothingGroup; // 1 - 32
-    #byte groupIndex;
-    __slots__ = (
-            PROP_NAME_FLAGS,
-            "_vertexIndices",
-            "_vertexNormals",
-            "_s",
-            "_t",
-            "smoothingGroup",
-            "groupIndex"
-            )
-
-    def __init__(
-            self,
-            defaultFlags=FLAG_NONE,
-            defaultVertexIndices=(0, 0, 0),
-            defaultVertexNormals=(
-                    (0.0, 0.0, 0.0),
-                    (0.0, 0.0, 0.0),
-                    (0.0, 0.0, 0.0)),
-            defaultS=(0.0, 0.0, 0.0),
-            defaultT=(0.0, 0.0, 0.0),
-            defaultSmoothingGroup=1,
-            defaultGroupIndex=0
-            ):
-        """
-        initialize
-
-        :arg flags: selection flag
-        :type flags: :class:`word`
-        :arg vertexIndices: vertex indices
-        :type vertexIndices: :class:`word[3]`
-        :arg vertexNormals: vertex normales
-        :type vertexNormals: :class:`float[3][3]`
-        :arg s: s-component
-        :type s: :class:`float[3]`
-        :arg t: t-component
-        :type t: :class:`float[3]`
-        :arg smoothingGroup: smooth group
-        :type smoothingGroup: :class:`byte`
-        :arg groupIndex: group index
-        :type groupIndex: :class:`byte`
-        """
-
-        self.flags = defaultFlags
-        self._vertexIndices = defaultVertexIndices
-        self._vertexNormals = defaultVertexNormals
-        self._s = defaultS
-        self._t = defaultT
-        self.smoothingGroup = defaultSmoothingGroup
-        self.groupIndex = defaultGroupIndex
-
-    def __repr__(self):
-        return "\n<flags={0}, vertexIndices={1}, vertexNormals={2}, s={3},"\
-                " t={4}, smoothingGroup={5}, groupIndex={6}>".format(
-                self.flags,
-                self.vertexIndices,
-                self.vertexNormals,
-                self.s,
-                self.t,
-                self.smoothingGroup,
-                self.groupIndex
-                )
-
-
-    @property
-    def vertexIndices(self):
-        return self._vertexIndices
-
-    @property
-    def vertexNormals(self):
-        return self._vertexNormals
-
-    @property
-    def s(self):
-        return self._s
-
-    @property
-    def t(self):
-        return self._t
-
-
-    def read(self, file):
-        self.flags = read_word(file)
-        self._vertexIndices = read_array(file, read_word, 3)
-        self._vertexNormals = read_array2(file, read_float, 3, 3)
-        self._s = read_array(file, read_float, 3)
-        self._t = read_array(file, read_float, 3)
-        self.smoothingGroup = read_byte(file)
-        self.groupIndex = read_byte(file)
-        return self
-
-    def write(self, file):
-        write_word(file, self.flags)
-        write_array(file, write_word, 3, self.vertexIndices)
-        write_array2(file, write_float, 3, 3, self.vertexNormals)
-        write_array(file, write_float, 3, self.s)
-        write_array(file, write_float, 3, self.t)
-        write_byte(file, self.smoothingGroup)
-        write_byte(file, self.groupIndex)
-
-
-###############################################################################
-class ms3d_group_t:
-    """
-    ms3d_group_t
-    """
-    #byte flags; // FLAG_NONE | FLAG_SELECTED | FLAG_HIDDEN
-    #char name[32];
-    #word numtriangles;
-    #word triangleIndices[numtriangles]; // the groups group the triangles
-    #char materialIndex; // -1 = no material
-    __slots__ = (
-            PROP_NAME_FLAGS,
-            PROP_NAME_NAME,
-            "_numtriangles",
-            "_triangleIndices",
-            "materialIndex"
-            )
-
-    def __init__(
-            self,
-            defaultFlags=FLAG_NONE,
-            defaultName="",
-            defaultNumtriangles=0,
-            defaultTriangleIndices=None,
-            defaultMaterialIndex=-1
-            ):
-        """
-        initialize
-
-        :arg flags: selection flag
-        :type flags: :class:`byte`
-        :arg name: name
-        :type name: :class:`string`
-        :arg numtriangles: number of triangles
-        :type numtriangles: :class:`word`
-        :arg triangleIndices: array of triangle indices
-        :type triangleIndices: :class:`word`
-        :arg materialIndex: material index
-        :type materialIndex: :class:`char`
-        """
-
-        if (defaultName is None):
-            defaultName = ""
-
-        if (defaultTriangleIndices is None):
-            defaultTriangleIndices = []
-
-        self.flags = defaultFlags
-        self.name = defaultName
-        #self._numtriangles = defaultNumtriangles
-        self._triangleIndices = defaultTriangleIndices
-        self.materialIndex = defaultMaterialIndex
-
-    def __repr__(self):
-        return "\n<flags={0}, name='{1}', numtriangles={2},"\
-                " triangleIndices={3}, materialIndex={4}>".format(
-                self.flags,
-                self.name,
-                self.numtriangles,
-                self.triangleIndices,
-                self.materialIndex
-                )
-
-
-    @property
-    def numtriangles(self):
-        if self.triangleIndices is None:
-            return 0
-        return len(self.triangleIndices)
-
-    @property
-    def triangleIndices(self):
-        return self._triangleIndices
-
-
-    def read(self, file):
-        self.flags = read_byte(file)
-        self.name = read_string(file, LENGTH_NAME)
-        _numtriangles = read_word(file)
-        self._triangleIndices = read_array(file, read_word, _numtriangles)
-        self.materialIndex = read_char(file)
-        return self
-
-    def write(self, file):
-        write_byte(file, self.flags)
-        write_string(file, LENGTH_NAME, self.name)
-        write_word(file, self.numtriangles)
-        write_array(file, write_word, self.numtriangles, self.triangleIndices)
-        write_char(file, self.materialIndex)
-
-
-###############################################################################
-class ms3d_material_t:
-    """
-    ms3d_material_t
-    """
-    #char name[LENGTH_NAME];
-    #float ambient[4];
-    #float diffuse[4];
-    #float specular[4];
-    #float emissive[4];
-    #float shininess; // 0.0f - 128.0f
-    #float transparency; // 0.0f - 1.0f
-    #char mode; // 0, 1, 2 is unused now
-    #char texture[LENGTH_FILENAME]; // texture.bmp
-    #char alphamap[LENGTH_FILENAME]; // alpha.bmp
-    __slots__ = (
-            PROP_NAME_NAME,
-            "_ambient",
-            "_diffuse",
-            "_specular",
-            "_emissive",
-            "shininess",
-            "transparency",
-            PROP_NAME_MODE,
-            PROP_NAME_TEXTURE,
-            PROP_NAME_ALPHAMAP
-            )
-
-    def __init__(
-            self,
-            defaultName="",
-            defaultAmbient=(0.0, 0.0, 0.0, 0.0),
-            defaultDiffuse=(0.0, 0.0, 0.0, 0.0),
-            defaultSpecular=(0.0, 0.0, 0.0, 0.0),
-            defaultEmissive=(0.0, 0.0, 0.0, 0.0),
-            defaultShininess=0.0,
-            defaultTransparency=0.0,
-            defaultMode=0,
-            defaultTexture="",
-            defaultAlphamap=""
-            ):
-        """
-        initialize
-
-        :arg name: name
-        :type name: :class:`string`
-        :arg ambient: ambient
-        :type ambient: :class:`float[4]`
-        :arg diffuse: diffuse
-        :type diffuse: :class:`float[4]`
-        :arg specular: specular
-        :type specular: :class:`float[4]`
-        :arg emissive: emissive
-        :type emissive: :class:`float[4]`
-        :arg shininess: shininess
-        :type shininess: :class:`float`
-        :arg transparency: transparency
-        :type transparency: :class:`float`
-        :arg mode: mode
-        :type mode: :class:`char`
-        :arg texture: texture name
-        :type texture: :class:`string`
-        :arg alphamap: alphamap name
-        :type alphamap: :class:`string`
-        """
-
-        if (defaultName is None):
-            defaultName = ""
-
-        if (defaultTexture is None):
-            defaultTexture = ""
-
-        if (defaultAlphamap is None):
-            defaultAlphamap = ""
-
-        self.name = defaultName
-        self._ambient = defaultAmbient
-        self._diffuse = defaultDiffuse
-        self._specular = defaultSpecular
-        self._emissive = defaultEmissive
-        self.shininess = defaultShininess
-        self.transparency = defaultTransparency
-        self.mode = defaultMode
-        self.texture = defaultTexture
-        self.alphamap = defaultAlphamap
-
-    def __repr__(self):
-        return "\n<name='{0}', ambient={1}, diffuse={2}, specular={3},"\
-                " emissive={4}, shininess={5}, transparency={6}, mode={7},"\
-                " texture='{8}', alphamap='{9}'>".format(
-                self.name,
-                self.ambient,
-                self.diffuse,
-                self.specular,
-                self.emissive,
-                self.shininess,
-                self.transparency,
-                self.mode,
-                self.texture,
-                self.alphamap
-                )
-
-    def __hash__(self):
-        return (hash(self.name)
-
-                ^ hash(self.ambient)
-                ^ hash(self.diffuse)
-                ^ hash(self.specular)
-                ^ hash(self.emissive)
-
-                ^ hash(self.shininess)
-                ^ hash(self.transparency)
-                ^ hash(self.mode)
-
-                ^ hash(self.texture)
-                ^ hash(self.alphamap)
-                )
-
-    def __eq__(self, other):
-        return ((self.name == other.name)
-
-                and (self.ambient == other.ambient)
-                and (self.diffuse == other.diffuse)
-                and (self.specular == other.specular)
-                and (self.emissive == other.emissive)
-
-                and (self.shininess == other.shininess)
-                and (self.transparency == other.transparency)
-                and (self.mode == other.mode)
-
-                #and (self.texture == other.texture)
-                #and (self.alphamap == other.alphamap)
-                )
-
-
-    @property
-    def ambient(self):
-        return self._ambient
-
-    @property
-    def diffuse(self):
-        return self._diffuse
-
-    @property
-    def specular(self):
-        return self._specular
-
-    @property
-    def emissive(self):
-        return self._emissive
-
-
-    def read(self, file):
-        self.name = read_string(file, LENGTH_NAME)
-        self._ambient = read_array(file, read_float, 4)
-        self._diffuse = read_array(file, read_float, 4)
-        self._specular = read_array(file, read_float, 4)
-        self._emissive = read_array(file, read_float, 4)
-        self.shininess = read_float(file)
-        self.transparency = read_float(file)
-        self.mode = read_char(file)
-        self.texture = read_string(file, LENGTH_FILENAME)
-        self.alphamap = read_string(file, LENGTH_FILENAME)
-        return self
-
-    def write(self, file):
-        write_string(file, LENGTH_NAME, self.name)
-        write_array(file, write_float, 4, self.ambient)
-        write_array(file, write_float, 4, self.diffuse)
-        write_array(file, write_float, 4, self.specular)
-        write_array(file, write_float, 4, self.emissive)
-        write_float(file, self.shininess)
-        write_float(file, self.transparency)
-        write_char(file, self.mode)
-        write_string(file, LENGTH_FILENAME, self.texture)
-        write_string(file, LENGTH_FILENAME, self.alphamap)
-
-
-###############################################################################
-class ms3d_keyframe_rot_t:
-    """
-    ms3d_keyframe_rot_t
-    """
-    #float time; // time in seconds
-    #float rotation[3]; // x, y, z angles
-    __slots__ = (
-            "time",
-            "_rotation"
-            )
-
-    def __init__(
-            self,
-            defaultTime=0.0,
-            defaultRotation=(0.0, 0.0, 0.0)
-            ):
-        """
-        initialize
-
-        :arg time: time
-        :type time: :class:float`
-        :arg rotation: rotation
-        :type rotation: :class:`float[3]`
-        """
-
-        self.time = defaultTime
-        self._rotation = defaultRotation
-
-    def __repr__(self):
-        return "\n<time={0}, rotation={1}>".format(
-                self.time,
-                self.rotation,
-                )
-
-
-    @property
-    def rotation(self):
-        return self._rotation
-
-
-    def read(self, file):
-        self.time = read_float(file)
-        self._rotation = read_array(file, read_float, 3)
-        return self
-
-    def write(self, file):
-        write_float(file, self.time)
-        write_array(file, write_float, 3, self.rotation)
-
-
-###############################################################################
-class ms3d_keyframe_pos_t:
-    """
-    ms3d_keyframe_pos_t
-    """
-    #float time; // time in seconds
-    #float position[3]; // local position
-    __slots__ = (
-            "time",
-            "_position"
-            )
-
-    def __init__(
-            self,
-            defaultTime=0.0,
-            defaultPosition=(0.0, 0.0, 0.0)
-            ):
-        """
-        initialize
-
-        :arg time: time
-        :type time: :class:`float`
-        :arg position: position
-        :type position: :class:`float[3]`
-        """
-
-        self.time = defaultTime
-        self._position = defaultPosition
-
-    def __repr__(self):
-        return "\n<time={0}, position={1}>".format(
-                self.time,
-                self.position,
-                )
-
-
-    @property
-    def position(self):
-        return self._position
-
-
-    def read(self, file):
-        self.time = read_float(file)
-        self._position = read_array(file, read_float, 3)
-        return self
-
-    def write(self, file):
-        write_float(file, self.time)
-        write_array(file, write_float, 3, self.position)
-
-
-###############################################################################
-class ms3d_joint_t:
-    """
-    ms3d_joint_t
-    """
-    #byte flags; // FLAG_NONE | FLAG_SELECTED | FLAG_DIRTY
-    #char name[LENGTH_NAME];
-    #char parentName[LENGTH_NAME];
-    #float rotation[3]; // local reference matrix
-    #float position[3];
-    #word numKeyFramesRot;
-    #word numKeyFramesTrans;
-    #// local animation matrices
-    #ms3d_keyframe_rot_t keyFramesRot[numKeyFramesRot];
-    #// local animation matrices
-    #ms3d_keyframe_pos_t keyFramesTrans[numKeyFramesTrans];
-    __slots__ = (
-            PROP_NAME_FLAGS,
-            PROP_NAME_NAME,
-            PROP_NAME_PARENTNAME,
-            "_rotation",
-            "_position",
-            "_numKeyFramesRot",
-            "_numKeyFramesTrans",
-            "_keyFramesRot",
-            "_keyFramesTrans"
-            )
-
-    def __init__(
-            self,
-            defaultFlags=FLAG_NONE,
-            defaultName="",
-            defaultParentName="",
-            defaultRotation=(0.0, 0.0, 0.0),
-            defaultPosition=(0.0, 0.0, 0.0),
-            defaultNumKeyFramesRot=0,
-            defaultNumKeyFramesTrans=0,
-            defaultKeyFramesRot=None,
-            defaultKeyFramesTrans=None
-            ):
-        """
-        initialize
-
-        :arg flags: flags
-        :type flags: :class:`byte`
-        :arg name: name
-        :type name: :class:`string`
-        :arg parentName: parentName
-        :type parentName: :class:`string`
-        :arg rotation: rotation
-        :type rotation: :class:`float[3]`
-        :arg position: position
-        :type position: :class:`float[3]`
-        :arg numKeyFramesRot: numKeyFramesRot
-        :type numKeyFramesRot: :class:`word`
-        :arg numKeyFramesTrans: numKeyFramesTrans
-        :type numKeyFramesTrans: :class:`word`
-        :arg keyFramesRot: keyFramesRot
-        :type nkeyFramesRotame: :class:`ms3d_spec.ms3d_keyframe_rot_t[]`
-        :arg keyFramesTrans: keyFramesTrans
-        :type keyFramesTrans: :class:`ms3d_spec.ms3d_keyframe_pos_t[]`
-        """
-
-        if (defaultName is None):
-            defaultName = ""
-
-        if (defaultParentName is None):
-            defaultParentName = ""
-
-        if (defaultKeyFramesRot is None):
-            defaultKeyFramesRot = [] #ms3d_keyframe_rot_t()
-
-        if (defaultKeyFramesTrans is None):
-            defaultKeyFramesTrans = [] #ms3d_keyframe_pos_t()
-
-        self.flags = defaultFlags
-        self.name = defaultName
-        self.parentName = defaultParentName
-        self._rotation = defaultRotation
-        self._position = defaultPosition
-        #self._numKeyFramesRot = defaultNumKeyFramesRot
-        #self._numKeyFramesTrans = defaultNumKeyFramesTrans
-        self._keyFramesRot = defaultKeyFramesRot
-        self._keyFramesTrans = defaultKeyFramesTrans
-
-    def __repr__(self):
-        return "\n<flags={0}, name='{1}', parentName='{2}', rotation={3},"\
-                " position={4}, numKeyFramesRot={5}, numKeyFramesTrans={6},"\
-                " keyFramesRot={7}, keyFramesTrans={8}>".format(
-                self.flags,
-                self.name,
-                self.parentName,
-                self.rotation,
-                self.position,
-                self.numKeyFramesRot,
-                self.numKeyFramesTrans,
-                self.keyFramesRot,
-                self.keyFramesTrans
-                )
-
-
-    @property
-    def rotation(self):
-        return self._rotation
-
-    @property
-    def position(self):
-        return self._position
-
-    @property
-    def numKeyFramesRot(self):
-        if self.keyFramesRot is None:
-            return 0
-        return len(self.keyFramesRot)
-
-    @property
-    def numKeyFramesTrans(self):
-        if self.keyFramesTrans is None:
-            return 0
-        return len(self.keyFramesTrans)
-
-    @property
-    def keyFramesRot(self):
-        return self._keyFramesRot
-
-    @property
-    def keyFramesTrans(self):
-        return self._keyFramesTrans
-
-
-    def read(self, file):
-        self.flags = read_byte(file)
-        self.name = read_string(file, LENGTH_NAME)
-        self.parentName = read_string(file, LENGTH_NAME)
-        self._rotation = read_array(file, read_float, 3)
-        self._position = read_array(file, read_float, 3)
-        _numKeyFramesRot = read_word(file)
-        _numKeyFramesTrans = read_word(file)
-        self._keyFramesRot = []
-        for i in range(_numKeyFramesRot):
-            self.keyFramesRot.append(ms3d_keyframe_rot_t().read(file))
-        self._keyFramesTrans = []
-        for i in range(_numKeyFramesTrans):
-            self.keyFramesTrans.append(ms3d_keyframe_pos_t().read(file))
-        return self
-
-    def write(self, file):
-        write_byte(file, self.flags)
-        write_string(file, LENGTH_NAME, self.name)
-        write_string(file, LENGTH_NAME, self.parentName)
-        write_array(file, write_float, 3, self.rotation)
-        write_array(file, write_float, 3, self.position)
-        write_word(file, self.numKeyFramesRot)
-        write_word(file, self.numKeyFramesTrans)
-        for i in range(self.numKeyFramesRot):
-            self.keyFramesRot[i].write(file)
-        for i in range(self.numKeyFramesTrans):
-            self.keyFramesTrans[i].write(file)
-
-
-###############################################################################
-class ms3d_comment_t:
-    """
-    ms3d_comment_t
-    """
-    #int index; // index of group, material or joint
-    #int commentLength; // length of comment (terminating '\0' is not saved),
-    #    "MC" has comment length of 2 (not 3)
-    #char comment[commentLength]; // comment
-    __slots__ = (
-            "index",
-            "_commentLength",
-            PROP_NAME_COMMENT
-            )
-
-    def __init__(
-            self,
-            defaultIndex=0,
-            defaultCommentLength=0,
-            defaultComment=""
-            ):
-        """
-        initialize
-
-        :arg index: index
-        :type index: :class:`dword`
-        :arg commentLength: commentLength
-        :type commentLength: :class:`dword`
-        :arg comment: comment
-        :type comment: :class:`string`
-        """
-
-        if (defaultComment is None):
-            defaultComment = ""
-
-        self.index = defaultIndex
-        #self._commentLength = defaultCommentLength
-        self.comment = defaultComment
-
-    def __repr__(self):
-        return "\n<index={0}, commentLength={1}, comment={2}>".format(
-                self.index,
-                self.commentLength,
-                self.comment
-                )
-
-
-    @property
-    def commentLength(self):
-        if self.comment is None:
-            return 0
-        return len(self.comment)
-
-
-    def read(self, file):
-        self.index = read_dword(file)
-        _commentLength = read_dword(file)
-        self.comment = read_string(file, _commentLength)
-        return self
-
-    def write(self, file):
-        write_dword(file, self.index)
-        write_dword(file, self.commentLength)
-        write_string(file, self.commentLength, self.comment)
-
-
-###############################################################################
-class ms3d_modelcomment_t:
-    """
-    ms3d_modelcomment_t
-    """
-    #int commentLength; // length of comment (terminating '\0' is not saved),
-    #    "MC" has comment length of 2 (not 3)
-    #char comment[commentLength]; // comment
-    __slots__ = (
-            "_commentLength",
-            PROP_NAME_COMMENT
-            )
-
-    def __init__(
-            self,
-            defaultCommentLength=0,
-            defaultComment=""
-            ):
-        """
-        initialize
-
-        :arg commentLength: commentLength
-        :type commentLength: :class:`dword`
-        :arg comment: comment
-        :type comment: :class:`string`
-        """
-
-        if (defaultComment is None):
-            defaultComment = ""
-
-        #self._commentLength = defaultCommentLength
-        self.comment = defaultComment
-
-    def __repr__(self):
-        return "\n<commentLength={0}, comment={1}>".format(
-                self.commentLength,
-                self.comment
-                )
-
-
-    @property
-    def commentLength(self):
-        if self.comment is None:
-            return 0
-        return len(self.comment)
-
-
-    def read(self, file):
-        _commentLength = read_dword(file)
-        self.comment = read_string(file, _commentLength)
-        return self
-
-    def write(self, file):
-        write_dword(file, self.commentLength)
-        write_string(file, self.commentLength, self.comment)
-
-
-###############################################################################
-class ms3d_vertex_ex1_t:
-    """
-    ms3d_vertex_ex1_t
-    """
-    #char boneIds[3]; // index of joint or -1, if -1, then that weight is
-    #    ignored, since subVersion 1
-    #byte weights[3]; // vertex weight ranging from 0 - 255, last weight is
-    #    computed by 1.0 - sum(all weights), since subVersion 1
-    #// weight[0] is the weight for boneId in ms3d_vertex_t
-    #// weight[1] is the weight for boneIds[0]
-    #// weight[2] is the weight for boneIds[1]
-    #// 1.0f - weight[0] - weight[1] - weight[2] is the weight for boneIds[2]
-    __slots__ = (
-            "_boneIds",
-            "_weights"
-            )
-
-    def __init__(
-            self,
-            defaultBoneIds=(-1, -1, -1),
-            defaultWeights=(0, 0, 0)
-            ):
-        """
-        initialize
-
-        :arg boneIds: boneIds
-        :type boneIds: :class:`char[3]`
-        :arg weights: weights
-        :type weights: :class:`byte[3]`
-        """
-
-        self._boneIds = defaultBoneIds
-        self._weights = defaultWeights
-
-    def __repr__(self):
-        return "\n<boneIds={0}, weights={1}>".format(
-                self.boneIds,
-                self.weights
-                )
-
-
-    @property
-    def boneIds(self):
-        return self._boneIds
-
-    @property
-    def weights(self):
-        return self._weights
-
-
-    def read(self, file):
-        self._boneIds = read_array(file, read_char, 3)
-        self._weights = read_array(file, read_byte, 3)
-        return self
-
-    def write(self, file):
-        write_array(file, write_char, 3, self.boneIds)
-        write_array(file, write_byte, 3, self.weights)
-
-
-###############################################################################
-class ms3d_vertex_ex2_t:
-    """
-    ms3d_vertex_ex2_t
-    """
-    #char boneIds[3]; // index of joint or -1, if -1, then that weight is
-    #    ignored, since subVersion 1
-    #byte weights[3]; // vertex weight ranging from 0 - 100, last weight is
-    #    computed by 1.0 - sum(all weights), since subVersion 1
-    #// weight[0] is the weight for boneId in ms3d_vertex_t
-    #// weight[1] is the weight for boneIds[0]
-    #// weight[2] is the weight for boneIds[1]
-    #// 1.0f - weight[0] - weight[1] - weight[2] is the weight for boneIds[2]
-    #unsigned int extra; // vertex extra, which can be used as color or
-    #    anything else, since subVersion 2
-    __slots__ = (
-            "_boneIds",
-            "_weights",
-            PROP_NAME_EXTRA
-            )
-
-    def __init__(
-            self,
-            defaultBoneIds=(-1, -1, -1),
-            defaultWeights=(0, 0, 0),
-            defaultExtra=0
-            ):
-        """
-        initialize
-
-        :arg boneIds: boneIds
-        :type boneIds: :class:`char[3]`
-        :arg weights: weights
-        :type weights: :class:`byte[3]`
-        :arg extra: extra
-        :type extra: :class:`dword`
-        """
-
-        self._boneIds = defaultBoneIds
-        self._weights = defaultWeights
-        self.extra = defaultExtra
-
-    def __repr__(self):
-        return "\n<boneIds={0}, weights={1}, extra={2}>".format(
-                self.boneIds,
-                self.weights,
-                self.extra
-                )
-
-
-    @property
-    def boneIds(self):
-        return self._boneIds
-
-    @property
-    def weights(self):
-        return self._weights
-
-
-    def read(self, file):
-        self._boneIds = read_array(file, read_char, 3)
-        self._weights = read_array(file, read_byte, 3)
-        self.extra = read_dword(file)
-        return self
-
-    def write(self, file):
-        write_array(file, write_char, 3, self.boneIds)
-        write_array(file, write_byte, 3, self.weights)
-        write_dword(file, self.extra)
-
-
-###############################################################################
-class ms3d_vertex_ex3_t:
-    """
-    ms3d_vertex_ex3_t
-    """
-    #char boneIds[3]; // index of joint or -1, if -1, then that weight is
-    #    ignored, since subVersion 1
-    #byte weights[3]; // vertex weight ranging from 0 - 100, last weight is
-    #    computed by 1.0 - sum(all weights), since subVersion 1
-    #// weight[0] is the weight for boneId in ms3d_vertex_t
-    #// weight[1] is the weight for boneIds[0]
-    #// weight[2] is the weight for boneIds[1]
-    #// 1.0f - weight[0] - weight[1] - weight[2] is the weight for boneIds[2]
-    #unsigned int extra; // vertex extra, which can be used as color or
-    #    anything else, since subVersion 2
-    __slots__ = (
-            "_boneIds",
-            "_weights",
-            PROP_NAME_EXTRA
-            )
-
-    def __init__(
-            self,
-            defaultBoneIds=(-1, -1, -1),
-            defaultWeights=(0, 0, 0),
-            defaultExtra=0
-            ):
-        """
-        initialize
-
-        :arg boneIds: boneIds
-        :type boneIds: :class:`char[3]`
-        :arg weights: weights
-        :type weights: :class:`byte[3]`
-        :arg extra: extra
-        :type extra: :class:`dword`
-        """
-
-        self._boneIds = defaultBoneIds
-        self._weights = defaultWeights
-        self.extra = defaultExtra
-
-    def __repr__(self):
-        return "\n<boneIds={0}, weights={1}, extra={2}>".format(
-                self.boneIds,
-                self.weights,
-                self.extra
-                )
-
-
-    @property
-    def boneIds(self):
-        return self._boneIds
-
-    @property
-    def weights(self):
-        return self._weights
-
-
-    def read(self, file):
-        self._boneIds = read_array(file, read_char, 3)
-        self._weights = read_array(file, read_byte, 3)
-        self.extra = read_dword(file)
-        return self
-
-    def write(self, file):
-        write_array(file, write_char, 3, self.boneIds)
-        write_array(file, write_byte, 3, self.weights)
-        write_dword(file, self.extra)
-
-
-###############################################################################
-class ms3d_joint_ex_t:
-    """
-    ms3d_joint_ex_t
-    """
-    #float color[3]; // joint color, since subVersion == 1
-    __slots__ = (
-            "_color"
-            )
-
-    def __init__(
-            self,
-            defaultColor=(0.0, 0.0, 0.0)
-            ):
-        """
-        initialize
-
-        :arg color: color
-        :type color: :class:`float[3]`
-        """
-
-        self._color = defaultColor
-
-    def __repr__(self):
-        return "\n<color={0}>".format(self.color)
-
-
-    @property
-    def color(self):
-        return self._color
-
-
-    def read(self, file):
-        self._color = read_array(file, read_float, 3)
-        return self
-
-    def write(self, file):
-        write_array(file, write_float, 3, self.color)
-
-
-###############################################################################
-class ms3d_model_ex_t:
-    """
-    ms3d_model_ex_t
-    """
-    #float jointSize; // joint size, since subVersion == 1
-    #int transparencyMode; // 0 = simple, 1 = depth buffered with alpha ref,
-    #    2 = depth sorted triangles, since subVersion == 1
-    #float alphaRef; // alpha reference value for transparencyMode = 1,
-    #    since subVersion == 1
-    __slots__ = (
-            "jointSize",
-            "transparencyMode",
-            "alphaRef"
-            )
-
-    def __init__(
-            self,
-            defaultJointSize=0.0,
-            defaultTransparencyMode=0,
-            defaultAlphaRef=0.0
-            ):
-        """
-        initialize
-
-        :arg jointSize: jointSize
-        :type jointSize: :class:`float[3]`
-        :arg transparencyMode: transparencyMode
-        :type transparencyMode: :class:`dword`
-        :arg alphaRef: alphaRef
-        :type alphaRef: :class:`float[3]`
-        """
-
-        self.jointSize = defaultJointSize
-        self.transparencyMode = defaultTransparencyMode
-        self.alphaRef = defaultAlphaRef
-
-    def __repr__(self):
-        return "\n<jointSize={0}, transparencyMode={1}, alphaRef={2}>".format(
-                self.jointSize,
-                self.transparencyMode,
-                self.alphaRef
-                )
-
-    def read(self, file):
-        self.jointSize = read_float(file)
-        self.transparencyMode = read_dword(file)
-        self.alphaRef = read_float(file)
-        return self
-
-    def write(self, file):
-        write_float(file, self.jointSize)
-        write_dword(file, self.transparencyMode)
-        write_float(file, self.alphaRef)
-
-
-###############################################################################
-#
-# file format
-#
-###############################################################################
-class ms3d_file_t:
-    """
-    ms3d_file_t
-    """
-    __slot__ = (
-            "header",
-            "_nNumVertices",
-            "_vertices",
-            "_nNumTriangles",
-            "_triangles",
-            "_nNumGroups",
-            "_groups",
-            "_nNumMaterials",
-            "_materials",
-            "fAnimationFPS",
-            "fCurrentTime",
-            "iTotalFrames",
-            "_nNumJoints",
-            "_joints",
-            "subVersionComments",
-            "_nNumGroupComments",
-            "_groupComments",
-            "_nNumMaterialComments",
-            "_materialComments",
-            "_nNumJointComments",
-            "_jointComments",
-            "_nHasModelComment",
-            "_modelComment",
-            "subVersionVertexExtra",
-            "_vertex_ex",
-            "subVersionJointExtra",
-            "_joint_ex",
-            "subVersionModelExtra",
-            "model_ex",
-            "_str_cash",
-            PROP_NAME_NAME
-            )
-
-    def __init__(
-            self,
-            defaultName=""
-            ):
-        """
-        initialize
-        """
-
-        if (defaultName is None):
-            defaultName = ""
-
-        self.name = defaultName
-
-        # First comes the header (sizeof(ms3d_header_t) == 14)
-        self.header = ms3d_header_t()
-
-        # Then comes the number of vertices
-        #self.nNumVertices = 0
-
-        # Then comes nNumVertices times ms3d_vertex_t structs
-        # (sizeof(ms3d_vertex_t) == 15)
-        self._vertices = [] #ms3d_vertex_t()
-
-        # Then comes the number of triangles
-        #self.nNumTriangles = 0
-
-        # Then come nNumTriangles times ms3d_triangle_t structs
-        # (sizeof(ms3d_triangle_t) == 70)
-        self._triangles = [] #ms3d_triangle_t()
-
-
-        # Then comes the number of groups
-        #self.nNumGroups = 0
-
-        # Then comes nNumGroups times groups (the sizeof a group is dynamic,
-        # because of triangleIndices is numtriangles long)
-        self._groups = [] #ms3d_group_t()
-
-
-        # number of materials
-        #self.nNumMaterials = 0
-
-        # Then comes nNumMaterials times ms3d_material_t structs
-        # (sizeof(ms3d_material_t) == 361)
-        self._materials = [] #ms3d_material_t()
-
-
-        # save some keyframer data
-        self.fAnimationFPS = 0.0
-        self.fCurrentTime = 0.0
-        self.iTotalFrames = 0
-
-
-        # number of joints
-        #self.nNumJoints = 0
-
-        # Then comes nNumJoints joints (the size of joints are dynamic,
-        # because each joint has a differnt count of keys
-        self._joints = [] #ms3d_joint_t()
-
-
-        # Then comes the subVersion of the comments part, which is not
-        # available in older files
-        self.subVersionComments = 1
-
-
-        # Then comes the numer of group comments
-        #self.nNumGroupComments = 0
-
-        # Then comes nNumGroupComments times group comments, which are dynamic,
-        # because the comment can be any length
-        self._groupComments = [] #ms3d_comment_t()
-
-
-        # Then comes the number of material comments
-        #self.nNumMaterialComments = 0
-
-        # Then comes nNumMaterialComments times material comments, which are
-        # dynamic, because the comment can be any length
-        self._materialComments = [] #ms3d_comment_t()
-
-
-        # Then comes the number of joint comments
-        #self.nNumJointComments = 0
-
-        # Then comes nNumJointComments times joint comments, which are dynamic,
-        # because the comment can be any length
-        self._jointComments = [] #ms3d_comment_t()
-
-
-        # Then comes the number of model comments, which is always 0 or 1
-        #self.nHasModelComment = 0
-
-        # Then comes nHasModelComment times model comments, which are dynamic,
-        # because the comment can be any length
-        self._modelComment = None #ms3d_modelcomment_t()
-
-
-        # Then comes the subversion of the vertex extra information like bone
-        # weights, extra etc.
-        self.subVersionVertexExtra = 2
-
-        # ms3d_vertex_ex_t for subVersionVertexExtra in {1, 2, 3}
-        #ms3d_vertex_ex1_t() #ms3d_vertex_ex2_t() #ms3d_vertex_ex3_t()
-        self._vertex_ex = []
-        # Then comes nNumVertices times ms3d_vertex_ex_t structs
-        # (sizeof(ms3d_vertex_ex_t) == 10)
-        ##
-
-        # Then comes the subversion of the joint extra information like
-        # color etc.
-        self.subVersionJointExtra = 1 # ??? in spec it is 2,
-        # but in MilkShake3D 1.8.4 a joint subversion of 2 is unknown
-
-        # ms3d_joint_ex_t for subVersionJointExtra == 1
-        self._joint_ex = [] #ms3d_joint_ex_t()
-        # Then comes nNumJoints times ms3d_joint_ex_t structs
-        # (sizeof(ms3d_joint_ex_t) == 12)
-        ##
-
-        # Then comes the subversion of the model extra information
-        self.subVersionModelExtra = 1
-
-        # ms3d_model_ex_t for subVersionModelExtra == 1
-        self.model_ex = ms3d_model_ex_t()
-
-
-    @property
-    def nNumVertices(self):
-        if self.vertices is None:
-            return 0
-        return len(self.vertices)
-
-    @property
-    def vertices(self):
-        return self._vertices
-
-
-    @property
-    def nNumTriangles(self):
-        if self.triangles is None:
-            return 0
-        return len(self.triangles)
-
-    @property
-    def triangles(self):
-        return self._triangles
-
-
-    @property
-    def nNumGroups(self):
-        if self.groups is None:
-            return 0
-        return len(self.groups)
-
-    @property
-    def groups(self):
-        return self._groups
-
-
-    @property
-    def nNumMaterials(self):
-        if self.materials is None:
-            return 0
-        return len(self.materials)
-
-    @property
-    def materials(self):
-        return self._materials
-
-
-    @property
-    def nNumJoints(self):
-        if self.joints is None:
-            return 0
-        return len(self.joints)
-
-    @property
-    def joints(self):
-        return self._joints
-
-
-    @property
-    def nNumGroupComments(self):
-        if self.groupComments is None:
-            return 0
-        return len(self.groupComments)
-
-    @property
-    def groupComments(self):
-        return self._groupComments
-
-
-    @property
-    def nNumMaterialComments(self):
-        if self.materialComments is None:
-            return 0
-        return len(self.materialComments)
-
-    @property
-    def materialComments(self):
-        return self._materialComments
-
-
-    @property
-    def nNumJointComments(self):
-        if self.jointComments is None:
-            return 0
-        return len(self.jointComments)
-
-    @property
-    def jointComments(self):
-        return self._jointComments
-
-
-    @property
-    def nHasModelComment(self):
-        if self.modelComment is None:
-            return 0
-        return 1
-
-    @property
-    def modelComment(self):
-        return self._modelComment
-
-
-    @property
-    def vertex_ex(self):
-        return self._vertex_ex
-
-    @property
-    def joint_ex(self):
-        return self._joint_ex
-
-
-    def print_internal(self):
-        print()
-        print("##############################################################")
-        print("## the internal data of ms3d_file_t object...")
-        print("##")
-
-        print("header={0}".format(self.header))
-
-        print("nNumVertices={0}".format(self.nNumVertices))
-        print("vertices=[", end="")
-        if self.vertices:
-            for obj in self.vertices:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("nNumTriangles={0}".format(self.nNumTriangles))
-        print("triangles=[", end="")
-        if self.triangles:
-            for obj in self.triangles:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("nNumGroups={0}".format(self.nNumGroups))
-        print("groups=[", end="")
-        if self.groups:
-            for obj in self.groups:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("nNumMaterials={0}".format(self.nNumMaterials))
-        print("materials=[", end="")
-        if self.materials:
-            for obj in self.materials:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("fAnimationFPS={0}".format(self.fAnimationFPS))
-        print("fCurrentTime={0}".format(self.fCurrentTime))
-        print("iTotalFrames={0}".format(self.iTotalFrames))
-
-        print("nNumJoints={0}".format(self.nNumJoints))
-        print("joints=[", end="")
-        if self.joints:
-            for obj in self.joints:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("subVersionComments={0}".format(self.subVersionComments))
-
-        print("nNumGroupComments={0}".format(self.nNumGroupComments))
-        print("groupComments=[", end="")
-        if self.groupComments:
-            for obj in self.groupComments:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("nNumMaterialComments={0}".format(self.nNumMaterialComments))
-        print("materialComments=[", end="")
-        if self.materialComments:
-            for obj in self.materialComments:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("nNumJointComments={0}".format(self.nNumJointComments))
-        print("jointComments=[", end="")
-        if self.jointComments:
-            for obj in self.jointComments:
-                print("{0}".format(obj), end="")
-        print("]")
-
-        print("nHasModelComment={0}".format(self.nHasModelComment))
-        print("modelComment={0}".format(self.modelComment))
-
-        print("subVersionVertexExtra={0}".format(self.subVersionVertexExtra))
-        print("vertex_ex={0}".format(self.vertex_ex))
-
-        print("subVersionJointExtra={0}".format(self.subVersionJointExtra))
-        print("joint_ex={0}".format(self.joint_ex))
-
-        print("subVersionModelExtra={0}".format(self.subVersionModelExtra))
-        print("model_ex={0}".format(self.model_ex))
-
-        print("##")
-        print("## ...end")
-        print("##############################################################")
-        print()
-
-
-    def read(self, file):
-        """
-        opens, reads and pars MS3D file.
-        add content to blender scene
-
-        :arg file: file
-        :type file: :class:`io.FileIO`
-        """
-
-        self.header.read(file)
-
-        _nNumVertices = read_word(file)
-        self._vertices = []
-        for i in range(_nNumVertices):
-            self.vertices.append(ms3d_vertex_t().read(file))
-
-        _nNumTriangles = read_word(file)
-        self._triangles = []
-        for i in range(_nNumTriangles):
-            self.triangles.append(ms3d_triangle_t().read(file))
-
-        _nNumGroups = read_word(file)
-        self._groups = []
-        for i in range(_nNumGroups):
-            self.groups.append(ms3d_group_t().read(file))
-
-        _nNumMaterials = read_word(file)
-        self._materials = []
-        for i in range(_nNumMaterials):
-            self.materials.append(ms3d_material_t().read(file))
-
-        self.fAnimationFPS = read_float(file)
-        self.fCurrentTime = read_float(file)
-        self.iTotalFrames = read_dword(file)
-
-        progressCount = 0
-
-        try:
-            # optional part
-            # doesn't matter if doesn't existing.
-
-            _nNumJoints = read_word(file)
-            self._joints = []
-            for i in range(_nNumJoints):
-                self.joints.append(ms3d_joint_t().read(file))
-
-            progressCount += 1
-
-            self.subVersionComments = read_dword(file)
-
-            progressCount += 1
-
-            _nNumGroupComments = read_dword(file)
-            self._groupComments = []
-            for i in range(_nNumGroupComments):
-                self.groupComments.append(ms3d_comment_t().read(file))
-
-            progressCount += 1
-
-            _nNumMaterialComments = read_dword(file)
-            self._materialComments = []
-            for i in range(_nNumMaterialComments):
-                self.materialComments.append(ms3d_comment_t().read(file))
-
-            progressCount += 1
-
-            _nNumJointComments = read_dword(file)
-            self._jointComments = []
-            for i in range(_nNumJointComments):
-                self.jointComments.append(ms3d_comment_t().read(file))
-
-            progressCount += 1
-
-            _nHasModelComment = read_dword(file)
-            if (_nHasModelComment != 0):
-                self._modelComment = ms3d_modelcomment_t().read(file)
-            else:
-                self._modelComment = None
-
-            progressCount += 1
-
-            self.subVersionVertexExtra = read_dword(file)
-            if (self.subVersionVertexExtra in {1, 2, 3}):
-                self._vertex_ex = []
-                for i in range(_nNumVertices):
-                    if self.subVersionVertexExtra == 1:
-                        item = ms3d_vertex_ex1_t()
-                    if self.subVersionVertexExtra == 2:
-                        item = ms3d_vertex_ex2_t()
-                    if self.subVersionVertexExtra == 3:
-                        item = ms3d_vertex_ex3_t()
-                    self.vertex_ex.append(item.read(file))
-            else:
-                self._vertex_ex = None
-
-            progressCount += 1
-
-            self.subVersionJointExtra = read_dword(file)
-            self._joint_ex = []
-            for i in range(_nNumJoints):
-                self.joint_ex.append(ms3d_joint_ex_t().read(file))
-
-            progressCount += 1
-
-            self.subVersionModelExtra = read_dword(file)
-
-            progressCount += 1
-
-            self.model_ex.read(file)
-
-        except Exception:
-            #type, value, traceback = sys.exc_info()
-            #print("ms3d_file.read - exception in optional try block,"
-            #        " progressCount={0}\n  type: '{1}'\n  value: '{2}'".format(
-            #        progressCount, type, value, traceback))
-
-            if (progressCount):
-                if (progressCount <= 0):
-                    _nNumJoints = None
-                    self._joints = None
-
-                if (progressCount <= 1):
-                    self.subVersionComments = None
-
-                if (progressCount <= 2):
-                    _nNumGroupComments = None
-                    self._groupComments = None
-
-                if (progressCount <= 3):
-                    _nNumMaterialComments = None
-                    self._materialComments = None
-
-                if (progressCount <= 4):
-                    _nNumJointComments = None
-                    self._jointComments = None
-
-                if (progressCount <= 5):
-                    _nHasModelComment = None
-                    self._modelComment = None
-
-                if (progressCount <= 6):
-                    self.subVersionVertexExtra = None
-                    self._vertex_ex = None
-
-                if (progressCount <= 7):
-                    self.subVersionJointExtra = None
-                    self._joint_ex = None
-
-                if (progressCount <= 8):
-                    self.subVersionModelExtra = None
-
-                if (progressCount <= 9):
-                    self.model_ex = None
-
-        else:
-            pass
-
-        return
-
-
-    def write(self, file):
-        """
-        add blender scene content to MS3D
-        creates, writes MS3D file.
-
-        :arg file: file
-        :type file: :class:`io.FileIO`
-        """
-
-        self.header.write(file)
-
-        write_word(file, self.nNumVertices)
-        for i in range(self.nNumVertices):
-            self.vertices[i].write(file)
-
-        write_word(file, self.nNumTriangles)
-        for i in range(self.nNumTriangles):
-            self.triangles[i].write(file)
-
-        write_word(file, self.nNumGroups)
-        for i in range(self.nNumGroups):
-            self.groups[i].write(file)
-
-        write_word(file, self.nNumMaterials)
-        for i in range(self.nNumMaterials):
-            self.materials[i].write(file)
-
-        write_float(file, self.fAnimationFPS)
-        write_float(file, self.fCurrentTime)
-        write_dword(file, self.iTotalFrames)
-
-        try:
-            # optional part
-            # doesn't matter if it doesn't complete.
-            write_word(file, self.nNumJoints)
-            for i in range(self.nNumJoints):
-                self.joints[i].write(file)
-
-            write_dword(file, self.subVersionComments)
-
-            write_dword(file, self.nNumGroupComments)
-            for i in range(self.nNumGroupComments):
-                self.groupComments[i].write(file)
-
-            write_dword(file, self.nNumMaterialComments)
-            for i in range(self.nNumMaterialComments):
-                self.materialComments[i].write(file)
-
-            write_dword(file, self.nNumJointComments)
-            for i in range(self.nNumJointComments):
-                self.jointComments[i].write(file)
-
-            write_dword(file, self.nHasModelComment)
-            if (self.nHasModelComment != 0):
-                self.modelComment.write(file)
-
-            write_dword(file, self.subVersionVertexExtra)
-            if (self.subVersionVertexExtra in {1, 2, 3}):
-                for i in range(self.nNumVertices):
-                    self.vertex_ex[i].write(file)
-
-            write_dword(file, self.subVersionJointExtra)
-            for i in range(self.nNumJoints):
-                self.joint_ex[i].write(file)
-
-            write_dword(file, self.subVersionModelExtra)
-            self.model_ex.write(file)
-
-        except Exception:
-            #type, value, traceback = sys.exc_info()
-            #print("ms3d_file.write - exception in optional try block"
-            #        "\n  type: '{0}'\n  value: '{1}'".format(
-            #        type, value, traceback))
-            pass
-
-        else:
-            pass
-
-        return
-
-
-    def isValid(self):
-        valid = True
-        result = []
-
-        format1 = "\n  number of {0}: {1}"
-        format2 = " limit exceeded! (limit is {0})"
-
-        result.append("MS3D statistics:")
-        result.append(format1.format("vertices ........", self.nNumVertices))
-        if (self.nNumVertices > MAX_VERTICES):
-            result.append(format2.format(MAX_VERTICES))
-            valid &= False
-
-        result.append(format1.format("triangles .......", self.nNumTriangles))
-        if (self.nNumTriangles > MAX_TRIANGLES):
-            result.append(format2.format(MAX_TRIANGLES))
-            valid &= False
-
-        result.append(format1.format("groups ..........", self.nNumGroups))
-        if (self.nNumGroups > MAX_GROUPS):
-            result.append(format2.format(MAX_GROUPS))
-            valid &= False
-
-        result.append(format1.format("materials .......", self.nNumMaterials))
-        if (self.nNumMaterials > MAX_MATERIALS):
-            result.append(format2.format(MAX_MATERIALS))
-            valid &= False
-
-        result.append(format1.format("joints ..........", self.nNumJoints))
-        if (self.nNumJoints > MAX_JOINTS):
-            result.append(format2.format(MAX_JOINTS))
-            valid &= False
-
-        result.append(format1.format("model comments ..",
-                self.nHasModelComment))
-        result.append(format1.format("group comments ..",
-                self.nNumGroupComments))
-        result.append(format1.format("material comments",
-                self.nNumMaterialComments))
-        result.append(format1.format("joint comments ..",
-                self.nNumJointComments))
-
-        #if (not valid):
-        #    result.append("\n\nthe data may be corrupted.")
-
-        return (valid, ("".join(result)))
-
-
-    # some other helper
-    def get_group_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.groups
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            if (key >= 0) and (key < self.nNumGroups):
-                return items[key]
-
-        elif isinstance(key, string):
-            for item in items:
-                if item.name == key:
-                    return item
-
-        elif isinstance(key, ms3d_spec.ms3d_triangle_t):
-            if (key.groupIndex >= 0) and (key.groupIndex < self.nNumGroups):
-                return item[key.groupIndex]
-
-        return None
-
-
-    def get_group_comment_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.groupComments
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            for item in items:
-                if (item.index == key):
-                    return item
-
-        return None
-
-
-    def get_material_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.materials
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            if (key >= 0) and (key < self.nNumMaterials):
-                return items[key]
-
-        elif isinstance(key, string):
-            for item in items:
-                if item.name == key:
-                    return item
-
-        elif isinstance(key, ms3d_spec.ms3d_group_t):
-            if (key.materialIndex >= 0) and (key.materialIndex < self.nNumMaterials):
-                return item[key.materialIndex]
-
-        return None
-
-
-    def get_material_comment_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.materialComments
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            for item in items:
-                if (item.index == key):
-                    return item
-
-        return None
-
-
-    def get_joint_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.joints
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            if (key >= 0) and (key < self.nNumJoints):
-                return items[key]
-
-        elif isinstance(key, string):
-            for item in items:
-                if item.name == key:
-                    return item
-
-        elif isinstance(key, ms3d_spec.ms3d_vertex_t):
-            if (key.boneId >= 0) and (key.boneId < self.nNumJoints):
-                return item[key.boneId]
-
-        return None
-
-
-    def get_joint_ex_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.joint_ex
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            if (key >= 0) and (key < self.nNumJoints):
-                return items[key]
-
-        elif isinstance(key, string):
-            for i, item in enumerate(self.joints):
-                if item.name == key:
-                    return items[i]
-
-        elif isinstance(key, ms3d_spec.ms3d_joint_t):
-            for i, item in enumerate(self.joints):
-                if item.name == key.name:
-                    return items[i]
-
-        elif isinstance(key, ms3d_spec.ms3d_vertex_t):
-            if (key.boneId >= 0) and (key.boneId < self.nNumJoints):
-                return item[key.boneId]
-
-        return None
-
-
-    def get_joint_comment_by_key(self, key):
-        if key is None:
-            return None
-
-        items = self.jointComments
-
-        if items is None:
-            return None
-
-        elif isinstance(key, int):
-            for item in items:
-                if (item.index == key):
-                    return item
-
-        return None
-
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py
deleted file mode 100644
index f8415f9..0000000
--- a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py
+++ /dev/null
@@ -1,464 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-
-
-# ##### BEGIN COPYRIGHT BLOCK #####
-#
-# initial script copyright (c)2011 Alexander Nussbaumer
-#
-# ##### END COPYRIGHT BLOCK #####
-
-
-#import python stuff
-import math
-import mathutils
-import os
-import sys
-
-
-#import blender stuff
-import bpy
-import bpy.ops
-
-
-_VERBOSE_DEFAULT = bpy.app.debug
-
-
-###############################################################################
-TEXT_OPERATOR = "MilkShape3D MS3D (.ms3d)"
-
-FILE_EXT = ".ms3d"
-FILE_FILTER = "*.ms3d"
-
-
-###############################################################################
-OPT_HIDDEN = 'HIDDEN'
-OPT_ANIMATABLE = 'ANIMATABLE'
-OPT_ENUM_FLAG = 'ENUM_FLAG'
-
-LABEL_NAME_OPTIONS = "Advanced Options:"
-LABEL_ICON_OPTIONS = 'LAMP'
-
-LABEL_NAME_OBJECT = "World Processing:"
-LABEL_ICON_OBJECT = 'WORLD'
-
-LABEL_NAME_PROCESSING = "Object Processing:"
-LABEL_ICON_PROCESSING = 'OBJECT_DATAMODE'
-
-LABEL_NAME_ANIMATION = "Animation Processing:"
-LABEL_ICON_ANIMATION = 'RENDER_ANIMATION'
-
-LABLE_NAME_REUSE = "ReUse existing data"
-LABLE_ICON_REUSE = 'FILE_REFRESH'
-
-
-###############################################################################
-PROP_NAME_VERBOSE = "Verbose"
-PROP_DESC_VERBOSE = "Run the converter in debug mode. Check the console for"\
-        " output (Warning, may be very slow)"
-PROP_DEFAULT_VERBOSE = _VERBOSE_DEFAULT
-PROP_OPT_VERBOSE = {OPT_ANIMATABLE}
-
-
-###############################################################################
-PROP_ITEM_COORDINATESYSTEM_1_BY_1 = '0'
-PROP_ITEM_COORDINATESYSTEM_IMP = '1'
-PROP_ITEM_COORDINATESYSTEM_EXP = '2'
-PROP_NAME_COORDINATESYSTEM = "Coordinate system"
-PROP_DESC_COORDINATESYSTEM = "Select a coordinate system to export to"
-PROP_DEFAULT_COORDINATESYSTEM_IMP = PROP_ITEM_COORDINATESYSTEM_IMP
-PROP_DEFAULT_COORDINATESYSTEM_EXP = PROP_ITEM_COORDINATESYSTEM_EXP
-PROP_ITEMS_COORDINATESYSTEM = (
-        (PROP_ITEM_COORDINATESYSTEM_1_BY_1, "xyz -> xyz (1:1)", "Take axis as"\
-                " is (1:1)"),
-        (PROP_ITEM_COORDINATESYSTEM_IMP, "yzx -> xyz (import)", "swap axis to"\
-                " fit to viewport (import ms3d to blender)"),
-        (PROP_ITEM_COORDINATESYSTEM_EXP, "xyz -> yzx (export)", "swap axis to"\
-                " fit to viewport (export blender to ms3d)"),
-        )
-PROP_OPT_COORDINATESYSTEM = {OPT_ANIMATABLE}
-
-
-###############################################################################
-PROP_NAME_SCALE = "Scale"
-PROP_DESC_SCALE = "Scale all data"
-PROP_DEFAULT_SCALE = 1.0
-PROP_MIN_SCALE = 0.001
-PROP_MAX_SCALE = 1000.0
-PROP_SMIN_SCALE = 0.01
-PROP_SMAX_SCALE = 100.0
-PROP_OPT_SCALE = {OPT_ANIMATABLE}
-
-
-###############################################################################
-PROP_NAME_UNIT_MM = "Metric [mm]"
-PROP_DESC_UNIT_MM = "Setup blender unit to metric [mm]"
-PROP_DEFAULT_UNIT_MM = True
-PROP_OPT_UNIT_MM = {OPT_ANIMATABLE}
-
-
-###############################################################################
-PROP_NAME_SELECTED = "Only selected mesh(es)"
-PROP_DESC_SELECTED = "Export only selected mesh(es), when enabled"
-PROP_DEFAULT_SELECTED = False
-PROP_OPT_SELECTED = {OPT_ANIMATABLE}
-
-
-###############################################################################
-PROP_ITEM_REUSE_NONE = 'NONE'
-PROP_ITEM_REUSE_MATCH_HASH = 'MATCH_HASH'
-PROP_ITEM_REUSE_MATCH_VALUES = 'MATCH_VALUES'
-###############################################################################
-PROP_NAME_REUSE = "Reuse existing data"
-PROP_DESC_REUSE = "Reuses existing blender data, by trying to find similar"\
-        " data objects to reduce the filesize. (With risk of taking the wrong"\
-        " existing data!)"
-PROP_DEFAULT_REUSE = PROP_ITEM_REUSE_NONE
-#PROP_DEFAULT_REUSE = PROP_ITEM_REUSE_MATCH_VALUES
-PROP_ITEMS_REUSE = (
-        (PROP_ITEM_REUSE_NONE, "Disabled", "Create every time new data."),
-        #(PROP_ITEM_REUSE_MATCH_HASH, "Match by hash ***)", "Take data with"\
-        #        " the same custom property 'ms3d_i_hash' value. (even if content is modified or different!)"),
-        (PROP_ITEM_REUSE_MATCH_VALUES, "Match by values ***)", "Take data"\
-                " with similar color values (diffuse_color, specular_color)"\
-                " and texture_slots (images). (even if untested content is"\
-                " different!)"),
-        )
-PROP_OPT_REUSE = {OPT_ANIMATABLE}
-
-
-###############################################################################
-PROP_ITEM_OBJECT_ANIMATION = 'ANIMATION'
-PROP_ITEM_OBJECT_GROUP = 'GROUP'
-PROP_ITEM_OBJECT_JOINT = 'JOINT'
-PROP_ITEM_OBJECT_MATERIAL = 'MATERIAL'
-PROP_ITEM_OBJECT_MESH = 'MESH'
-PROP_ITEM_OBJECT_SMOOTHGROUPS = 'SMOOTHGROUPS'
-PROP_ITEM_OBJECT_TRI_TO_QUAD = 'TRI_TO_QUAD'
-###############################################################################
-PROP_NAME_OBJECTS_IMP = "Import processing"
-PROP_DESC_OBJECTS_IMP = "What to process during import"
-PROP_DEFAULT_OBJECTS_IMP = {
-        #PROP_ITEM_OBJECT_MESH,
-        PROP_ITEM_OBJECT_MATERIAL,
-        PROP_ITEM_OBJECT_JOINT,
-        PROP_ITEM_OBJECT_SMOOTHGROUPS,
-        PROP_ITEM_OBJECT_GROUP,
-        #PROP_ITEM_OBJECT_TRI_TO_QUAD,
-        }
-PROP_ITEMS_OBJECTS_IMP = (
-        #(PROP_ITEM_OBJECT_MESH, "Meshes", "vertices, triangles, uv"),
-        (PROP_ITEM_OBJECT_MATERIAL, "Materials", "ambient, diffuse, specular,"\
-                " emissive, shininess, transparency, diffuse texture,"\
-                " alpha texture"),
-        (PROP_ITEM_OBJECT_JOINT, "Joints", "joints, bones"),
-        #(PROP_ITEM_OBJECT_ANIMATION, "Animation **)", "keyframes"),
-        (PROP_ITEM_OBJECT_SMOOTHGROUPS, "Smoothing Groups", "split mesh faces"\
-                " according its smoothing groups"),
-        (PROP_ITEM_OBJECT_GROUP, "Group", "organize all file objects to a"\
-                " single group, named with the filename"),
-        (PROP_ITEM_OBJECT_TRI_TO_QUAD, "Tris to Quad", "try to convert"\
-                " triangles to quads"),
-        )
-PROP_OPT_OBJECTS_IMP = {OPT_ENUM_FLAG}
-
-
-###############################################################################
-PROP_NAME_OBJECTS_EXP = "Export processing"
-PROP_DESC_OBJECTS_EXP = "What to process during export"
-PROP_DEFAULT_OBJECTS_EXP = {
-        #PROP_ITEM_OBJECT_MESH,
-        PROP_ITEM_OBJECT_MATERIAL,
-        }
-PROP_ITEMS_OBJECTS_EXP = (
-        #(PROP_ITEM_OBJECT_MESH, "Meshes", "vertices, triangles, uv, normals"),
-        (PROP_ITEM_OBJECT_MATERIAL, "Materials", "ambient, diffuse, specular,"\
-                " emissive, shininess, transparency, diffuse texture,"\
-                " alpha texture"),
-        (PROP_ITEM_OBJECT_JOINT, "Joints **)", "joints, bones"),
-        #(PROP_ITEM_OBJECT_ANIMATION, "Animation **)", "keyframes"),
-        )
-PROP_OPT_OBJECTS_EXP = {OPT_ENUM_FLAG}
-
-
-###############################################################################
-PROP_NAME_ANIMATION = "Animation **)"
-PROP_DESC_ANIMATION = "keyframes (rotations, positions)"
-PROP_DEFAULT_ANIMATION = True
-PROP_OPT_ANIMATION = {OPT_ANIMATABLE}
-
-
-###############################################################################
-REMARKS_1 = "*)   partial implemented yet"
-REMARKS_2 = "**) not implemented yet"
-REMARKS_3 = "***) risk of unwanted results"
-
-
-###############################################################################
-def SetupMenuImport(self, layout):
-    box = layout.box()
-    box.label(LABEL_NAME_OPTIONS, icon=LABEL_ICON_OPTIONS)
-    box.prop(self, "prop_verbose", icon='SPEAKER')
-
-    box2 = box.box()
-    box2.label(LABLE_NAME_REUSE, icon=LABLE_ICON_REUSE)
-    box2.prop(self, "prop_reuse", icon='FILE_REFRESH', expand=True)
-    if (PROP_ITEM_REUSE_NONE != self.prop_reuse):
-        box2.label(REMARKS_3, icon='ERROR')
-
-    box = layout.box()
-    box.label(LABEL_NAME_OBJECT, icon=LABEL_ICON_OBJECT)
-    box.prop(self, "prop_unit_mm", icon='SCENE_DATA', expand=True)
-    box.prop(self, "prop_coordinate_system", icon='WORLD_DATA', expand=True)
-    box.prop(self, "prop_scale", icon='MESH_DATA')
-
-    box = layout.box()
-    box.label(LABEL_NAME_PROCESSING, icon=LABEL_ICON_PROCESSING)
-    box.prop(self, "prop_objects", icon='MESH_DATA', expand=True)
-
-    if (PROP_ITEM_OBJECT_JOINT in self.prop_objects):
-        box = layout.box()
-        box.label(LABEL_NAME_ANIMATION, icon=LABEL_ICON_ANIMATION)
-        box.prop(self, "prop_animation")
-        if (self.prop_animation):
-            box.label(REMARKS_2, icon='ERROR')
-
-
-###############################################################################
-def SetupMenuExport(self, layout):
-    box = layout.box()
-    box.label(LABEL_NAME_OPTIONS, icon=LABEL_ICON_OPTIONS)
-    if (bpy.app.debug):
-        box.prop(self, "prop_debug", icon='ERROR')
-    box.prop(self, "prop_verbose", icon='SPEAKER')
-
-    box = layout.box()
-    box.label(LABEL_NAME_OBJECT, icon=LABEL_ICON_OBJECT)
-    box.prop(self, "prop_coordinate_system", icon='WORLD_DATA', expand=True)
-    box.prop(self, "prop_scale", icon='MESH_DATA')
-
-    box = layout.box()
-    box.label(LABEL_NAME_PROCESSING, icon=LABEL_ICON_PROCESSING)
-    box.prop(self, "prop_selected", icon='ROTACTIVE')
-    box.prop(self, "prop_objects", icon='MESH_DATA', expand=True)
-
-    if (PROP_ITEM_OBJECT_JOINT in self.prop_objects):
-        box.label(REMARKS_2, icon='ERROR')
-
-        box = layout.box()
-        box.label(LABEL_NAME_ANIMATION, icon=LABEL_ICON_ANIMATION)
-        box.prop(self, "prop_animation")
-
-
-###############################################################################
-
-
-###############################################################################
-
-
-TYPE_ARMATURE = 'ARMATURE'
-TYPE_EMPTY = 'EMPTY'
-TYPE_MESH = 'MESH'
-APPLY_TO = 'PREVIEW'
-
-
-###############################################################################
-def EnableEditMode(enable):
-    if enable:
-        modeString = 'EDIT'
-    else:
-        modeString = 'OBJECT'
-
-    if bpy.ops.object.mode_set.poll():
-        bpy.ops.object.mode_set(mode=modeString)
-
-
-###############################################################################
-def EnablePoseMode(enable):
-    if enable:
-        modeString = 'POSE'
-    else:
-        modeString = 'OBJECT'
-
-    if bpy.ops.object.mode_set.poll():
-        bpy.ops.object.mode_set(mode=modeString)
-
-
-###############################################################################
-def SelectAll(select):
-    if select:
-        actionString = 'SELECT'
-    else:
-        actionString = 'DESELECT'
-
-    if bpy.ops.object.select_all.poll():
-        bpy.ops.object.select_all(action=actionString)
-
-    if bpy.ops.mesh.select_all.poll():
-        bpy.ops.mesh.select_all(action=actionString)
-
-    if bpy.ops.pose.select_all.poll():
-        bpy.ops.pose.select_all(action=actionString)
-
-
-###############################################################################
-def CreateMatrixViewport(coordinate_system, scale):
-    matrixSwapAxis = None
-
-    if bpy.app.build_revision < '42816':
-        # for OLD implementation, older than blender rev. 42816
-        if (coordinate_system == PROP_ITEM_COORDINATESYSTEM_IMP):
-            # MS3D -> Blender
-            matrixSwapAxis = mathutils.Matrix((
-                    (0.0, 0.0, 1.0, 0.0),
-                    (1.0, 0.0, 0.0, 0.0),
-                    (0.0, 1.0, 0.0, 0.0),
-                    (0.0, 0.0, 0.0, 1.0)
-                    ))
-
-        elif (coordinate_system == PROP_ITEM_COORDINATESYSTEM_EXP):
-            # Blender -> MS3D
-            matrixSwapAxis = mathutils.Matrix((
-                    (0.0, 1.0, 0.0, 0.0),
-                    (0.0, 0.0, 1.0, 0.0),
-                    (1.0, 0.0, 0.0, 0.0),
-                    (0.0, 0.0, 0.0, 1.0)
-                    ))
-
-        else:
-            # 1:1
-            matrixSwapAxis = mathutils.Matrix((
-                    (1.0, 0.0, 0.0, 0.0),
-                    (0.0, 1.0, 0.0, 0.0),
-                    (0.0, 0.0, 1.0, 0.0),
-                    (0.0, 0.0, 0.0, 1.0)
-                    ))
-    else:
-        # for new implementation since blender rev. 42816
-        if (coordinate_system == PROP_ITEM_COORDINATESYSTEM_IMP):
-            # MS3D -> Blender (since Blender rev.42816)
-            matrixSwapAxis = mathutils.Matrix((
-                    (0.0, 1.0, 0.0, 0.0),
-                    (0.0, 0.0, 1.0, 0.0),
-                    (1.0, 0.0, 0.0, 0.0),
-                    (0.0, 0.0, 0.0, 1.0)
-                    ))
-
-        elif (coordinate_system == PROP_ITEM_COORDINATESYSTEM_EXP):
-            # Blender -> MS3D (since Blender rev.42816)
-            matrixSwapAxis = mathutils.Matrix((
-                    (0.0, 0.0, 1.0, 0.0),
-                    (1.0, 0.0, 0.0, 0.0),
-                    (0.0, 1.0, 0.0, 0.0),
-                    (0.0, 0.0, 0.0, 1.0)
-                    ))
-
-        else:
-            # 1:1
-            matrixSwapAxis = mathutils.Matrix((
-                    (1.0, 0.0, 0.0, 0.0),
-                    (0.0, 1.0, 0.0, 0.0),
-                    (0.0, 0.0, 1.0, 0.0),
-                    (0.0, 0.0, 0.0, 1.0)
-                    ))
-
-
-    return matrixSwapAxis * scale, matrixSwapAxis
-
-
-###############################################################################
-def PreSetupEnvironment(porterSelf):
-    # inject undo to self
-    # and turn off undo
-    porterSelf.undo = bpy.context.user_preferences.edit.use_global_undo
-    bpy.context.user_preferences.edit.use_global_undo = False
-
-    # inject activeObject to self
-    porterSelf.activeObject = bpy.context.scene.objects.active
-
-    # change to a well defined mode
-    EnableEditMode(True)
-
-    # enable face-selection-mode
-    bpy.context.tool_settings.mesh_select_mode = (False, False, True)
-
-    # change back to object mode
-    EnableEditMode(False)
-
-    bpy.context.scene.update()
-
-    # inject matrixViewport to self
-    porterSelf.matrixViewport, porterSelf.matrixSwapAxis =\
-            CreateMatrixViewport(
-                    porterSelf.prop_coordinate_system,
-                    porterSelf.prop_scale)
-
-    # inject splitted filepath
-    porterSelf.filepath_splitted = os.path.split(porterSelf.filepath)
-
-
-###############################################################################
-def PostSetupEnvironment(porterSelf, adjustView):
-    if (adjustView):
-        # set metrics
-        bpy.context.scene.unit_settings.system = 'METRIC'
-        bpy.context.scene.unit_settings.system_rotation = 'DEGREES'
-        bpy.context.scene.unit_settings.scale_length = 0.001 # 1.0mm
-        bpy.context.scene.unit_settings.use_separate = False
-        bpy.context.tool_settings.normal_size = 1.0 # 1.0mm
-
-        # set all 3D views to texture shaded
-        # and set up the clipping
-        for screen in bpy.context.blend_data.screens:
-            for area in screen.areas:
-                if (area.type != 'VIEW_3D'):
-                    continue
-
-                for space in area.spaces:
-                    if (space.type != 'VIEW_3D'):
-                        continue
-
-                    screen.scene.game_settings.material_mode = 'MULTITEXTURE'
-                    space.viewport_shade = 'SOLID'
-                    space.show_textured_solid = True
-                    space.clip_start = 0.1 # 0.1mm
-                    space.clip_end = 1000000.0 # 1km
-
-    bpy.context.scene.update()
-
-    # restore active object
-    bpy.context.scene.objects.active = porterSelf.activeObject
-
-    if ((not bpy.context.scene.objects.active)
-            and (bpy.context.selected_objects)):
-        bpy.context.scene.objects.active = bpy.context.selected_objects[0]
-
-    # restore pre operator undo state
-    bpy.context.user_preferences.edit.use_global_undo = porterSelf.undo
-
-
-###############################################################################
-#234567890123456789012345678901234567890123456789012345678901234567890123456789
-#--------1---------2---------3---------4---------5---------6---------7---------
-# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_open_street_map.py b/release/scripts/addons_contrib/io_scene_open_street_map.py
deleted file mode 100644
index 2ac806f..0000000
--- a/release/scripts/addons_contrib/io_scene_open_street_map.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-# <pep8 compliant>
-
-bl_info = {
-    "name": "Open Street Map (.osm)",
-    "author": "Michael Anthrax Schlachter",
-    "version": (0, 1),
-    "blender": (2, 6, 3),
-    "location": "File > Import",
-    "description": "Load Open Street Map File",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Import-Export"}
-
-# originally written for blender 2.4x by (manthrax _at_ hotmail.com),
-# updated by for blender 2.6x by ideasman42
-# If you use it for something cool, send me an email and let me know!
-
-import bpy
-from mathutils import Vector, Matrix
-
-
-def parseBranch(nodes, bm, nmap, scale=100.0):
-    tidx = 0
-    inNode = 0
-    dlat = dlong = clat = clong = minlat = maxlat = minlong = maxlong = 0.0
-    for node in nodes:
-        if node.localName == "bounds":
-            if node.hasAttributes():
-                for i in range(node.attributes.length):
-                    at = node.attributes.item(i)
-                    if at.name == "minlat":
-                        minlat = float(at.nodeValue)
-                    elif at.name == "minlon":
-                        minlong = float(at.nodeValue)
-                    elif at.name == "maxlat":
-                        maxlat = float(at.nodeValue)
-                    elif at.name == "maxlon":
-                        maxlong = float(at.nodeValue)
-                dlat = maxlat - minlat
-                dlong = maxlong - minlong
-                clat = (maxlat + minlat) * 0.5
-                clong = (maxlong + minlong) * 0.5
-
-                print(dlat, dlong, clat, clong)
-
-        if node.localName == "way":
-            nid = None
-            refs = []
-            '''
-            if node.hasAttributes():
-                for i in range(node.attributes.length):
-                    at=node.attributes.item(i)
-                    print(at.name)
-            '''
-
-            for ch in node.childNodes:
-                if ch.localName == "nd":
-                    for i in range(ch.attributes.length):
-                        at = ch.attributes.item(i)
-                        #print(at.name)
-                        if at.name == "ref":
-                            refs.append(int(at.nodeValue))
-
-            first = 1
-            for r in refs:
-                if first == 0:
-                    edge = bm.edges.get((nmap[pr], nmap[r]))
-                    if edge is None:
-                        edge = bm.edges.new((nmap[pr], nmap[r]))
-                    del edge  # don't actually use it
-                else:
-                    first = 0
-                pr = r
-
-        if node.localName == "node":
-            if node.hasAttributes():
-                nid = None
-                nlong = None
-                nlat = None
-                logged = 0
-                for i in range(node.attributes.length):
-                    at = node.attributes.item(i)
-                    #print(at.name)
-                    if at.name == "id":
-                        nid = at.nodeValue
-                    elif at.name == "lon":
-                        nlong = at.nodeValue
-                    elif at.name == "lat":
-                        nlat = at.nodeValue
-
-                    if (nid is not None) and (nlat is not None) and (nlong is not None):
-                        fla = (float(nlat) - clat) * scale / dlat
-                        flo = (float(nlong) - clong) * scale / dlat
-                        vert = bm.verts.new((fla, flo, 0.0))
-                        nmap[int(nid)] = vert
-                        logged = 1
-                        break
-        tidx += 1
-        #if tidx > 1000:
-        #    break
-        tidx += parseBranch(node.childNodes, bm, nmap)
-
-    return tidx
-
-
-def read(context, filepath, scale=100.0):
-    import bmesh
-    from xml.dom import minidom
-
-    xmldoc = minidom.parse(filepath)
-
-    print("Starting parse: %r..." % filepath)
-    bm = bmesh.new()
-
-    nmap = {}
-    tidx = parseBranch(xmldoc.childNodes, bm, nmap)
-
-    # create mesh
-    name = bpy.path.display_name_from_filepath(filepath)
-    me = bpy.data.meshes.new(name)
-    bm.to_mesh(me)
-    obj = bpy.data.objects.new(name, me)
-
-    # scale by 1.5 is odd, need to look into that
-    global_matrix = Matrix(((+0.0, +1.0, +0.0, +0.0),
-                            (+1.5, -0.0, +0.0, +0.0),
-                            (+0.0, -0.0, -1.0, +0.0),
-                            (+0.0, +0.0, +0.0, +1.0)))
-    me.transform(global_matrix)
-
-    # create the object in the scene
-    scene = context.scene
-    scene.objects.link(obj)
-    scene.objects.active = obj
-    obj.select = True
-
-    print("Parse done... %d" % tidx)
-
-    return {'FINISHED'}
-
-## for testing
-#if __name__ == "__main__":
-#    read("/data/downloads/osm_parser/map.osm", bpy.context)
-
-
-# ----------------------------------------------------------------------------
-# blender integration
-
-from bpy.types import Operator
-from bpy_extras.io_utils import ImportHelper
-
-from bpy.props import StringProperty, FloatProperty
-
-
-class ImportOSM(Operator, ImportHelper):
-    '''Import OSM'''
-    bl_idname = "import.open_street_map"
-    bl_label = "Import OpenStreetMap (.osm)"
-
-    # ExportHelper mixin class uses this
-    filename_ext = ".osm"
-
-    filter_glob = StringProperty(
-            default="*.osm",
-            options={'HIDDEN'},
-            )
-
-    # List of operator properties, the attributes will be assigned
-    # to the class instance from the operator settings before calling.
-    scale = FloatProperty(
-            name="Scale",
-            default=100.0,
-            )
-
-    def execute(self, context):
-        return read(context, self.filepath, self.scale)
-
-
-# Only needed if you want to add into a dynamic menu
-def menu_func_export(self, context):
-    self.layout.operator(ImportOSM.bl_idname)
-
-
-def register():
-    bpy.utils.register_class(ImportOSM)
-    bpy.types.INFO_MT_file_import.append(menu_func_export)
-
-
-def unregister():
-    bpy.utils.unregister_class(ImportOSM)
-    bpy.types.INFO_MT_file_import.remove(menu_func_export)
diff --git a/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py b/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py
deleted file mode 100644
index 6e16186..0000000
--- a/release/scripts/addons_contrib/io_sequencer_edl/import_edl.py
+++ /dev/null
@@ -1,1011 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Name: "Video Sequence (.edl)..."
-Blender: 248
-Group: "Import"
-Tooltip: "Load a CMX formatted EDL into the sequencer"
-"""
-
-
-class TimeCode(object):
-    """
-    Simple timecode class
-    also supports conversion from other time strings used by EDL
-    """
-    def __init__(self, data, fps):
-        self.fps = fps
-        if type(data) == str:
-            self.fromString(data)
-            frame = self.asFrame()
-            self.fromFrame(frame)
-        else:
-            self.fromFrame(data)
-
-    def fromString(self, text):
-        # hh:mm:ss:ff
-        # No dropframe support yet
-
-        if text.lower().endswith("mps"):  # 5.2mps
-            return self.fromFrame(int(float(text[:-3]) * self.fps))
-        elif text.lower().endswith("s"):  # 5.2s
-            return self.fromFrame(int(float(text[:-1]) * self.fps))
-        elif text.isdigit():  # 1234
-            return self.fromFrame(int(text))
-        elif ":" in text:  # hh:mm:ss:ff
-            text = text.replace(";", ":").replace(",", ":").replace(".", ":")
-            text = text.split(":")
-
-            self.hours = int(text[0])
-            self.minutes = int(text[1])
-            self.seconds = int(text[2])
-            self.frame = int(text[3])
-            return self
-        else:
-            print("ERROR: could not convert this into timecode %r" % test)
-            return self
-
-    def fromFrame(self, frame):
-
-        if frame < 0:
-            frame = -frame
-            neg = True
-        else:
-            neg = False
-
-        fpm = 60 * self.fps
-        fph = 60 * fpm
-
-        if frame < fph:
-            self.hours = 0
-        else:
-            self.hours = int(frame / fph)
-            frame = frame % fph
-
-        if frame < fpm:
-            self.minutes = 0
-        else:
-            self.minutes = int(frame / fpm)
-            frame = frame % fpm
-
-        if frame < self.fps:
-            self.seconds = 0
-        else:
-            self.seconds = int(frame / self.fps)
-            frame = frame % self.fps
-
-        self.frame = frame
-
-        if neg:
-            self.frame = -self.frame
-            self.seconds = -self.seconds
-            self.minutes = -self.minutes
-            self.hours = -self.hours
-
-        return self
-
-    def asFrame(self):
-        abs_frame = self.frame
-        abs_frame += self.seconds * self.fps
-        abs_frame += self.minutes * 60 * self.fps
-        abs_frame += self.hours * 60 * 60 * self.fps
-
-        return abs_frame
-
-    def asString(self):
-        self.fromFrame(int(self))
-        return "%.2d:%.2d:%.2d:%.2d" % (self.hours, self.minutes, self.seconds, self.frame)
-
-    def __repr__(self):
-        return self.asString()
-
-    # Numeric stuff, may as well have this
-    def __neg__(self):
-        return TimeCode(-int(self), self.fps)
-
-    def __int__(self):
-        return self.asFrame()
-
-    def __sub__(self, other):
-        return TimeCode(int(self) - int(other), self.fps)
-
-    def __add__(self, other):
-        return TimeCode(int(self) + int(other), self.fps)
-
-    def __mul__(self, other):
-        return TimeCode(int(self) * int(other), self.fps)
-
-    def __div__(self, other):
-        return TimeCode(int(self) // int(other), self.fps)
-
-    def __abs__(self):
-        return TimeCode(abs(int(self)), self.fps)
-
-    def __iadd__(self, other):
-        return self.fromFrame(int(self) + int(other))
-
-    def __imul__(self, other):
-        return self.fromFrame(int(self) * int(other))
-
-    def __idiv__(self, other):
-        return self.fromFrame(int(self) // int(other))
-# end timecode
-
-
-"""Comments
-Comments can appear at the beginning of the EDL file (header) or between the edit lines in the EDL. The first block of comments in the file is defined to be the header comments and they are associated with the EDL as a whole. Subsequent comments in the EDL file are associated with the first edit line that appears after them.
-Edit Entries
-<filename|tag>  <EditMode>  <TransitionType>[num]  [duration]  [srcIn]  [srcOut]  [recIn]  [recOut]
-
-    * <filename|tag>: Filename or tag value. Filename can be for an MPEG file, Image file, or Image file template. Image file templates use the same pattern matching as for command line glob, and can be used to specify images to encode into MPEG. i.e. /usr/data/images/image*.jpg
-    * <EditMode>: 'V' | 'A' | 'VA' | 'B' | 'v' | 'a' | 'va' | 'b' which equals Video, Audio, Video_Audio edits (note B or b can be used in place of VA or va).
-    * <TransitonType>: 'C' | 'D' | 'E' | 'FI' | 'FO' | 'W' | 'c' | 'd' | 'e' | 'fi' | 'fo' | 'w'. which equals Cut, Dissolve, Effect, FadeIn, FadeOut, Wipe.
-    * [num]: if TransitionType = Wipe, then a wipe number must be given. At the moment only wipe 'W0' and 'W1' are supported.
-    * [duration]: if the TransitionType is not equal to Cut, then an effect duration must be given. Duration is in frames.
-    * [srcIn]: Src in. If no srcIn is given, then it defaults to the first frame of the video or the first frame in the image pattern. If srcIn isn't specified, then srcOut, recIn, recOut can't be specified.
-    * [srcOut]: Src out. If no srcOut is given, then it defaults to the last frame of the video - or last image in the image pattern. if srcOut isn't given, then recIn and recOut can't be specified.
-    * [recIn]: Rec in. If no recIn is given, then it is calculated based on its position in the EDL and the length of its input.
-      [recOut]: Rec out. If no recOut is given, then it is calculated based on its position in the EDL and the length of its input. first frame of the video.
-
-For srcIn, srcOut, recIn, recOut, the values can be specified as either timecode, frame number, seconds, or mps seconds. i.e.
-[tcode | fnum | sec | mps], where:
-
-    * tcode : SMPTE timecode in hh:mm:ss:ff
-    * fnum : frame number (the first decodable frame in the video is taken to be frame 0).
-    * sec : seconds with 's' suffix (e.g. 5.2s)
-    * mps : seconds with 'mps' suffix (e.g. 5.2mps). This corresponds to the 'seconds' value displayed by Windows MediaPlayer.
-
-More notes,
-Key
-
-"""
-
-enum = 0
-TRANSITION_UNKNOWN = enum
-TRANSITION_CUT = enum
-enum += 1
-TRANSITION_DISSOLVE = enum
-enum += 1
-TRANSITION_EFFECT = enum
-enum += 1
-TRANSITION_FADEIN = enum
-enum += 1
-TRANSITION_FADEOUT = enum
-enum += 1
-TRANSITION_WIPE = enum
-enum += 1
-TRANSITION_KEY = enum
-enum += 1
-
-TRANSITION_DICT = {
-    "c": TRANSITION_CUT,
-    "d": TRANSITION_DISSOLVE,
-    "e": TRANSITION_EFFECT,
-    "fi": TRANSITION_FADEIN,
-    "fo": TRANSITION_FADEOUT,
-    "w": TRANSITION_WIPE,
-    "k": TRANSITION_KEY,
-    }
-
-enum = 0
-EDIT_UNKNOWN = 1 << enum
-enum += 1
-EDIT_VIDEO = 1 << enum
-enum += 1
-EDIT_AUDIO = 1 << enum
-enum += 1
-EDIT_AUDIO_STEREO = 1 << enum
-enum += 1
-EDIT_VIDEO_AUDIO = 1 << enum
-enum += 1
-
-EDIT_DICT = {
-    "v": EDIT_VIDEO,
-    "a": EDIT_AUDIO,
-    "aa": EDIT_AUDIO_STEREO,
-    "va": EDIT_VIDEO_AUDIO,
-    "b": EDIT_VIDEO_AUDIO,
-    }
-
-
-enum = 0
-WIPE_UNKNOWN = enum
-WIPE_0 = enum
-enum += 1
-WIPE_1 = enum
-enum += 1
-
-enum = 0
-KEY_UNKNOWN = enum
-KEY_BG = enum  # K B
-enum += 1
-KEY_IN = enum  # This is assumed if no second type is set
-enum += 1
-KEY_OUT = enum  # K O
-enum += 1
-
-
-"""
-Most sytems:
-Non-dropframe: 1:00:00:00 - colon in last position
-Dropframe: 1:00:00;00 - semicolon in last position
-PAL/SECAM: 1:00:00:00 - colon in last position
-
-SONY:
-Non-dropframe: 1:00:00.00 - period in last position
-Dropframe: 1:00:00,00 - comma in last position
-PAL/SECAM: 1:00:00.00 - period in last position
-"""
-
-"""
-t = abs(timecode('-124:-12:-43:-22', 25))
-t /= 2
-print t
-"""
-
-
-def editFlagsToText(flag):
-    items = []
-    for item, val in EDIT_DICT.items():
-        if val & flag:
-            items.append(item)
-    return "/".join(items)
-
-
-class EditDecision(object):
-    def __init__(self, text=None, fps=25):
-        # print text
-        self.number = -1
-        self.reel = ""  # Uniqie name for this 'file' but not filename, when BL signifies black
-        self.transition_duration = 0
-        self.edit_type = EDIT_UNKNOWN
-        self.transition_type = TRANSITION_UNKNOWN
-        self.wipe_type = WIPE_UNKNOWN
-        self.key_type = KEY_UNKNOWN
-        self.key_fade = -1  # true/false
-        self.srcIn = None   # Where on the original field recording the event begins
-        self.srcOut = None  # Where on the original field recording the event ends
-        self.recIn = None   # Beginning of the original event in the edited program
-        self.recOut = None  # End of the original event in the edited program
-        self.m2 = None      # fps set by the m2 command
-        self.filename = ""
-
-        self.custom_data = []  # use for storing any data you want (blender strip for eg)
-
-        if text != None:
-            self.read(text, fps)
-
-    def __repr__(self):
-        txt = "num: %d, " % self.number
-        txt += "reel: %s, " % self.reel
-        txt += "edit_type: "
-        txt += editFlagsToText(self.edit_type) + ", "
-
-        txt += "trans_type: "
-        for item, val in TRANSITION_DICT.items():
-            if val == self.transition_type:
-                txt += item + ", "
-                break
-
-        txt += "m2: "
-        if self.m2:
-            txt += "%g" % float(self.m2.fps)
-            txt += "\n\t"
-            txt += self.m2.data
-        else:
-            txt += "nil"
-
-        txt += ", "
-        txt += "recIn: " + str(self.recIn) + ", "
-        txt += "recOut: " + str(self.recOut) + ", "
-        txt += "srcIn: " + str(self.srcIn) + ", "
-        txt += "srcOut: " + str(self.srcOut) + ", "
-
-        return txt
-
-    def read(self, line, fps):
-        line = line.split()
-        index = 0
-        self.number = int(line[index])
-        index += 1
-        self.reel = line[index].lower()
-        index += 1
-
-        # AA/V can be an edit type
-        self.edit_type = 0
-        for edit_type in line[index].lower().split("/"):
-            self.edit_type |= EDIT_DICT[edit_type]
-        index += 1
-
-        tx_name = "".join([c for c in line[index].lower() if not c.isdigit()])
-        self.transition_type = TRANSITION_DICT[tx_name]  # advance the index later
-
-        if self.transition_type == TRANSITION_WIPE:
-            tx_num = "".join([c for c in line[index].lower() if c.isdigit()])
-            if tx_num:
-                tx_num = int(tx_num)
-            else:
-                tx_num = 0
-
-            self.wipe_type = tx_num
-
-        elif self.transition_type == TRANSITION_KEY:  # UNTESTED
-
-            val = line[index + 1].lower()
-
-            if val == "b":
-                self.key_type = KEY_BG
-                index += 1
-            elif val == "o":
-                self.key_type = KEY_OUT
-                index += 1
-            else:
-                self.key_type = KEY_IN  # if no args given
-
-            # there may be an (F) after, eg 'K B (F)'
-            # in the docs this should only be after K B but who knows, it may be after K O also?
-            val = line[index + 1].lower()
-            if val == "(f)":
-                index += 1
-                self.key_fade = True
-            else:
-                self.key_fade = False
-
-        index += 1
-
-        if self.transition_type in {TRANSITION_DISSOLVE, TRANSITION_EFFECT, TRANSITION_FADEIN, TRANSITION_FADEOUT, TRANSITION_WIPE}:
-            self.transition_duration = TimeCode(line[index], fps)
-            index += 1
-
-        if index < len(line):
-            self.srcIn = TimeCode(line[index], fps)
-            index += 1
-        if index < len(line):
-            self.srcOut = TimeCode(line[index], fps)
-            index += 1
-
-        if index < len(line):
-            self.recIn = TimeCode(line[index], fps)
-            index += 1
-        if index < len(line):
-            self.recOut = TimeCode(line[index], fps)
-            index += 1
-
-    def renumber(self):
-        self.edits.sort(key=lambda e: int(e.recIn))
-        for i, edit in enumerate(self.edits):
-            edit.number = i
-
-    def clean(self):
-        """
-        Clean up double ups
-        """
-        self.renumber()
-
-        # TODO
-    def asName(self):
-        cut_type = "nil"
-        for k, v in TRANSITION_DICT.items():
-            if v == self.transition_type:
-                cut_type = k
-                break
-
-        return "%d_%s_%s" % (self.number, self.reel, cut_type)
-
-
-class M2(object):
-    def __init__(self):
-        self.reel = None
-        self.fps = None
-        self.time = None
-        self.data = None
-
-        self.index = -1
-        self.tot = -1
-
-    def read(self, line, fps):
-
-        # M2   TAPEC          050.5                00:08:11:08
-        words = line.split()
-
-        self.reel = words[1].lower()
-        self.fps = float(words[2])
-        self.time = TimeCode(words[3], fps)
-
-        self.data = line
-
-
-class EditList(object):
-    def __init__(self):
-        self.edits = []
-        self.title = ""
-
-    def parse(self, filename, fps):
-        try:
-            file = open(filename, "rU")
-        except:
-            return False
-
-        self.edits = []
-        edits_m2 = []  # edits with m2's
-
-        has_m2 = False
-
-        for line in file:
-            line = " ".join(line.split())
-
-            if not line or line.startswith("*") or line.startswith("#"):
-                continue
-            elif line.startswith("TITLE:"):
-                self.title = " ".join(line.split()[1:])
-            elif line.split()[0].lower() == "m2":
-                has_m2 = True
-                m2 = M2()
-                m2.read(line, fps)
-                edits_m2.append(m2)
-            elif not line.split()[0].isdigit():
-                print("Ignoring:", line)
-            else:
-                self.edits.append(EditDecision(line, fps))
-                edits_m2.append(self.edits[-1])
-
-        if has_m2:
-            # Group indexes
-            i = 0
-            for item in edits_m2:
-                if isinstance(item, M2):
-                    item.index = i
-                    i += 1
-                else:
-                    # not an m2
-                    i = 0
-
-            # Set total group indexes
-            for item in reversed(edits_m2):
-                if isinstance(item, M2):
-                    if tot_m2 == -1:
-                        tot_m2 = item.index + 1
-
-                    item.tot = tot_m2
-                else:
-                    # not an m2
-                    tot_m2 = -1
-
-            for i, item in enumerate(edits_m2):
-                if isinstance(item, M2):
-                    # make a list of all items that match the m2's reel name
-                    edits_m2_tmp = [item_tmp for item_tmp in edits_m2 if (isinstance(item, M2) or item_tmp.reel == item.reel)]
-
-                    # get the new index
-                    i_tmp = edits_m2_tmp.index(item)
-
-                    # Seek back to get the edit.
-                    edit = edits_m2[i_tmp - item.tot]
-
-                    # Note, docs say time should also match with edit start time
-                    # but from final cut pro, this seems not to be the case
-                    if not isinstance(edit, EditDecision):
-                        print("ERROR!", "M2 incorrect")
-                    else:
-                        edit.m2 = item
-
-        return True
-
-    def testOverlap(self, edit_test):
-        recIn = int(edit_test.recIn)
-        recOut = int(edit_test.recOut)
-
-        for edit in self.edits:
-            if edit is edit_test:
-                break
-
-            recIn_other = int(edit.recIn)
-            recOut_other = int(edit.recOut)
-
-            if recIn_other < recIn < recOut_other:
-                return True
-            if recIn_other < recOut < recOut_other:
-                return True
-
-            if recIn < recIn_other < recOut:
-                return True
-            if recIn < recOut_other < recOut:
-                return True
-
-        return False
-
-    def getReels(self):
-        reels = {}
-        for edit in self.edits:
-            reels.setdefault(edit.reel, []).append(edit)
-
-        return reels
-
-# from DNA
-SEQ_IMAGE = 0
-SEQ_META = 1
-SEQ_SCENE = 2
-SEQ_MOVIE = 3
-SEQ_RAM_SOUND = 4
-SEQ_HD_SOUND = 5
-SEQ_MOVIE_AND_HD_SOUND = 6
-
-SEQ_EFFECT = 8
-SEQ_CROSS = 8
-SEQ_ADD = 9
-SEQ_SUB = 10
-SEQ_ALPHAOVER = 11
-SEQ_ALPHAUNDER = 12
-SEQ_GAMCROSS = 13
-SEQ_MUL = 14
-SEQ_OVERDROP = 15
-SEQ_PLUGIN = 24
-SEQ_WIPE = 25
-SEQ_GLOW = 26
-SEQ_TRANSFORM = 27
-SEQ_COLOR = 28
-SEQ_SPEED = 29
-
-# Blender spesific stuff starts here
-import bpy
-import Blender
-
-
-def scale_meta_speed(seq, mov, scale):
-    # Add an effect
-    speed = seq.new((SEQ_SPEED, mov,), 199, mov.channel + 1)
-    speed.speedEffectFrameBlending = True
-    meta = seq.new([mov, speed], 199, mov.channel)
-
-    if scale >= 1.0:
-        mov.endStill = int(mov.length * (scale - 1.0))
-    else:
-        speed.speedEffectGlobalSpeed = 1.0 / scale
-        meta.endOffset = mov.length - int(mov.length * scale)
-
-    speed.update()
-    meta.update()
-    return meta
-
-
-def apply_dissolve_ipo(mov, blendin):
-    len_disp = float(mov.endDisp - mov.startDisp)
-
-    if len_disp <= 0.0:
-        print("Error, strip is zero length")
-        return
-
-    mov.ipo = ipo = bpy.data.ipos.new("fade", "Sequence")
-    icu = ipo.addCurve("Fac")
-
-    icu.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
-    icu.append((0, 0))
-    icu.append(((int(blendin) / len_disp) * 100, 1))
-
-    if mov.type not in (SEQ_HD_SOUND, SEQ_RAM_SOUND):
-        mov.blendMode = Blender.Scene.Sequence.BlendModes.ALPHAOVER
-
-
-def replace_ext(path, ext):
-    return path[:path.rfind(".") + 1] + ext
-
-
-def load_edl(filename, reel_files, reel_offsets):
-    """
-    reel_files - key:reel <--> reel:filename
-    """
-
-    # For test file
-    # frame_offset = -769
-
-    sce = bpy.data.scenes.active
-    fps = sce.render.fps
-
-    elist = EditList()
-    if not elist.parse(filename, fps):
-        return "Unable to parse %r" % filename
-    # elist.clean()
-
-    seq = sce.sequence
-
-    track = 0
-
-    edits = elist.edits[:]
-    # edits.sort(key = lambda edit: int(edit.recIn))
-
-    prev_edit = None
-    for edit in edits:
-        print(edit)
-        frame_offset = reel_offsets[edit.reel]
-
-        src_start = int(edit.srcIn) + frame_offset
-        src_end = int(edit.srcOut) + frame_offset
-        src_length = src_end - src_start
-
-        rec_start = int(edit.recIn) + 1
-        rec_end = int(edit.recOut) + 1
-        rec_length = rec_end - rec_start
-
-        # print src_length, rec_length, src_start
-
-        if edit.m2 != None:
-            scale = fps / edit.m2.fps
-        else:
-            scale = 1.0
-
-        unedited_start = rec_start - src_start
-        offset_start = src_start - int(src_start * scale)  # works for scaling up AND down
-
-        if edit.transition_type == TRANSITION_CUT and (not elist.testOverlap(edit)):
-            track = 1
-
-        strip = None
-        final_strips = []
-        if edit.reel.lower() == "bw":
-            strip = seq.new((0, 0, 0), rec_start, track + 1)
-            strip.length = rec_length  # for color its simple
-            final_strips.append(strip)
-        else:
-
-            path_full = reel_files[edit.reel]
-            path_fileonly = path_full.split("/")[-1].split("\\")[-1]  # os.path.basename(full)
-            path_dironly = path_full[:-len(path_fileonly)]  # os.path.dirname(full)
-
-            if edit.edit_type & EDIT_VIDEO:  # and edit.transition_type == TRANSITION_CUT:
-
-                try:
-                    strip = seq.new((path_fileonly, path_dironly, path_full, "movie"), unedited_start + offset_start, track + 1)
-                except:
-                    return "Invalid input for movie"
-
-                # Apply scaled rec in bounds
-                if scale != 1.0:
-                    meta = scale_meta_speed(seq, strip, scale)
-                    final_strip = meta
-                else:
-                    final_strip = strip
-
-                final_strip.update()
-                final_strip.startOffset = rec_start - final_strip.startDisp
-                final_strip.endOffset = rec_end - final_strip.endDisp
-                final_strip.update()
-                final_strip.endOffset += (final_strip.endDisp - rec_end)
-                final_strip.update()
-
-                if edit.transition_duration:
-                    if not prev_edit:
-                        print("Error no previous strip")
-                    else:
-                        new_end = rec_start + int(edit.transition_duration)
-                        for other in prev_edit.custom_data:
-                            if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND:
-                                other.endOffset += (other.endDisp - new_end)
-                                other.update()
-
-                # Apply disolve
-                if edit.transition_type == TRANSITION_DISSOLVE:
-                    apply_dissolve_ipo(final_strip, edit.transition_duration)
-
-                if edit.transition_type == TRANSITION_WIPE:
-                    other_track = track + 2
-                    for other in prev_edit.custom_data:
-                        if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND:
-
-                            strip_wipe = seq.new((SEQ_WIPE, other, final_strip), 1, other_track)
-
-                            if edit.wipe_type == WIPE_0:
-                                strip_wipe.wipeEffectAngle = +90
-                            else:
-                                strip_wipe.wipeEffectAngle = -90
-
-                            other_track += 1
-
-                # strip.endOffset = strip.length - int(edit.srcOut)
-                # end_offset = (unedited_start+strip.length) - end
-                # print start, end, end_offset
-                # strip.endOffset = end_offset
-                #
-                # break
-                # print(strip)
-
-                final_strips.append(final_strip)
-
-            if edit.edit_type & (EDIT_AUDIO | EDIT_AUDIO_STEREO | EDIT_VIDEO_AUDIO):
-
-                if scale == 1.0:  # TODO - scaled audio
-
-                    try:
-                        strip = seq.new((path_fileonly, path_dironly, path_full, "audio_hd"), unedited_start + offset_start, track + 6)
-                    except:
-
-                        # See if there is a wave file there
-                        path_full_wav = replace_ext(path_full, "wav")
-                        path_fileonly_wav = replace_ext(path_fileonly, "wav")
-
-                        #try:
-                        strip = seq.new((path_fileonly_wav, path_dironly, path_full_wav, "audio_hd"), unedited_start + offset_start, track + 6)
-                        #except:
-                        #   return "Invalid input for audio"
-
-                    final_strip = strip
-
-                    # Copied from above
-                    final_strip.update()
-                    final_strip.startOffset = rec_start - final_strip.startDisp
-                    final_strip.endOffset = rec_end - final_strip.endDisp
-                    final_strip.update()
-                    final_strip.endOffset += (final_strip.endDisp - rec_end)
-                    final_strip.update()
-
-                    if edit.transition_type == TRANSITION_DISSOLVE:
-                        apply_dissolve_ipo(final_strip, edit.transition_duration)
-
-                    final_strips.append(final_strip)
-
-            # strip = seq.new((0.6, 0.6, 0.6), start, track+1)
-
-        if final_strips:
-            for strip in final_strips:
-                # strip.length = length
-                final_strip.name = edit.asName()
-                edit.custom_data[:] = final_strips
-                # track = not track
-                prev_edit = edit
-            track += 1
-
-        #break
-
-    def recursive_update(s):
-        s.update(1)
-        for s_kid in s:
-            recursive_update(s_kid)
-
-    for s in seq:
-        recursive_update(s)
-
-    return ""
-
-
-#load_edl("/fe/edl/EP30CMXtrk1.edl") # /tmp/test.edl
-#load_edl("/fe/edl/EP30CMXtrk2.edl") # /tmp/test.edl
-#load_edl("/fe/edl/EP30CMXtrk3.edl") # /tmp/test.edl
-#load_edl("/root/vid/rush/blender_edl.edl", ["/root/vid/rush/rushes3.avi",]) # /tmp/test.edl
-
-# ---------------------- Blender UI part
-from Blender import Draw, Window
-import BPyWindow
-
-if 0:
-    DEFAULT_FILE_EDL = "/root/vid/rush/blender_edl.edl"
-    DEFAULT_FILE_MEDIA = "/root/vid/rush/rushes3_wav.avi"
-    DEFAULT_FRAME_OFFSET = -769
-else:
-    DEFAULT_FILE_EDL = ""
-    DEFAULT_FILE_MEDIA = ""
-    DEFAULT_FRAME_OFFSET = 0
-
-B_EVENT_IMPORT = 1
-B_EVENT_RELOAD = 2
-B_EVENT_FILESEL_EDL = 3
-B_EVENT_NOP = 4
-
-B_EVENT_FILESEL = 100  # or greater
-
-
-class ReelItemUI(object):
-    __slots__ = "filename_but", "offset_but", "ui_text"
-
-    def __init__(self):
-        self.filename_but = Draw.Create(DEFAULT_FILE_MEDIA)
-        self.offset_but = Draw.Create(DEFAULT_FRAME_OFFSET)
-        self.ui_text = ""
-
-
-REEL_UI = {}    # reel:ui_string
-
-
-#REEL_FILENAMES = {}        # reel:filename
-#REEL_OFFSETS = {}      # reel:filename
-
-PREF = {}
-
-PREF["filename"] = Draw.Create(DEFAULT_FILE_EDL)
-PREF["reel_act"] = ""
-
-
-def edl_reload():
-    Window.WaitCursor(1)
-    filename = PREF["filename"].val
-    sce = bpy.data.scenes.active
-    fps = sce.render.fps
-
-    elist = EditList()
-
-    if filename:
-        if not elist.parse(filename, fps):
-            Draw.PupMenu("Error%t|Could not open the file %r" % filename)
-        reels = elist.getReels()
-    else:
-        reels = {}
-
-    REEL_UI.clear()
-    for reel_key, edits in reels.items():
-
-        if reel_key == "bw":
-            continue
-
-        flag = 0
-        for edit in edits:
-            flag |= edit.edit_type
-
-        reel_item = REEL_UI[reel_key] = ReelItemUI()
-
-        reel_item.ui_text = "%s (%s): " % (reel_key, editFlagsToText(flag))
-
-    Window.WaitCursor(0)
-
-
-def edl_set_path(filename):
-    PREF["filename"].val = filename
-    edl_reload()
-    Draw.Redraw()
-
-
-def edl_set_path_reel(filename):
-    REEL_UI[PREF["reel_act"]].filename_but.val = filename
-    Draw.Redraw()
-
-
-def edl_reel_keys():
-    reel_keys = REEL_UI.keys()
-
-    if "bw" in reel_keys:
-        reel_keys.remove("bw")
-
-    reel_keys.sort()
-    return reel_keys
-
-
-def edl_draw():
-
-    MARGIN = 4
-    rect = BPyWindow.spaceRect()
-    but_width = int((rect[2] - MARGIN * 2) / 4.0)  # 72
-    # Clamp
-    if but_width > 100:
-        but_width = 100
-    but_height = 17
-
-    x = MARGIN
-    y = rect[3] - but_height - MARGIN
-    xtmp = x
-
-    # ---------- ---------- ---------- ----------
-    Blender.Draw.BeginAlign()
-    PREF["filename"] = Draw.String("edl path: ", B_EVENT_RELOAD, xtmp, y, (but_width * 3) - 20, but_height, PREF["filename"].val, 256, "EDL Path")
-    xtmp += (but_width * 3) - 20
-
-    Draw.PushButton("..", B_EVENT_FILESEL_EDL, xtmp, y, 20, but_height, "Select an EDL file")
-    xtmp += 20
-
-    Blender.Draw.EndAlign()
-
-    Draw.PushButton("Reload", B_EVENT_RELOAD, xtmp + MARGIN, y, but_width - MARGIN, but_height, "Read the ID Property settings from the active curve object")
-    xtmp += but_width
-
-    y -= but_height + MARGIN
-    xtmp = x
-    # ---------- ---------- ---------- ----------
-
-    reel_keys = edl_reel_keys()
-
-    if reel_keys:
-        text = "Reel file list..."
-    elif PREF["filename"].val == "":
-        text = "No EDL loaded."
-    else:
-        text = "No reels found!"
-
-    Draw.Label(text, xtmp + MARGIN, y, but_width * 4, but_height)
-    xtmp += but_width * 4
-
-    y -= but_height + MARGIN
-    xtmp = x
-
-    # ---------- ---------- ---------- ----------
-
-    for i, reel_key in enumerate(reel_keys):
-        reel_item = REEL_UI[reel_key]
-
-        Blender.Draw.BeginAlign()
-        REEL_UI[reel_key].filename_but = Draw.String(reel_item.ui_text, B_EVENT_NOP, xtmp, y, (but_width * 3) - 20, but_height, REEL_UI[reel_key].filename_but.val, 256, "Select the reel path")
-        xtmp += (but_width * 3) - 20
-        Draw.PushButton("..", B_EVENT_FILESEL + i, xtmp, y, 20, but_height, "Media path to use for this reel")
-        xtmp += 20
-        Blender.Draw.EndAlign()
-
-        reel_item.offset_but = Draw.Number("ofs:", B_EVENT_NOP, xtmp + MARGIN, y, but_width - MARGIN, but_height, reel_item.offset_but.val, -100000, 100000, "Start offset in frames when applying timecode")
-        xtmp += but_width - MARGIN
-
-        y -= but_height + MARGIN
-        xtmp = x
-
-    # ---------- ---------- ---------- ----------
-
-    Draw.PushButton("Import CMX-EDL Sequencer Strips", B_EVENT_IMPORT, xtmp + MARGIN, MARGIN, but_width * 4 - MARGIN, but_height, "Load the EDL file into the sequencer")
-    xtmp += but_width * 4
-    y -= but_height + MARGIN
-    xtmp = x
-
-
-def edl_event(evt, val):
-    pass
-
-
-def edl_bevent(evt):
-
-    if evt == B_EVENT_NOP:
-        pass
-    elif evt == B_EVENT_IMPORT:
-        """
-        Load the file into blender with UI settings
-        """
-        filename = PREF["filename"].val
-
-        reel_files = {}
-        reel_offsets = {}
-
-        for reel_key, reel_item in REEL_UI.items():
-            reel_files[reel_key] = reel_item.filename_but.val
-            reel_offsets[reel_key] = reel_item.offset_but.val
-
-        error = load_edl(filename, reel_files, reel_offsets)
-        if error != "":
-            Draw.PupMenu("Error%t|" + error)
-        else:
-            Window.RedrawAll()
-
-    elif evt == B_EVENT_RELOAD:
-        edl_reload()
-        Draw.Redraw()
-
-    elif evt == B_EVENT_FILESEL_EDL:
-        filename = PREF["filename"].val
-        if not filename:
-            filename = Blender.sys.join(Blender.sys.expandpath("//"), "*.edl")
-
-        Window.FileSelector(edl_set_path, "Select EDL", filename)
-
-    elif evt >= B_EVENT_FILESEL:
-        reel_keys = edl_reel_keys()
-        reel_key = reel_keys[evt - B_EVENT_FILESEL]
-
-        filename = REEL_UI[reel_key].filename_but.val
-        if not filename:
-            filename = Blender.sys.expandpath("//")
-
-        PREF["reel_act"] = reel_key  # so file set path knows which one to set
-        Window.FileSelector(edl_set_path_reel, "Reel Media", filename)
-
-
-if __name__ == "__main__":
-    Draw.Register(edl_draw, edl_event, edl_bevent)
-    edl_reload()
diff --git a/release/scripts/addons_contrib/lamp_geographical_sun.py b/release/scripts/addons_contrib/lamp_geographical_sun.py
deleted file mode 100644
index 0315b90..0000000
--- a/release/scripts/addons_contrib/lamp_geographical_sun.py
+++ /dev/null
@@ -1,581 +0,0 @@
-# -*- coding: utf8 -*-
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# --------------------------------------------------------------------------
-# Blender 2.5 Geographical Sun Add-On
-# --------------------------------------------------------------------------
-#
-# Authors:
-# Doug Hammond
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-
-# System imports
-#-----------------------------------------------------------------------------
-import datetime, math, time
-today = datetime.datetime.now()
-
-# Blender imports
-#----------------------------------------------------------------------------- 
-import bpy
-from extensions_framework import Addon, declarative_property_group
-from extensions_framework.ui import property_group_renderer
-
-# Addon setup
-#----------------------------------------------------------------------------- 
-bl_info = {
-    "name": "Geographical Sun",
-    "author": "Doug Hammond (dougal2)",
-    "version": (0, 0, 1),
-    "blender": (2, 5, 6),
-    "category": "Object",
-    "location": "Lamp data > Geographical Sun",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "",
-    "description": "Set SUN Lamp rotation according to geographical time and location."
-}
-GeoSunAddon = Addon(bl_info)
-
-# Sun rotation calculator implementation
-#----------------------------------------------------------------------------- 
-class sun_calculator(object):
-    """
-    Based on SunLight v1.0 by Miguel Kabantsov (miguelkab at gmail.com)
-    Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand),
-    Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
-    Author: Nils-Peter Fischer (Nils-Peter.Fischer at web.de)
-    """
-    
-    location_list = [
-        ("EUROPE",[
-            ("Antwerp, Belgium",            67),
-            ("Berlin, Germany",             1),
-            ("Bratislava, Slovak Republic", 70),
-            ("Brno, Czech Republic",        72),
-            ("Brussles, Belgium",           68),
-            ("Geneva, Switzerland",         65),
-            ("Helsinki, Finland",           7),
-            ("Innsbruck, Austria",          62),
-            ("Kyiv, Ukraine",               64),
-            ("London, England",             10),
-            ("Lyon, France",                66),
-            ("Nitra, Slovak Republic",      69),
-            ("Oslo, Norway",                58),
-            ("Paris, France",               15),
-            ("Praha, Czech Republic",       71),
-            ("Rome, Italy",                 18),
-            ("Telfs, Austria",              63),
-            ("Warsaw, Poland",              74),
-            ("Wroclaw, Poland",             73),
-            ("Zurich, Switzerland",         21),
-        ]),
-        
-        ("WORLD CITIES", [
-            ("Beijing, China",              0),
-            ("Bombay, India",               2),
-            ("Buenos Aires, Argentina",     3),
-            ("Cairo, Egypt",                4),
-            ("Cape Town, South Africa",     5),
-            ("Caracas, Venezuela",          6),
-            ("Curitiba, Brazil",            60),
-            ("Hong Kong, China",            8),
-            ("Jerusalem, Israel",           9),
-            ("Joinville, Brazil",           61),
-            ("Mexico City, Mexico",         11),
-            ("Moscow, Russia",              12),
-            ("New Delhi, India",            13),
-            ("Ottawa, Canada",              14),
-            ("Rio de Janeiro, Brazil",      16),
-            ("Riyadh, Saudi Arabia",        17),
-            ("Sao Paulo, Brazil",           59),
-            ("Sydney, Australia",           19),
-            ("Tokyo, Japan",                20),
-        ]),
-        
-        ("US CITIES", [
-            ("Albuquerque, NM",             22),
-            ("Anchorage, AK",               23),
-            ("Atlanta, GA",                 24),
-            ("Austin, TX",                  25),
-            ("Birmingham, AL",              26),
-            ("Bismarck, ND",                27),
-            ("Boston, MA",                  28),
-            ("Boulder, CO",                 29),
-            ("Chicago, IL",                 30),
-            ("Dallas, TX",                  31),
-            ("Denver, CO",                  32),
-            ("Detroit, MI",                 33),
-            ("Honolulu, HI",                34),
-            ("Houston, TX",                 35),
-            ("Indianapolis, IN",            36),
-            ("Jackson, MS",                 37),
-            ("Kansas City, MO",             38),
-            ("Los Angeles, CA",             39),
-            ("Menomonee Falls, WI",         40),
-            ("Miami, FL",                   41),
-            ("Minneapolis, MN",             42),
-            ("New Orleans, LA",             43),
-            ("New York City, NY",           44),
-            ("Oklahoma City, OK",           45),
-            ("Philadelphia, PA",            46),
-            ("Phoenix, AZ",                 47),
-            ("Pittsburgh, PA",              48),
-            ("Portland, ME",                49),
-            ("Portland, OR",                50),
-            ("Raleigh, NC",                 51),
-            ("Richmond, VA",                52),
-            ("Saint Louis, MO",             53),
-            ("San Diego, CA",               54),
-            ("San Francisco, CA",           55),
-            ("Seattle, WA",                 56),
-            ("Washington DC",               57),
-        ])
-    ]
-    
-    location_data = {
-        # Europe
-        67: ( 51.2167, -4.4, 1),
-        1:  ( 52.33, -13.30, 1),
-        70: ( 48.17, -17.17, 1),
-        72: ( 49.2, -16.63, 1),
-        68: ( 58.8467, -4.3525, 1),
-        65: ( 46.217, -6.150, 1),
-        7:  ( 60.1667, -24.9667,2),
-        62: ( 47.2672, -11.3928, 1),
-        64: ( 50.75, -30.0833, 2),
-        10: ( 51.50, 0.0, 0),
-        66: ( 45.767, -4.833, 1),
-        69: ( 48.32, -18.07, 1),
-        58: ( 59.56, -10.41, 1),
-        15: ( 48.8667, -2.667, 1),
-        71: ( 50.08, -14.46, 1),
-        18: ( 41.90, -12.4833, 1),
-        63: ( 47.3, -11.0667, 1),
-        74: ( 52.232, -21.008, 1),
-        73: ( 51.108, -17.038, 1),
-        21: ( 47.3833, -8.5333, 1),
-        
-        # World Cities
-        0:  ( 39.9167, -116.4167, 8),
-        2:  ( 18.9333, -72.8333, 5.5),
-        3:  (-34.60, 58.45, -3),
-        4:  ( 30.10, -31.3667, 2),
-        5:  (-33.9167, -18.3667, 2),
-        6:  ( 10.50, 66.9333, -4),
-        60: (-25.4278, 49.2731, -3),
-        8:  ( 22.25, -114.1667, 8),
-        9:  ( 31.7833, -35.2333, 2),
-        61: (-29.3044, 48.8456, -3),
-        11: ( 19.4, 99.15, -6),
-        12: ( 55.75, -37.5833, 3),
-        13: ( 28.6, -77.2, 5.5),
-        14: ( 45.41667, 75.7, -5),
-        16: (-22.90, 43.2333, -3),
-        17: ( 24.633, -46.71667, 3),
-        59: ( -23.5475, 46.6361, -3),
-        19: (-33.8667, -151.2167,10),
-        20: ( 35.70, -139.7667, 9), 
-        
-        # US Cities
-        22: ( 35.0833, 106.65, -7),
-        23: ( 61.217, 149.90, -9),
-        24: ( 33.733, 84.383, -5),
-        25: ( 30.283, 97.733, -6),
-        26: ( 33.521, 86.8025, -6),
-        27: ( 46.817, 100.783, -6),
-        28: ( 42.35, 71.05, -5),
-        29: ( 40.125, 105.237, -7),
-        30: ( 41.85, 87.65, -6),
-        31: ( 32.46, 96.47, -6),
-        32: ( 39.733, 104.983, -7),
-        33: ( 42.333, 83.05, -5),
-        34: ( 21.30, 157.85, -10),
-        35: ( 29.75, 95.35, -6),
-        36: ( 39.767, 86.15, -5),
-        37: ( 32.283, 90.183, -6),
-        38: ( 39.083, 94.567, -6),
-        39: ( 34.05, 118.233, -8),
-        40: ( 43.11, 88.10, -6),
-        41: ( 25.767, 80.183, -5),
-        42: ( 44.967, 93.25, -6),
-        43: ( 29.95, 90.067, -6),
-        44: ( 40.7167, 74.0167, -5),
-        45: ( 35.483, 97.533, -6),
-        46: ( 39.95, 75.15, -5),
-        47: ( 33.433, 112.067,-7),
-        48: ( 40.433, 79.9833, -5),
-        49: ( 43.666, 70.283, -5),
-        50: ( 45.517, 122.65, -8),
-        51: ( 35.783, 78.65, -5),
-        52: ( 37.5667, 77.450, -5),
-        53: ( 38.6167, 90.1833, -6),
-        54: ( 32.7667, 117.2167, -8),
-        55: ( 37.7667, 122.4167, -8),
-        56: ( 47.60, 122.3167, -8),
-        57: ( 38.8833, 77.0333, -5),
-    }
-    
-    # mathematical helpers
-    @staticmethod
-    def sind(deg):
-        return math.sin(math.radians(deg))
-    
-    @staticmethod
-    def cosd(deg):
-        return math.cos(math.radians(deg))
-    
-    @staticmethod
-    def tand(deg):
-        return math.tan(math.radians(deg))
-    
-    @staticmethod
-    def asind(deg):
-        return math.degrees(math.asin(deg))
-    
-    @staticmethod
-    def atand(deg):
-        return math.degrees(math.atan(deg))
-    
-    @staticmethod
-    def geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone):
-        if Month > 2.0:
-            Y = Year
-            M = Month
-        else:
-            Y = Year - 1.0
-            M = Month + 12.0
-            
-        UT = LocalTime - Timezone
-        hour = UT / 24.0
-        A = int(Y/100.0)
-        
-        JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour - 1524.4
-        
-        # The following section is adopted from netCDF4 netcdftime implementation.
-        # Copyright: 2008 by Jeffrey Whitaker
-        # License: http://www.opensource.org/licenses/mit-license.php
-        if JD >= 2299170.5:
-            # 1582 October 15 (Gregorian Calendar)
-            B = 2.0 - A + int(A/4.0)
-        elif JD < 2299160.5:
-            # 1582 October 5 (Julian Calendar)
-            B = 0
-        else:
-            raise Exception('ERROR: Date falls in the gap between Julian and Gregorian calendars.')
-            B = 0
-        
-        return JD+B
-    
-    @staticmethod
-    def geoSunData(Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
-        JD = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
-        
-        phi = Latitude
-        llambda = Longitude
-                
-        n = JD - 2451545.0
-        LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
-        gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
-        LambdaDeg = LDeg + 1.915 * sun_calculator.sind(gDeg) + 0.02 * sun_calculator.sind(2.0*gDeg)
-        
-        epsilonDeg = 23.439 - 0.0000004*n
-        
-        alphaDeg = sun_calculator.atand( (sun_calculator.cosd(epsilonDeg) * sun_calculator.sind(LambdaDeg)) / sun_calculator.cosd(LambdaDeg) )
-        if sun_calculator.cosd(LambdaDeg) < 0.0:
-            alphaDeg += 180.0
-            
-        deltaDeg = sun_calculator.asind( sun_calculator.sind(epsilonDeg) * sun_calculator.sind(LambdaDeg) )
-        
-        JDNull = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
-        
-        TNull = (JDNull - 2451545.0) / 36525.0
-        T = LocalTime - Timezone
-        
-        thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
-        thetaGh -= math.floor(thetaGh/24.0) * 24.0
-        
-        thetaG = thetaGh * 15.0
-        theta = thetaG + llambda
-        
-        tau = theta - alphaDeg
-        
-        a = sun_calculator.atand( sun_calculator.sind(tau) / ( sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi)) )
-        if sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi) < 0.0:
-            a += 180.0
-        
-        h = sun_calculator.asind( sun_calculator.cosd(deltaDeg)*sun_calculator.cosd(tau)*sun_calculator.cosd(phi) + sun_calculator.sind(deltaDeg)*sun_calculator.sind(phi) )
-        
-        R = 1.02 / (sun_calculator.tand (h+(10.3/(h+5.11))))
-        hR = h + R/60.0
-        
-        azimuth = a
-        elevation = hR
-        
-        return azimuth, elevation
-
-# Addon classes
-#----------------------------------------------------------------------------- 
- at GeoSunAddon.addon_register_class
-class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator):
-    bl_idname = 'object.set_geographical_sun_now'
-    bl_label = 'Set time to NOW'
-    
-    @classmethod
-    def poll(cls, context):
-        cl = context.lamp
-        return cl and cl.type == 'SUN'
-    
-    def execute(self, context):
-        GSP = context.lamp.GeoSunProperties
-        
-        now = datetime.datetime.now()
-        for p in ("hour", "minute", "day", "month", "year"):
-            setattr(
-                GSP,
-                p,
-                getattr(now, p)
-            )
-        GSP.tz = time.timezone
-        GSP.dst = False
-        
-        return {'FINISHED'}
-
- at GeoSunAddon.addon_register_class
-class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator):
-    bl_idname = 'object.set_geographical_sun_pos'
-    bl_label = 'Set SUN position'
-    
-    @classmethod
-    def poll(cls, context):
-        cl = context.lamp
-        return cl and cl.type == 'SUN'
-    
-    def execute(self, context):
-        try:
-            GSP = context.lamp.GeoSunProperties
-            
-            dst = 1 if GSP.dst else 0
-            
-            az,el = sun_calculator.geoSunData(
-                GSP.lat,
-                GSP.long,
-                GSP.year,
-                GSP.month,
-                GSP.day,
-                GSP.hour + GSP.minute/60.0,
-                -GSP.tz + dst
-            )
-            
-            context.object.rotation_euler = ( math.radians(90-el), 0, math.radians(-az) )
-            return {'FINISHED'}
-        except Exception as err:
-            self.report({'ERROR'}, str(err))
-            return {'CANCELLED'}
-
- at GeoSunAddon.addon_register_class
-class OBJECT_OT_set_geographical_location_preset(bpy.types.Operator):
-    bl_idname = 'object.set_geographical_location_preset'
-    bl_label = 'Apply location preset'
-    
-    index = bpy.props.IntProperty()
-    
-    @classmethod
-    def poll(cls, context):
-        cl = context.lamp
-        return cl and cl.type == 'SUN'
-    
-    def execute(self, context):
-        GSP = context.lamp.GeoSunProperties
-        GSP.lat, GSP.long, GSP.tz = sun_calculator.location_data[self.properties.index]
-        return {'FINISHED'}
-
-# Dynamic submenu magic !
-
-def draw_generator(locations):
-    def draw(self, context):
-        sl = self.layout
-        for location in locations:
-            location_name, location_index = location
-            sl.operator('OBJECT_OT_set_geographical_location_preset', text=location_name).index = location_index
-    return draw
-
-submenus = []
-for label, locations in sun_calculator.location_list:
-    submenu_idname = 'OBJECT_MT_geo_sun_location_cat%d'%len(submenus)
-    submenu = type(
-        submenu_idname,
-        (bpy.types.Menu,),
-        {
-            'bl_idname': submenu_idname,
-            'bl_label': label,
-            'draw': draw_generator(locations)
-        }
-    )
-    GeoSunAddon.addon_register_class(submenu)
-    submenus.append(submenu)
-
- at GeoSunAddon.addon_register_class
-class OBJECT_MT_geo_sun_location(bpy.types.Menu):
-    bl_label = 'Location preset'
-    
-    def draw(self, context):
-        sl = self.layout
-        for sm in submenus:
-            sl.menu(sm.bl_idname)
-
- at GeoSunAddon.addon_register_class
-class GeoSunProperties(declarative_property_group):
-    ef_attach_to = ['Lamp']
-    
-    controls = [
-        ['hour', 'minute'],
-        ['day', 'month', 'year'],
-        ['tz', 'dst'],
-        'location_menu',
-        ['lat', 'long'],
-        ['set_time', 'set_posn'],
-    ]
-    
-    properties = [
-        {
-            'type': 'int',
-            'attr': 'minute',
-            'name': 'Minute',
-            'min': 0,
-            'soft_min': 0,
-            'max': 59,
-            'soft_max': 59,
-            'default': today.minute
-        },
-        {
-            'type': 'int',
-            'attr': 'hour',
-            'name': 'Hour',
-            'min': 0,
-            'soft_min': 0,
-            'max': 24,
-            'soft_max': 24,
-            'default': today.hour
-        },
-        {
-            'type': 'int',
-            'attr': 'day',
-            'name': 'Day',
-            'min': 1,
-            'soft_min': 1,
-            'max': 31,
-            'soft_max': 31,
-            'default': today.day
-        },
-        {
-            'type': 'int',
-            'attr': 'month',
-            'name': 'Month',
-            'min': 1,
-            'soft_min': 1,
-            'max': 12,
-            'soft_max': 12,
-            'default': today.month
-        },
-        {
-            'type': 'int',
-            'attr': 'year',
-            'name': 'Year',
-            'min': datetime.MINYEAR,
-            'soft_min': datetime.MINYEAR,
-            'max': datetime.MAXYEAR,
-            'soft_max': datetime.MAXYEAR,
-            'default': today.year
-        },
-        {
-            'type': 'int',
-            'attr': 'tz',
-            'name': 'Time zone',
-            'min': -13,
-            'soft_min': -13,
-            'max': 13,
-            'soft_max': 13,
-            'default': time.timezone
-        },
-        {
-            'type': 'bool',
-            'attr': 'dst',
-            'name': 'DST',
-            'default': False
-        },
-        {
-            'type': 'float',
-            'attr': 'lat',
-            'name': 'Lat.',
-            'min': -180.0,
-            'soft_min': -180.0,
-            'max': 180.0,
-            'soft_max': 180.0,
-            'default': 0.0
-        },
-        {
-            'type': 'float',
-            'attr': 'long',
-            'name': 'Long.',
-            'min': -90.0,
-            'soft_min': -90.0,
-            'max': 90.0,
-            'soft_max': 90.0,
-            'default': 0.0
-        },
-        
-        # draw operators and menus
-        {
-            'attr': 'location_menu',
-            'type': 'menu',
-            'menu': 'OBJECT_MT_geo_sun_location'
-        },
-        {
-            'attr': 'set_time',
-            'type': 'operator',
-            'operator': 'object.set_geographical_sun_now',
-            'icon': 'PREVIEW_RANGE'
-        },
-        {
-            'attr': 'set_posn',
-            'type': 'operator',
-            'operator': 'object.set_geographical_sun_pos',
-            'icon': 'WORLD_DATA'
-        },
-    ]
-
- at GeoSunAddon.addon_register_class
-class GeoSunPanel(property_group_renderer):
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'data'
-    bl_label = 'Geographical Sun'
-    
-    display_property_groups = [
-        ( ('lamp',), 'GeoSunProperties' )
-    ]
-    
-    @classmethod
-    def poll(cls, context):
-        cl = context.lamp
-        return cl and cl.type == 'SUN'
-
-# Bootstrap the Addon
-#----------------------------------------------------------------------------- 
-register, unregister = GeoSunAddon.init_functions()
diff --git a/release/scripts/addons_contrib/mesh_bevel_round.py b/release/scripts/addons_contrib/mesh_bevel_round.py
deleted file mode 100644
index d2f494b..0000000
--- a/release/scripts/addons_contrib/mesh_bevel_round.py
+++ /dev/null
@@ -1,2862 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-# Ported from RoundCorner Ruby program for Sketchup by Fredo6
-# Fredo6 gave permission to port and distribute with Blender
-
-bl_info = {
-    "name": "Bevel Round",
-    "author": "Fredo6, Howard Trickey",
-    "version": (0, 1),
-    "blender": (2, 6, 3),
-    "location": "View3D > Tools",
-    "description": "Bevel selected edges, possibly rounded",
-    "warning": "",
-    "wiki_url": \
-      "TODO",
-    "tracker_url": \
-      "TODO",
-    "category": "Mesh"}
-
-import math
-import functools
-import bpy
-import bmesh
-import mathutils
-from bpy.props import (BoolProperty,
-                       EnumProperty,
-                       IntProperty,
-                       FloatProperty,
-                       )
-from mathutils import Vector
-
-EPSILON = 1e-6
-
-class BevelRound(bpy.types.Operator):
-    bl_idname = "mesh.bevel_round"
-    bl_label = "Bevel Round"
-    bl_description = "Bevel selected edges, possibly rounded"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    bevel_kind = EnumProperty(name="Bevel Kind",
-        description="Style for beveling edges and corners",
-        items=[
-            ('ROUND', "Round",
-                "Round edges and corners"),
-            ('SHARP', "Sharp",
-                "Round edges, peaked corners"),
-            ('BEVEL', "Bevel",
-                "Flat edges and corners")
-            ],
-        default='BEVEL')
-
-    offset_amount = FloatProperty(name="Offset",
-        description="Amount to offset edges along faces",
-        default=0.2,
-        min=0.0,
-        max=1000.0,
-        soft_min=0.0,
-        soft_max=10.0,
-        unit='LENGTH')
-
-    segments = IntProperty(name="Segments",
-        description="How many segments on bevel profile",
-        min=1,
-        max=100,
-        default=1)
-
-    strict_offset = BoolProperty(name="Strict Offset",
-        description="Keep offset the same on all faces",
-        default=True)
-
-    rounding = BoolProperty(name="Inner Rounding",
-        description="Round inside faces at concave corners",
-        default=True)
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        box.label("Bevel Round Options:")
-        box.prop(self, "bevel_kind")
-        box.prop(self, "offset_amount")
-        box.prop(self, "segments")
-        box.prop(self, "strict_offset")
-        box.prop(self, "rounding")
-
-    def invoke(self, context, event):
-        self.action(context)
-        return {'FINISHED'}
-
-    def execute(self, context):
-        self.action(context)
-        return {'FINISHED'}
-
-    def action(self, context):
-        obj = bpy.context.active_object
-        bm = bmesh.from_edit_mesh(obj.data)
-        # make sure vert, edge, face indexes match their positions
-        bm.verts.index_update()
-        bm.edges.index_update()
-        bm.faces.index_update()
-        algo = BevelRoundAlgo(bm, self.bevel_kind, self.offset_amount,
-            self.segments, self.strict_offset, self.rounding)
-        algo.execute()
-        # Force mesh data recalculation
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.object.editmode_toggle()
-
-
-class BevelRoundAlgo(object):
-    def __init__(self, bm, kind, offset, num_seg, strict, round):
-        # The bmesh object
-        self.bm = bm
-
-        # How much to move offset edges
-        # (projected onto 90deg angle planes, unless strict_offset)
-        self.offset = offset
-
-        # How many segments in the profile of an edge
-        self.num_seg = num_seg
-
-        # Cache of profiles in standard position, keyed by "kind-numseg"
-        # Kind will be one of 'C' or 'P', for now
-        self.hsh_profile_pts = {}
-
-        # bmesh Edge index -> BEdge for it
-        # Will have one for all the edges in the bevel selection
-        self.hsh_ed = {}
-
-        # bmesh Vertex index -> BCorner for it
-        # Will have one for all ends of edges in hsh_ed
-        self.hsh_corners = {}
-
-        # bmesh Face index -> BFace for it
-        self.hsh_faces = {}
-
-        # List of [Vector, Vector], each a border line segment (for display only?)
-        self.lpt_borders = []
-
-        # Catenas are chains of edges with related offsets
-        # Each has eds, a list of BEdges;
-        #  chain, a list of [BEdge, face index]l
-        #  nbsmall: seems to be some kind of edge count
-        self.lst_catenas = []
-
-        # List of Vector, pivot points for star corners
-        self.lst_mark_points = []
-
-        # lst_triangulate is list of [vd, ed1, ed2, seg1, seg2]
-        # for each vd for a vert with only two edges and >=3 pairs
-        self.lst_triangulated = []
-
-        # List of BCorner, those signaled as errors (pair lines don't cross (?))
-        self.hsh_error_vertex = {}
-
-        # Edge index -> bmesh Edge for edges to bevel
-        self.hash_edges = {}
-
-        # hash_edges_extra : Edge index -> bmesh Edge added for valence >= 4 reasons
-        self.hash_edges_extra = {}
-
-        # Vertex index -> list of bmesh edges to bevel attached
-        self.hsh_vertex_edges = {}
-
-        # Vertex index -> list of all bmesh edges attached to it
-        self.hsh_vertex_info = {}
-
-        # Map from point to BMVert
-        self.points = Points(self.bm)
-
-        # Used to orient asymmetric corner mesh patterns
-        self.golden_axis = Vector([0.0, 0.0, 1.0])
-
-        # Profile spec for edges: [string, number]
-        # where string is 'C' for quarter circle, 'CR' for concave quarter circle,
-        # 'BZ' for Bezier, 'P' for 'perso' (?, some kind of multi-bezier).
-        # number is number of line segments in profile (so 1 means just
-        # a single straight line from start to end)
-        if kind == 'BEVEL':
-            self.profile_type = ['C', 1]
-            self.num_seg = 1
-        else:
-            self.profile_type = ['C', num_seg]
-
-        # Controls whether or not to use a round profile in certain disagreeing cases (?)
-        self.mode_profile = 1
-
-        # Corners come to peaks if mode_sharp
-        self.mode_sharp = True if kind == 'SHARP' else False
-
-        # Forces offset along faces to  be uniform rather than adjusted
-        # to make them uniform when projected on 90deg-meeting-faces
-        self.strict_offset = strict
-
-        # Should we round the edges in the faces themselves too?
-        self.mode_rounding = round
-
-    def execute(self):
-        bm = self.bm
-
-        # Add the bmesh edges and compute everything
-        # needed for bevel
-        self.build_model(bm)
-
-        # print("after build:")
-        # self.print()
-
-        # Initialization for geometry making
-        self.prepare_geometry()
-
-        # print("after prepare_geometry")
-        # self.print()
-
-        self.lst_corners = list(self.hsh_corners.values())
-        self.nb_corners = len(self.lst_corners) - 1
-        self.lst_eds = list(self.hsh_ed.values())
-        self.nb_eds = len(self.lst_eds) - 1
-        self.hsh_edge_erase = {}
-        self.nb_borders = len(self.lpt_borders) // 2 - 1
-
-        # Process geometry
-
-        self.lst_edge_erase = []
-        self.nb_edge_erase = -1
-
-        # Creating the rounding faces
-        for k in range(0, self.nb_eds + 1):
-            ed = self.lst_eds[k]
-            if ed.vmesh:
-                self.create_geometry_vmesh(ed.vmesh)
-
-        # Creating the triangulated  vmesh if any
-        self.create_geometry_vmesh(self.lst_vmesh_triangulated)
-        self.create_geometry_vborders(self.lst_vborders_triangulated)
-
-        # Creating the corner round faces
-        for k in range(0, self.nb_corners + 1):
-           vd = self.lst_corners[k]
-           if vd.vmesh:
-               self.create_geometry_vmesh(vd.vmesh)
-
-        # Creating the new faces
-        for fc in self.hsh_faces.values():
-            lv = []
-            for i in range(len(fc.bmverts)):
-                npl = fc.newpts[i]
-                if npl:
-                    lv.extend(self.get_bmverts(npl))
-                else:
-                    lv.append(fc.bmverts[i])
-            self.bm.faces.new(lv)
-
-        # Deleting the unneeded geometry
-        for f in self.hsh_faces.values():
-            if f.face.is_valid:
-                fedges = f.face.edges[::]
-                self.bm.faces.remove(f.face)
-                for e in fedges:
-                    if e.is_valid:
-                        if e.is_wire:
-                            self.bm.edges.remove(e)
-        for k in range(0, self.nb_corners + 1):
-            vd = self.lst_corners[k]
-            if len(vd.leds) == 1:
-                edge = vd.leds[0].edge
-                if edge.is_valid:
-                    self.bm.edges.remove(edge)
-            else:
-                # print("remove edges:", vd.vertex.link_edges)
-                pass  # is there stuff to do here?
-            if vd.vertex.is_valid:
-                self.bm.verts.remove(vd.vertex)
-
-    # Prepare the geometry
-    def prepare_geometry(self):
-        # Compute the corners
-        for vd in self.hsh_corners.values():
-            self.corner_compute(vd)
-
-        # Compute the edge roundings
-        for ed in self.hsh_ed.values():
-            self.compute_mesh_edge(ed)
-
-        # Compute the edge roundings for triangulated corners, if any
-        self.lst_vmesh_triangulated = []
-        self.lst_vborders_triangulated = []
-        for ll in self.lst_triangulated:
-            self.compute_mesh_edge_triangulated(ll[0], ll[1], ll[2], ll[3], ll[4])
-
-        # Compute the faces
-        for fc in self.hsh_faces.values():
-            self.compute_face(fc)
-
-    # Adds more edges if needed to make it so that for
-    # vertices of valence 4 or more, all edges are beveled if any are.
-    # Fills hsh_vertex_info for involved vertices with list of all bmesh
-    # edges attached to a vertex.
-    # Fills hsh_ed with BEdge for each edge to be beveled.
-    # Fills hsh_corners with BCorner for each vertex involved in each BEdge.
-    # Computes pairs at each BCorner.
-    # Add bmesh edges to be beveled and compute the other
-    # structures needed for the bevel.
-    def build_model(self, bm):
-        # Fill self.hash_edges with selected bmesh edges
-        # if they are acceptable (separate two faces, not-coplanar)
-        for bme in bm.edges:
-            if bme.select and self.acceptable_edge(bme):
-                self.hash_edges[bme.index] = bme
-
-        if len(self.hash_edges) == 0:
-            return
-
-       # Fill self.hash_vertex_edges[i] with list of
-       # bmesh edges attached to vertex with bmesh index i
-        self.hsh_vertex_edges = {}
-        for edge in self.hash_edges.values():
-            self.register_vertex(edge.verts[0], edge)
-            self.register_vertex(edge.verts[1], edge)
-
-        # Add extra edges needed to make valence
-        # >=4 verts have all edges beveled if any are.
-        # Extra edges go in self.hash_edges and
-        # self.hash_edges_extra.
-        self.hash_edges_extra = {}
-        for edge in self.hash_edges.values():
-            self.verify_vertex(edge.verts[0])
-            self.verify_vertex(edge.verts[1])
-        
-        # create BEdges in hsh_ed, BCorners in hsh_corners
-        for edge in self.hash_edges.values():
-            self.integrate_edge(edge)
-
-        # create BPairs in vd.pairs for each BCorner vd.
-        for vd in self.hsh_corners.values():
-            self.compute_pairs_at_vertex(vd)
-
-        # create BCatenas in ed.catenas for each BEdge ed.
-        self.catena_compute_all()
-        if self.strict_offset:
-            self.catena_offset_all()
-
-        self.lpt_borders = []
-        for ed in self.hsh_ed.values():
-            self.nsection = None
-            for pair in ed.pairs:
-                pair.ptcross = None
-            self.compute_borders(ed)
-
-        # Scan the corners to determine the roundings
-        self.corner_scan_all()
-
-        # Compute the faces orientation: tricky when # segments is odd
-        self.compute_face_orientation()
-
-        # Compute alone pairs in case of triangulation
-        self.evaluate_pair_triangulated()
-
-        # Compute the roundings
-        for vd in self.hsh_corners.values():
-            self.rounding_compute(vd)
-        for ed in self.hsh_ed.values():
-            self.compute_borders_for_display(ed)
-
-
-    def acceptable_edge(self, bme):
-        # algorithm requires that edges separate
-        # exactly two, non coplanar faces
-        if len(bme.link_faces) == 2:
-            f1 = bme.link_faces[0]
-            f2 = bme.link_faces[1]
-            return not parallel(f1.normal, f2.normal)
-        return False
-
-    def register_vertex(self, vertex, bme):
-        if vertex.index not in self.hsh_vertex_edges:
-            self.hsh_vertex_edges[vertex.index] = []
-        ledges = self.hsh_vertex_edges[vertex.index]
-        if bme not in ledges:
-            ledges.append(bme)
-        self.register_faces(vertex.link_faces)
-
-    def verify_vertex(self, vertex):
-        # algorithm requires that vertices with valence >= 4
-        # must have all edges included
-        if vertex.index not in self.hsh_vertex_info:
-            ledges = []
-            self.hsh_vertex_info[vertex.index] = list(vertex.link_edges)
-        ledges = self.hsh_vertex_info[vertex.index]  # list of bmesh edges
-        lsel = self.hsh_vertex_edges[vertex.index]
-        nsel = len(lsel)
-        if nsel <=3 or nsel == len(ledges):
-            return
-        # add extra edges
-        for bme in ledges:
-            if bme.index in self.hash_edges:
-                continue
-            # kind of an impasse if edge is unacceptable - oh well
-            if self.acceptable_edge(bme):
-                self.hash_edges[edge.index] = bme
-                self.register_vertex(edge.verts[0], bme)
-                self.register_vertex(edge.verts[1], bme)
-                self.hash_edges_extra[edge.index] = bme
-
-    def register_faces(self, faces):
-        for f in faces:
-            if f.index not in self.hsh_faces:
-                self.hsh_faces[f.index] = BFace(f)
-
-    # Evaluate and treat pairs at triangulated corners
-    def evaluate_pair_triangulated(self):
-        self.lst_triangulated = []
-        lalone = [ vd for vd in self.hsh_corners.values() \
-                   if len(vd.leds) == 2 and len(vd.pairs) >= 3 ]
-        for i, vd in enumerate(lalone):
-            ed1 = vd.leds[0]
-            ed2 = vd.leds[1]
-            pairs1 = [ pair for pair in vd.pairs if pair.alone and pair.leds[0] == ed1 ]
-            pairs2 = [ pair for pair in vd.pairs if pair.alone and pair.leds[0] == ed2 ]
-            if not pairs1 or not pairs2:
-                continue
-            ptcross10 = pairs1[0].ptcross
-            ptcross11 = pairs1[1].ptcross if len(pairs1) > 1 else None
-            ptcross20 = pairs2[0].ptcross
-            ptcross21 = pairs2[1].ptcross if len(pairs2) > 1 else None
-            if ptcross21 and (ptcross21 - ptcross10).length < (ptcross20 - ptcross10).length:
-                seg1 = [ptcross10, ptcross21]
-            else:
-                seg1 = [ptcross10, ptcross20]
-            seg2 = None
-            if ptcross11:
-                if ptcross21 and (ptcross21 - ptcross11).length < (ptcross20 - ptcross11).length:
-                    seg2 = [ptcross11, ptcross21]
-                else:
-                    seg2 = [ptcross11, ptcross20]
-            self.lpt_borders.extend(seg1)
-            if seg2:
-                self.lpt_borders.extend(seg2)
-            self.lst_triangulated.append([vd, ed1, ed2, seg1, seg2])
-
-    def integrate_edge(self, edge):
-        if not self.acceptable_edge(edge):
-            return None
-        index = edge.index
-        if index in self.hsh_ed:
-            return self.hsh_ed[index]
-        ed = BEdge(edge)
-        self.hsh_ed[index] = ed
-        ed.corners.append(self.create_corner(edge.verts[0], ed))
-        ed.corners.append(self.create_corner(edge.verts[1], ed))
-        return ed
-
-    def create_corner(self, vertex, ed):
-        index = vertex.index
-        if index not in self.hsh_corners:
-            vd = BCorner(vertex, ed)
-            self.hsh_corners[index] = vd
-        else:
-            vd = self.hsh_corners[index]
-            if ed not in vd.leds:
-                vd.leds.append(ed)
-        return vd
-
-    # vd should be for a vertex and one end of ed1's edge and face1
-    # should be one or the other of the faces incident to it.
-    # Similarly for ed2, face2 if present
-    def create_pair(self, vd, ed1, face1, ed2=None, face2=None):
-        edge1 = ed1.edge
-        edge2 = ed2.edge if ed2 else None
-        pair = BPair(vd, ed1, face1, ed2, face2)
-        vd.pairs.append(pair)
-        vertex = vd.vertex
-        iface1 = 0 if face1 == ed1.lfaces[0] else 1
-        ivtx = 0 if vertex == edge1.verts[0] else 1
-        ed1.pairs[iface1 + 2 * ivtx] = pair
-        if edge2:
-            iface2 = 0 if face2 == ed2.lfaces[0] else 1
-            ivtx = 0 if vertex == edge2.verts[0] else 1
-            if not ed2.pairs:
-                ed2.pairs = [None, None, None, None]
-            ed2.pairs[iface2 + 2 * ivtx] = pair
-            pair.monoface = (face1 == face2) or parallel(face1.normal, face2.normal)
-            if pair.monoface:
-                pair.convex = convex_at_vertex(vertex, face1, ed1.edge, ed2.edge, face2)
-                pair.vd.convex = pair.convex
-        # computing planes for cross points - special for termination corners
-        if pair.alone:
-            self.compute_edge_terms(pair, pair.ledges[0], pair.lfaces[0], pair.vd.vertex)
-        return pair
-
-    # Find the matching edges at a vertex
-    def compute_pairs_at_vertex(self, vd):
-        nb_edge = len(vd.leds)
-        if nb_edge == 1:
-            ed = vd.leds[0]
-            self.create_pair(vd, ed, ed.lfaces[0])
-            self.create_pair(vd, ed, ed.lfaces[1])
-        elif nb_edge == 2:
-            self.check_pair_2(vd, vd.leds[0], vd.leds[1])
-        else:
-            for i in range(0, nb_edge - 1):
-                for j in range(i+1, nb_edge):
-                    self.check_pair_N(vd, vd.leds[i], vd.leds[j], vd.leds)
-
-    # Find the common faces (or coplanar) to 2 edges when there are 2 at vertex.
-    # Makes a pair for the two edges matching when there's common or coplanar faces.
-    # Also makes pairs for the two edges matching when there's a common edge
-    # between them (and some convexity test I don't understand).
-    # Finally, makes an alone pair for any (edge, face) pairs not otherwise used.
-    def check_pair_2(self, vd, ed1, ed2):
-        edge1 = ed1.edge
-        edge2 = ed2.edge
-        faces1 = list(edge1.link_faces)
-        faces2 = list(edge2.link_faces)
-
-        # Finding faces on the same plane
-        for f1 in edge1.link_faces:
-            for f2 in edge2.link_faces:
-                if f1 == f2 or parallel(f1.normal, f2.normal):
-                    self.create_pair(vd, ed1, f1, ed2, f2)
-                    faces1.remove(f1)
-                    faces2.remove(f2)
-
-        # Finding faces with common edges
-        lf1 = []
-        lf2 = []
-        for f1 in faces1:
-            for f2 in faces2:
-                linter = list(set(f1.edges).intersection(set(f2.edges)))
-                if len(linter) > 0:
-                    e = linter[0]
-                    if not (convex_at_vertex(vd.vertex, f1, edge1, e) or \
-                            convex_at_vertex(vd.vertex, f2, edge2, e)):
-                        self.create_pair(vd, ed1, f1, ed2, f2)
-                        lf1.append(f1)
-                        lf2.append(f2)
-
-        # Creating alone pair if any unaffected faces left
-        for f1 in faces1:
-            if f1 not in lf1:
-                self.create_pair(vd, ed1, f1)
-        for f2 in faces2:
-            if f2 not in lf2:
-                self.create_pair(vd, ed2, f2)
-
-    # Find the common faces (or coplanar) to 2 edges when there are more than 2 total.
-    # Makes a pair for the the two edges matching the first of any common faces
-    # and returns if so.
-    # Else makes a pair matching up the two edges with faces that are parallel
-    # and returns if it finds one.
-    # Else makes a pair matching up the two edges with faces sharing an edge
-    # and that edge isn't in leds, and returns if it finds one.
-    # Otherwise makes no pair.
-    def check_pair_N(self, vd, ed1, ed2, leds):
-        edge1 = ed1.edge
-        edge2 = ed2.edge
-        if edge1 == edge2:
-            return
-        faces1 = list(edge1.link_faces)
-        faces2 = list(edge2.link_faces)
-        lfaces = list(set(faces1).intersection(set(faces2)))
-
-        # Common face found
-        if len(lfaces) >= 1:
-            return self.create_pair(vd, ed1, lfaces[0], ed2, lfaces[0])
-
-        # Finding faces that are on the same plane
-        for f1 in edge1.link_faces:
-            for f2 in edge2.link_faces:
-                if parallel(f1.normal, f2.normal):
-                    return self.create_pair(vd, ed1, f1, ed2, f2)
- 
-        # Check common edges
-        for f1 in faces1:
-            for f2 in faces2:
-                linter = list(set(f1.edges).intersection(set(f2.edges)))
-                if len(linter) > 0 and not find(leds, lambda ed: ed.edge == linter[0]):
-                    return self.create_pair(vd, ed1, f1, ed2, f2)
-                    
-    def compute_borders(self, ed):
-        pairs = ed.pairs
-        for i in range(0,4):
-            if pairs[i]:
-               self.compute_pair_ptcross(pairs[i])
-
-    # Compute the borders for display, including the rounding
-    def compute_borders_for_display(self, ed):
-        pairs = ed.pairs
-        lseg = []
-        lroundings = []
-        for i in [0, 2, 1, 3]:
-            pair = pairs[i]
-            lpt = pair.rounding
-            if lpt and lpt.length > 0:
-                if on_line(lpt[0], [pair.ptcross, ed.vec]):
-                    pt = lpt[0]
-                else:
-                    pt = lpt[-1]
-            else:
-                pt = pair.ptcross
-            lseg.append(pt)
-        self.lpt_borders.extend(lseg)
-
-
-    # Compute and return the vector representing the border
-    def compute_edge_terms(self, pair, edge, face, vertex):
-        normal = face.normal
-        for e in vertex.link_edges:
-            if e == edge:
-                continue
-            for f in e.link_faces:
-                if f == face or parallel(f.normal, normal):
-                    pair.edge_terms.append(e)
-
-    # Compute the cross points for the pair
-    def compute_pair_ptcross(self, pair):
-        if pair.ptcross:
-            return
-        line1 = self.line_border(pair, 0)
-        if pair.alone:
-            pair.ptcross = self.find_intersect_edge_term(pair, line1)
-        else:
-            line2 = self.line_border(pair, 1)
-            if parallel(line1[1], line2[1]):
-                pair.ptcross = intersect_line_plane(line1,
-                        [pair.vd.vertex.co, line1[1]])
-            else:
-                pair.ptcross = intersect_line_line(line1, line2)
-                if not pair.ptcross:
-                    self.signal_error_vd(pair.vd)
-                    lpt = closest_points(line1, line2)
-                    pair.ptcross = lpt[0]
-
-    # Fine the best stop point for a standalone edge pair
-    def find_intersect_edge_term(self, pair, line):
-        ed = pair.leds[0]
-        lptinter = []
-        for edge in pair.edge_terms:
-            pt = intersect_edge_line(edge, line)
-            if pt:
-                lptinter.append(pt)
-        # if no intersection just take the orthogonal plane
-        if len(lptinter) == 0:
-            return intersect_line_plane(line, [pair.vd.vertex.co, ed.vec])
-        # sort the interesection point and take the farthest
-        ptmid = ed.ptmid
-        lptinter.sort(key = lambda p: (ptmid-p).length)
-        return lptinter[-1]
-
-    # Compute the line defining a border on  a face
-    # (Maybe don't need this function if not drawing borders)
-    def line_border(self, pair, iedge):
-        edge = pair.ledges[iedge]
-        ed = self.hsh_ed[edge.index]
-        face = pair.lfaces[iedge]
-        iface = 0 if face == ed.lfaces[0] else 1
-        offset = self.offset * ed.lfactors[iface]
-        vecin = normal_in_to_edge(edge, face)
-        pt = ed.ptmid + offset * vecin
-        return [pt, ed.vec]
-
-    # Compute the orthogonal profile for an edge at its midpoint
-    def compute_profile_edge(self, ed):
-        if ed.nsection:
-            return ed.nsection
-        offset1 = self.offset * ed.lfactors[0]
-        offset2 = self.offset * ed.lfactors[1]
-        vec1 = ed.lvecins[0]
-        vec2 = ed.lvecins[1]
-        ptcenter = ed.ptmid
-        profile = ['C', self.num_seg] if ed.round_profile else self.profile_type
-        section = self.profile_compute_by_offset(profile, ptcenter,
-                    vec1, offset1, vec2, offset2)
-        if not on_plane(section[0], face_plane(ed.facemain)):
-            section.reverse()
-        ed.nsection = section
-        return section
-
-    # Compute the section for an edge at corners
-    # The section will go from the facemain face to the non-facemain one.
-    def compute_sections_multi(self, ed, icorner):
-        vd = ed.corners[icorner]
-        vpos = vd.vertex.co
-        iA = 0 if ed.facemain == ed.lfaces[0] else 1
-        iB = 1 - iA
-        pairA = ed.pairs[2 * icorner + iA]
-        pairB = ed.pairs[2 * icorner + iB]
-
-        ptA = pairA.ptcross
-        ptB = pairB.ptcross
-
-        profile = ['C', self.num_seg] if ed.round_profile else self.profile_type
-
-        if len(vd.leds) <= 1:
-            vecA = ptA - vpos
-            vecB = ptB - vpos
-            offsetA = vecA.length
-            offsetB = vecB.length
-            section = self.profile_compute_by_offset(profile, vpos,
-                        vecA, offsetA, vecB, offsetB)
-        elif len(vd.leds) == 2:
-            vecA = ptA - vpos
-            vecB = ptB - vpos
-            section = self.profile_compute_by_vectors(profile,
-                        ptA, vecA, ptB, ed.vec.cross(vecB))
-        else:
-            edA = find(pairA.leds, lambda edd: edd != ed)
-            edB = find(pairB.leds, lambda edd: edd != ed)
-            vecA = edA.vec.copy()
-            if vecA.dot(edA.ptmid - vpos) < 0:
-                vecA.negate()
-            vecB = edB.vec.copy()
-            if vecB.dot(edB.ptmid - vpos) < 0:
-                vecB.negate()
-            section = self.profile_compute_by_vectors(profile,
-                        ptA, vecA, ptB, ed.vec.cross(vecB))
-
-        if not on_plane(section[0], face_plane(ed.facemain)):
-            section.reverse()
-        ed.cross_sections[icorner] = section
-        return section
-
-    # Construct the lattice for the rounding of an edge
-    def build_lattice(self, i, xsection1, xsection2, sh_section1, sh_section2):
-        if vec_approx_eq(xsection1[i], xsection2[i]):
-            lpts = [xsection1[i]]
-        else:
-            lpts = [xsection1[i], xsection2[i]]
-
-        if sh_section2 and sh_section2[i] and len(sh_section2[i]) > 0:
-            for pt in sh_section2[i]:
-                if not (vec_approx_eq(pt, xsection2[i]) or vec_approx_eq(pt, xsection2[i+1])):
-                    lpts.append(pt)
-
-        lpts.append(xsection2[i + 1])
-        if not vec_approx_eq(xsection2[i + 1], xsection1[i + 1]):
-            lpts.append(xsection1[i + 1])
-
-        if sh_section1 and sh_section1[i] and len(sh_section1[i]) > 0:
-            lpt1 = []
-            for pt in sh_section1[i]:
-                if not (vec_approx_eq(pt, xsection1[i]) or vec_approx_eq(pt, xsection1[i+1])):
-                    lpt1.append(pt)
-            lpt1.reverse()
-            lpts.extend(lpt1)
-
-        return lpts
-
-    # Compute the round border on an edge as a vmesh
-    def compute_mesh_edge(self, ed):
-        xsection1 = ed.cross_sections[0]
-        xsection2 = ed.cross_sections[1]
-        sh_section1 = ed.sharp_sections[0]
-        sh_section2 = ed.sharp_sections[1]
- 
-        nblat = len(xsection1) - 1
-        n2 = nblat // 2
-        n1 = nblat - n2
- 
-        # Part close to main face
-        face1 = ed.facemain
-        mesh1 = []
-        for i in range(0, n1):
-            mesh1.append(self.build_lattice(i, xsection1, xsection2, sh_section1, sh_section2))
-        if n1 > 0:
-            normalref1 = self.compute_normal_reference(ed, face1, xsection1[0], xsection1[1])
-
-        # Part close to the other face
-        face2 = ed.lfaces[1] if ed.lfaces[0] == ed.facemain else ed.lfaces[0]
-        mesh2 = []
-        for i in range(n1, nblat):
-            mesh2.append(self.build_lattice(i, xsection1, xsection2, sh_section1, sh_section2))
-        if n2 > 0:
-            normalref2 = self.compute_normal_reference(ed, face2, xsection1[n1+1], xsection1[n1])
-
-        # Creating the vmesh, single or double
-        ed.vmesh = []
-        if edge_reversed_in_face(ed.edge, face1) == edge_reversed_in_face(ed.edge, face2):
-            if n1 > 0:
-                ed.vmesh.append([mesh1, face1, normalref1])
-            if n2 > 0:
-                ed.vmesh.append([mesh2, face2, normalref2])
-        else:
-            ed.vmesh.append([mesh1 + mesh2, face1, normalref1])
-
-        # Creating the border edges
-        ed.vborders = []
-        ed.vborders.append([[xsection1[0], xsection2[0]], 'S'])
-        ed.vborders.append([[xsection1[-1], xsection2[-1]], 'S'])
-
-        # Termination edges
-        xs = [xsection1, xsection2]
-        for i in range(0, 2):
-            if len(ed.corners[i].leds) == 1:
-                ed.vborders.append([xs[i], 'P'])
-
-    def compute_mesh_edge_triangulated(self, vd, ed1, ed2, seg1, seg2):
-        icorner1 = 0 if ed1.corners[0] == vd else 1
-        icorner2 = 0 if ed2.corners[0] == vd else 1
-        xsection1 = ed1.cross_sections[icorner1]
-        xsection2 = ed2.cross_sections[icorner2]
-        reversed = (xsection1[0] - xsection2[0]).length > (xsection1[0] - xsection2[-1]).length and \
-                   (xsection1[-1] - xsection2[-1]).length >= (xsection1[-1] - xsection2[0]).length
-
-        nblat = len(xsection1) - 1
-        n2 = nblat // 2
-        n1 = nblat - n2
-
-        # Part close to main face
-        face1 = ed1.facemain
-        mesh1 = []
-        for i in range(0, n1):
-            mesh1.append(self.build_lattice(i, xsection1, xsection2, None, None))
-        if n1 > 0:
-            normalref1 = self.compute_normal_reference(ed1, face1, xsection1[0], xsection1[1])
-
-        # Parse close to the other face
-        if reversed:
-            face2 = ed2.facemain
-        else:
-            face2 = find(ed2.lfaces, lambda f: f != ed2.facemain)
-        if n2 > 0:
-            normalref2 = self.compute_normal_reference(ed2, face2, xsection1[n1+1], xsection1[n1])
-
-        # Creating the vmesh, single or double
-        if n1 > 0:
-            self.lst_vmesh_triangulated.append([mesh1, face1, normalref1])
-        if n2 > 0:
-            self.lst_vmesh_triangulated.append([mesh2, face2, normalref2])
-
-        # Creating the border edges
-        if xsection1[0] != xsection2[0]:
-            self.lst_vborders_triangulated.append([[xsection1[0], xsection2[0]], 'S'])
-        if xsection1[-1] != xsection2[-1]:
-            self.lst_vborders_triangulated.append([[xsection1[-1], xsection2[-1]], 'S'])
-
-    def sort_corners_for_orientation(self, vda, vdb):
-        eda = vda.gold_ed
-        edb = vdb.gold_ed
-        if vda.convex:
-            return -1
-        if vdb.convex:
-            return 1
-        if eda and edb:
-            return  cmp(eda.golden, edb.golden)
-        elif eda:
-            return -1
-        elif edb:
-            return 1
-        else:
-            return 0
-
-    # Compute right orientation at corner
-    def orientation_at_corner(self, vd):
-        edgold = vd.gold_ed
-        if not edgold:
-            return
-        ledface = []
-        for ed in vd.leds:
-            for face in ed.lfaces:
-                if ed == edgold:
-                    continue
-                if self.ed_common_face(ed, face, edgold):
-                    iface = 0 if ed.lfaces[0] == face else 1
-                    ledface.append([ed, iface])
-                    break
-        main = 0 if find(ledface, lambda ll: ll[0].facemain) else 1
-        for ll in ledface:
-            ed = ll[0]
-            iface = ll[1]
-            iface2 = (iface + main) % 2
-            if not ed.facemain:
-                ed.facemain = ed.lfaces[iface2]
-            catena = ed.catenas[iface2]
-            if catena.nbsmall <= 0:
-                self.assign_ed_facemain(catena)
-            ed.catenas[iface].nbsmall += 1
-
-    # Find if 2 edges share a common face
-    def ed_common_face(self, ed0, face0, ed1):
-        for face in ed1.lfaces:
-            if parallel(face.normal, face0.normal):
-                return True
-        return False
-
-    # Compute all face orientations - needed for odd number of segments
-    def compute_face_orientation(self):
-        # Starting with the round corners
-        lcorners = list(self.hsh_corners.values())
-        lcorners.sort(key = functools.cmp_to_key(
-            lambda x, y : self.sort_corners_for_orientation(x,y)))
-
-        hsh = {}
-        for vd in lcorners:
-            if vd in hsh:
-                continue
-            hsh[vd] = True
-            edgold = vd.gold_ed
-            if not edgold:
-                continue
-            self.orientation_at_corner(vd)
-            vd2 = edgold.corners[1] if edgold.corners[0] == vd else edgold.corners[0]
-            if vd2 and vd2 not in hsh:
-                hsh[vd2] = True
-                self.orientation_at_corner(vd)
-
-        # Assigning the main faces to edge
-        for catena in self.lst_catenas:
-            if catena.nbsmall == 0:
-                self.assign_ed_facemain(catena)
-
-        # Remaining edges
-        for ed in self.hsh_ed.values():
-            if not ed.facemain:
-                ed.facemain = ed.lfaces[0]
-
-    # Propagate face orientation on a catena
-    def assign_ed_facemain(self, catena):
-        for ll in catena.chain:
-            ed = ll[0]
-            iface = ll[1]
-            other_catena = ed.catenas[1] if ed.catenas[0] == catena else ed.catenas[1]
-            if not ed.facemain:
-                ed.facemain = ed.lfaces[iface]
-            other_catena.nbsmall += 1
-
-    # Scan all corners for determining golden edges
-    def corner_scan_all(self):
-        # find golden edge if vd has valence 3 or 4
-        for vd in self.hsh_corners.values():
-            self.corner_scan_golden(vd)
-        # Final golden edge calc, for valence 3
-        for vd in self.hsh_corners.values():
-            self.corner_determine_golden(vd)
-
-        # For valence 3, which have round profile?
-        # (TODO: is it really necessary to do this twice?)
-        for vd in self.hsh_corners.values():
-            self.corner_round_profile(vd)
-        for vd in self.hsh_corners.values():
-            self.corner_round_profile(vd)
-
-    # Search and propagate the golden edges.
-    # Only assigns a value if valence is 3 or 4.
-    # In those caes, sets the vd.gold_ed to
-    # the corner's ed that is best for golden edge.
-    # When valence is 3, picks the golden edge
-    # (somehow) and sets the edge's aligned property
-    # to True if the other pairs edges intersect.
-    def corner_scan_golden(self, vd):
-        if len(vd.leds) == 4:
-            vd.leds.sort(key = functools.cmp_to_key(compare_gold_ed))
-            vd.gold_ed = vd.leds[0]
-
-        if len(vd.leds) != 3:
-            return
-
-        # Identifying convex corners
-        leds = vd.leds
-        pairs = vd.pairs
-        for pair in pairs:
-            ed1 = pair.leds[0]
-            ed2 = pair.leds[1]
-            ed0 = find(leds, lambda ed: ed != ed1 and ed != ed2)
-            if pair.convex:
-                ed0.golden = -1
-                vd.gold_ed = ed0
-            otherpairs = [p for p in pairs if p != pair]
-            if ed1 in otherpairs[0].leds:
-                pair1 = otherpairs[0]
-                pair2 = otherpairs[1]
-            else:
-                pair1 = otherpairs[1]
-                pair2 = otherpairs[0]
-            ed0.aligned = intersect_line_line(
-                [pair1.ptcross, ed1.vec],
-                [pair2.ptcross, ed2.vec])
-
-    # Compare two edges to determine which one has to be gold.
-    # If the vertex is convex, then the 'golden' member of the
-    # edge should be set to something to help compare.
-    # Else if the cosines of the angles the edges faces
-    # differ from 90 differ a lot then the one that
-    # is more acute wins.
-    # Else the one that is more closely aligned with the
-    # golden axis wins.
-    # Else the longer edge wins.
-    def compare_gold_ed(self, vd, eda, edb):
-        if vd.convex:
-            return cmp(eda.golden, edb.golden)
-        if eda.aligned and not edb.aligned:
-            return -1
-        elif edb.aligned and not eda.aligned:
-            return 1
-        cosa = eda.cos
-        cosb = edb.cos
-        val = 0 if abs(cosa - cosb) < 0.5 else cmp(cosa, cosb)
-        if val == 0:
-            val = -cmp(abs(eda.vec.dot(self.golden_axis)), abs(edb.vec.dot(self.golden_axis)))
-        if val == 0:
-            val = -cmp(eda.length, edb.length)
-        return val
-
-    # Determine the golden edge at a 3 edges corner
-    def corner_determine_golden(self, vd):
-        if len(vd.leds) != 3:
-            return
-        lsgold = vd.leds[::]
-        lsgold.sort(key = functools.cmp_to_key(lambda x, y: self.compare_gold_ed(vd, x, y)))
-        ed0 = lsgold[0]
-        if not vd.gold_ed:
-            vd.gold_ed = ed0
-        for pair in vd.pairs:
-            if ed0 in pair.leds:
-                continue
-            vd.round_pair = pair
-
-    # Calculate whether edges at a vertex should have a round profile
-    def corner_round_profile(self, vd):
-        if len(vd.leds) != 3:
-            return
-        ed0 = vd.gold_ed
-        ledothers = [ed for ed in vd.leds if ed != ed0]
-        ed1 = ledothers[0]
-        ed2 = ledothers[1]
- 
-        ed0.round_profile = self.use_round_profile(ed0)
-        if self.use_round_profile(ed1) or self.use_round_profile(ed2):
-            ed1.round_profile = True
-            ed2.round_profile = True
-
-    # Get the profiles for the edge depending on the hybrid settings
-    def use_round_profile(self, ed):
-        if ed.round_profile:
-            return True
-        if self.mode_profile == -1:
-            return False
-        elif self.mode_profile == 0:
-            return ed.golden == -1
-        else:
-            return ed.golden == -1 or ed.corners[0].gold_ed == ed or ed.corners[1].gold_ed == ed
- 
-    # Calculate rounding at corner, if applicable
-    def rounding_compute(self, vd):
-        if not self.mode_rounding:
-            return
-        if self.num_seg == 1 or (self.mode_sharp and not vd.convex) or len(vd.leds) !=3:
-            return
-        # Getting the golden edge and determining the metal pair
-        ed_gold = vd.gold_ed
-        pair_gold = find(vd.pairs, lambda pair: ed_gold not in pair.leds)
-        pair_silver = None
-        pair_bronze = None
-        ed_silver = None
-        ed_bronze = None
-        facemain = ed_gold.facemain
-        otherface = ed_gold.lfaces[1] if ed_gold.lfaces[0] == facemain else ed_gold.lfaces[0]
-        for pair in vd.pairs:
-            if pair == pair_gold:
-                continue
-            if on_plane(pair.ptcross, face_plane(facemain)):
-                pair_silver = pair
-                ed_silver = pair.leds[1] if pair.leds[0] == ed_gold else pair.leds[0]
-            else:
-                pair_bronze = pair
-                ed_bronze = pair.leds[1] if pair.leds[0] == ed_gold else pair.leds[0]
-        if not (pair_silver and pair_bronze):
-            return
-
-        # Calculate the planes for the golden edge
-        gold_ptcross = pair_gold.ptcross
-        plane_silver = [pair_silver.ptcross, ed_silver.vec]
-        line_silver = [gold_ptcross, ed_silver.vec]
-        plane_bronze = [pair_bronze, ed_bronze.vec]
-        line_bronze = [gold_ptcross, ed_bronze.vec]
-        pt_silver = intersect_line_plane([gold_ptcross, ed_silver.vec], [pair_silver.ptcross, ed_silver.vec])
-        pt_bronze = intersect_line_plane([gold_ptcross, ed_bronze.vec], [pair_bronze.ptcross, ed_bronze.vec])
-
-        # Rounding is not materialized
-        if not pt_silver or not pt_bronze or vec_approx_eq(pt_silver, pt_bronze) or \
-                vec_approx_eq(pt_silver, gold_ptcross) or vec_approx_eq(pt_bronze, gold_ptcross):
-            return
-
-
-        # Computing the rounding
-        vpos = vd.vertex.co
-        vec1 = ed_silver.ptmid - vpos
-        vec2 = ed_bronze.ptmid - vpos
-        normal2 = vec1.cross(vec2)
-        offset1 = (pt_silver - gold_ptcross).length
-        offset2 = (pt_bronze - gold.ptcross).length
-        pair_gold.rounding = self.profile_compute_by_offset(['C', self.num_seg],
-                gold_ptcross, ve1, offset1, vec2, offset2)
-
-    # Corner calculation
-    def corner_compute(self, vd):
-        mode_sharp = self.mode_sharp
-        n = len(vd.leds)
-        if n == 1 or n == 2:
-            self.corner_compute_12(vd)
-        elif n == 3:
-            if self.num_seg == 1:
-                self.corner_compute_3round(vd)
-            elif (not mode_sharp and self.num_seg != 1) or vd.convex:
-                self.corner_compute_3round(vd)
-            elif self.strict_offset:
-                self.corner_compute_any_sharp(vd)
-            else:
-                self.corner_compute_3sharp(vd)
-        elif n == 4:
-            if mode_sharp:
-                self.corner_compute_any_sharp(vd)
-            else:
-                self.corner_compute_round_4(vd)
-        else:
-            if mode_sharp:
-                self.corner_compute_any_sharp(vd)
-            else:
-                self.corner_compute_star(vd)
- 
-    # Compute a corner with 1 or 2 edges (sharp)
-    def corner_compute_12(self, vd):
-        for ed in vd.leds:
-            icorner = 0 if ed.corners[0] == vd else 1
-            section = self.compute_sections_multi(ed, icorner)
-            if len(vd.leds) == 1:
-                # Do we need an extra face between end of beveled
-                # edge and vd?  We do if the end of the beveled edge
-                # isn't in the plane of other faces not adjacent to the edge
-                needcornerface = False
-                for f in vd.vertex.link_faces:
-                    if f == ed.lfaces[0] or f == ed.lfaces[1]:
-                        continue
-                    plane = face_plane(f)
-                    if not (on_plane(section[0], plane) and on_plane(section[-1], plane)):
-                        needcornerface = True
-                        break
-                if needcornerface:
-                    facepts = section + [vd.vertex.co]
-                    norm = ed.lfaces[0].normal + ed.lfaces[1].normal
-                    norm.normalize()
-                    vd.vmesh = [[[facepts], ed.lfaces[0], norm]]
- 
-    # Compute a round corner with 3 edges
-    def corner_compute_3round(self, vd):
-        leds = vd.leds
-
-        # Using the golden edge and compute the golden section0
-        # which is the profile for the end of the golden edge,
-        # going from its main face to its non-main face.
-        ed0 = vd.gold_ed
-        icorner0 = 0 if ed0.corners[0] == vd else 1
-        section0 = self.compute_sections_multi(ed0, icorner0)
-
-        # Computing the other edges
-        # Pair A is the one for ed0 going around its facemain
-        # Pair B is the remaining one
-        iA = 0 if ed0.facemain == ed0.lfaces[0] else 1
-        iB = 1 - iA
-        pairA = ed0.pairs[2 * icorner0 + iA]
-        pairB = ed0.pairs[2 * icorner0 + iB]
-        ed1 = find(pairA.leds, lambda ed: ed != ed0 and \
-                        self.ed_common_face(ed0, ed0.facemain, ed))
-        ed2 = find(pairB.leds, lambda ed: ed != ed0 and ed != ed1)
-        pair_other = find(vd.pairs, lambda pair: ed0 not in pair.leds)
-
-        # Computing the grid
-        # Make lpts be an array of sections, where the start points
-        # are the cross-point of the non-golden-edge pair (or, if that
-        # is rounded, the rounding points for that), and the end points
-        # are the points on the golden section (going from its facemain
-        # to the other face).
-        n0 = len(section0) - 1
-        origin = pair_other.ptcross
-        if pair_other.rounding:
-            lorigin = pair_other.rounding[::]
-            lorigin.reverse()
-        else:
-            lorigin = (n0+1) * [ None ]
-            for i in range(0, n0+1):
-                lorigin[i] = origin
-        vec0 = ed0.vec
-        if icorner0 == 1:
-            vec0 = vec0.copy()
-            vec0.negate()
-        normal = ed1.vec.cross(ed2.vec)
-        vec = origin - vd.vertex.co
-        lpts = []
-        profile = ['C', self.num_seg] if (ed1.round_profile or ed2.round_profile) \
-                else self.profile_type
-        for i in range(0, n0 + 1):
-            lpt = self.profile_compute_by_vectors(profile, section0[i],
-                vec0, lorigin[i], normal)
-            lpts.append(lpt)
-        icorner1 = 0 if ed1.corners[0] == vd else 1
-        icorner2 = 0 if ed2.corners[0] == vd else 1
-
-        # ed1 is the edge sharing the golden edge's facemain, so it
-        # gets the first section in lpts
-        section1 = lpts[0]
-        if not on_plane(section1[0], face_plane(ed1.facemain)):
-            section1 = section1[::]
-            section1.reverse()
-
-        # ed2 is the other of the non-golden pair, so it gets the last
-        # section in lpts
-        section2 = lpts[-1]
-        if not on_plane(section2[0], face_plane(ed2.facemain)):
-            section2 = section2[::]
-            section2.reverse()
-
-        ed1.cross_sections[icorner1] = section1
-        ed2.cross_sections[icorner2] = section2
-
-        # Constructing the mesh.
-        # Makes nseg strips of nseg quads (the first quad
-        # in the strip will really be a tri unless this corner has rounding).
-        # Strip i starts at the other-pair cross point (or the ith point on
-        # it, if rounded), and proceeds to end at the edge between
-        # (section0[i], section0[i+1]).
-        vmesh = []
-        lquads =[]
-        n = len(lpts) - 2
-        for i in range(0, n + 1):
-            pts1 = lpts[i]
-            pts2 = lpts[i + 1]
-            m = len(pts1) - 2
-            for j in range(0, m + 1):
-                if vec_approx_eq(pts1[j + 1], pts2[j + 1]):
-                    pts = [pts1[j], pts1[j + 1], pts2[j]]
-                elif vec_approx_eq(pts1[j], pts2[j]):
-                    pts = [pts1[j], pts1[j + 1], pts2[j + 1]]
-                else:
-                    pts = [pts1[j], pts1[j + 1], pts2[j + 1], pts2[j]]
-                lquads.append(pts)
-
-        nb = self.num_seg
-        n0 = nb // 2
-        odd = (nb % 2) != 0
-
-        # Triangle corner
-        if parallel(ed1.facemain.normal, ed0.facemain.normal):
-            n1 = n0 - 1
-            face1 = ed1.lfaces[1] if ed1.lfaces[0] == ed1.facemain else ed1.lfaces[0]
-        else:
-            n1 = n0 - 1 + odd
-            face1 = ed1.facemain
-        lq1 = []
-        for i in range(0, nb):
-            for j in range(0, n1 + 1):
-                lq1.append(lquads[i * nb + j])
-        if len(lq1) > 0:
-            quad = lquads[0]
-            normalref = self.compute_normal_reference(ed1, face1, quad[0], quad[1])
-            vmesh.append([lq1, face1, normalref])
-
-        # Side corner 1
-        lq2 = []
-        for i in range(0, n0 + odd):
-            for j in range(n1 + 1, nb):
-                lq2.append(lquads[i * nb + j])
-        if len(lq2) > 0:
-            quad = lquads[n1 + 1]
-            normalref = self.compute_normal_reference(ed1, ed0.facemain, quad[1], quad[0])
-            vmesh.append([lq2, ed0.facemain, normalref])
-
-        # Side corner 2
-        lq3 = []
-        for i in range(n0 + odd, nb):
-            for j in range(n1 + 1, nb):
-                lq3.append(lquads[i * nb + j])
-        if parallel(ed2.facemain.normal, face1.normal):
-            face2 = ed2.lfaces[1] if ed2.lfaces[0] == ed2.facemain else ed2.lfaces[0]
-        else:
-            face2 = ed2.lfaces[0] if ed2.lfaces[0] == ed2.facemain else ed2.lfaces[1]
-        if len(lq3) > 0:
-            quad = lquads[(n0 + odd) * nb + 1]
-            normalref = self.compute_normal_reference(ed2, face2, quad[1], quad[0])
-            vmesh.append([lq3, face2, normalref])
-
-        # Storing the mesh
-        vd.vmesh = vmesh
-
-    # Compute round corner for termination with 4 edges
-    def corner_compute_round_4(self, vd):
-        # Computing the cross sections for each edge
-        leds = vd.leds
-        for ed in leds:
-            icorner0 = 0 if ed.corners[0] == vd else 1
-            self.compute_sections_multi(ed, icorner0)
-
-        # picking one edge
-        ed0 = leds[0]
-
-        # looking for adjacent edges
-        oface0 = ed0.lfaces[1] if ed0.facemain == ed0.lfaces[0] else ed0.lfaces[0]
-        ed1 = find(leds, lambda ed: ed != ed0 and self.ed_common_face(ed0, ed0.facemain, ed))
-        ed2 = find(leds, lambda ed: ed != ed0 and ed != ed1 and \
-                        self.ed_common_face(ed0, oface, ed))
-        ed4 = find(leds, lambda ed: ed != ed0 and ed != ed1 and ed != ed2)
-
-        # orientation of the edges
-        icorner0 = 0 if ed0.corners[0] == vd else 1
-        icorner1 = 0 if ed1.corners[0] == vd else 1
-        icorner2 = 0 if ed2.corners[0] == vd else 1
-        icorner4 = 0 if ed4.corners[0] == vd else 1
-
-        xsection0 = ed0.cross_sections[icorner0]
-        xsection1 = ed1.cross_sections[icorner1]
-        xsection2 = ed2.cross_sections[icorner2]
-        xsection4 = ed4.cross_sections[icorner4]
- 
-        if xsection1[0] in xsection0:
-            xfirst = xsection0
-            xlast = xsection4
-        else:
-            xlast = xsection0
-            xfirst = xsection4
-
-        if xfirst[0] in xsection1:
-            xfirst = xfirst[::]
-            xfirst.reverse()
-        if xlast[0] in xsection1:
-            xlast = xlast[::]
-            xlast.reverse()
-        if (xsection2[0] - xsection1[0]).length > (xsection2[0] - xsection1[-1]).length and \
-            (xsection2[-1] - xsection1[0]).length < (xsection2[-1] - xsection1[-1]).length:
-            xsection2 = xsection2[::]
-            xsection2.reverse()
- 
-        # creating the grid sections
-        profile0 = ['C', self.num_seg] if ed0.round_profile else self.profile_type
-        vec1 = ed1.ptmid - vd.vertex.co
-        vec2 = ed2.ptmid - vd.vertex.co
-
-        lpts = [xfirst]
-        n = len(xsection1) - 2
-        n1 = n // 2
-        for i in range(1, n1 + 1):
-            norm = (xsection1[i + 1] - xsection1[i]).cross(vec1)
-            sec = self.profile_compute_by_vectors(profile0, xsection2[i], vec2,
-                    xsection1[i], norm)
-            sec.reverse()
-            lpts.append(sec)
-        for i in range(n1 + 1, n + 1):
-            norm = (xsection2[i + 1] - xsection2[i]).cross(vec2)
-            lpts.append(self.profile_compute_by_vectors(profile0, xsection1[i],
-                    vec1, xsection2[i], norm))
-        lpts.append(xlast)
-
-        # Constructing the vmesh
-        vmesh = []
-        lquads = []
-        n = len(lpts) - 2
-        for i in range(0, n + 1):
-            pts1 = lpts[i]
-            pts2 = lpts[i + 1]
-            m = len(pts1) - 2
-            for j in range(0, m + 1):
-                if vec_approx_eq(pts1[j + 1], pts2[j + 1]):
-                    pts = [pts1[j], pts1[j + 1], pts2[j]]
-                elif vec_approx_eq(pts1[j], pts2[j]):
-                    pts = [pts1[j], pts1[j + 1], pts2[j + 1]]
-                else:
-                    pts = [pts1[j], pts1[j + 1], pts2[j + 1], pts2[j]]
-                lquads.append(pts)
-
-        # List of faces
-        nb = self.num_seg
-        n0 = nb // 2
-        odd = (nb % 2) == 1
-
-        # First quadrant
-        quad = lquads[0]
-        pt = quad[0]
-        ll = self.locate_point_face_4(pt, ed0, ed1, ed2, ed4)
-        faceA = ll[0]
-        edA = ll[1]
-        edB = ll[2]
-        lq = []
-        ni = n0 + odd if parallel(faceA.normal, edB.facemain.normal) else n0
-        nj = n0 + odd if faceA == edA.facemain else n0
-        for i in range(0, ni):
-            for j in range(0, nj):
-                lq.append(lquads[i * nb + j])
-        if len(lq) > 0:
-            normalref = self.compute_normal_reference(edA, faceA, quad[0], quad[1])
-            vmesh.push([lq, faceA, normalref])
-
-        # second quadrant
-        quad = lquads[nb - 1]
-        pt = quad[1]
-        ll = self.locate_point_face_4(pt, ed0, ed1, ed2, ed4)
-        faceA = ll[0]
-        edA = ll[1]
-        edB = ll[2]
-        ni2 = n0 + odd if parallel(faceA.normal, edB.facemain.normal) else n0
-        for i in range(0, ni2):
-            for j in range(nj, nb):
-                lq.append(lquads[i * nb + j])
-        if len(lq) > 0:
-            normalref = self.compute_normal_reference(edA, faceA, quad[1], quad[2])
-            vmesh.append([lq, faceA, normalref])
-
-        # third quadrant
-        quad = lquads[nb * (nb - 1)]
-        pt = quad[3]
-        ll = self.locate_point_face_4(pt, ed0, ed1, ed2, ed4)
-        faceA = ll[0]
-        edA = ll[1]
-        edB = ll[2]
-        lq = []
-        nj = n0 + odd if faceA == edA.facemain else n0
-        for i in range(ni, nb):
-            for j in range(0, nj):
-                lq.append(lquads[i * nb + j])
-
-        if len(lq) > 0:
-            normalref = self.compute_normal_reference(edA, faceA, quad[0], quad[1])
-            vmesh.append([lq, faceA, normalref])
-
-        # fourth quadrant
-        quad = lquads[nb * nb - 1]
-        pt = quad[2]
-        ll = self.locate_point_face_4(pt, ed0, ed1, ed2, ed4)
-        faceA = ll[0]
-        edA = ll[1]
-        edB = ll[2]
-        lq = []
-        for i in range(ni2, nb):
-            for j in range(nj, nb):
-                lq.append(lquads[i * nb + j])
-        if len(lq) > 0:
-            normalref = self.compute_normal_reference(edA, faceA, quad[1], quad[0])
-            vmesh.append([lq, faceA, normalref])
-
-        # Storing the vmesh
-        vd.mesh = vmesh
-
-    # Locate on which edge is the given point
-    def locate_point_face_4(self, pt, ed0, ed1, ed2, ed4):
-        for ll in [[ed0, ed1], [ed0, ed2], [ed4, ed1], [ed4, ed2]]:
-            face = self.which_face_4(pt, ll[0], ll[1])
-            if face:
-                return [face] + ll
-        return None
-
-    # Determine on which face is a given point
-    def which_face_4(self, pt, eda, edb):
-        plane = [eda.ptmid, eda.vec.cross(edb.vec)]
-        if not on_plane(pt, plane):
-            return
-        for face in eda.lfaces:
-            if self.ed_common_face(eda, face, edb):
-                return face
-        return None
-
-    # Orthogonal section to an edge at a vertex
-    # Let ptA and ptB be the pair intersection points
-    # at for the edge at the vertex.
-    # Make a plane that goes through ptA and the
-    # average normal of the two planes for the edge.
-    # Calculate the cross section for the edge at the
-    # vertex and project onto the plane, and return that.
-    def orthogonal_section_ed(self, ed, vd):
-        # getting the pairs and cross points
-        icorner = 0 if ed.corners[0] == vd else 1
-        iA = 0 if ed.facemain == ed.lfaces[0] else 1
-        iB = 1 - iA
-        pairA = ed.pairs[2 * icorner + iA]
-        pairB = ed.pairs[2 * icorner + iB]
-        ptA = pairA.ptcross
-        ptB = pairB.ptcross
-        vf1 = ed.lfaces[0].normal
-        vf2 = ed.lfaces[1].normal
-        if vf1.dot(vf2) <= 0:
-            vf2 = vf2.copy()
-            vf2.negate()
-        vfmean = vf1.lerp(vf2, 0.5)
-
-        # computing the projection on plane
-        plane = [ptA, vfmean.cross(ptB - ptA)]
-        section = self.compute_profile_edge(ed)
-        ed.cross_sections[icorner] = [intersect_line_plane([pt, ed.vec], plane) \
-                                        for pt in section]
-        return ed.cross_sections[icorner]
-
-    # Compute a round corner with 5 or more edges -
-    # Triangulation of Rastapopoulos
-    def corner_compute_star(self, vd):
-        # Computing the cross sections for each edge
-        # These cross sections are at the corner but projected onto a plane
-        # (see comment for orthogonal_section_ed).
-        lsec = [[ed, self.orthogonal_section_ed(ed, vd)] for ed in vd.leds]
-
-        # Finding the pivot point and plane that best fit cross points
-        # ptpivot will be the point in the center of the star.
-        # It is fac (0.5) of the way between the corner vertex and
-        # a point on the best-fitting plane for points on the edge cross sections.
-        nb = self.num_seg // 2 + 1
-        lptcross = [ll[1][nb] for ll in lsec]
-        plane = fit_plane_to_points(lptcross)
-        vpos = vd.vertex.co
-        ptproj = project_to_plane(vpos, plane)
-        normal = vpos - ptproj
-        fac = 0.5
-        ptpivot = vpos.lerp(ptproj, fac)
-        self.lst_mark_points.append(ptpivot)
-
-        # Create the mesh
-        vmesh = []
-        profile0 = ['C', nb]
-        for ll in lsec:
-            ed = ll[0]
-            xsection = ll[1]
-            # For edge ed, take each point in the cross section and make a profile going
-            # from the pivot to that point, putting the results lpts.
-            lpts = [self.profile_compute_by_vectors(profile0, pt, (pt - vpos), ptpivot, normal) \
-                    for pt in xsection]
-            lquads = []
-            n = len(lpts) - 2
-            # For each i, use the pivot->point on edge cross section profile
-            # for i and i+1 to make tris and quads.  The first will be a tri.
-            for i in range(0, n + 1):
-                pts1 = lpts[i]
-                pts2 = lpts[i + 1]
-                m = len(pts1) - 2
-                for j in range(0, m + 1):
-                    if vec_approx_eq(pts1[j + 1], pts2[j + 1]):
-                        pts = [pts1[j], pts1[j + 1], pts2[j]]
-                    elif vec_approx_eq(pts1[j], pts2[j]):
-                        pts = [pts1[j], pts1[j + 1], pts2[j + 1]]
-                    else:
-                        pts = [pts1[j], pts1[j + 1], pts2[j + 1], pts2[j]]
-                    lquads.append(pts)
-
-            # Separating the vmesh in two parts
-            odd = (self.num_seg % 2) == 1
-            if odd == 0:
-                n1 = self.num_seg // 2 + odd
-                m1 = n1 * (nb + odd) - 1
-            else:
-                n1 = self.num_seg // 2 + odd + 1
-                m1 = n1 * (nb - odd)
-
-            quad = lquads[0]
-            faceref = ed.facemain
-            normalref = self.compute_normal_reference(ed, faceref, quad[1], quad[0])
-            vmesh.append([lquads[0:m1 + 1], faceref, normalref])
-
-            quad = lquads[-1]
-            faceref = ed.lfaces[1] if ed.lfaces[0] == ed.facemain else ed.lfaces[0]
-            normalref = self.compute_normal_reference(ed, faceref, quad[1], quad[0])
-            if m1 >= 0:
-                vmesh.append([lquads[m1 + 1:], faceref, normalref])
-
-        vd.vmesh = vmesh
-
-    # Compute a sharp corner with 3 edges in standardized offset mode
-    def corner_compute_3sharp(self, vd):
-        leds = vd.leds
-
-        # Calculating the bisecting planes
-        vpos = vd.vertex.co
-        lplanes = []
-        for pair in vd.pairs:
-            ed1 = pair.leds[0]
-            ed2 = pair.leds[1]
-            ed0 = find(leds, lambda ed: ed != ed1 and ed != ed2)
-            plane = plane_by_3_points(pair.ptcross, vpos, ed0.ptmid)
-            lplanes.append([ed0, plane])
-
-        # Calculating the intersections of edge profiles with stop planes
-        for ed in leds:
-            cross_section = []
-            section = compute_profile_edge(ed)
-            ptmid = ed.ptmid
-            vec = vpos - ptmid
-            icorner = 0 if ed.corners[0] == vd else 1
-            ed_planes = []
-            for ll in lplanes:
-                if ll[0] != ed:
-                    ed_planes.append(ll[1])
-            for pt in section:
-                pt1 = intersect_line_plane([pt, vec], ed_planes[0])
-                pt2 = intersect_line_plane([pt, vec], ed_planes[1])
-                cross_section.append(pt1 \
-                    if (pt1 - ptmid).length < (pt2 - ptmid).length else pt2)
-            if not on_plane(cross_section[0], plane(ed.facemain)):
-                cross_section.reverse()
-            ed.cross_sections[icorner] = cross_section
-
-        # Compute the corner triangle if the number of segments is odd
-        n = self.num_seg // 2
-        if n * 2 == self.num_seg:
-            return
-        lfaces = []
-        for ed in leds:
-            lfaces.append(ed.facemain)
-        face0 = lfaces[0]
-        if parallel(face0.normal, lfaces[1].normal):
-            ieds = [0, 1]
-        elif parallel(face0.normal, lfaces[2].normal):
-            ieds = [0, 2]
-        else:
-            ieds = [1, 2]
-        lpt = []
-        ed1 = leds[ieds[0]]
-        icorner1 = 0 if ed1.corners[0] == vd else 1
-        ed2 = leds[ieds[1]]
-        icorner2 = 0 if ed2.corners[0] == vd else 1
-
-        pt1 = ed1.cross_sections[icorner1][n]
-        pt2 = ed1.cross_sections[icorner1][n+1]
-        pt3 = ed2.cross_sections[icorner2][n+1]
-        if pt3 == pt1 or pt3 == pt2:
-            pt3 = ed2.cross_sections[icorner2][n]
-
-        lpt.extend([pt1, pt2, pt3]) # or should it be .append??
-        faceref = ed1.facemain
-        normalref = compute_normal_reference(ed1, faceref, pt1, pt2)
-        vd.mesh = [[[lpt], faceref, normalref]]
-
-    # Compute a sharp corner with any number of edges
-    def corner_compute_any_sharp(self, vd):
-        leds = vd.leds
-
-        hshcross = {}
-        for ed in leds:
-            hshcross[ed] = []
-
-        # Calculating the sections
-        for ed in leds:
-            self.intersection_any_sharp(vd, ed)
-
-        # Filtering the edge termination
-        # linter will be a hash from (ed, index in cross section for ed)
-        # to one of the intersection data calculated for ed at vd.
-        # We want the one that minimizes the length of the intersection
-        # to the point on the mid-point edge for the index.
-        linter = {}
-        for inter in vd.sharp_inter:
-            pt = inter[0]
-            ed0 = inter[1]
-            i0 = inter[2]
-            icorner0 = 0 if ed0.corners[0] == vd else 1
-            nsection0 = ed0.nsection
-            make_index_valid(ed0.cross_sections[icorner0], i0)
-            ptold = ed0.cross_sections[icorner0][i0]
-            if ptold and (pt - nsection0[i0]).length > (ptold - nsection0[i0]).length:
-                continue
-            ed0.cross_sections[icorner0][i0] = pt
-            make_index_valid(inter, 5)
-            inter[5] = 0
-            make_index_valid(hshcross[ed0], i0)
-            hshcross[ed0][i0] = [inter]
-            linter[(ed0, i0)] = inter
-
-        # Assigning the intermediate points
-        for inter in linter.values():
-            pt = inter[0]
-            ed1 = inter[3]
-            j1 = inter[4]
-            icorner1 = 0 if ed1.corners[0] == vd else 1
-            ptcross = ed1.cross_sections[icorner1][j1]
-            if vec_approx_eq(pt, ptcross):
-                continue
-            inter = inter[::]
-            line = [ptcross, ed1.cross_sections[icorner1][j1 + 1] - ptcross]
-
-            origin = ed1.cross_sections[icorner1][j1]
-            ptmid = ed1.cross_sections[icorner1][j1 + 1]
-            vec0 = origin - ptmid
-
-            inter[5] = vec0.angle(pt - ptmid)
-
-            hsh = hshcross[ed1][j1]
-            hsh.append(inter)
-            hsh.sort(key = lambda inter: inter[5])
-            make_index_valid(ed1.sharp_sections[icorner1], j1)
-            ed1.sharp_sections[icorner1][j1] = [inter[0] for inter in hsh]
-
-        # Identifying the holes
-        hsh_edplanes = {}
-        for ed in leds:
-            lcross = hshcross[ed]
-            n0 = len(lcross) - 2
-            for i in range(0, n0 + 1):
-                linter = lcross[i] + [lcross[i + 1][0]]
-                n1 = len(linter) - 2
-                for j in range(0, n1 + 1):
-                    inter1 = linter[j]
-                    inter2 = linter[j + 1]
-                    lled = []
-                    edc = None
-                    for edd in [inter1[1], inter1[3], inter2[1], inter2[3]]:
-                        if edd in lled:
-                            edc = edd
-                        else:
-                            lled.append(edd)
-                    if len(lled) > 2:
-                        self.lst_mark_points.extend([inter1[0], inter2[0]])
-                        pt = edc.nsection[i].lerp(edc.nsection[i + 1], 0.5)
-                        plane = [pt, (edc.nsection[i + 1] - edc.nsection[i]).cross(edc.vec)]
-                        key = (edc, i)
-                        hsh_edplanes[key] = [key, edc, i, plane, inter1[0], inter2[0]]
-                        self.lst_mark_points.append(pt)
-
-        # Finding the plane intersections
-        lst_loops = self.sharp_find_loops(hsh_edplanes)
-        for loop in lst_loops:
-            for i in range(0, len(loop)):
-                lst_insert = self.sharp_intersect_planes(vd, loop)
-                if lst_insert:
-                    for ll in lst_insert:
-                        self.sharp_insert_in_section(vd, ll[0], ll[1], ll[2])
-                    break
-
-    # Compute the section for an edge in Sharp mode at a vertex
-    # Sets vd.sharp_inter to a list of data about where lines on
-    # the cross section for ed0 intersect lines on segments
-    # of cross sections of other edges at vd.
-    # Each element of list is:
-    # [intersection pt, ed0, index in ed0's cross section,
-    #  ed1 (another edge), index in ed1's cross section]
-    def intersection_any_sharp(self, vd, ed0):
-        nsection0 = self.compute_profile_edge(ed0)
-        n0 = len(nsection0) - 1
-        vec0 = ed0.vec
-        for ed1 in vd.leds:
-            if ed1 == ed0:
-                continue
-            vec1 = ed1.vec
-            nsection1 = self.compute_profile_edge(ed1)
-            for i0 in range(0, n0 + 1):
-                pt0 = nsection0[i0]
-                line0 = [pt0, vec0]
-                for j1 in range(0, n0):
-                    pt = self.intersect_between_two_lines(line0, vec1,
-                                nsection1[j1], nsection1[j1+1])
-                    if pt:
-                        vd.sharp_inter.append([pt, ed0, i0, ed1, j1])
-
-    # Determine if a line cuts a segment defined by two points and a vector.
-    # line0 is the line we are trying to intersect.
-    # Two other lines are defined by direction v1 through points pt1A and pt1B.
-    # Where line0 intersections the plane defined by those other two lines,
-    # the segment in question is between the two lines at the closest points
-    # to the intersection point.
-    def intersect_between_two_lines(self, line0, vec1, pt1A, pt1B):
-        plane1 = [pt1A, (pt1B - pt1A).cross(vec1)]
-        pt = intersect_line_plane(line0, plane1)
-        if not pt:
-            return None
-        ptprojA = project_to_line(pt, [pt1A, vec1])
-        ptprojB = project_to_line(pt, [pt1B, vec1])
-        vA = ptprojA - pt
-        if vA.length < EPSILON:
-            return pt
-        vB = ptprojB - pt
-        if vB.length < EPSILON:
-            return pt
-        if vA.dot(vB) <= 0.0:
-            return pt
-        else:
-            return None
-
-    # Identify the loops in the holes
-    def sharp_find_loops(self, hsh_edplanes):
-        lplanes = hsh_edplanes.values()
-
-        # Loop on edges to det
-        hshed = {}
-        lst_loops = []
-        loop = []
-
-        while True:
-            # Resuming or continuing at current loop end, or initiating a new loop
-            if len(loop) > 0:
-                edp0 = loop[-1][1]
-                ptend = edp0[4] if edp0[5] == loop[-1][0] else edp0[5]
-            else:
-                edp0 = find(lplanes, lambda edp: edp[0] not in hshed)
-                if not edp0:
-                    break
-                ptend = edp0[5]
-                loop = [[edp0[4], edp0]]
-            hshed[edp0[0]] = 1
-
-            # Getting new segment
-            edp1 = find(lplanes, lambda edp: edp[0]!= edp0[0] and \
-                        (edp[0] not in hshed or hshed[edp[0]] != -1) and \
-                        (vec_approx_eq(edp[4], ptend) or vec_approx_eq(edp[5], ptend)))
-            if not edp1:
-                break
-
-            # Checking if segment was already set
-            for i, ll in enumerate(loop):
-                if ptend == ll[0]:
-                    newloop = [a[1] for a in loop[i:]]
-                    for edp in newloop:
-                        hshed[edp[0]] = -1
-                    lst_loops.append(newloop)
-                    loop[i:] = []
-                    edp1 = None
-
-            # New segment in loop
-            if edp1:
-                loop.append([ptend, edp1])
-
-        lst_loops.append([a[1] for a in loop if len(loop) > 0])
-        return lst_loops
-
-    # Determinethe intersection of planes for sharp corners.
-    # Progressive algorithm, based on heuristics
-    def sharp_intersect_planes(self, vd, lplanes):
-
-        # Sorting the planes by inclinations
-        # lplanes = self.sharp_sort_planes_by_inclination(vd, lplanes)
-
-        # Algorithm to explore intersections of planes by group of 3
-        n = len(lplanes)
-        for i0 in range(0, n):
-            lst_insert = []
-            lst_pt = []
-            for i in range(i0, n + i0):
-                icur = i0 % n
-                inext = (i + 1) % n
-                iprev = (i + 2) % n
-                lst_3planes = [lplanes[icur], lplanes[inext], lplanes[iprev]]
-                ptinter = self.sharp_compute_intersect_planes(vd, lplanes, lst_3planes)
-                if not ptinter:
-                    continue
-                lst_pt.append(ptinter)
-                for edp in lst_3planes:
-                    lst_insert.append([edp[1], edp[2], ptinter])
-                if len(lst_pt) == n - 2:
-                    for pt in lst_pt:
-                        self.lst_mark_points.append(pt)
-                    return lst_insert
-        return None
-
-    # Determine the intersection point between 3 planes, and check if valid
-    def sharp_compute_intersect_planes(self, vd, all_planes, lst_3planes):
-        # Computing the intersection of the 3 planes
-        planes = [edp[3] for edp in lst_3planes]
-        line = intersect_plane_plane(planes[0], planes[1])
-        if not line:
-            return None
-        ptinter = intersect_line_plane(line, planes[2])
-        if not ptinter:
-            return None
-        if len(all_planes) == 3:
-            return ptinter
-
-        # List of all other planes
-        otherplanes = [p for p in all_planes if p not in lst_3planes]
-
-        # Check if point is not 'above' otherplane
-        vpos = vd.vertex.co
-        for edp in otherplanes:
-            plane = edp[3]
-            if on_plane(ptinter, plane):
-                continue
-            vdproj = project_to_plane(vpos, plane)
-            ptproj = project_to_plane(ptinter, plane)
-            if (vdproj - vpos).dot(ptproj - ptinter) > 0:
-                # Above
-                return None
-        return ptinter
-
-    # Insert an intermediate point for the latte
-    def sharp_insert_in_section(self, vd, ed, j, ptinter):
-        icorner = 0 if ed.corners[0] == vd else 1
-        sharp_section = ed.sharp_sections[icorner][j]
-
-        # No point already in the intermediate section
-        if not (sharp_section and len(sharp_section) > 0):
-            ed.sharp_sections[icorner][j] = [ptinter]
-            return
-
-        # Inserting the point in the right place
-        ptmid = ed.cross_sections[icorner][j + 1]
-        vec0 = ed.cross_sections[icorner][j] - ptmid
-        angle0 = vec0.angle(ptinter - ptmid)
-        for i, pt in enumerate(sharp_section):
-            if pt == ptinter:
-                return
-            angle = vec0.angle(pt - ptmid)
-            if angle > angle0:
-                if i == 0:
-                    ed.sharp_sections[icorner][j] = [ptinter] + sharp_section
-                else:
-                    ed.sharp_sections[icorner][j] = sharp_section[0:i] + \
-                            [ptinter] + sharp_section[i:]
-                return
-        ed.sharp_section[icorner][j].append(ptinter)
-
-
-    # Compute the normal reference at a position of the edge or corner profile,
-    # This is done for the right orientation of faces created
-    def compute_normal_reference(self, ed, face, pt1, pt2):
-        iface = 0 if ed.lfaces[0] == face else 1
-        vy = ed.lvecins[iface] + face.normal
-        vec = pt2 - pt1
-        return vec.cross(vy)
-
-    def compute_face(self, fc):
-        f = fc.face
-        for i, bmv in enumerate(fc.bmverts):
-            if bmv.index in self.hsh_corners:
-                v = self.hsh_corners[bmv.index]
-                pr = self.pair_for_face(v.pairs, f)
-                if pr:
-                   fc.newpts[i] = [pr.ptcross]
-                else:
-                    # This is a face that is not adjacent to
-                    # a beveled edge, yet there is a beveled
-                    # edge going into this corner.
-                    # What to do depends on whether or
-                    # not this face is adjacent to a face
-                    # that is adjacent to a beveled edge.
-
-                    # One case is that this is a valence-three corner
-                    # with only one beveled edge,
-                    # and this is the third (unaffected) face.
-                    # We need to cut the corner off this face if
-                    # we are in the case where the beveled end
-                    # is in the plane of this face - we should have
-                    # a corner mesh, if so.
-                    # TODO: this corner cutting may happen even in
-                    # valence > 3 cases, but hard to do.
-                    if len(v.vertex.link_edges) == 3 and not v.vmesh:
-                       ed = v.leds[0]
-                       icorner = 0 if ed.corners[0] == v else 1
-                       section = ed.cross_sections[icorner]
-                       # Now need to find if we have to
-                       # reverse the section.
-                       # Find the pairs.
-                       e1 = f.loops[i].edge
-                       e2 = f.loops[i].link_loop_prev.edge
-                       for f1 in e1.link_faces:
-                           if f1 != f:
-                               pr1 = self.pair_for_face(v.pairs, f1)
-                               if pr1:
-                                   break
-                       for f2 in e2.link_faces:
-                           if f2 != f:
-                               pr2 = self.pair_for_face(v.pairs, f2)
-                               if pr2:
-                                   break
-                       if not pr1 or not pr2:
-                           print("whoops, couldn't find term face pairs")
-                           # just so we won't create a dup face:
-                           fc.newpts[i] = [v.vertex.co]
-                       else:
-                           if vec_approx_eq(pr2.ptcross, section[0]):
-                               fc.newpts[i] = section
-                           else:
-                               rsection = section[::]
-                               rsection.reverse()
-                               fc.newpts[i] = rsection
-                    elif len(v.vertex.link_edges) > 3:
-                        # Either or both of the edges into this vertex
-                        # may have been split because the adjacent face
-                        # was adjacent to a beveled edge.
-                        e1 = f.loops[i].edge
-                        f1 = find(e1.link_faces, lambda g: g != f)
-                        e2 = f.loops[i].link_loop_prev.edge
-                        f2 = find(e2.link_faces, lambda g: g != f)
-                        nco1 = None
-                        nco2 = None
-                        for ed in v.leds:
-                            if f in ed.lfaces:
-                                continue
-                            if f1 in ed.lfaces:
-                                pr1 = self.pair_for_face(v.pairs, f1)
-                                if pr1:
-                                    nco1 = pr1.ptcross
-                            if f2 in ed.lfaces:
-                                pr2 = self.pair_for_face(v.pairs, f2)
-                                if pr2:
-                                    nco2 = pr2.ptcross
-                        fc.newpts[i] = [v.vertex.co]
-                        if nco1:
-                            fc.newpts[i] = fc.newpts[i] + [nco1]
-                        if nco2:
-                            fc.newpts[i] = [nco2] + fc.newpts[i]
-
-    def pair_for_face(self, lpairs, f):
-        for pr in lpairs:
-            if pr.lfaces[0] == f:
-                return pr
-            if pr.lfaces[1] == f:
-                return pr
-        return None
-
-    # Catena calculations: chain of edges with related offsets
- 
-    # Compute the extension of a catena for an edge, and its face and corner
-    def catena_extend(self, catena, chain, ed, iface, icorner):
-        k = 2 * icorner + iface
-        if k >= len(ed.pairs):
-            return None  # shouldn't happen
-        pair = ed.pairs[k]
-        if not pair or pair.alone:
-            return None
-        # should only be two ed's in pair.leds,
-        # one is for ed, the other is ed2
-        ed2 = find(pair.leds, lambda edd: edd != ed)
-        n = 0
-        for i, pair2 in enumerate(ed2.pairs):
-            if pair2 == pair:
-                n = i
-                break
-        iface2 = n % 2
-        if ed2.catenas[iface2] == catena:
-            return None
-        icorner2 = (n - iface2) // 2
-        icorner2 = (icorner2 + 1) % 2
-        chain.append([ed2, iface2])
-        ed2.catenas[iface2] = catena
-        return [ed2, iface2, icorner2]
-
-    # Compute the half chain in a direction for an edge.
-    # This is the extension of the chain for (ed, iface) in the
-    # direction given by the end of the edge whose vertex
-    # has index icorner.
-    def catena_compute_half_by_face(self, catena, ed, iface, icorner):
-        chain = []
-        ll = [ed, iface, icorner]
-        while True:
-            ll = self.catena_extend(catena, chain, ll[0], ll[1], ll[2])
-            if not ll or ll[0] == ed:
-                break
-        return chain
-
-    # Compute the catena for an initial edge.
-    # The catena is for the edge ed as associated
-    # with the side of the edge indicated by index
-    # iface in its faces.
-    def catena_compute(self, ed, iface):
-        catena = BCatena()
-        self.lst_catenas.append(catena)
-        ed.catenas[iface] = catena
-        chain1 = self.catena_compute_half_by_face(catena, ed, iface, 0)
-        chain2 = []
-        if len(chain1) == 0 or chain1[-1] == None or chain1[-1][0] != ed:
-            chain2 = self.catena_compute_half_by_face(catena, ed, iface, 1)
-        chain2.reverse()
-        catena.chain = chain2 + [[ed, iface]] + chain1
-        return catena
-
-    # Compute all the catenas in the selection.
-    # There are two catenas for each BEdge: one for each incident face.
-    # The catena is a chain - list of [ed, face-index] pairs that
-    # traverse along matched-up pairs as computed at each vertex.
-    def catena_compute_all(self):
-        for ed in self.hsh_ed.values():
-            for iface in range(0, 2):
-                if ed.catenas[iface] is None:
-                    self.catena_compute(ed, iface)
-
-        # sorting the eds by angle
-        for i, catena in enumerate(self.lst_catenas):
-            catena.leds = [ll[0] for ll in catena.chain]
-            catena.leds.sort(key = functools.cmp_to_key(lambda ed1, ed2: cmp(ed1.cos, ed2.cos)))
-
-        # sorting the catenas
-        for i, catena in enumerate(self.lst_catenas):
-            self.catena_sort(catena)
-
-    def catena_offset_all(self):
-        for catena in self.lst_catenas:
-            icur = self.catena_begin_ed(catena)
-            while self.catena_propagate_offset_factors(catena, icur, 1):
-                icur += 1
-            while self.catena_propagate_offset_factors(catena, icur, -1):
-                icur -= 1
-
-    def catena_begin_ed(self, catena):
-        # Assigning 1 to the first edge in the sorted list
-        ed = catena.leds[0]
-        for icur, ll in enumerate(catena.chain):
-            if ll[0] == ed:
-                if self.strict_offset:
-                     ed.lfactors[ll[1]] = 1.0
-                return icur
- 
-    # Propagate the offset factors from an edge to the next one
-    def catena_propagate_offset_factors(self, catena, icur, incr):
-        chain = catena.chain
-
-        # Checking if end of chain
-        inext = icur + incr
-        if inext < 0 or inext >= len(catena.chain):
-            return False
-        llnext = catena.chain[inext]
- 
-        # Current edge
-        llcur = catena.chain[icur]
-        edcur = llcur[0]
-        ifacecur = llcur[1]
-        edgecur = edcur.edge
-        facecur = edcur.lfaces[ifacecur]
-        ptmidcur = edcur.ptmid
-        factorcur = edcur.lfactors[ifacecur]
-
-        # Next edge
-        ednext = llnext[0]
-        ifacenext = llnext[1]
-        edgenext = ednext.edge
-        facenext = ednext.lfaces[ifacenext]
-        ptmidnext = ednext.ptmid
-
-        # Computing the intersection of the two face planes
-        normalcur = facecur.normal
-        normalnext = facenext.normal
-        if parallel(normalcur, normalnext):
-            if self.strict_offset:
-                ednext.lfactors[ifacenext] = edcur.lfactors[ifacecur]
-            return True
-        lineinter = intersect_plane_plane([ptmidcur, normalcur], [ptmidnext, normalnext])
-
-        # Computing the intersection of the offset lines with the intersection of faces
-        ptcur = intersect_line_line(edcur.parallels[ifacecur], lineinter)
-        ptnext = intersect_line_line(ednext.parallels[ifacenext], lineinter)
-
-        # It is possible that the offset lines don't intersect the face intersection if
-        # either face is non-planar.
-        if not ptcur or not ptnext:
-            return False
-
-        # Common vertex
-        vertex = None
-        for v1 in edgecur.verts:
-            for v2 in edgenext.verts:
-                if v1 == v2:
-                    vertex = v1
-                    break
-        vpos = vertex.co
-
-        # Computing the factor for next edge
-        dcur = (ptcur - vpos).length
-        dnext = (ptnext - vpos).length
-        if self.strict_offset:
-            ednext.lfactors[ifacenext] = factorcur * dcur / dnext
-
-        return True
-
-    # ??? This is a complete no-op
-    def catena_sort(self, catena):
-        for ll in catena.chain:
-            ed = ll[0]
-            iface = ll[1]
-
-    # Create geometry for mesh borders
-    def create_geometry_vborders(self, vborders):
-        for vb in vborders:
-            lpt = vb[0]
-            style = vb[1]
-            # print("new edge:", V3(lpt[0]), V3(lpt[1]), "style:", style)
-            # style could be 'S' or 'P'
-            # 'S' means: apply prop_borders (?) to edges
-            # 'P' means: not soft or smooth
-
-    # Create geometry for mesh
-    def create_geometry_vmesh(self, vmesh):
-        for vm in vmesh:
-            faceref = vm[1]
-            normalref = vm[2]
-            # use faceref as example for material, etc.
-            allfaces = []
-            for lpt in vm[0]:
-                # print("new face:", LV3(lpt), "norm:", V3(normalref), "ref:", faceref)
-                bmverts = self.get_bmverts(lpt)
-                newf = self.bm.faces.new(bmverts)
-                allfaces.append(newf)
-            for lface in allfaces:
-                if normalref and allfaces[0] and allfaces[0].normal.dot(normalref) < 0:
-                    bmesh.utils.face_flip(lface)
-
-    def get_bmverts(self, ptlist):
-        return [ self.points.get_bmvert(p) for p in ptlist ]
-
-    # Signal errors in preparing the geometry
-    def signal_error_vd(self, vd):
-        if vd:
-            self.hsh_error_vertex[vd.vertex.index] = vd.vertex
-
-    # Profile methods
-
-    # Compute the transformed profile by indicating the start and end point,
-    # and the start vector and end face normal.
-    # The profile will go from pt2 to pt1, and the origin for the profile
-    # will be at the intersection of the line through pt1 in direction vec1
-    # and the plane containing pt2 with normal normal2.
-    def profile_compute_by_vectors(self, profile_type, pt1, vec1, pt2, normal2):
-        origin = intersect_line_plane([pt1, vec1], [pt2, normal2])
-        if not origin:
-            # Can happen if one of the faces is non-planar
-            # Just make an origin to avoid a crash
-            origin = pt1.lerp(pt2, 0.5) + (pt2 - pt1).length * Vector([0.1, 0.1, 0.2])
-        offset1 = (pt1 - origin).length
-        offset2 = (pt2 - origin).length
-        vec2 = pt2 - origin
-        return self.profile_compute_by_offset(profile_type, origin, vec1, offset1, vec2, offset2)
-
-    def profile_compute_by_vectors2(self, profile_type, pt1, vec1, pt2, vec2):
-        lpt = closest_points([pt1, vec1], [pt2, vec2])
-        origin = lpt[0].lerp(lpt[1], 0.5)
-        vec1 = pt1 - origin
-        vec2 = pt2 - origin
-        offset1 = vec1.length
-        offset2 = vec2.length
-        return self.profile_compute_by_offset(profile_type, origin, vec1, offset1, vec2, offset2)
-
-    # Compute the transformed profile by indicating the offsets and direction on faces.
-    # The origin is mapped to the 0,0 of the profile (e.g., the center of the circle
-    # for a quarter-circle profile).
-    # The start of the profile will be mapped to offset2 in the direction of vec2 from origin.
-    # The end of the profile will be mapped to offset1 in the direction of vec1 from the origin.
-    # (Think of vec1 -> the x-axis, vec2 -> y-axis, and profile goes from (0, 1) to (1, 0) in 2d).
-    def profile_compute_by_offset(self, profile_type, origin, vec1, offset1, vec2, offset2):
-        # Getting the nominal profile
-        pts = self.nominal_profile(profile_type)
-
-        # Transformation from golden normalized form:
-        # Takes nominal profile endpoints (0,1,0) and (1,0,0)
-        # to (0, offset1, 0) and (offset1, 0, 0) respectively
-        tsg = mathutils.Matrix([[0.0, -offset1, 0.0, offset1],
-                               [-offset1, 0.0, 0.0, offset1],
-                               [0.0, 0.0, 1.0, 0.0],
-                               [0.0, 0.0, 0.0, 1.0]])
-
-        # Scaling and shearing to adjust differences of offset and angle
-        angle = 0.5 * math.pi - vec1.angle(vec2, 0.0)
-        tgt = math.tan(angle)
-        fac = offset2 / offset1 * math.cos(angle)
-
-        # Stretch y by fac
-        ts = mathutils.Matrix([[1.0, 0.0, 0.0, 0.0],
-                               [0.0, fac, 0.0, 0.0],
-                               [0.0, 0.0, 1.0, 0.0],
-                               [0.0, 0.0, 1.0, 1.0]])
-
-        # Shear in x, by factor of tgt as move up in y
-        tsh = mathutils.Matrix([[1.0, tgt, 0.0, 0.0],
-                                [0.0, 1.0, 0.0, 0.0],
-                                [0.0, 0.0, 1.0, 0.0],
-                                [0.0, 0.0, 0.0, 1.0]])
-
-        # Transforming to match given coordinates at origin, vec1, vec2
-        normal = vec1.cross(vec2)
-        normal.normalize()
-        ux = vec1
-        ux.normalize()
-        uy = normal.cross(ux)
-        uz = normal
-        taxe = mathutils.Matrix()
-        taxe = mathutils.Matrix([[ux[0], uy[0], uz[0], origin[0]],
-                                 [ux[1], uy[1], uz[1], origin[1]],
-                                 [ux[2], uy[2], uz[2], origin[2]],
-                                 [0.0, 0.0, 0.0, 1.0]])
-        t = taxe * tsh * ts * tsg
-
-        # Performing the transformation
-        return [t * pt for pt in pts]
-
-    # Get the nominal profile and compute Nb of segment
-    def verify_profile(self, profile_type, numseg = None):
-        ty = profile_type
-        self.num_seg_lock = ty == 'P'
-        if numseg and not self.num_seg_lock:
-            self.profile_type[1] = numseg
-        pts = self.nominal_profile(self.profile_type)
-        self.num_seg = len(pts) - 1
-
-    # Get the nominal profile and compute Nb of segment
-    def nominal_profile(self, profile_type):
-        # Computing the normalized profile in X, Y
-        ty = profile_type[0]
-        param = profile_type[1]
-        key = ty + "-" + str(param)
-
-        # Standard profiles
-        if key in self.hsh_profile_pts:
-            pts = self.hsh_profile_pts[key]
-        else:
-            if ty == 'BZ':
-                pts = self.golden_bezier(param)
-            elif key == 'CR':
-                pts = self.golden_circular_reverse(param)
-            elif key == 'P':
-                pts = self.golden_perso(param)
-            else:
-                pts = self.golden_circular(param)
-            self.hsh_profile_pts[key] = pts
-        return pts
-
-    # Makes a quarter circle profile from
-    # (0, 1, 0) to (1, 0, 0) with nb_seg line segments
-    def golden_circular(self, nb_seg):
-        pts = []
-        anglesec = 0.5 * math.pi / nb_seg
-        for i in range(0, nb_seg + 1):
-            angle = anglesec * i
-            x = math.cos(angle)
-            y = math.sin(angle)
-            pts.append(Vector([x, y, 0.0]))
-        pts.reverse()
-        return pts
-
-    # Makes a a concave quarter circle profile from
-    # (0, 1, 0) to (1, 0, 0)
-    def golden_circular_reverse(self, nb_seg):
-        pts = []
-        anglesec = 0.5 * math.pi / nb_seg
-        for i in range(0, nb_seg + 1):
-            angle = anglesec * i
-            x = 1.0 - math.sin(angle)
-            y = 1.0 - math.cos(angle)
-            pts.append(Vector([x, y, 0.0]))
-        pts.reverse()
-        return pts
-
-    def golden_bezier(self, nb_seg):
-        pt1 = Vector([0.0, 1.0, 0.0])
-        pt2 = Vector([1.0, 1.0, 0.0])
-        pt3 = Vector([1.0, 0.0, 0.0])
-        ctrl_pts = [pt1, pt2, pt3]
-        # TODO: BezierCurve.compute(ctrl_pts, nb_seg)
-        return []
-
-    def golden_perso(self, fac):
-        pt1 = Vector([0.0, 1.0, 0.0])
-        pt2 = Vector([1.0, 1.0, 0.0])
-        pt3 = Vector([1.0, 0.0, 0.0])
-        pt4 = Vector([fac, fac, 0.0])
-        ctrl_pts = [pt1, pt2, pt3]
-        # TODO: BezierCurve.compute(ctrl_pts, 8)
-        ctrl_pts = [crv[3], pt4, crv[5]]
-        crv2 = BezierCurve.compute(ctrl_pts, 6)
-        crv = crv1[1:3] + crv2 + crv1[6:]
-        return crv
-
-    def print(self):
-        print("BevelRoundAlgo:")
-        print("offset", self.offset)
-        print("num_seg", self.num_seg)
-        print("hsh_ed:")
-        for i, ed in self.hsh_ed.items():
-            print("E%d ->" % i)
-            ed.print()
-        print("hsh_corners:")
-        for i, v in self.hsh_corners.items():
-            print("V%d ->"  % i)
-            v.print()
-        print("hsh_faces:")
-        for i, fc in self.hsh_faces.items():
-            print("F%d ->" % i)
-            fc.print()
-        print("lst_catenas", " ".join([str(cat) for cat in self.lst_catenas]))
-        print("lpt_borders:")
-        print("  ", " ".join([V3(p) for p in self.lpt_borders]))
-        print("hsh_profile_pts:")
-        for s, pts in self.hsh_profile_pts.items():
-            print(s, "->", LV3(pts))
-        print("lst_mark_points", self.lst_mark_points)
-        print("lst_triangulated", self.lst_triangulated)
-        print("hsh_error_vertex", self.hsh_error_vertex)
-        print("hash_edges", self.hash_edges)
-        print("hash_edges_extra", self.hash_edges_extra)
-        print("hsh_vertex_info", self.hsh_vertex_info)
-        print("profile_type", self.profile_type)
-        print("mode_profile", self.mode_profile)
-        print("mode_sharp", self.mode_sharp)
-        print("strict_offset", self.strict_offset)
-        print("mode_rounding", self.mode_rounding)
-
-
-# Wraps a bmesh edge involved in beveling
-class BEdge(object):
-    def __init__(self, edge):
-        self.edge = edge
-        self.index = edge.index
-        if len(edge.link_faces) != 2:
-            print("whoops, edge doesn't have exactly two faces")
-            return
-        face1 = edge.link_faces[0]
-        face2 = edge.link_faces[1]
-        self.lfaces = [face1, face2]
-        # lvecins are in face1, face2 planes, perp to edge, pointing in
-        self.lvecins = [normal_in_to_edge(edge, face1), normal_in_to_edge(edge, face2)]
-        # angle is deviation of two planes meeting angle from 90 degrees
-        # (positive angle: they meet at less than 90)
-        self.angle = 0.5 * math.pi - self.lvecins[0].angle(self.lvecins[1], 0.0)
-        self.cos = math.cos(self.angle)
-        # cosinv is the amount one should move along a face to have the
-        # same effect as moving 1.0 along the 90 degree-meeting face
-        self.cosinv = 1 / self.cos if abs(self.cos) >= 1e-2 else 100.0
-        self.lfactors = [self.cosinv, self.cosinv]
-        self.corners = []
-        # catenas is indexed by corner index (0 for first vert, 1 for second)
-        self.catenas = [None, None]
-        # pairs is indexed by 2 * (corner index) + face index
-        # each gives a pair matching the this to a corresponding
-        # (edge, corner index, face index) that this edge can continue to
-        self.pairs = [None, None, None, None]
-        self.cross_sections = [[], []]
-        self.sharp_sections = [[], []]
-        self.golden = 100
-        self.aligned = False
-        vxbeg = edge.verts[0]
-        vxend = edge.verts[1]
-        # vec is normalized edge direction and length is edge length
-        self.vec = vxend.co - vxbeg.co
-        self.length = self.vec.length
-        self.vec.normalize()
-        self.round_profile = False
-        # ptmid is the midpoint of the edge
-        self.ptmid = vxend.co.lerp(vxbeg.co, 0.5)
-        self.parallels = [[self.ptmid + vecin, self.vec] for vecin in self.lvecins]
-        self.loffset = [None, None]
-        self.profile = None
-        self.facemain = None
-        self.nsection = None
-        self.vmesh = None
-        self.vborders = None
-
-    def __str__(self):
-        return "ed%d" % self.index
-
-    def print(self):
-        print("BEdge", self.index)
-        print("  edge", V3(self.edge.verts[0].co), V3(self.edge.verts[1].co))
-        print("  lfaces", F(self.lfaces[0]), F(self.lfaces[1]))
-        print("  lvecins", V3(self.lvecins[0]), V3(self.lvecins[1]))
-        print("  angle %.3f" % self.angle)
-        print("  lfactors", ["%.3f" % fac for fac in self.lfactors])
-        print("  corners", [str(v) for v in self.corners])
-        print("  catenas", [str(cat) for cat in self.catenas])
-        print("  vec", V3(self.vec))
-        print("  ptmid", V3(self.ptmid))
-        print("  pairs: (icorner, iface) in (0,0), (0,1), (1,0), (1,1)")
-        for pair in self.pairs:
-            pair.print()
-        print("  parallels", [[V3(p), V3(n)] for (p,n) in self.parallels])
-        if self.cross_sections:
-            print("  cross_sections:")
-            for cs in self.cross_sections:
-                print("   ", LV3(cs))
-        if self.sharp_sections:
-            print("  sharp_sections:")
-            for cs in self.sharp_sections:
-                print("   ", cs)
-        print("  round_profile", self.round_profile)
-        print("  loffset", self.loffset)
-        print("  profile", self.profile)
-        print("  facemain", F(self.facemain))
-        print("  nsection", LV3(self.nsection))
-        if self.vmesh:
-            print("  vmesh:")
-            for vm in self.vmesh:
-                print("    face: faceref=%s, norm=%s" % (F(vm[1]), V3(vm[2])))
-                for lpt in vm[0]:
-                    print("     ", ",".join([V3(p) for p in lpt]))
-        if self.vborders:
-            print("  vborders:")
-            for vb in self.vborders:
-                if len(vb[0]) == 2:
-                    (p1, p2) = vb[0]
-                    print("    edge:", V3(p1), V3(p2), vb[1])
-
-
-# Wraps a bmesh vertex involved in beveling
-class BCorner(object):
-    def __init__(self, v, ed):
-        self.vertex = v
-        self.index = v.index
-        self.leds = [ed]
-        self.pairs = []
-        self.gold_ed = None
-        self.sharp_inter = []
-        self.round_pair = None
-        self.convex = None
-        self.vmesh = None
-
-    def __str__(self):
-        return "c%d" % self.index
-
-    def print(self):
-        print("BCorner", self.index)
-        print("  vertex", V3(self.vertex.co))
-        print("  leds", [str(ed) for ed in self.leds])
-        print("  pairs", [str(pair) for pair in self.pairs])
-        print("  gold_ed", self.gold_ed)
-        if self.sharp_inter:
-            print("  sharp_inter:")
-            for si in self.sharp_inter:
-                print(V3(si[0]), si[1], si[2], si[3], si[4])
-        print("  round_pair", self.round_pair)
-        print("  convex", self.convex)
-        if self.vmesh:
-            print("  vmesh:")
-            for vm in self.vmesh:
-                print("    face: faceref=%s, norm=%s" % (F(vm[1]), V3(vm[2])))
-                for lpt in vm[0]:
-                    print("     ", ",".join([V3(p) for p in lpt]))
-
-# Wraps a bmesh face involved in beveling
-class BFace(object):
-    def __init__(self, f):
-        self.face = f
-        self.index = f.index
-        self.bmverts = [lp.vert for lp in f.loops]
-        self.bmedges = [lp.edge for lp in f.loops]
-        self.edgereversed = [self.bmedges[i].verts[0] == self.bmverts[i] \
-            for i in range(0, len(self.bmverts))]
-        # for verts that change to one or more new points,
-        # self.newpts[i] is list of float triple for replacement
-        self.newpts = len(self.bmverts) * [None]
-
-    def __str__(self):
-        return "f%d" % self.index
-
-    def print(self):
-        print("BFace", self.index)
-        print("  bmverts", [V(v) for v in self.bmverts])
-        print("  bmedges", [E(e) for e in self.bmedges])
-        print("  edgereversed", self.edgereversed)
-        print("  newpts", [LV3(pl) if pl else 'None' \
-            for pl in self.newpts])
-        
-
-# At vertices to be beveled, the incoming edges involved
-# in beveling are matched up in pairs (to be connected up).
-# There will be two pairs for such a matchup: one for each
-# face-side of the edge.
-# So (ed1, face1) is a BEdge and one of the bmesh faces
-# that is incident on it, and similarly for (ed2, face2).
-# Some edges won't get matched and are 'alone' pairs
-# with None for all of the second components.
-class BPair(object):
-    def __init__(self, vd, ed1, face1, ed2, face2):
-        edge1 = ed1.edge
-        edge2 = ed2.edge if ed2 else None
-        self.vd = vd
-        self.ledges = [edge1, edge2]
-        self.leds = [ed1, ed2]
-        self.lfaces = [face1, face2]
-        self.ptcross = None
-        self.edge_terms = []
-        self.monoface = True
-        self.convex = False
-        self.alone = not edge2
-        self.rounding = None
-        self.mode = None
-
-    def __str__(self):
-        if not self.alone:
-            return "pr2(%s,%s)(%s,%s)" % \
-                (self.leds[0], F(self.lfaces[0]), self.leds[1], F(self.lfaces[1]))
-        else:
-            return "pr1(%s,%s)" % (self.leds[0], F(self.lfaces[0]))
-
-    def print(self):
-        print("BPair", str(self))
-        print("  ptcross", V3(self.ptcross))
-        print("  edge_terms", [E(e) for e in self.edge_terms])
-        print("  monoface", self.monoface, "convex", self.convex,
-            "rounding", self.rounding, "mode", self.mode)
-
-# A catena is a chain - a list of [ed, face-index] pairs that
-# traverse along matched-up pairs as computed at each vertex.
-class BCatena(object):
-    def __init__(self):
-        self.chain = []
-        self.leds = []
-        self.nbsmall = 0
-
-    def __str__(self):
-        return "catena(" + \
-            " ".join(["(%s,%d)" % (p[0], p[1]) for p in self.chain]) + \
-            ", %d)" % self.nbsmall
-
-
-# distances less than about DISTTOL will be considered
-# essentially zero
-DISTTOL = 1e-4
-INVDISTTOL = 1e4
-
-class Points(object):
-    """Container of points without duplication, each mapped to a BMVert
-
-    Points are triples of floats.
-
-    Implementation:
-    In order to efficiently find duplicates, we quantize the points
-    to triples of ints and map from quantized triples to vertex
-    index.
-    """
-
-    def __init__(self, bm):
-        self.pos = []
-        self.bm = bm
-        self.invmap = dict()
-
-    def get_bmvert(self, p):
-        """Return the BMVert for the given point, making one if necessary.
-
-        Args:
-          p: 3-tuple of float - coordinates
-        Returns:
-          BMVert - the vertex of added (or existing) point
-        """
-
-        qp = tuple([int(round(v * INVDISTTOL)) for v in p])
-        if qp in self.invmap:
-            return self.invmap[qp]
-        else:
-            newv = self.bm.verts.new(p)
-            self.invmap[qp] = newv
-            self.pos.append(p)
-            return newv
-
-
-# Returns vector perpendicular to edge in face plane
-# pointing to the interior of the fac
-def normal_in_to_edge(edge, face):
-    pt1 = edge.verts[0].co
-    pt2 = edge.verts[1].co
-    vec = face.normal.cross(pt2 - pt1)
-    vec.normalize()
-    if edge_reversed_in_face(edge, face):
-        vec.negate()
-    return vec
-
-
-# Returns True if if two edges form a convex corner in face
-# at vertex
-def convex_at_vertex(vertex, face, edge1, edge2, face2=None):
-    vother1 = edge1.other_vert(vertex)
-    vec1 = vother1.co - vertex.co
-    vecin1 = normal_in_to_edge(edge1, face)
-    vecin2 = normal_in_to_edge(edge2, face2 if face2 else face)
-    # I don't understand this computation: seems to take dot
-    # product of two vectors that are the face normal (?)
-    return vec1.cross(vecin1).dot(vecin1.cross(vecin2)) >= 0
-
-
-# For the functions on 'planes' and 'lines':
-# A plane defined by [point-on-plane, plane-normal]
-# A line is defined by [point-on-line, line-direction-vector]
-
-
-# Return Vector that is point where line intersects plane,
-def intersect_line_plane(line, plane):
-    (lv, vec) = line
-    (pp, pnorm) = plane
-    return mathutils.geometry.intersect_line_plane(lv, lv + vec, pp, pnorm)
-
-
-# Return intersection point of the two lines, or None.
-def intersect_line_line(linea, lineb):
-    (av, avec) = linea
-    (bv, bvec) = lineb
-    (cv1, cv2) = mathutils.geometry.intersect_line_line(av, av + avec, bv, bv + bvec)
-    if vec_approx_eq(cv1, cv2):
-        return cv1
-    else:
-        return None
-
-
-# Return intersection line of two planes
-def intersect_plane_plane(plane1, plane2):
-    (pp1, pnorm1) = plane1
-    (pp2, pnorm2) = plane2
-    (a, b) = mathutils.geometry.intersect_plane_plane(pp1, pnorm1, pp2, pnorm2)
-    # seems like it returns (pt-on-line, line-dir)
-    return (a, b)
-
-# Return closes points of two lines as tuple of two.
-def closest_points(linea, lineb):
-    (av, avec) = linea
-    (bv, bvec) = lineb
-    return mathutils.geometry.intersect_line_line(av, av + avec, bv, bv + bvec)
-
-
-# Intersection where point must be between endpoints of edge
-def intersect_edge_line(edge, line):
-    pt = intersect_line_line([edge.verts[0].co, edge.verts[1].co - edge.verts[0].co], line)
-    if not pt:
-        return None
-    ptbeg = edge.verts[0].co
-    if vec_approx_eq(pt, ptbeg):
-        return pt
-    ptend = edge.verts[1].co
-    if vec_approx_eq(pt, ptend):
-        return pt
-    if (ptbeg-pt).dot(ptend-pt) < 0:
-        return pt
-    else:
-        return None
-
-
-# Project a point onto a plane
-def project_to_plane(point, plane):
-    (pco, pnorm) = plane
-    ptb = point + pnorm
-    return mathutils.geometry.intersect_line_plane(point, ptb, pco, pnorm)
-
-
-# Project a point onto a line
-def project_to_line(point, line):
-    (lv, lvec) = line
-    (ptproj, _) = mathutils.geometry.intersect_point_line(point, lv, lv + lvec)
-    return ptproj
-
-
-# Return the plane the best fits the points.
-# The right way to do this involves finding a singular value decomposition.
-# (search for "Orthogonal Distance Regression Planes").
-# For now, just use the centroid as point on the plane and
-# the average normal.
-def fit_plane_to_points(pts):
-    n = len(pts)
-    if n < 3:
-        return None
-    center = pts[0]
-    for i in range(1, n):
-        center = center + pts[i]
-    center = center / n
-    # Newell method for normal, pretending this is a polynomail
-    sumx = 0.0
-    sumy = 0.0
-    sumz = 0.0
-    for i in range(0, n):
-        a = pts[i]
-        b = pts[(i + 1) % n]
-        sumx += (a[1] - b[1]) * (a[2] + b[2])
-        sumy += (a[2] - b[2]) * (a[0] + b[0])
-        sumz += (a[0] - b[0]) * (a[1] + b[1])
-    norm = mathutils.Vector([sumx, sumy, sumz])
-    norm.normalize()
-    return [center, norm]
-
-
-# Return True if point is on the plane
-def on_plane(point, plane):
-    (pp, pnorm) = plane
-    d = mathutils.geometry.distance_point_to_plane(point, pp, pnorm)
-    return abs(d) < EPSILON
-
-
-# Return True if point is on the line
-def on_line(point, line):
-    (lv, lvec) = line
-    (vint, _) = mathutils.geometry.intersect_point_line(point, lv, lv + vec)
-    return (point-vint).length < EPSILON
-
-
-def parallel(v1, v2):
-    return abs(v1.cross(v2).length) < EPSILON
-
-
-# A plane is a [point-on-plane, normal-vec] tuple
-def face_plane(face):
-    return [face.verts[0].co, face.normal]
-
-
-# Return True if Vectors are approximately equal
-def vec_approx_eq(a, b):
-    return (a-b).length < EPSILON
-
-
-# Return True if edge points in CW direction around face
-# when viewed from the side the normal is pointing to
-def edge_reversed_in_face(edge, face):
-    for lp in face.loops:
-        if lp.edge == edge:
-            return lp.vert != edge.verts[0]
-    print("whoops, edge_reversed_in_face: edge not in face")
-    return False
-    
-
-# Three-way compare
-def cmp(a, b):
-    return (a > b) - (a < b)
-
-
-# A find-in-iterable function
-def find(iterable, func):
-    for x in iterable:
-        if func(x):
-            return x
-    return None
-
-# Grow a sequence, if necessary, with Nones, to make i a valid index
-def make_index_valid(s, i):
-    if i >= len(s):
-        s.extend((i - len(s) + 1) * [None])
-
-# for debug prints
-def V3(v):
-    return "None" if not v else "(%.2f,%.2f,%.2f)" % (v[0], v[1], v[2])
-
-def LV3(lv):
-    return "None" if not lv else ",".join([V3(v) for v in lv])
-
-def F(f):
-    return "None" if not f else "F%d" % f.index
-
-def E(e):
-    return "None" if not e else "E%d" % e.index
-
-def V(v):
-    return "None" if not v else "V%d" % v.index
-
-def printmat(mat, str):
-    print(str)
-    for i in range(0,4):
-        print("  |" + " ".join(["%5.2f" % mat[i][j] for j in range(0,4)]) + "|")
-
-
-def panel_func(self, context):
-    self.layout.label(text="Bevel Round:")
-    self.layout.operator("mesh.bevel_round", text="Bevel Round")
-
-
-def register():
-    bpy.utils.register_class(BevelRound)
-    bpy.types.VIEW3D_PT_tools_meshedit.append(panel_func)
-
-
-def unregister():
-    bpy.utils.unregister_class(BevelRound)
-    bpy.types.VIEW3D_PT_tools_meshedit.remove(panel_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_edge_intersection_tools.py b/release/scripts/addons_contrib/mesh_edge_intersection_tools.py
deleted file mode 100644
index d2c3bad..0000000
--- a/release/scripts/addons_contrib/mesh_edge_intersection_tools.py
+++ /dev/null
@@ -1,332 +0,0 @@
-'''
-BEGIN GPL LICENSE BLOCK
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-END GPL LICENCE BLOCK
-'''
-
-bl_info = {
-    "name": "Edge tools : tinyCAD VTX",
-    "author": "zeffii",
-    "version": (0, 5, 1),
-    "blender": (2, 5, 6),
-    "category": "Mesh",
-    "location": "View3D > EditMode > (w) Specials",
-    "warning": "Still under development",
-    "wiki_url": "http://wiki.blender.org/index.php/"\
-        "Extensions:2.5/Py/Scripts/Modeling/Edge_Slice",
-    "tracker_url": "http://projects.blender.org/tracker/"\
-        "?func=detail&aid=25227"
-   }
-
-'''
-parts based on Keith (Wahooney) Boshoff, cursor to intersection script and
-Paul Bourke's Shortest Line Between 2 lines, and thanks to PKHG from BA.org
-for attempting to explain things to me that i'm not familiar with.
-TODO: [ ] allow multi selection ( > 2 ) for Slice/Weld intersection mode
-TODO: [ ] streamline this code !
-
-1) Edge Extend To Edge ( T )
-2) Edge Slice Intersecting ( X )
-3) Edge Project Converging  ( V )
-
-'''
-
-import bpy
-import sys
-from mathutils import Vector, geometry
-from mathutils.geometry import intersect_line_line as LineIntersect
-
-VTX_PRECISION = 1.0e-5 # or 1.0e-6 ..if you need
-
-#   returns distance between two given points
-def mDist(A, B): return (A-B).length
-
-
-#   returns True / False if a point happens to lie on an edge
-def isPointOnEdge(point, A, B):
-    eps = ((mDist(A, B) - mDist(point,B)) - mDist(A,point))
-    if abs(eps) < VTX_PRECISION: return True
-    else:
-        print('distance is ' + str(eps))
-        return False
-
-
-#   returns the number of edges that a point lies on.
-def CountPointOnEdges(point, outer_points):
-    count = 0
-    if(isPointOnEdge(point, outer_points[0][0], outer_points[0][1])): count+=1
-    if(isPointOnEdge(point, outer_points[1][0], outer_points[1][1])): count+=1
-    return count
-
-
-#   takes Vector List and returns tuple of points in expected order. 
-def edges_to_points(edges):
-    (vp1, vp2) = (Vector((edges[0][0])), Vector((edges[0][1])))
-    (vp3, vp4) = (Vector((edges[1][0])), Vector((edges[1][1])))
-    return (vp1,vp2,vp3,vp4)
-
-
-#   takes a list of 4 vectors and returns True or False depending on checks
-def checkIsMatrixCoplanar(verti):
-    (v1, v2, v3, v4) = edges_to_points(verti)   #unpack
-    shortest_line = LineIntersect(v1, v2, v3, v4)
-    if mDist(shortest_line[1], shortest_line[0]) > VTX_PRECISION: return False
-    else: return True
-
-
-#   point = the halfway mark on the shortlest line between two lines
-def checkEdges(Edge, obj):
-    (p1, p2, p3, p4) = edges_to_points(Edge)
-    line = LineIntersect(p1, p2, p3, p4)
-    point = ((line[0] + line[1]) / 2) # or point = line[0]
-    return point
-
-#   returns (object, number of verts, number of edges) && object mode == True
-def GetActiveObject():
-    bpy.ops.object.mode_set(mode='EDIT')
-    bpy.ops.mesh.delete(type='EDGE') # removes edges + verts
-    (vert_count, edge_count) = getVertEdgeCount()
-    (vert_num, edge_num) = (len(vert_count),len(edge_count))
-
-    bpy.ops.object.mode_set(mode='OBJECT') # to be sure.
-    o = bpy.context.active_object
-    return (o, vert_num, edge_num)
-
-
-def AddVertsToObject(vert_count, o, mvX, mvA, mvB, mvC, mvD):
-    o.data.vertices.add(5)
-    pointlist = [mvX, mvA, mvB, mvC, mvD]
-    for vpoint in range(len(pointlist)):
-        o.data.vertices[vert_count+vpoint].co = pointlist[vpoint]
-
-
-#   Used when the user chooses to slice/Weld, vX is intersection point
-def makeGeometryWeld(vX,outer_points):
-    (o, vert_count, edge_count) =  GetActiveObject()
-    (vA, vB, vC, vD) =  edges_to_points(outer_points)
-    AddVertsToObject(vert_count, o, vA, vX, vB, vC, vD) # o is the object
-
-    oe = o.data.edges
-    oe.add(4)
-    oe[edge_count].vertices = [vert_count,vert_count+1]
-    oe[edge_count+1].vertices = [vert_count+2,vert_count+1]
-    oe[edge_count+2].vertices = [vert_count+3,vert_count+1]
-    oe[edge_count+3].vertices = [vert_count+4,vert_count+1]
-
-
-#   Used for extending an edge to a point on another edge.
-def ExtendEdge(vX, outer_points, count):
-    (o, vert_count, edge_count) =  GetActiveObject()
-    (vA, vB, vC, vD) =  edges_to_points(outer_points)
-    AddVertsToObject(vert_count, o, vX, vA, vB, vC, vD)
-
-    oe = o.data.edges
-    oe.add(4)
-    # Candidate for serious optimization.
-    if isPointOnEdge(vX, vA, vB):
-        oe[edge_count].vertices = [vert_count, vert_count+1]
-        oe[edge_count+1].vertices = [vert_count, vert_count+2]
-        # find which of C and D is farthest away from X
-        if mDist(vD, vX) > mDist(vC, vX):
-            oe[edge_count+2].vertices = [vert_count, vert_count+3]
-            oe[edge_count+3].vertices = [vert_count+3, vert_count+4]
-        if mDist(vC, vX) > mDist(vD, vX):
-            oe[edge_count+2].vertices = [vert_count, vert_count+4]
-            oe[edge_count+3].vertices = [vert_count+3, vert_count+4]
-
-    if isPointOnEdge(vX, vC, vD):
-        oe[edge_count].vertices = [vert_count, vert_count+3]
-        oe[edge_count+1].vertices = [vert_count, vert_count+4]
-        # find which of A and B is farthest away from X 
-        if mDist(vB, vX) > mDist(vA, vX):
-            oe[edge_count+2].vertices = [vert_count, vert_count+1]
-            oe[edge_count+3].vertices = [vert_count+1, vert_count+2]
-        if mDist(vA, vX) > mDist(vB, vX):
-            oe[edge_count+2].vertices = [vert_count, vert_count+2]
-            oe[edge_count+3].vertices = [vert_count+1, vert_count+2]
-
-
-#   ProjectGeometry is used to extend two edges to their intersection point.
-def ProjectGeometry(vX, opoint):
-
-    def return_distance_checked(X, A, B):
-        dist1 = mDist(X, A)
-        dist2 = mDist(X, B)
-        point_choice = min(dist1, dist2)
-        if point_choice == dist1: return A, B
-        else: return B, A
-
-    (o, vert_count, edge_count) =  GetActiveObject()
-    vA, vB = return_distance_checked(vX, Vector((opoint[0][0])), Vector((opoint[0][1])))
-    vC, vD = return_distance_checked(vX, Vector((opoint[1][0])), Vector((opoint[1][1])))
-    AddVertsToObject(vert_count, o, vX, vA, vB, vC, vD)
-
-    oe = o.data.edges
-    oe.add(4)
-    oe[edge_count].vertices = [vert_count, vert_count+1]
-    oe[edge_count+1].vertices = [vert_count, vert_count+3]
-    oe[edge_count+2].vertices = [vert_count+1, vert_count+2]
-    oe[edge_count+3].vertices = [vert_count+3, vert_count+4]
-
-
-def getMeshMatrix(obj):
-    is_editmode = (obj.mode == 'EDIT')
-    if is_editmode:
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-    (edges, meshMatrix) = ([],[])
-    mesh = obj.data
-    verts = mesh.vertices
-    for e in mesh.edges:
-        if e.select:
-            edges.append(e)
-
-    edgenum = 0
-    for edge_to_test in edges:
-        p1 = verts[edge_to_test.vertices[0]].co
-        p2 = verts[edge_to_test.vertices[1]].co
-        meshMatrix.append([Vector(p1),Vector(p2)])
-        edgenum += 1
-
-    return meshMatrix
-
-
-def getVertEdgeCount():
-    bpy.ops.object.mode_set(mode='OBJECT')
-    vert_count = bpy.context.active_object.data.vertices
-    edge_count = bpy.context.active_object.data.edges
-    return (vert_count, edge_count)
-
-
-def runCleanUp():
-    bpy.ops.object.mode_set(mode='EDIT')
-    bpy.ops.mesh.select_all(action='TOGGLE')
-    bpy.ops.mesh.select_all(action='TOGGLE')
-    bpy.ops.mesh.remove_doubles(mergedist=VTX_PRECISION)
-    bpy.ops.mesh.select_all(action='TOGGLE') #unselect all
-
-
-def initScriptV(context, self):
-    obj = bpy.context.active_object
-    meshMatrix = getMeshMatrix(obj)
-    (vert_count, edge_count) = getVertEdgeCount()
-
-    #need 2 edges to be of any use.
-    if len(meshMatrix) < 2: 
-        print(str(len(meshMatrix)) +" select, make sure (only) 2 are selected")
-        return
-
-    #dont go any further if the verts are not coplanar
-    if checkIsMatrixCoplanar(meshMatrix): print("seems within tolerance, proceed")
-    else: 
-        print("check your geometry, or decrease tolerance value")
-        return
-
-    # if we reach this point, the edges are coplanar
-    # force edit mode
-    bpy.ops.object.mode_set(mode='EDIT')
-    vSel = bpy.context.active_object.data.total_vert_sel
-
-    if checkEdges(meshMatrix, obj) == None: print("lines dont intersect")
-    else:
-        count = CountPointOnEdges(checkEdges(meshMatrix, obj), meshMatrix)
-        if count == 0:
-            ProjectGeometry(checkEdges(meshMatrix, obj), meshMatrix)
-            runCleanUp()
-        else:
-            print("The intersection seems to lie on 1 or 2 edges already")
-
-
-def initScriptT(context, self):
-    obj = bpy.context.active_object
-    meshMatrix = getMeshMatrix(obj)
-    ## force edit mode
-    bpy.ops.object.mode_set(mode='EDIT')
-    vSel = bpy.context.active_object.data.total_vert_sel
-
-    if len(meshMatrix) != 2:
-        print(str(len(meshMatrix)) +" select 2 edges")
-    else:
-        count = CountPointOnEdges(checkEdges(meshMatrix, obj), meshMatrix)
-        if count == 1:
-            print("Good, Intersection point lies on one of the two edges!")
-            ExtendEdge(checkEdges(meshMatrix, obj), meshMatrix, count)
-            runCleanUp()    #neutral function, for removing potential doubles
-        else:
-            print("Intersection point not on chosen edges")
-
-
-def initScriptX(context, self):
-    obj = bpy.context.active_object
-    meshMatrix = getMeshMatrix(obj)
-    ## force edit mode
-    bpy.ops.object.mode_set(mode='EDIT')
-
-    if len(meshMatrix) != 2:
-        print(str(len(meshMatrix)) +" select, make sure (only) 2 are selected")
-    else:
-        if checkEdges(meshMatrix, obj) == None:
-            print("lines dont intersect")
-        else: 
-            count = CountPointOnEdges(checkEdges(meshMatrix, obj), meshMatrix)
-            if count == 2:
-                makeGeometryWeld(checkEdges(meshMatrix, obj), meshMatrix)
-                runCleanUp()
-
-
-class EdgeIntersections(bpy.types.Operator):
-    '''Makes a weld/slice/extend to intersecting edges/lines'''
-    bl_idname = 'mesh.intersections'
-    bl_label = 'Edge tools : tinyCAD VTX'
-    # bl_options = {'REGISTER', 'UNDO'}
-
-    mode = bpy.props.IntProperty(name = "Mode",
-                    description = "switch between intersection modes",
-                    default = 2)
-
-    @classmethod
-    def poll(self, context):
-        obj = context.active_object
-        return obj != None and obj.type == 'MESH'
-
-    def execute(self, context):
-        if self.mode == -1:
-            initScriptV(context, self)
-        if self.mode == 0:
-            initScriptT(context, self)
-        if self.mode == 1:
-            initScriptX(context, self)
-        if self.mode == 2:
-            print("something undefined happened, send me a test case!")
-        return {'FINISHED'}
-
-
-def menu_func(self, context):
-    self.layout.operator(EdgeIntersections.bl_idname, text="Edges V Intersection").mode = -1
-    self.layout.operator(EdgeIntersections.bl_idname, text="Edges T Intersection").mode = 0
-    self.layout.operator(EdgeIntersections.bl_idname, text="Edges X Intersection").mode = 1
-
-def register():
-    bpy.utils.register_class(EdgeIntersections)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.append(menu_func)
-
-def unregister():
-    bpy.utils.unregister_class(EdgeIntersections)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_face_info_select.py b/release/scripts/addons_contrib/mesh_face_info_select.py
deleted file mode 100644
index cd9d48d..0000000
--- a/release/scripts/addons_contrib/mesh_face_info_select.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Face info / select by type",
-    "author": "CoDEmanX",
-    "version": (0, 0, 3),
-    "blender": (2, 6, 2),
-    "location": "Object data > Face info / select",
-    "description": "Displays triangle, quad and ngon count of the active object. Allows to select faces by these type.",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "",
-    "support": 'TESTING',
-    "category": "Mesh"
-}
-
-# Written by CoDEmanX for frivus
-
-
-import bpy
-from bpy.props import EnumProperty
-
-class DATA_OP_facetype_select(bpy.types.Operator):
-    '''Selects all faces of a certain type'''
-    bl_idname = "data.facetype_select"
-    bl_label = "Select by face type"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    face_type = EnumProperty(name="Select faces:",
-                             items = (("3","Triangles","Faces made up of 3 vertices"),
-                                      ("4","Quads","Faces made up of 4 vertices"),
-                                      ("5","Ngons","Faces made up of 5 and more vertices")),
-                             default = "5")
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None and context.active_object.type == 'MESH'
-
-    def execute(self, context):
-
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.select_all(action='DESELECT')
-        context.tool_settings.mesh_select_mode=(False, False, True)
-
-        if self.face_type == "3":
-            bpy.ops.mesh.select_by_number_vertices(number=3, type='EQUAL')
-        elif self.face_type == "4":
-            bpy.ops.mesh.select_by_number_vertices(number=4, type='EQUAL')
-        else:
-            bpy.ops.mesh.select_by_number_vertices(number=4, type='GREATER')
-
-        return {'FINISHED'}
-        
-
-class DATA_PT_info_panel(bpy.types.Panel):
-    """Creates a face info / select panel in the Object properties window"""
-    bl_label = "Face info / select"
-    bl_idname = "DATA_PT_face_info"
-    bl_space_type = "PROPERTIES"
-    bl_region_type = "WINDOW"
-    bl_context = "data"
-
-    @classmethod
-    def poll(self, context):
-        return context.active_object is not None and context.active_object.type == 'MESH'
-
-    def draw(self, context):
-        layout = self.layout
-
-        ob = context.active_object
-        
-        info_str = ""
-        tris = quads = ngons = 0
-
-        for p in ob.data.polygons:
-            count = p.loop_total
-            if count == 3:
-                tris += 1
-            elif count == 4:
-                quads += 1
-            else:
-                ngons += 1
-
-        info_str = "  Ngons: %i  Quads: %i  Tris: %i" % (ngons, quads, tris)
-        
-        col = layout.column()
-        col.label(info_str, icon='MESH_DATA')
-
-        col = layout.column()
-        col.label("Select faces by type:")
-
-        row = layout.row()
-        row.operator("data.facetype_select", text="Ngons").face_type = "5"
-        row.operator("data.facetype_select", text="Quads").face_type = "4"
-        row.operator("data.facetype_select", text="Tris").face_type = "3"
-
-
-def register():
-    bpy.utils.register_class(DATA_PT_info_panel)
-    bpy.utils.register_class(DATA_OP_facetype_select)
-
-
-def unregister():
-    bpy.utils.unregister_class(DATA_PT_info_panel)
-    bpy.utils.unregister_class(DATA_OP_facetype_select)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_inset_extrude.py b/release/scripts/addons_contrib/mesh_inset_extrude.py
deleted file mode 100644
index b53c6af..0000000
--- a/release/scripts/addons_contrib/mesh_inset_extrude.py
+++ /dev/null
@@ -1,637 +0,0 @@
-bl_info = {
-    'name': "Inset Extrude",
-    'description': "Inset and Extrude selected polygons, useful modeling tool",
-    'author': "Jon Sandstrom",
-    'version': (0, 6),
-    'blender': (2, 5, 9),
-    'location': 'Search for Inset Extrude, map a key to the operator "mesh.inset_extrude", or use the default "I-key"',
-    'warning': "Broken",
-    'category': 'Mesh',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Inset-Extrude'}
-
-import bpy, bmesh
-import bgl
-import blf
-from math import *
-from mathutils import Vector
-from bpy.props import FloatProperty, BoolProperty
-
-def find_sel_faces(mesh, individual_faces):
-    selected_faces = []
-    selected_islands = []
-    if individual_faces:
-        for face in mesh.polygons:
-            if face.select and not face.hide:
-                selected_islands.append([face.index])
-        return(selected_islands)
-    
-    for face in mesh.polygons:
-        if face.select and not face.hide: selected_faces.append(face.index)
-    selected_islands = []
-    while len(selected_faces) != 0:
-        face = selected_faces[0]
-        selected_faces.remove(face)
-        active_island = [face]
-        active_faces = [face]
-        
-        while len(active_faces) > 0:
-            connected_faces = island_extend(mesh, active_faces, selected_faces)
-            active_island.extend(connected_faces)
-            active_faces = connected_faces
-        selected_islands.append(active_island)    
-    
-    sel_f  = [] 
-    for island in selected_islands:
-        sel_f.extend(island) 
-    
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.mesh.select_less()
-    bpy.ops.object.vertex_group_assign(new=True)
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    
-    return (selected_islands)
-
-def island_extend(mesh, active_faces, selected_faces):
-    connected_faces = []
-    for face in active_faces:
-        cf = []
-        for f in selected_faces:
-            for edge in mesh.polygons[face].edge_keys:
-                if edge in mesh.polygons[f].edge_keys and f not in connected_faces:
-                    connected_faces.append(f)
-                    cf.append(f)
-                    break
-
-        for f in cf: selected_faces.remove(f)
-    return(connected_faces)
-
-def find_outer_edge(mesh, island):
-    edges = []
-    for face in island:
-        for edge in mesh.polygons[face].edge_keys: edges.append(edge)
-    outer_edges = []
-    for edge in edges:
-        if edges.count(edge) == 1:
-            outer_edges.append(edge)
-    return (outer_edges)
-
-def extend_vert_dict(mesh, edges, vert_dict):
-    for edge in edges:
-        for vert in edge:
-            if vert not in vert_dict: 
-                vert_dict[vert] = edge_vertex(vert)
-                vert_dict[vert].edges.append(edge)
-            else:
-                vert_dict[vert].edges.append(edge)
-
-
-class edge_vertex:
-    def __init__(self, index):
-        self.index = index
-        self.faces = []
-        self.edges = []
-
-def find_norm_vectors(mesh, vert_dict):
-    vertices = list(vert_dict.keys())
-    for vert in vertices:
-        edge_vectors = []
-        for edge in vert_dict[vert].edges:
-            if vert == edge[0]:
-                vec = mesh.vertices[edge[0]].co.copy() - mesh.vertices[edge[1]].co.copy()
-            else:
-                vec = mesh.vertices[edge[1]].co.copy() - mesh.vertices[edge[0]].co.copy()
-            edge_vectors.append(vec/vec.length)
-        vec1 = Vector.cross(edge_vectors[0], edge_vectors[1])
-        edges_vec = edge_vectors[1] + edge_vectors[0]
-        norm_vec = Vector.cross(vec1, edges_vec)
-        if norm_vec.length < 1e-12:           #hackish fix for flat surfaces and straight edges
-            norm_vec = edge_vectors[0] 
-        
-        vert_dict[vert].new_index = len(mesh.vertices) + vertices.index(vert)
-        vert_dict[vert].norm_vec = norm_vec
-        vert_dict[vert].edge_vec = edge_vectors[0]
-
-
-def find_edge_faces(mesh, sel_faces, vert_dict):
-    edge_faces = []
-    for face in sel_faces:
-        for vert in mesh.polygons[face].vertices:
-            if vert in vert_dict:
-                vert_dict[vert].faces.append(mesh.polygons[face].index)
-                if face not in edge_faces: edge_faces.append(mesh.polygons[face].index)
-    return edge_faces
-
-def find_offset_vec(mesh, vert_dict):
-    for vert in list(vert_dict.keys()):
-        for face in vert_dict[vert].faces:
-            rel_vec = []         # vertex vectors relative to active vertex
-            a = 0       # nr of verts on side 'a' of plane
-            b = 0       # on side b
-            for v in mesh.polygons[face].vertices:
-                if v == vert: continue
-                rel_co = mesh.vertices[vert].co.copy() - mesh.vertices[v].co.copy()
-                rel_vec = rel_co/rel_co.length
-                
-                case1 = rel_co - vert_dict[vert].norm_vec 
-                case2 = rel_co + vert_dict[vert].norm_vec
-                
-                if case1.length < case2.length:
-                    a += 1
-                else:
-                    b += 1
-            if a > 0 and b > 0:
-                middle_face = face
-                break
-        
-        # find offset_vector
-        offset_vec_raw = Vector.cross(mesh.polygons[middle_face].normal, vert_dict[vert].norm_vec)
-        offset_vec_norm = offset_vec_raw / offset_vec_raw.length
-        angle = acos(offset_vec_norm * vert_dict[vert].edge_vec)
-        if sin(angle) == 0:
-            angle = pi/2
-        offset_vec = offset_vec_norm / sin(angle)
-        
-        if len(vert_dict[vert].faces) == 1:
-            face_center = Vector([0, 0, 0])
-            for v in mesh.polygons[middle_face].vertices:
-                face_center += mesh.vertices[v].co.copy()
-            face_center /= len(mesh.polygons[middle_face].vertices)
-            
-            case1 = (face_center - mesh.vertices[vert].co.copy()) + offset_vec
-            case2 = (face_center - mesh.vertices[vert].co.copy()) - offset_vec
-            if case1.length < case2.length:
-                offset_vec.negate()        
-        
-        else:
-            for edge in mesh.polygons[middle_face].edge_keys:
-                test = False
-                for face in vert_dict[vert].faces:
-                    if face == middle_face: continue
-                    if edge in mesh.polygons[face].edge_keys: 
-                        test = True
-                        break
-                if test:
-                    if edge[0] == vert:
-                        edge_vec = mesh.vertices[edge[1]].co - mesh.vertices[edge[0]].co
-                    else:
-                        edge_vec = mesh.vertices[edge[0]].co - mesh.vertices[edge[1]].co
-                    continue
-            case1 = edge_vec + offset_vec
-            case2 = edge_vec - offset_vec
-            if case1.length < case2.length:
-                offset_vec.negate()
-
-        vert_dict[vert].offset_vec = offset_vec
-
-def new_faces(mesh, island_dicts, edge_faces, outer_edges):
-    
-    faces_new = []
-    for island in edge_faces:
-        vert_dict = island_dicts[edge_faces.index(island)]
-        for face in island:
-            f_verts = []
-            for vert in mesh.polygons[face].vertices:
-                if vert in vert_dict:
-                    f_verts.append(vert_dict[vert].new_index)
-                else:
-                    f_verts.append(vert)
-            if len(f_verts) == 3:
-                f_verts.append(f_verts[-1])
-            faces_new.append(f_verts)
-    
-    not_selected = 0
-    for edge_island in outer_edges:
-        vert_dict = island_dicts[outer_edges.index(edge_island)]
-        for edge in edge_island:
-            f_verts = [edge[0], edge[1], vert_dict[edge[1]].new_index, vert_dict[edge[0]].new_index]
-            faces_new.append(f_verts)
-            not_selected += 1
-        
-    
-    ef_size = 0
-    for i in edge_faces: ef_size += len(i)
-    n_faces_old = len(mesh.polygons)
-    rim_select = range(n_faces_old - ef_size, (n_faces_old+len(faces_new)) - not_selected - ef_size)
-    rim_noSelect = range((n_faces_old - ef_size) + (len(faces_new) - not_selected), n_faces_old - ef_size + len(faces_new))
-    mesh.polygons.add(len(faces_new))
-    for i in range(len(faces_new)):
-        mesh.polygons[n_faces_old + i].vertices = faces_new[i]
-    mesh.update(calc_edges = True)
-    
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.mesh.select_all(action='DESELECT')
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    for island in edge_faces:
-        for face in island:
-            mesh.polygons[face].select = True
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.mesh.delete(type='FACE')
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    return (rim_select, rim_noSelect, n_faces_old)  # return number of old faces to determine the first new face and compare normals to it
-    
-    
-def find_shortest_edge(mesh, edge_faces, vert_dict, outer_edges):
-    # finds the shortest edge that is connected to the outer rim
-    # will be used for scaling the sensitivity of the interface
-    shortest_edge = -1
-    if len(edge_faces) == 1:
-        for edge in mesh.polygons[edge_faces[0]].edge_keys:
-            edgeco = mesh.vertices[edge[0]].co - mesh.vertices[edge[1]].co
-            if shortest_edge < 0 or edgeco.length < shortest_edge:
-                shortest_edge = edgeco.length
-    for face in edge_faces:        
-        for edge in mesh.polygons[face].edge_keys:
-            if (edge not in outer_edges) and (edge[0] in vert_dict or edge[1] in vert_dict):
-                edgeco = mesh.vertices[edge[0]].co - mesh.vertices[edge[1]].co
-                if shortest_edge < 0 or edgeco.length < shortest_edge:
-                    shortest_edge = edgeco.length
-    return(shortest_edge)
-
-def find_displace_vecs(mesh, sel_faces, vert_dict):
-    area = 0
-    inside_verts = {}
-    for face in sel_faces:
-        for vert in mesh.polygons[face].vertices:
-            if vert in inside_verts:
-                inside_verts[vert].append(mesh.polygons[face].normal)
-            else:
-                inside_verts[vert] = [mesh.polygons[face].normal]
-        area += mesh.polygons[face].area
-    displace_vecs = {}
-    for vert in list(inside_verts.keys()):
-        vec_norm = Vector([0,0,0])
-        for normal in inside_verts[vert]:
-            vec_norm += normal
-        vec_norm /= len(inside_verts[vert])
-        dot = vec_norm * inside_verts[vert][0]
-        if dot > 1: dot = 1
-        angle = acos(dot)
-        vec = vec_norm / sin(pi/2 - angle)
-        if vert in vert_dict:
-            displace_vecs[vert] = vec
-        else:
-            displace_vecs[vert] = [mesh.vertices[vert].co.copy(), vec]
-
-    return(displace_vecs, area)
-
-def select_faces(mesh, rim_select, rim_noSelect, edge_faces, n_faces_old, ref_normal, use_smooth):
-    all = []
-    all.extend(rim_select)
-    all.extend(rim_noSelect)
-    for face in all:
-        face = bpy.context.object.data.polygons.active = True
-        mesh.polygons[face].use_smooth = use_smooth
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.object.vertex_group_select()
-    bpy.ops.mesh.normals_make_consistent()
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    ef_size = 0
-    for i in edge_faces: ef_size += len(i)
-    if mesh.polygons[n_faces_old - ef_size].normal * ref_normal < 0.9:
-        bpy.ops.mesh.flip_normals()
-    bpy.ops.mesh.select_all(action='DESELECT')
-    bpy.ops.object.vertex_group_select()
-    bpy.ops.object.vertex_group_remove()
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    for face in rim_select:
-        bpy.context.object.data.polygons.active = True
-
-def run_inset_extrude(mesh, individual_faces):
-    sel_faces = find_sel_faces(mesh, individual_faces)
-    outer_edges = []
-    island_dicts = []
-    shortest_edge = None
-    area = -1
-    disp_islands = []
-    n_faces_old = 0
-    edge_faces_islands = []
-    for island in sel_faces:
-        out_edges = find_outer_edge(mesh, island)
-        outer_edges.append(out_edges)
-        vert_dict = {}
-        
-        extend_vert_dict(mesh, out_edges, vert_dict)
-        find_norm_vectors(mesh, vert_dict)
-        
-        edge_faces = find_edge_faces(mesh, island, vert_dict)
-        edge_faces_islands.append(edge_faces)
-        ref_normal = mesh.polygons[edge_faces[0]].normal.copy()
-        use_smooth = mesh.polygons[edge_faces[0]].use_smooth
-        find_offset_vec(mesh, vert_dict)
-        
-        short_edge = find_shortest_edge(mesh, edge_faces, vert_dict, out_edges)
-        if shortest_edge == None or shortest_edge > short_edge:
-            shortest_edge = short_edge
-        
-        disp_vecs, ar = find_displace_vecs(mesh, island, vert_dict)
-        if area < 0 or ar < area:
-            area = ar 
-        disp_islands.append(disp_vecs)
-        
-        island_dicts.append(vert_dict)
-        
-        mesh.vertices.add(len(vert_dict.keys()))
-        offset_verts(mesh, vert_dict, 0.03)
-
-    
-    rim_select, rim_noSelect, n_f_old = new_faces(mesh, island_dicts, edge_faces_islands, outer_edges)
-    
-    select_faces(mesh, rim_select, rim_noSelect, edge_faces_islands, n_faces_old, ref_normal, use_smooth)
-    return([island_dicts, disp_islands, shortest_edge, area])
-
-def offset_verts(mesh, vert_dict, offset):
-    verts = list(vert_dict.keys())
-    for vert in verts:
-        new_co = mesh.vertices[vert].co.copy() + vert_dict[vert].offset_vec * offset
-        mesh.vertices[vert_dict[vert].new_index].co = new_co
-
-def displace_verts(mesh, vert_dict, displace_vecs, displace):
-    for vert in list(displace_vecs.keys()):
-        if vert in vert_dict:
-            mesh.vertices[vert_dict[vert].new_index].co += displace_vecs[vert] * displace
-        else:
-            mesh.vertices[vert].co = displace_vecs[vert][0] + displace_vecs[vert][1] * displace
-
-
-
-def draw_UI(self, context):
-    # creates all lines and appends them to a list, then draws these to the UI
-    font_id = 0
-    lines = []
-    
-    if self.switch:
-        blf.position(font_id, self.initial_mouse_region[0]+5, self.current_mouse_region[1]+8, 0)
-        blf.size(font_id, 20, 38)
-        blf.draw(font_id, str(round(self.offset, 3)))
-        
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glColor4f(1.0, 1.0, 1.0, 0.2)
-        bgl.glLineWidth(2)
-        
-        length = 0
-        while length < abs(self.current_mouse_region[0] - self.initial_mouse_region[0])-10:
-            
-            if self.current_mouse_region[0] - self.initial_mouse_region[0] >= 0:
-                lines.append([(self.initial_mouse_region[0]+length+4, self.current_mouse_region[1]),
-                              (self.initial_mouse_region[0]+length+10, self.current_mouse_region[1])])
-                
-            else:
-                lines.append([(self.initial_mouse_region[0]-length-4, self.current_mouse_region[1]),
-                              (self.initial_mouse_region[0]-length-10, self.current_mouse_region[1])])
-            length +=10
-            
-        lines.append([(self.initial_mouse_region[0]+1, self.current_mouse_region[1]+15),
-                  (self.initial_mouse_region[0]+1, self.current_mouse_region[1]-8)])
-        
-    else:
-        blf.position(font_id, self.current_mouse_region[0]+5, self.initial_mouse_region[1]+8, 0)
-        blf.size(font_id, 20, 38)
-        blf.draw(font_id, str(round(self.displace, 3)))
-        
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glColor4f(1.0, 1.0, 1.0, 0.2)
-        bgl.glLineWidth(2)
-        
-        length = 0
-        while length < abs(self.current_mouse_region[1] - self.initial_mouse_region[1])-10:
-            
-            if self.current_mouse_region[1] - self.initial_mouse_region[1] >= 0:
-                lines.append([(self.current_mouse_region[0], self.initial_mouse_region[1]+length+4),
-                              (self.current_mouse_region[0], self.initial_mouse_region[1]+length+10)])
-                
-            else:
-                lines.append([(self.current_mouse_region[0], self.initial_mouse_region[1]-length-4),
-                              (self.current_mouse_region[0], self.initial_mouse_region[1]-length-10)])
-            length +=10
-        
-        lines.append([(self.current_mouse_region[0]+15, self.initial_mouse_region[1]+1),
-                  (self.current_mouse_region[0]-8, self.initial_mouse_region[1]+1)])
-    
-    
-    # draw lines
-    for i in lines:
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        for x, y in i:
-            bgl.glVertex2i(x, y)
-        bgl.glEnd()
- 
-    # restore opengl defaults
-    bgl.glLineWidth(1)
-    bgl.glDisable(bgl.GL_BLEND)
-    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-    
-
-def initialize():
-    
-    global_undo = bpy.context.user_preferences.edit.use_global_undo
-    bpy.context.user_preferences.edit.use_global_undo = False
-    bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    mesh = bpy.context.active_object.data
-    vert_dict, displace_vecs, shortest_edge, area = run_inset_extrude(mesh, False)
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    return ([global_undo, mesh, vert_dict, displace_vecs, shortest_edge, area])
-
-def terminate(global_undo):
-    bpy.ops.object.mode_set(mode='EDIT')
-    bpy.context.user_preferences.edit.use_global_undo = global_undo
-
-class MESH_OT_inset_extrude(bpy.types.Operator):
-    bl_idname = "mesh.inset_extrude"
-    bl_label = "Inset Extrude"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    displace = FloatProperty(name='Extrude', 
-                description='displacement from original surface',
-                default=0.0, min=-100, max=100)
-    offset = FloatProperty(name='Inset', 
-                description='inset from selcetion border',
-                default=0.0, min=-100, max=100)
-    individual_faces = BoolProperty(name='Individual Faces', 
-                default=False)
-    switch = True
-    multiplier = 1
-    shift_value = 0
-    ctrl = False
-    run_modal = False
-    key_input = ''
-    
-    def draw(self, context):
-        layout = self.layout
-        col_top = layout.column(align = True)
-        row = col_top.row(align = True)
-        col_left = row.column(align = True)
-        col_left.prop(self, 'offset')
-        col_left.prop(self, 'displace')
-#        col_left.prop(self, 'individual_faces')
-    
-    def execute(self, context):
-        bpy.ops.object.mode_set(mode='OBJECT')
-        if not self.run_modal:
-            run_inset_extrude(self.mesh, self.individual_faces)
-        for vert_dict in self.island_dicts:
-            offset_verts(self.mesh, vert_dict, self.offset)
-            displace_verts(self.mesh, vert_dict, self.disp_islands[self.island_dicts.index(vert_dict)], self.displace)
-        bpy.ops.object.mode_set(mode='EDIT')
-        return{'FINISHED'}
-    
-    def modal(self, context, event):
-        v3d = context.space_data
-        context.area.tag_redraw()
-        
-        if event.type == 'LEFTMOUSE' and event.value == 'PRESS':
-            self.switch = not self.switch
-            self.shift_value = 0
-            self.initial_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
-            self.initial_mouse_region = [event.mouse_region_x, event.mouse_region_y]
-            
-#        elif event.type == 'I' and event.value == 'PRESS':
-#            self.individual_faces = not self.individual_faces
-#            self.island_dicts, self.disp_islands, self.shortest_edge, self.area = run_inset_extrude(self.mesh, self.individual_faces)
-        
-        elif event.type == 'MOUSEMOVE':
-            current_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
-            offset_vector = (self.initial_mouse - current_mouse)
-            self.current_mouse_region = [event.mouse_region_x, event.mouse_region_y]
-                
-            if self.switch:
-                self.offset = - offset_vector[0] * self.shortest_edge * 0.0015 * self.multiplier + self.shift_value
-            else:
-                self.displace = - offset_vector[1] * 0.002 * self.multiplier * sqrt(self.area) + self.shift_value
-            
-            if self.ctrl:
-                if self.multiplier!=1:
-                    self.offset = round(self.offset, 2)
-                    self.displace = round(self.displace, 2)
-                else:
-                    self.offset = round(self.offset, 1)
-                    self.displace = round(self.displace, 1)
-            
-            self.execute(context)
-            return {'RUNNING_MODAL'}
-            
-        elif event.type =='LEFT_SHIFT' or event.type == 'RIGHT_SHIFT':
-            if event.value == 'PRESS':
-                self.multiplier = 0.1
-                if self.switch:
-                    self.shift_value = self.offset * 0.9
-                else:
-                    self.shift_value = self.displace * 0.9
-            if event.value == 'RELEASE':
-                self.multiplier = 1
-                self.shift_value = 0
-            return {'RUNNING_MODAL'}
-        
-        elif event.type =='LEFT_CTRL' or event.type == 'RIGHT_CTRL':
-            if event.value == 'PRESS': self.ctrl = True
-            if event.value == 'RELEASE': self.ctrl = False
-            return {'RUNNING_MODAL'}
-        
-        elif event.type in list(self.key_dict.keys()) and event.value == 'PRESS':
-            if event.type == 'NUMPAD_ENTER':
-                context.area.header_text_set()
-                if self.switch:
-                    self.key_input = ''
-                    self.shift_value = 0
-                    self.initial_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
-                    self.initial_mouse_region = [event.mouse_region_x, event.mouse_region_y]
-                    self.switch = not self.switch
-                    return {'RUNNING_MODAL'}
-                else:
-                    terminate(self.global_undo)
-                    context.region.callback_remove(self._handle) 
-                    self.run_modal = False
-                    return {'FINISHED'}
-            else:
-                if event.type == 'BACK_SPACE':
-                    self.key_input = self.key_input[:-1]
-                    if len(self.key_input) == 0:
-                        self.key_input = ''
-                        context.area.header_text_set(self.key_input)
-                        return{'RUNNING_MODAL'}
-                else:
-                    self.key_input += self.key_dict[event.type]
-                    if self.key_dict[event.type] in ['+', '-', '*', '/']:
-                        context.area.header_text_set(self.key_input)    
-                        return {'RUNNING_MODAL'}
-                context.area.header_text_set(self.key_input)
-                try:
-                    if self.switch:
-                        self.offset = eval(self.key_input)
-                    else:
-                        self.displace = eval(self.key_input)
-                except SyntaxError:
-                    return {'RUNNING_MODAL'}
-                self.execute(context)
-                return {'RUNNING_MODAL'}
-        
-        
-        elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
-            context.area.header_text_set()
-            terminate(self.global_undo)
-            context.region.callback_remove(self._handle) 
-            self.run_modal = False
-            return {'FINISHED'}
-
-        elif event.type in {'RIGHTMOUSE', 'ESC'}:
-            context.area.header_text_set()
-            context.region.callback_remove(self._handle)
-            self.run_modal = False
-            return {'CANCELLED'}
-        return {'RUNNING_MODAL'}
-
-    def invoke(self, context, event):
-        initial_selection_mode = [bool for bool in bpy.context.tool_settings.mesh_select_mode]
-        self.global_undo, self.mesh, self.island_dicts, self.disp_islands, self.shortest_edge, self.area = initialize()
-        bpy.context.tool_settings.mesh_select_mode = initial_selection_mode
-        self.displace = 0
-        self.run_modal = True
-        
-        self.key_dict = {
-                        'NUMPAD_0':'0', 'NUMPAD_1':'1', 'NUMPAD_2':'2', 
-                        'NUMPAD_3':'3', 'NUMPAD_4':'4', 'NUMPAD_5':'5', 
-                        'NUMPAD_6':'6', 'NUMPAD_7':'7', 'NUMPAD_8':'8', 
-                        'NUMPAD_9':'9', 'NUMPAD_PERIOD':'.', 'NUMPAD_SLASH':'/', 
-                        'NUMPAD_ASTERIX':'*', 'NUMPAD_MINUS':'-', 'NUMPAD_ENTER':None, 
-                        'NUMPAD_PLUS':'+', 'ONE':'1', 'TWO':'2', 'THREE':'3', 
-                        'FOUR':'4', 'FIVE':'5', 'SIX':'6', 'SEVEN':'7', 
-                        'EIGHT':'8', 'NINE':'9', 'ZERO':'0', 'PERIOD':'.', 'BACK_SPACE':None
-                        }
-        
-        if context.space_data.type == 'VIEW_3D':
-            v3d = context.space_data
-
-            context.window_manager.modal_handler_add(self)
-            self.current_mouse_region = [event.mouse_region_x, event.mouse_region_y]
-            self.initial_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
-            self.initial_mouse_region = [event.mouse_region_x, event.mouse_region_y]
-            self._handle = context.region.callback_add(draw_UI, (self, context), 'POST_PIXEL')
-            
-            return {'RUNNING_MODAL'}
-        else:
-            self.report({'WARNING'}, "Active space must be a View3d")
-            return {'CANCELLED'}
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    wm = bpy.context.window_manager
-    km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
-    kmi = km.keymap_items.new('mesh.inset_extrude', 'I', 'PRESS')
- #   kmi.properties.name = "MESH_OT_inset_extrude"
-	
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    wm = bpy.context.window_manager
-    km = wm.keyconfigs.addon.keymaps['3D View']
-    for kmi in km.keymap_items:
-        if kmi.idname == 'mesh.inset_extrude':
-#            if kmi.properties.name == "MESH_OT_inset_extrude":
-            km.keymap_items.remove(kmi)
-            break
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_looptools.py b/release/scripts/addons_contrib/mesh_looptools.py
deleted file mode 100644
index cee5de6..0000000
--- a/release/scripts/addons_contrib/mesh_looptools.py
+++ /dev/null
@@ -1,3728 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    'name': "LoopTools",
-    'author': "Bart Crouch",
-    'version': (3, 2, 4),
-    'blender': (2, 6, 2),
-    'location': "View3D > Toolbar and View3D > Specials (W-key)",
-    'warning': "Bridge & Loft functions removed",
-    'description': "Mesh modelling toolkit. Several tools to aid modelling",
-    'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Modeling/LoopTools",
-    'tracker_url': "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=26189",
-    'category': 'Mesh'}
-
-
-import bpy
-import mathutils
-import math
-
-
-##########################################
-####### General functions ################
-##########################################
-
-
-# used by all tools to improve speed on reruns
-looptools_cache = {}
-
-
-# force a full recalculation next time
-def cache_delete(tool):
-    if tool in looptools_cache:
-        del looptools_cache[tool]
-
-
-# check cache for stored information
-def cache_read(tool, object, mesh, input_method, boundaries):
-    # current tool not cached yet
-    if tool not in looptools_cache:
-        return(False, False, False, False, False)
-    # check if selected object didn't change
-    if object.name != looptools_cache[tool]["object"]:
-        return(False, False, False, False, False)
-    # check if input didn't change
-    if input_method != looptools_cache[tool]["input_method"]:
-        return(False, False, False, False, False)
-    if boundaries != looptools_cache[tool]["boundaries"]:
-        return(False, False, False, False, False)
-    modifiers = [mod.name for mod in object.modifiers if mod.show_viewport \
-        and mod.type == 'MIRROR']
-    if modifiers != looptools_cache[tool]["modifiers"]:
-        return(False, False, False, False, False)
-    input = [v.index for v in mesh.vertices if v.select and not v.hide]
-    if input != looptools_cache[tool]["input"]:
-        return(False, False, False, False, False)
-    # reading values
-    single_loops = looptools_cache[tool]["single_loops"]
-    loops = looptools_cache[tool]["loops"]
-    derived = looptools_cache[tool]["derived"]
-    mapping = looptools_cache[tool]["mapping"]
-    
-    return(True, single_loops, loops, derived, mapping)
-
-
-# store information in the cache
-def cache_write(tool, object, mesh, input_method, boundaries, single_loops,
-loops, derived, mapping):
-    # clear cache of current tool
-    if tool in looptools_cache:
-        del looptools_cache[tool]
-    # prepare values to be saved to cache
-    input = [v.index for v in mesh.vertices if v.select and not v.hide]
-    modifiers = [mod.name for mod in object.modifiers if mod.show_viewport \
-        and mod.type == 'MIRROR']
-    # update cache
-    looptools_cache[tool] = {"input": input, "object": object.name,
-        "input_method": input_method, "boundaries": boundaries,
-        "single_loops": single_loops, "loops": loops,
-        "derived": derived, "mapping": mapping, "modifiers": modifiers}
-
-
-# calculates natural cubic splines through all given knots
-def calculate_cubic_splines(mesh_mod, tknots, knots):
-    # hack for circular loops
-    if knots[0] == knots[-1] and len(knots) > 1:
-        circular = True
-        k_new1 = []
-        for k in range(-1, -5, -1):
-            if k - 1 < -len(knots):
-                k += len(knots)
-            k_new1.append(knots[k-1])
-        k_new2 = []
-        for k in range(4):
-            if k + 1 > len(knots) - 1:
-                k -= len(knots)
-            k_new2.append(knots[k+1])
-        for k in k_new1:
-            knots.insert(0, k)
-        for k in k_new2:
-            knots.append(k)
-        t_new1 = []
-        total1 = 0
-        for t in range(-1, -5, -1):
-            if t - 1 < -len(tknots):
-                t += len(tknots)
-            total1 += tknots[t] - tknots[t-1]
-            t_new1.append(tknots[0] - total1)
-        t_new2 = []
-        total2 = 0
-        for t in range(4):
-            if t + 1 > len(tknots) - 1:
-                t -= len(tknots)
-            total2 += tknots[t+1] - tknots[t]
-            t_new2.append(tknots[-1] + total2)
-        for t in t_new1:
-            tknots.insert(0, t)
-        for t in t_new2:
-            tknots.append(t)
-    else:
-        circular = False
-    # end of hack
-    
-    n = len(knots)
-    if n < 2:
-        return False
-    x = tknots[:]
-    locs = [mesh_mod.vertices[k].co[:] for k in knots]
-    result = []
-    for j in range(3):
-        a = []
-        for i in locs:
-            a.append(i[j])
-        h = []
-        for i in range(n-1):
-            if x[i+1] - x[i] == 0:
-                h.append(1e-8)
-            else:
-                h.append(x[i+1] - x[i])
-        q = [False]
-        for i in range(1, n-1):
-            q.append(3/h[i]*(a[i+1]-a[i]) - 3/h[i-1]*(a[i]-a[i-1]))
-        l = [1.0]
-        u = [0.0]
-        z = [0.0]
-        for i in range(1, n-1):
-            l.append(2*(x[i+1]-x[i-1]) - h[i-1]*u[i-1])
-            if l[i] == 0:
-                l[i] = 1e-8
-            u.append(h[i] / l[i])
-            z.append((q[i] - h[i-1] * z[i-1]) / l[i])
-        l.append(1.0)
-        z.append(0.0)
-        b = [False for i in range(n-1)]
-        c = [False for i in range(n)]
-        d = [False for i in range(n-1)]
-        c[n-1] = 0.0
-        for i in range(n-2, -1, -1):
-            c[i] = z[i] - u[i]*c[i+1]
-            b[i] = (a[i+1]-a[i])/h[i] - h[i]*(c[i+1]+2*c[i])/3
-            d[i] = (c[i+1]-c[i]) / (3*h[i])
-        for i in range(n-1):
-            result.append([a[i], b[i], c[i], d[i], x[i]])
-    splines = []
-    for i in range(len(knots)-1):
-        splines.append([result[i], result[i+n-1], result[i+(n-1)*2]])
-    if circular: # cleaning up after hack
-        knots = knots[4:-4]
-        tknots = tknots[4:-4]
-    
-    return(splines)
-
-
-# calculates linear splines through all given knots
-def calculate_linear_splines(mesh_mod, tknots, knots):
-    splines = []
-    for i in range(len(knots)-1):
-        a = mesh_mod.vertices[knots[i]].co
-        b = mesh_mod.vertices[knots[i+1]].co
-        d = b-a
-        t = tknots[i]
-        u = tknots[i+1]-t
-        splines.append([a, d, t, u]) # [locStart, locDif, tStart, tDif]
-    
-    return(splines)
-
-
-# calculate a best-fit plane to the given vertices
-def calculate_plane(mesh_mod, loop, method="best_fit", object=False):
-    # getting the vertex locations
-    locs = [mesh_mod.vertices[v].co.copy() for v in loop[0]]
-    
-    # calculating the center of masss
-    com = mathutils.Vector()
-    for loc in locs:
-        com += loc
-    com /= len(locs)
-    x, y, z = com
-    
-    if method == 'best_fit':
-        # creating the covariance matrix
-        mat = mathutils.Matrix(((0.0, 0.0, 0.0),
-                                (0.0, 0.0, 0.0),
-                                (0.0, 0.0, 0.0),
-                                ))
-        for loc in locs:
-            mat[0][0] += (loc[0]-x)**2
-            mat[1][0] += (loc[0]-x)*(loc[1]-y)
-            mat[2][0] += (loc[0]-x)*(loc[2]-z)
-            mat[0][1] += (loc[1]-y)*(loc[0]-x)
-            mat[1][1] += (loc[1]-y)**2
-            mat[2][1] += (loc[1]-y)*(loc[2]-z)
-            mat[0][2] += (loc[2]-z)*(loc[0]-x)
-            mat[1][2] += (loc[2]-z)*(loc[1]-y)
-            mat[2][2] += (loc[2]-z)**2
-        
-        # calculating the normal to the plane
-        normal = False
-        try:
-            mat.invert()
-        except:
-            if sum(mat[0]) == 0.0:
-                normal = mathutils.Vector((1.0, 0.0, 0.0))
-            elif sum(mat[1]) == 0.0:
-                normal = mathutils.Vector((0.0, 1.0, 0.0))
-            elif sum(mat[2]) == 0.0:
-                normal = mathutils.Vector((0.0, 0.0, 1.0))
-        if not normal:
-            # warning! this is different from .normalize()
-            itermax = 500
-            iter = 0
-            vec = mathutils.Vector((1.0, 1.0, 1.0))
-            vec2 = (mat * vec)/(mat * vec).length
-            while vec != vec2 and iter<itermax:
-                iter+=1
-                vec = vec2
-                vec2 = mat * vec
-                if vec2.length != 0:
-                    vec2 /= vec2.length
-            if vec2.length == 0:
-                vec2 = mathutils.Vector((1.0, 1.0, 1.0))
-            normal = vec2
-    
-    elif method == 'normal':
-        # averaging the vertex normals
-        v_normals = [mesh_mod.vertices[v].normal for v in loop[0]]
-        normal = mathutils.Vector()
-        for v_normal in v_normals:
-            normal += v_normal
-        normal /= len(v_normals)
-        normal.normalize()
-        
-    elif method == 'view':
-        # calculate view normal
-        rotation = bpy.context.space_data.region_3d.view_matrix.to_3x3().\
-            inverted()
-        normal = rotation * mathutils.Vector((0.0, 0.0, 1.0))
-        if object:
-            normal = object.matrix_world.inverted().to_euler().to_matrix() * \
-                     normal
-    
-    return(com, normal)
-
-
-# calculate splines based on given interpolation method (controller function)
-def calculate_splines(interpolation, mesh_mod, tknots, knots):
-    if interpolation == 'cubic':
-        splines = calculate_cubic_splines(mesh_mod, tknots, knots[:])
-    else: # interpolations == 'linear'
-        splines = calculate_linear_splines(mesh_mod, tknots, knots[:])
-    
-    return(splines)
-
-
-# check loops and only return valid ones
-def check_loops(loops, mapping, mesh_mod):
-    valid_loops = []
-    for loop, circular in loops:
-        # loop needs to have at least 3 vertices
-        if len(loop) < 3:
-            continue
-        # loop needs at least 1 vertex in the original, non-mirrored mesh
-        if mapping:
-            all_virtual = True
-            for vert in loop:
-                if mapping[vert] > -1:
-                    all_virtual = False
-                    break
-            if all_virtual:
-                continue
-        # vertices can not all be at the same location
-        stacked = True
-        for i in range(len(loop) - 1):
-            if (mesh_mod.vertices[loop[i]].co - \
-            mesh_mod.vertices[loop[i+1]].co).length > 1e-6:
-                stacked = False
-                break
-        if stacked:
-            continue    
-        # passed all tests, loop is valid
-        valid_loops.append([loop, circular])
-    
-    return(valid_loops)
-
-
-# input: mesh, output: dict with the edge-key as key and face-index as value
-def dict_edge_faces(mesh):
-    edge_faces = dict([[edge.key, []] for edge in mesh.edges if not edge.hide])
-    for face in mesh.tessfaces:
-        if face.hide:
-            continue
-        for key in face.edge_keys:
-            edge_faces[key].append(face.index)
-    
-    return(edge_faces)
-
-# input: mesh (edge-faces optional), output: dict with face-face connections
-def dict_face_faces(mesh, edge_faces=False):
-    if not edge_faces:
-        edge_faces = dict_edge_faces(mesh)
-    
-    connected_faces = dict([[face.index, []] for face in mesh.tessfaces if \
-        not face.hide])
-    for face in mesh.tessfaces:
-        if face.hide:
-            continue
-        for edge_key in face.edge_keys:
-            for connected_face in edge_faces[edge_key]:
-                if connected_face == face.index:
-                    continue
-                connected_faces[face.index].append(connected_face)
-    
-    return(connected_faces)
-
-
-# input: mesh, output: dict with the vert index as key and edge-keys as value
-def dict_vert_edges(mesh):
-    vert_edges = dict([[v.index, []] for v in mesh.vertices if not v.hide])
-    for edge in mesh.edges:
-        if edge.hide:
-            continue
-        for vert in edge.key:
-            vert_edges[vert].append(edge.key)
-    
-    return(vert_edges)
-
-
-# input: mesh, output: dict with the vert index as key and face index as value
-def dict_vert_faces(mesh):
-    vert_faces = dict([[v.index, []] for v in mesh.vertices if not v.hide])
-    for face in mesh.tessfaces:
-        if not face.hide:
-            for vert in face.vertices:
-                vert_faces[vert].append(face.index)
-                
-    return(vert_faces)
-
-
-# input: list of edge-keys, output: dictionary with vertex-vertex connections
-def dict_vert_verts(edge_keys):
-    # create connection data
-    vert_verts = {}
-    for ek in edge_keys:
-        for i in range(2):
-            if ek[i] in vert_verts:
-                vert_verts[ek[i]].append(ek[1-i])
-            else:
-                vert_verts[ek[i]] = [ek[1-i]]
-    
-    return(vert_verts)
-
-
-# calculate input loops
-def get_connected_input(object, mesh, scene, input):
-    # get mesh with modifiers applied
-    derived, mesh_mod = get_derived_mesh(object, mesh, scene)
-    
-    # calculate selected loops
-    edge_keys = [edge.key for edge in mesh_mod.edges if \
-        edge.select and not edge.hide]
-    loops = get_connected_selections(edge_keys)
-    
-    # if only selected loops are needed, we're done
-    if input == 'selected':
-        return(derived, mesh_mod, loops)
-    # elif input == 'all':    
-    loops = get_parallel_loops(mesh_mod, loops)
-    
-    return(derived, mesh_mod, loops)
-
-
-# sorts all edge-keys into a list of loops
-def get_connected_selections(edge_keys):
-    # create connection data
-    vert_verts = dict_vert_verts(edge_keys)
-    
-    # find loops consisting of connected selected edges
-    loops = []
-    while len(vert_verts) > 0:
-        loop = [iter(vert_verts.keys()).__next__()]
-        growing = True
-        flipped = False
-        
-        # extend loop
-        while growing:
-            # no more connection data for current vertex
-            if loop[-1] not in vert_verts:
-                if not flipped:
-                    loop.reverse()
-                    flipped = True
-                else:
-                    growing = False
-            else:
-                extended = False
-                for i, next_vert in enumerate(vert_verts[loop[-1]]):
-                    if next_vert not in loop:
-                        vert_verts[loop[-1]].pop(i)
-                        if len(vert_verts[loop[-1]]) == 0:
-                            del vert_verts[loop[-1]]
-                        # remove connection both ways
-                        if next_vert in vert_verts:
-                            if len(vert_verts[next_vert]) == 1:
-                                del vert_verts[next_vert]
-                            else:
-                                vert_verts[next_vert].remove(loop[-1])
-                        loop.append(next_vert)
-                        extended = True
-                        break
-                if not extended:
-                    # found one end of the loop, continue with next
-                    if not flipped:
-                        loop.reverse()
-                        flipped = True
-                    # found both ends of the loop, stop growing
-                    else:
-                        growing = False
-        
-        # check if loop is circular
-        if loop[0] in vert_verts:
-            if loop[-1] in vert_verts[loop[0]]:
-                # is circular
-                if len(vert_verts[loop[0]]) == 1:
-                    del vert_verts[loop[0]]
-                else:
-                    vert_verts[loop[0]].remove(loop[-1])
-                if len(vert_verts[loop[-1]]) == 1:
-                    del vert_verts[loop[-1]]
-                else:
-                    vert_verts[loop[-1]].remove(loop[0])
-                loop = [loop, True]
-            else:
-                # not circular
-                loop = [loop, False]
-        else:
-            # not circular
-            loop = [loop, False]
-        
-        loops.append(loop)
-    
-    return(loops)
-
-
-# get the derived mesh data, if there is a mirror modifier
-def get_derived_mesh(object, mesh, scene):
-    # check for mirror modifiers
-    if 'MIRROR' in [mod.type for mod in object.modifiers if mod.show_viewport]:
-        derived = True
-        # disable other modifiers
-        show_viewport = [mod.name for mod in object.modifiers if \
-            mod.show_viewport]
-        for mod in object.modifiers:
-            if mod.type != 'MIRROR':
-                mod.show_viewport = False
-        # get derived mesh
-        mesh_mod = object.to_mesh(scene, True, 'PREVIEW')
-        # re-enable other modifiers
-        for mod_name in show_viewport:
-            object.modifiers[mod_name].show_viewport = True
-    # no mirror modifiers, so no derived mesh necessary
-    else:
-        derived = False
-        mesh_mod = mesh
-    
-    return(derived, mesh_mod)
-
-
-# return a mapping of derived indices to indices
-def get_mapping(derived, mesh, mesh_mod, single_vertices, full_search, loops):
-    if not derived:
-        return(False)
-    
-    if full_search:
-        verts = [v for v in mesh.vertices if not v.hide]
-    else:
-        verts = [v for v in mesh.vertices if v.select and not v.hide]
-    
-    # non-selected vertices around single vertices also need to be mapped
-    if single_vertices:
-        mapping = dict([[vert, -1] for vert in single_vertices])
-        verts_mod = [mesh_mod.vertices[vert] for vert in single_vertices]
-        for v in verts:
-            for v_mod in verts_mod:
-                if (v.co - v_mod.co).length < 1e-6:
-                    mapping[v_mod.index] = v.index
-                    break
-        real_singles = [v_real for v_real in mapping.values() if v_real>-1]
-        
-        verts_indices = [vert.index for vert in verts]
-        for face in [face for face in mesh.tessfaces if not face.select \
-        and not face.hide]:
-            for vert in face.vertices:
-                if vert in real_singles:
-                    for v in face.vertices:
-                        if not v in verts_indices:
-                            if mesh.vertices[v] not in verts:
-                                verts.append(mesh.vertices[v])
-                    break
-    
-    # create mapping of derived indices to indices
-    mapping = dict([[vert, -1] for loop in loops for vert in loop[0]])
-    if single_vertices:
-        for single in single_vertices:
-            mapping[single] = -1
-    verts_mod = [mesh_mod.vertices[i] for i in mapping.keys()]
-    for v in verts:
-        for v_mod in verts_mod:
-            if (v.co - v_mod.co).length < 1e-6:
-                mapping[v_mod.index] = v.index
-                verts_mod.remove(v_mod)
-                break
-    
-    return(mapping)
-
-
-# returns a list of all loops parallel to the input, input included
-def get_parallel_loops(mesh_mod, loops):
-    # get required dictionaries
-    edge_faces = dict_edge_faces(mesh_mod)
-    connected_faces = dict_face_faces(mesh_mod, edge_faces)
-    # turn vertex loops into edge loops
-    edgeloops = []
-    for loop in loops:
-        edgeloop = [[sorted([loop[0][i], loop[0][i+1]]) for i in \
-            range(len(loop[0])-1)], loop[1]]
-        if loop[1]: # circular
-            edgeloop[0].append(sorted([loop[0][-1], loop[0][0]]))
-        edgeloops.append(edgeloop[:])
-    # variables to keep track while iterating
-    all_edgeloops = []
-    has_branches = False
-    
-    for loop in edgeloops:
-        # initialise with original loop
-        all_edgeloops.append(loop[0])
-        newloops = [loop[0]]
-        verts_used = []
-        for edge in loop[0]:
-            if edge[0] not in verts_used:
-                verts_used.append(edge[0])
-            if edge[1] not in verts_used:
-                verts_used.append(edge[1])
-        
-        # find parallel loops
-        while len(newloops) > 0:
-            side_a = []
-            side_b = []
-            for i in newloops[-1]:
-                i = tuple(i)
-                forbidden_side = False
-                if not i in edge_faces:
-                    # weird input with branches
-                    has_branches = True
-                    break
-                for face in edge_faces[i]:
-                    if len(side_a) == 0 and forbidden_side != "a":
-                        side_a.append(face)
-                        if forbidden_side:
-                            break
-                        forbidden_side = "a"
-                        continue
-                    elif side_a[-1] in connected_faces[face] and \
-                    forbidden_side != "a":
-                        side_a.append(face)
-                        if forbidden_side:
-                            break
-                        forbidden_side = "a"
-                        continue
-                    if len(side_b) == 0 and forbidden_side != "b":
-                        side_b.append(face)
-                        if forbidden_side:
-                            break
-                        forbidden_side = "b"
-                        continue
-                    elif side_b[-1] in connected_faces[face] and \
-                    forbidden_side != "b":
-                        side_b.append(face)
-                        if forbidden_side:
-                            break
-                        forbidden_side = "b"
-                        continue
-            
-            if has_branches:
-                # weird input with branches
-                break
-            
-            newloops.pop(-1)
-            sides = []
-            if side_a:
-                sides.append(side_a)
-            if side_b:
-                sides.append(side_b)
-            
-            for side in sides:
-                extraloop = []
-                for fi in side:
-                    for key in mesh_mod.tessfaces[fi].edge_keys:
-                        if key[0] not in verts_used and key[1] not in \
-                        verts_used:
-                            extraloop.append(key)
-                            break
-                if extraloop:
-                    for key in extraloop:
-                        for new_vert in key:
-                            if new_vert not in verts_used:
-                                verts_used.append(new_vert)
-                    newloops.append(extraloop)
-                    all_edgeloops.append(extraloop)
-    
-    # input contains branches, only return selected loop
-    if has_branches:
-        return(loops)
-    
-    # change edgeloops into normal loops
-    loops = []
-    for edgeloop in all_edgeloops:
-        loop = []
-        # grow loop by comparing vertices between consecutive edge-keys
-        for i in range(len(edgeloop)-1):
-            for vert in range(2):
-                if edgeloop[i][vert] in edgeloop[i+1]:
-                    loop.append(edgeloop[i][vert])
-                    break
-        if loop:
-            # add starting vertex
-            for vert in range(2):
-                if edgeloop[0][vert] != loop[0]:
-                    loop = [edgeloop[0][vert]] + loop
-                    break
-            # add ending vertex
-            for vert in range(2):
-                if edgeloop[-1][vert] != loop[-1]:
-                    loop.append(edgeloop[-1][vert])
-                    break
-            # check if loop is circular
-            if loop[0] == loop[-1]:
-                circular = True
-                loop = loop[:-1]
-            else:
-                circular = False
-        loops.append([loop, circular])
-    
-    return(loops)
-
-
-# gather initial data
-def initialise():
-    global_undo = bpy.context.user_preferences.edit.use_global_undo
-    bpy.context.user_preferences.edit.use_global_undo = False
-    bpy.ops.object.mode_set(mode='OBJECT')
-    object = bpy.context.active_object
-    mesh = bpy.context.active_object.data
-    
-    return(global_undo, object, mesh)
-
-
-# move the vertices to their new locations
-def move_verts(mesh, mapping, move, influence):
-    for loop in move:
-        for index, loc in loop:
-            if mapping:
-                if mapping[index] == -1:
-                    continue
-                else:
-                    index = mapping[index]
-            if influence >= 0:
-                mesh.vertices[index].co = loc*(influence/100) + \
-                    mesh.vertices[index].co*((100-influence)/100)
-            else:
-                mesh.vertices[index].co = loc
-
-
-# load custom tool settings 
-def settings_load(self):
-    lt = bpy.context.window_manager.looptools
-    tool = self.name.split()[0].lower()
-    keys = self.as_keywords().keys()
-    for key in keys:
-        setattr(self, key, getattr(lt, tool + "_" + key))
-
-
-# store custom tool settings
-def settings_write(self):
-    lt = bpy.context.window_manager.looptools
-    tool = self.name.split()[0].lower()
-    keys = self.as_keywords().keys()
-    for key in keys:
-        setattr(lt, tool + "_" + key, getattr(self, key))
-
-
-# clean up and set settings back to original state
-def terminate(global_undo):
-    bpy.ops.object.mode_set(mode='EDIT')
-    bpy.context.user_preferences.edit.use_global_undo = global_undo
-
-
-##########################################
-####### Bridge functions #################
-##########################################
-
-# calculate a cubic spline through the middle section of 4 given coordinates
-def bridge_calculate_cubic_spline(mesh, coordinates):
-    result = []
-    x = [0, 1, 2, 3]
-    
-    for j in range(3):
-        a = []
-        for i in coordinates:
-            a.append(float(i[j]))
-        h = []
-        for i in range(3):
-            h.append(x[i+1]-x[i])
-        q = [False]
-        for i in range(1,3):
-            q.append(3.0/h[i]*(a[i+1]-a[i])-3.0/h[i-1]*(a[i]-a[i-1]))
-        l = [1.0]
-        u = [0.0]
-        z = [0.0]
-        for i in range(1,3):
-            l.append(2.0*(x[i+1]-x[i-1])-h[i-1]*u[i-1])
-            u.append(h[i]/l[i])
-            z.append((q[i]-h[i-1]*z[i-1])/l[i])
-        l.append(1.0)
-        z.append(0.0)
-        b = [False for i in range(3)]
-        c = [False for i in range(4)]
-        d = [False for i in range(3)]
-        c[3] = 0.0
-        for i in range(2,-1,-1):
-            c[i] = z[i]-u[i]*c[i+1]
-            b[i] = (a[i+1]-a[i])/h[i]-h[i]*(c[i+1]+2.0*c[i])/3.0
-            d[i] = (c[i+1]-c[i])/(3.0*h[i])
-        for i in range(3):
-            result.append([a[i], b[i], c[i], d[i], x[i]])
-    spline = [result[1], result[4], result[7]]
-
-    return(spline)
-
-
-# return a list with new vertex location vectors, a list with face vertex 
-# integers, and the highest vertex integer in the virtual mesh
-def bridge_calculate_geometry(mesh, lines, vertex_normals, segments,
-interpolation, cubic_strength, min_width, max_vert_index):
-    new_verts = []
-    faces = []
-    
-    # calculate location based on interpolation method
-    def get_location(line, segment, splines):
-        v1 = mesh.vertices[lines[line][0]].co
-        v2 = mesh.vertices[lines[line][1]].co
-        if interpolation == 'linear':
-            return v1 + (segment/segments) * (v2-v1)
-        else: # interpolation == 'cubic'
-            m = (segment/segments)
-            ax,bx,cx,dx,tx = splines[line][0]
-            x = ax+bx*m+cx*m**2+dx*m**3
-            ay,by,cy,dy,ty = splines[line][1]
-            y = ay+by*m+cy*m**2+dy*m**3
-            az,bz,cz,dz,tz = splines[line][2]
-            z = az+bz*m+cz*m**2+dz*m**3
-            return mathutils.Vector((x, y, z))
-        
-    # no interpolation needed
-    if segments == 1:
-        for i, line in enumerate(lines):
-            if i < len(lines)-1:
-                faces.append([line[0], lines[i+1][0], lines[i+1][1], line[1]])
-    # more than 1 segment, interpolate
-    else:
-        # calculate splines (if necessary) once, so no recalculations needed
-        if interpolation == 'cubic':
-            splines = []
-            for line in lines:
-                v1 = mesh.vertices[line[0]].co
-                v2 = mesh.vertices[line[1]].co
-                size = (v2-v1).length * cubic_strength
-                splines.append(bridge_calculate_cubic_spline(mesh,
-                    [v1+size*vertex_normals[line[0]], v1, v2,
-                    v2+size*vertex_normals[line[1]]]))
-        else:
-            splines = False
-        
-        # create starting situation
-        virtual_width = [(mesh.vertices[lines[i][0]].co -
-                          mesh.vertices[lines[i+1][0]].co).length for i
-                          in range(len(lines)-1)]
-        new_verts = [get_location(0, seg, splines) for seg in range(1,
-            segments)]
-        first_line_indices = [i for i in range(max_vert_index+1,
-            max_vert_index+segments)]
-        
-        prev_verts = new_verts[:] # vertex locations of verts on previous line
-        prev_vert_indices = first_line_indices[:]
-        max_vert_index += segments - 1 # highest vertex index in virtual mesh
-        next_verts = [] # vertex locations of verts on current line
-        next_vert_indices = []
-        
-        for i, line in enumerate(lines):
-            if i < len(lines)-1:
-                v1 = line[0]
-                v2 = lines[i+1][0]
-                end_face = True
-                for seg in range(1, segments):
-                    loc1 = prev_verts[seg-1]
-                    loc2 = get_location(i+1, seg, splines)
-                    if (loc1-loc2).length < (min_width/100)*virtual_width[i] \
-                    and line[1]==lines[i+1][1]:
-                        # triangle, no new vertex
-                        faces.append([v1, v2, prev_vert_indices[seg-1],
-                            prev_vert_indices[seg-1]])
-                        next_verts += prev_verts[seg-1:]
-                        next_vert_indices += prev_vert_indices[seg-1:]
-                        end_face = False
-                        break
-                    else:
-                        if i == len(lines)-2 and lines[0] == lines[-1]:
-                            # quad with first line, no new vertex
-                            faces.append([v1, v2, first_line_indices[seg-1],
-                                prev_vert_indices[seg-1]])
-                            v2 = first_line_indices[seg-1]
-                            v1 = prev_vert_indices[seg-1]
-                        else:
-                            # quad, add new vertex
-                            max_vert_index += 1
-                            faces.append([v1, v2, max_vert_index,
-                                prev_vert_indices[seg-1]])
-                            v2 = max_vert_index
-                            v1 = prev_vert_indices[seg-1]
-                            new_verts.append(loc2)
-                            next_verts.append(loc2)
-                            next_vert_indices.append(max_vert_index)
-                if end_face:
-                    faces.append([v1, v2, lines[i+1][1], line[1]])
-                
-                prev_verts = next_verts[:]
-                prev_vert_indices = next_vert_indices[:]
-                next_verts = []
-                next_vert_indices = []
-    
-    return(new_verts, faces, max_vert_index)
-
-
-# calculate lines (list of lists, vertex indices) that are used for bridging
-def bridge_calculate_lines(mesh, loops, mode, twist, reverse):
-    lines = []
-    loop1, loop2 = [i[0] for i in loops]
-    loop1_circular, loop2_circular = [i[1] for i in loops]
-    circular = loop1_circular or loop2_circular
-    circle_full = False
-    
-    # calculate loop centers
-    centers = []
-    for loop in [loop1, loop2]:
-        center = mathutils.Vector()
-        for vertex in loop:
-            center += mesh.vertices[vertex].co
-        center /= len(loop)
-        centers.append(center)
-    for i, loop in enumerate([loop1, loop2]):
-        for vertex in loop:
-            if mesh.vertices[vertex].co == centers[i]:
-                # prevent zero-length vectors in angle comparisons
-                centers[i] += mathutils.Vector((0.01, 0, 0))
-                break
-    center1, center2 = centers
-    
-    # calculate the normals of the virtual planes that the loops are on
-    normals = []
-    normal_plurity = False
-    for i, loop in enumerate([loop1, loop2]):
-        # covariance matrix
-        mat = mathutils.Matrix(((0.0, 0.0, 0.0),
-                                (0.0, 0.0, 0.0),
-                                (0.0, 0.0, 0.0)))
-        x, y, z = centers[i]
-        for loc in [mesh.vertices[vertex].co for vertex in loop]:
-            mat[0][0] += (loc[0]-x)**2
-            mat[1][0] += (loc[0]-x)*(loc[1]-y)
-            mat[2][0] += (loc[0]-x)*(loc[2]-z)
-            mat[0][1] += (loc[1]-y)*(loc[0]-x)
-            mat[1][1] += (loc[1]-y)**2
-            mat[2][1] += (loc[1]-y)*(loc[2]-z)
-            mat[0][2] += (loc[2]-z)*(loc[0]-x)
-            mat[1][2] += (loc[2]-z)*(loc[1]-y)
-            mat[2][2] += (loc[2]-z)**2
-        # plane normal
-        normal = False
-        if sum(mat[0]) < 1e-6 or sum(mat[1]) < 1e-6 or sum(mat[2]) < 1e-6:
-            normal_plurity = True
-        try:
-            mat.invert()
-        except:
-            if sum(mat[0]) == 0:
-                normal = mathutils.Vector((1.0, 0.0, 0.0))
-            elif sum(mat[1]) == 0:
-                normal = mathutils.Vector((0.0, 1.0, 0.0))
-            elif sum(mat[2]) == 0:
-                normal = mathutils.Vector((0.0, 0.0, 1.0))
-        if not normal:
-            # warning! this is different from .normalize()
-            itermax = 500
-            iter = 0
-            vec = mathutils.Vector((1.0, 1.0, 1.0))
-            vec2 = (mat * vec)/(mat * vec).length
-            while vec != vec2 and iter<itermax:
-                iter+=1
-                vec = vec2
-                vec2 = mat * vec
-                if vec2.length != 0:
-                    vec2 /= vec2.length
-            if vec2.length == 0:
-                vec2 = mathutils.Vector((1.0, 1.0, 1.0))
-            normal = vec2
-        normals.append(normal)
-    # have plane normals face in the same direction (maximum angle: 90 degrees)
-    if ((center1 + normals[0]) - center2).length < \
-    ((center1 - normals[0]) - center2).length:
-        normals[0].negate()
-    if ((center2 + normals[1]) - center1).length > \
-    ((center2 - normals[1]) - center1).length:
-        normals[1].negate()
-    
-    # rotation matrix, representing the difference between the plane normals
-    axis = normals[0].cross(normals[1])
-    axis = mathutils.Vector([loc if abs(loc) > 1e-8 else 0 for loc in axis])
-    if axis.angle(mathutils.Vector((0, 0, 1)), 0) > 1.5707964:
-        axis.negate()
-    angle = normals[0].dot(normals[1])
-    rotation_matrix = mathutils.Matrix.Rotation(angle, 4, axis)
-    
-    # if circular, rotate loops so they are aligned
-    if circular:
-        # make sure loop1 is the circular one (or both are circular)
-        if loop2_circular and not loop1_circular:
-            loop1_circular, loop2_circular = True, False
-            loop1, loop2 = loop2, loop1
-        
-        # match start vertex of loop1 with loop2
-        target_vector = mesh.vertices[loop2[0]].co - center2
-        dif_angles = [[(rotation_matrix * (mesh.vertices[vertex].co - center1)
-                       ).angle(target_vector, 0), False, i] for
-                       i, vertex in enumerate(loop1)]
-        dif_angles.sort()
-        if len(loop1) != len(loop2):
-            angle_limit = dif_angles[0][0] * 1.2 # 20% margin
-            dif_angles = [[(mesh.vertices[loop2[0]].co - \
-                mesh.vertices[loop1[index]].co).length, angle, index] for \
-                angle, distance, index in dif_angles if angle <= angle_limit]
-            dif_angles.sort()
-        loop1 = loop1[dif_angles[0][2]:] + loop1[:dif_angles[0][2]]
-    
-    # have both loops face the same way
-    if normal_plurity and not circular:
-        second_to_first, second_to_second, second_to_last = \
-            [(mesh.vertices[loop1[1]].co - center1).\
-            angle(mesh.vertices[loop2[i]].co - center2) for i in [0, 1, -1]]
-        last_to_first, last_to_second = [(mesh.vertices[loop1[-1]].co - \
-            center1).angle(mesh.vertices[loop2[i]].co - center2) for \
-            i in [0, 1]]
-        if (min(last_to_first, last_to_second)*1.1 < min(second_to_first, \
-        second_to_second)) or (loop2_circular and second_to_last*1.1 < \
-        min(second_to_first, second_to_second)):
-            loop1.reverse()
-            if circular:
-                loop1 = [loop1[-1]] + loop1[:-1]
-    else:
-        angle = (mesh.vertices[loop1[0]].co - center1).\
-            cross(mesh.vertices[loop1[1]].co - center1).angle(normals[0], 0)
-        target_angle = (mesh.vertices[loop2[0]].co - center2).\
-            cross(mesh.vertices[loop2[1]].co - center2).angle(normals[1], 0)
-        limit = 1.5707964 # 0.5*pi, 90 degrees
-        if not ((angle > limit and target_angle > limit) or \
-        (angle < limit and target_angle < limit)):
-            loop1.reverse()
-            if circular:
-                loop1 = [loop1[-1]] + loop1[:-1]
-        elif normals[0].angle(normals[1]) > limit:
-            loop1.reverse()
-            if circular:
-                loop1 = [loop1[-1]] + loop1[:-1]
-    
-    # both loops have the same length
-    if len(loop1) == len(loop2):
-        # manual override
-        if twist:
-            if abs(twist) < len(loop1):
-                loop1 = loop1[twist:]+loop1[:twist]
-        if reverse:
-            loop1.reverse()
-        
-        lines.append([loop1[0], loop2[0]])
-        for i in range(1, len(loop1)):
-            lines.append([loop1[i], loop2[i]])
-    
-    # loops of different lengths
-    else:
-        # make loop1 longest loop
-        if len(loop2) > len(loop1):
-            loop1, loop2 = loop2, loop1
-            loop1_circular, loop2_circular = loop2_circular, loop1_circular
-        
-        # manual override
-        if twist:
-            if abs(twist) < len(loop1):
-                loop1 = loop1[twist:]+loop1[:twist]
-        if reverse:
-            loop1.reverse()
-            
-        # shortest angle difference doesn't always give correct start vertex
-        if loop1_circular and not loop2_circular:
-            shifting = 1
-            while shifting:
-                if len(loop1) - shifting < len(loop2):
-                    shifting = False
-                    break
-                to_last, to_first = [(rotation_matrix *
-                    (mesh.vertices[loop1[-1]].co - center1)).angle((mesh.\
-                    vertices[loop2[i]].co - center2), 0) for i in [-1, 0]]
-                if to_first < to_last:
-                    loop1 = [loop1[-1]] + loop1[:-1]
-                    shifting += 1
-                else:
-                    shifting = False
-                    break
-        
-        # basic shortest side first
-        if mode == 'basic':
-            lines.append([loop1[0], loop2[0]])
-            for i in range(1, len(loop1)):
-                if i >= len(loop2) - 1:
-                    # triangles
-                    lines.append([loop1[i], loop2[-1]])
-                else:
-                    # quads
-                    lines.append([loop1[i], loop2[i]])
-        
-        # shortest edge algorithm
-        else: # mode == 'shortest'
-            lines.append([loop1[0], loop2[0]])
-            prev_vert2 = 0
-            for i in range(len(loop1) -1):
-                if prev_vert2 == len(loop2) - 1 and not loop2_circular:
-                    # force triangles, reached end of loop2
-                    tri, quad = 0, 1
-                elif prev_vert2 == len(loop2) - 1 and loop2_circular:
-                    # at end of loop2, but circular, so check with first vert
-                    tri, quad = [(mesh.vertices[loop1[i+1]].co -
-                                  mesh.vertices[loop2[j]].co).length
-                                 for j in [prev_vert2, 0]]
-
-                    circle_full = 2
-                elif len(loop1) - 1 - i == len(loop2) - 1 - prev_vert2 and \
-                not circle_full:
-                    # force quads, otherwise won't make it to end of loop2
-                    tri, quad = 1, 0
-                else:
-                    # calculate if tri or quad gives shortest edge
-                    tri, quad = [(mesh.vertices[loop1[i+1]].co -
-                                  mesh.vertices[loop2[j]].co).length
-                                 for j in range(prev_vert2, prev_vert2+2)]
-                
-                # triangle
-                if tri < quad:
-                    lines.append([loop1[i+1], loop2[prev_vert2]])
-                    if circle_full == 2:
-                        circle_full = False
-                # quad
-                elif not circle_full:
-                    lines.append([loop1[i+1], loop2[prev_vert2+1]])
-                    prev_vert2 += 1
-                # quad to first vertex of loop2
-                else:
-                    lines.append([loop1[i+1], loop2[0]])
-                    prev_vert2 = 0
-                    circle_full = True
-    
-    # final face for circular loops
-    if loop1_circular and loop2_circular:
-        lines.append([loop1[0], loop2[0]])
-    
-    return(lines)
-
-
-# calculate number of segments needed
-def bridge_calculate_segments(mesh, lines, loops, segments):
-    # return if amount of segments is set by user
-    if segments != 0:
-        return segments
-    
-    # edge lengths
-    average_edge_length = [(mesh.vertices[vertex].co - \
-        mesh.vertices[loop[0][i+1]].co).length for loop in loops for \
-        i, vertex in enumerate(loop[0][:-1])]
-    # closing edges of circular loops
-    average_edge_length += [(mesh.vertices[loop[0][-1]].co - \
-        mesh.vertices[loop[0][0]].co).length for loop in loops if loop[1]] 
-    
-    # average lengths
-    average_edge_length = sum(average_edge_length) / len(average_edge_length)
-    average_bridge_length = sum([(mesh.vertices[v1].co - \
-        mesh.vertices[v2].co).length for v1, v2 in lines]) / len(lines)
-    
-    segments = max(1, round(average_bridge_length / average_edge_length))
-        
-    return(segments)
-
-
-# return dictionary with vertex index as key, and the normal vector as value
-def bridge_calculate_virtual_vertex_normals(mesh, lines, loops, edge_faces,
-edgekey_to_edge):
-    if not edge_faces: # interpolation isn't set to cubic
-        return False
-    
-    # pity reduce() isn't one of the basic functions in python anymore
-    def average_vector_dictionary(dic):
-        for key, vectors in dic.items():
-            #if type(vectors) == type([]) and len(vectors) > 1:
-            if len(vectors) > 1:
-                average = mathutils.Vector()
-                for vector in vectors:
-                    average += vector
-                average /= len(vectors)
-                dic[key] = [average]
-        return dic
-    
-    # get all edges of the loop
-    edges = [[edgekey_to_edge[tuple(sorted([loops[j][0][i],
-        loops[j][0][i+1]]))] for i in range(len(loops[j][0])-1)] for \
-        j in [0,1]]
-    edges = edges[0] + edges[1]
-    for j in [0, 1]:
-        if loops[j][1]: # circular
-            edges.append(edgekey_to_edge[tuple(sorted([loops[j][0][0],
-                loops[j][0][-1]]))])
-    
-    """
-    calculation based on face topology (assign edge-normals to vertices)
-    
-    edge_normal = face_normal x edge_vector
-    vertex_normal = average(edge_normals)
-    """
-    vertex_normals = dict([(vertex, []) for vertex in loops[0][0]+loops[1][0]])
-    for edge in edges:
-        faces = edge_faces[edge.key] # valid faces connected to edge
-        
-        if faces:
-            # get edge coordinates
-            v1, v2 = [mesh.vertices[edge.key[i]].co for i in [0,1]]
-            edge_vector = v1 - v2
-            if edge_vector.length < 1e-4:
-                # zero-length edge, vertices at same location
-                continue
-            edge_center = (v1 + v2) / 2
-            
-            # average face coordinates, if connected to more than 1 valid face
-            if len(faces) > 1:
-                face_normal = mathutils.Vector()
-                face_center = mathutils.Vector()
-                for face in faces:
-                    face_normal += face.normal
-                    face_center += face.center
-                face_normal /= len(faces)
-                face_center /= len(faces)
-            else:
-                face_normal = faces[0].normal
-                face_center = faces[0].center
-            if face_normal.length < 1e-4:
-                # faces with a surface of 0 have no face normal
-                continue
-            
-            # calculate virtual edge normal
-            edge_normal = edge_vector.cross(face_normal)
-            edge_normal.length = 0.01
-            if (face_center - (edge_center + edge_normal)).length > \
-            (face_center - (edge_center - edge_normal)).length:
-                # make normal face the correct way
-                edge_normal.negate()
-            edge_normal.normalize()
-            # add virtual edge normal as entry for both vertices it connects
-            for vertex in edge.key:
-                vertex_normals[vertex].append(edge_normal)
-    
-    """ 
-    calculation based on connection with other loop (vertex focused method) 
-    - used for vertices that aren't connected to any valid faces
-    
-    plane_normal = edge_vector x connection_vector
-    vertex_normal = plane_normal x edge_vector
-    """
-    vertices = [vertex for vertex, normal in vertex_normals.items() if not \
-        normal]
-    
-    if vertices:
-        # edge vectors connected to vertices
-        edge_vectors = dict([[vertex, []] for vertex in vertices])
-        for edge in edges:
-            for v in edge.key:
-                if v in edge_vectors:
-                    edge_vector = mesh.vertices[edge.key[0]].co - \
-                        mesh.vertices[edge.key[1]].co
-                    if edge_vector.length < 1e-4:
-                        # zero-length edge, vertices at same location
-                        continue
-                    edge_vectors[v].append(edge_vector)
-    
-        # connection vectors between vertices of both loops
-        connection_vectors = dict([[vertex, []] for vertex in vertices])
-        connections = dict([[vertex, []] for vertex in vertices])
-        for v1, v2 in lines:
-            if v1 in connection_vectors or v2 in connection_vectors:
-                new_vector = mesh.vertices[v1].co - mesh.vertices[v2].co
-                if new_vector.length < 1e-4:
-                    # zero-length connection vector,
-                    # vertices in different loops at same location
-                    continue
-                if v1 in connection_vectors:
-                    connection_vectors[v1].append(new_vector)
-                    connections[v1].append(v2)
-                if v2 in connection_vectors:
-                    connection_vectors[v2].append(new_vector)
-                    connections[v2].append(v1)
-        connection_vectors = average_vector_dictionary(connection_vectors)
-        connection_vectors = dict([[vertex, vector[0]] if vector else \
-            [vertex, []] for vertex, vector in connection_vectors.items()])
-        
-        for vertex, values in edge_vectors.items():
-            # vertex normal doesn't matter, just assign a random vector to it
-            if not connection_vectors[vertex]:
-                vertex_normals[vertex] = [mathutils.Vector((1, 0, 0))]
-                continue
-            
-            # calculate to what location the vertex is connected, 
-            # used to determine what way to flip the normal
-            connected_center = mathutils.Vector()
-            for v in connections[vertex]:
-                connected_center += mesh.vertices[v].co
-            if len(connections[vertex]) > 1:
-                connected_center /= len(connections[vertex])
-            if len(connections[vertex]) == 0:
-                # shouldn't be possible, but better safe than sorry
-                vertex_normals[vertex] = [mathutils.Vector((1, 0, 0))]
-                continue
-            
-            # can't do proper calculations, because of zero-length vector
-            if not values:
-                if (connected_center - (mesh.vertices[vertex].co + \
-                connection_vectors[vertex])).length < (connected_center - \
-                (mesh.vertices[vertex].co - connection_vectors[vertex])).\
-                length:
-                    connection_vectors[vertex].negate()
-                vertex_normals[vertex] = [connection_vectors[vertex].\
-                    normalized()]
-                continue
-            
-            # calculate vertex normals using edge-vectors,
-            # connection-vectors and the derived plane normal
-            for edge_vector in values:
-                plane_normal = edge_vector.cross(connection_vectors[vertex])
-                vertex_normal = edge_vector.cross(plane_normal)
-                vertex_normal.length = 0.1
-                if (connected_center - (mesh.vertices[vertex].co + \
-                vertex_normal)).length < (connected_center - \
-                (mesh.vertices[vertex].co - vertex_normal)).length:
-                # make normal face the correct way
-                    vertex_normal.negate()
-                vertex_normal.normalize()
-                vertex_normals[vertex].append(vertex_normal)
-    
-    # average virtual vertex normals, based on all edges it's connected to
-    vertex_normals = average_vector_dictionary(vertex_normals)
-    vertex_normals = dict([[vertex, vector[0]] for vertex, vector in \
-        vertex_normals.items()])
-    
-    return(vertex_normals)
-
-
-# add vertices to mesh
-def bridge_create_vertices(mesh, vertices):
-    start_index = len(mesh.vertices)
-    mesh.vertices.add(len(vertices))
-    for i in range(len(vertices)):
-        mesh.vertices[start_index + i].co = vertices[i]
-
-
-# add faces to mesh
-def bridge_create_faces(mesh, faces, twist):
-    # have the normal point the correct way
-    if twist < 0:
-        [face.reverse() for face in faces]
-        faces = [face[2:]+face[:2] if face[0]==face[1] else face for \
-            face in faces]
-    
-    # eekadoodle prevention
-    for i in range(len(faces)):
-        if not faces[i][-1]:
-            if faces[i][0] == faces[i][-1]:
-                faces[i] = [faces[i][1], faces[i][2], faces[i][3], faces[i][1]]
-            else:
-                faces[i] = [faces[i][-1]] + faces[i][:-1]
-    
-    start_faces = len(mesh.tessfaces)
-    mesh.tessfaces.add(len(faces))
-    for i in range(len(faces)):
-        mesh.tessfaces[start_faces + i].vertices_raw = faces[i]
-    mesh.update(calc_edges = True) # calc_edges prevents memory-corruption
-
-
-# calculate input loops
-def bridge_get_input(mesh):
-    # create list of internal edges, which should be skipped
-    eks_of_selected_faces = [item for sublist in [face.edge_keys for face \
-        in mesh.tessfaces if face.select and not face.hide] for item in sublist]
-    edge_count = {}
-    for ek in eks_of_selected_faces:
-        if ek in edge_count:
-            edge_count[ek] += 1
-        else:
-            edge_count[ek] = 1
-    internal_edges = [ek for ek in edge_count if edge_count[ek] > 1]
-    
-    # sort correct edges into loops
-    selected_edges = [edge.key for edge in mesh.edges if edge.select \
-        and not edge.hide and edge.key not in internal_edges]
-    loops = get_connected_selections(selected_edges)
-    
-    return(loops)
-
-
-# return values needed by the bridge operator
-def bridge_initialise(mesh, interpolation):
-    if interpolation == 'cubic':
-        # dict with edge-key as key and list of connected valid faces as value
-        face_blacklist = [face.index for face in mesh.tessfaces if face.select or \
-            face.hide]
-        edge_faces = dict([[edge.key, []] for edge in mesh.edges if not \
-            edge.hide])
-        for face in mesh.tessfaces:
-            if face.index in face_blacklist:
-                continue
-            for key in face.edge_keys:
-                edge_faces[key].append(face)
-        # dictionary with the edge-key as key and edge as value
-        edgekey_to_edge = dict([[edge.key, edge] for edge in mesh.edges if \
-            edge.select and not edge.hide])
-    else:
-        edge_faces = False
-        edgekey_to_edge = False
-    
-    # selected faces input
-    old_selected_faces = [face.index for face in mesh.tessfaces if face.select \
-        and not face.hide]
-    
-    # find out if faces created by bridging should be smoothed
-    smooth = False
-    if mesh.tessfaces:
-        if sum([face.use_smooth for face in mesh.tessfaces])/len(mesh.tessfaces) \
-        >= 0.5:
-            smooth = True
-    
-    return(edge_faces, edgekey_to_edge, old_selected_faces, smooth)
-
-
-# return a string with the input method
-def bridge_input_method(loft, loft_loop):
-    method = ""
-    if loft:
-        if loft_loop:
-            method = "Loft loop"
-        else:
-            method = "Loft no-loop"
-    else:
-        method = "Bridge"
-    
-    return(method)
-
-
-# match up loops in pairs, used for multi-input bridging
-def bridge_match_loops(mesh, loops):
-    # calculate average loop normals and centers
-    normals = []
-    centers = []
-    for vertices, circular in loops:
-        normal = mathutils.Vector()
-        center = mathutils.Vector()
-        for vertex in vertices:
-            normal += mesh.vertices[vertex].normal
-            center += mesh.vertices[vertex].co
-        normals.append(normal / len(vertices) / 10)
-        centers.append(center / len(vertices))
-    
-    # possible matches if loop normals are faced towards the center
-    # of the other loop
-    matches = dict([[i, []] for i in range(len(loops))])
-    matches_amount = 0
-    for i in range(len(loops) + 1):
-        for j in range(i+1, len(loops)):
-            if (centers[i] - centers[j]).length > (centers[i] - (centers[j] \
-            + normals[j])).length and (centers[j] - centers[i]).length > \
-            (centers[j] - (centers[i] + normals[i])).length:
-                matches_amount += 1
-                matches[i].append([(centers[i] - centers[j]).length, i, j])
-                matches[j].append([(centers[i] - centers[j]).length, j, i])
-    # if no loops face each other, just make matches between all the loops
-    if matches_amount == 0:
-        for i in range(len(loops) + 1):
-            for j in range(i+1, len(loops)):
-                matches[i].append([(centers[i] - centers[j]).length, i, j])
-                matches[j].append([(centers[i] - centers[j]).length, j, i])
-    for key, value in matches.items():
-        value.sort()
-    
-    # matches based on distance between centers and number of vertices in loops
-    new_order = []
-    for loop_index in range(len(loops)):
-        if loop_index in new_order:
-            continue
-        loop_matches = matches[loop_index]
-        if not loop_matches:
-            continue
-        shortest_distance = loop_matches[0][0]
-        shortest_distance *= 1.1
-        loop_matches = [[abs(len(loops[loop_index][0]) - \
-            len(loops[loop[2]][0])), loop[0], loop[1], loop[2]] for loop in \
-            loop_matches if loop[0] < shortest_distance]
-        loop_matches.sort()
-        for match in loop_matches:
-            if match[3] not in new_order:
-                new_order += [loop_index, match[3]]
-                break
-    
-    # reorder loops based on matches
-    if len(new_order) >= 2:
-        loops = [loops[i] for i in new_order]
-    
-    return(loops)
-
-
-# have normals of selection face outside
-def bridge_recalculate_normals():
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.mesh.normals_make_consistent()
-
-
-# remove old_selected_faces
-def bridge_remove_internal_faces(mesh, old_selected_faces):
-    select_mode = [i for i in bpy.context.tool_settings.mesh_select_mode]
-    bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-    
-    # hack to keep track of the current selection
-    for edge in mesh.edges:
-        if edge.select and not edge.hide:
-            edge.bevel_weight = (edge.bevel_weight/3) + 0.2
-        else:
-            edge.bevel_weight = (edge.bevel_weight/3) + 0.6
-    
-    # remove faces
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.mesh.select_all(action = 'DESELECT')
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    for face in old_selected_faces:
-        mesh.tessfaces[face].select = True
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.mesh.delete(type = 'FACE')
-    
-    # restore old selection, using hack
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    bpy.context.tool_settings.mesh_select_mode = [False, True, False]
-    for edge in mesh.edges:
-        if edge.bevel_weight < 0.6:
-            edge.bevel_weight = (edge.bevel_weight-0.2) * 3
-            edge.select = True
-        else:
-            edge.bevel_weight = (edge.bevel_weight-0.6) * 3
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    bpy.context.tool_settings.mesh_select_mode = select_mode
-
-
-# update list of internal faces that are flagged for removal
-def bridge_save_unused_faces(mesh, old_selected_faces, loops):
-    # key: vertex index, value: lists of selected faces using it
-    vertex_to_face = dict([[i, []] for i in range(len(mesh.vertices))])
-    [[vertex_to_face[vertex_index].append(face) for vertex_index in \
-        mesh.tessfaces[face].vertices] for face in old_selected_faces]
-    
-    # group selected faces that are connected
-    groups = []
-    grouped_faces = []
-    for face in old_selected_faces:
-        if face in grouped_faces:
-            continue
-        grouped_faces.append(face)
-        group = [face]
-        new_faces = [face]
-        while new_faces:
-            grow_face = new_faces[0]
-            for vertex in mesh.tessfaces[grow_face].vertices:
-                vertex_face_group = [face for face in vertex_to_face[vertex] \
-                    if face not in grouped_faces]
-                new_faces += vertex_face_group
-                grouped_faces += vertex_face_group
-                group += vertex_face_group
-            new_faces.pop(0)
-        groups.append(group)
-    
-    # key: vertex index, value: True/False (is it in a loop that is used)
-    used_vertices = dict([[i, 0] for i in range(len(mesh.vertices))])
-    for loop in loops:
-        for vertex in loop[0]:
-            used_vertices[vertex] = True
-    
-    # check if group is bridged, if not remove faces from internal faces list
-    for group in groups:
-        used = False
-        for face in group:
-            if used:
-                break
-            for vertex in mesh.tessfaces[face].vertices:
-                if used_vertices[vertex]:
-                    used = True
-                    break
-        if not used:
-            for face in group:
-                old_selected_faces.remove(face)
-
-
-# add the newly created faces to the selection
-def bridge_select_new_faces(mesh, amount, smooth):
-    select_mode = [i for i in bpy.context.tool_settings.mesh_select_mode]
-    bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-    for i in range(amount):
-        mesh.tessfaces[-(i+1)].select = True
-        mesh.tessfaces[-(i+1)].use_smooth = smooth
-    bpy.ops.object.mode_set(mode = 'EDIT')
-    bpy.ops.object.mode_set(mode = 'OBJECT')
-    bpy.context.tool_settings.mesh_select_mode = select_mode
-
-
-# sort loops, so they are connected in the correct order when lofting
-def bridge_sort_loops(mesh, loops, loft_loop):
-    # simplify loops to single points, and prepare for pathfinding
-    x, y, z = [[sum([mesh.vertices[i].co[j] for i in loop[0]]) / \
-        len(loop[0]) for loop in loops] for j in range(3)]
-    nodes = [mathutils.Vector((x[i], y[i], z[i])) for i in range(len(loops))]
-    
-    active_node = 0
-    open = [i for i in range(1, len(loops))]
-    path = [[0,0]]
-    # connect node to path, that is shortest to active_node
-    while len(open) > 0:
-        distances = [(nodes[active_node] - nodes[i]).length for i in open]
-        active_node = open[distances.index(min(distances))]
-        open.remove(active_node)
-        path.append([active_node, min(distances)])
-    # check if we didn't start in the middle of the path
-    for i in range(2, len(path)):
-        if (nodes[path[i][0]]-nodes[0]).length < path[i][1]:
-            temp = path[:i]
-            path.reverse()
-            path = path[:-i] + temp
-            break
-    
-    # reorder loops
-    loops = [loops[i[0]] for i in path]
-    # if requested, duplicate first loop at last position, so loft can loop
-    if loft_loop:
-        loops = loops + [loops[0]]
-    
-    return(loops)
-
-
-##########################################
-####### Circle functions #################
-##########################################
-
-# convert 3d coordinates to 2d coordinates on plane
-def circle_3d_to_2d(mesh_mod, loop, com, normal):
-    # project vertices onto the plane
-    verts = [mesh_mod.vertices[v] for v in loop[0]]
-    verts_projected = [[v.co - (v.co - com).dot(normal) * normal, v.index]
-                       for v in verts]
-
-    # calculate two vectors (p and q) along the plane
-    m = mathutils.Vector((normal[0] + 1.0, normal[1], normal[2]))
-    p = m - (m.dot(normal) * normal)
-    if p.dot(p) == 0.0:
-        m = mathutils.Vector((normal[0], normal[1] + 1.0, normal[2]))
-        p = m - (m.dot(normal) * normal)
-    q = p.cross(normal)
-    
-    # change to 2d coordinates using perpendicular projection
-    locs_2d = []
-    for loc, vert in verts_projected:
-        vloc = loc - com
-        x = p.dot(vloc) / p.dot(p)
-        y = q.dot(vloc) / q.dot(q)
-        locs_2d.append([x, y, vert])
-    
-    return(locs_2d, p, q)
-
-
-# calculate a best-fit circle to the 2d locations on the plane
-def circle_calculate_best_fit(locs_2d):
-    # initial guess
-    x0 = 0.0
-    y0 = 0.0
-    r = 1.0
-    
-    # calculate center and radius (non-linear least squares solution)
-    for iter in range(500):
-        jmat = []
-        k = []
-        for v in locs_2d:
-            d = (v[0]**2-2.0*x0*v[0]+v[1]**2-2.0*y0*v[1]+x0**2+y0**2)**0.5
-            jmat.append([(x0-v[0])/d, (y0-v[1])/d, -1.0])
-            k.append(-(((v[0]-x0)**2+(v[1]-y0)**2)**0.5-r))
-        jmat2 = mathutils.Matrix(((0.0, 0.0, 0.0),
-                                  (0.0, 0.0, 0.0),
-                                  (0.0, 0.0, 0.0),
-                                  ))
-        k2 = mathutils.Vector((0.0, 0.0, 0.0))
-        for i in range(len(jmat)):
-            k2 += mathutils.Vector(jmat[i])*k[i]
-            jmat2[0][0] += jmat[i][0]**2
-            jmat2[1][0] += jmat[i][0]*jmat[i][1]
-            jmat2[2][0] += jmat[i][0]*jmat[i][2]
-            jmat2[1][1] += jmat[i][1]**2
-            jmat2[2][1] += jmat[i][1]*jmat[i][2]
-            jmat2[2][2] += jmat[i][2]**2
-        jmat2[0][1] = jmat2[1][0]
-        jmat2[0][2] = jmat2[2][0]
-        jmat2[1][2] = jmat2[2][1]
-        try:
-            jmat2.invert()
-        except:
-            pass
-        dx0, dy0, dr = jmat2 * k2
-        x0 += dx0
-        y0 += dy0
-        r += dr
-        # stop iterating if we're close enough to optimal solution
-        if abs(dx0)<1e-6 and abs(dy0)<1e-6 and abs(dr)<1e-6:
-            break
-    
-    # return center of circle and radius
-    return(x0, y0, r)
-
-
-# calculate circle so no vertices have to be moved away from the center
-def circle_calculate_min_fit(locs_2d):
-    # center of circle
-    x0 = (min([i[0] for i in locs_2d])+max([i[0] for i in locs_2d]))/2.0
-    y0 = (min([i[1] for i in locs_2d])+max([i[1] for i in locs_2d]))/2.0
-    center = mathutils.Vector([x0, y0])
-    # radius of circle
-    r = min([(mathutils.Vector([i[0], i[1]])-center).length for i in locs_2d])
-    
-    # return center of circle and radius
-    return(x0, y0, r)
-
-
-# calculate the new locations of the vertices that need to be moved
-def circle_calculate_verts(flatten, mesh_mod, locs_2d, com, p, q, normal):
-    # changing 2d coordinates back to 3d coordinates
-    locs_3d = []
-    for loc in locs_2d:
-        locs_3d.append([loc[2], loc[0]*p + loc[1]*q + com])
-    
-    if flatten: # flat circle
-        return(locs_3d)
-    
-    else: # project the locations on the existing mesh
-        vert_edges = dict_vert_edges(mesh_mod)
-        vert_faces = dict_vert_faces(mesh_mod)
-        faces = [f for f in mesh_mod.tessfaces if not f.hide]
-        rays = [normal, -normal]
-        new_locs = []
-        for loc in locs_3d:
-            projection = False
-            if mesh_mod.vertices[loc[0]].co == loc[1]: # vertex hasn't moved
-                projection = loc[1]
-            else:
-                dif = normal.angle(loc[1]-mesh_mod.vertices[loc[0]].co)
-                if -1e-6 < dif < 1e-6 or math.pi-1e-6 < dif < math.pi+1e-6:
-                    # original location is already along projection normal
-                    projection = mesh_mod.vertices[loc[0]].co
-                else:
-                    # quick search through adjacent faces
-                    for face in vert_faces[loc[0]]:
-                        verts = [mesh_mod.vertices[v].co for v in \
-                            mesh_mod.tessfaces[face].vertices]
-                        if len(verts) == 3: # triangle
-                            v1, v2, v3 = verts
-                            v4 = False
-                        else: # quad
-                            v1, v2, v3, v4 = verts
-                        for ray in rays:
-                            intersect = mathutils.geometry.\
-                            intersect_ray_tri(v1, v2, v3, ray, loc[1])
-                            if intersect:
-                                projection = intersect
-                                break
-                            elif v4:
-                                intersect = mathutils.geometry.\
-                                intersect_ray_tri(v1, v3, v4, ray, loc[1])
-                                if intersect:
-                                    projection = intersect
-                                    break
-                        if projection:
-                            break
-            if not projection:
-                # check if projection is on adjacent edges
-                for edgekey in vert_edges[loc[0]]:
-                    line1 = mesh_mod.vertices[edgekey[0]].co
-                    line2 = mesh_mod.vertices[edgekey[1]].co
-                    intersect, dist = mathutils.geometry.intersect_point_line(\
-                        loc[1], line1, line2)
-                    if 1e-6 < dist < 1 - 1e-6:
-                        projection = intersect
-                        break
-            if not projection:
-                # full search through the entire mesh
-                hits = []
-                for face in faces:
-                    verts = [mesh_mod.vertices[v].co for v in face.vertices]
-                    if len(verts) == 3: # triangle
-                        v1, v2, v3 = verts
-                        v4 = False
-                    else: # quad
-                        v1, v2, v3, v4 = verts
-                    for ray in rays:
-                        intersect = mathutils.geometry.intersect_ray_tri(\
-                            v1, v2, v3, ray, loc[1])
-                        if intersect:
-                            hits.append([(loc[1] - intersect).length,
-                                intersect])
-                            break
-                        elif v4:
-                            intersect = mathutils.geometry.intersect_ray_tri(\
-                                v1, v3, v4, ray, loc[1])
-                            if intersect:
-                                hits.append([(loc[1] - intersect).length,
-                                    intersect])
-                                break
-                if len(hits) >= 1:
-                    # if more than 1 hit with mesh, closest hit is new loc
-                    hits.sort()
-                    projection = hits[0][1]
-            if not projection:
-                # nothing to project on, remain at flat location
-                projection = loc[1]
-            new_locs.append([loc[0], projection])
-        
-        # return new positions of projected circle
-        return(new_locs)
-
-
-# check loops and only return valid ones
-def circle_check_loops(single_loops, loops, mapping, mesh_mod):
-    valid_single_loops = {}
-    valid_loops = []
-    for i, [loop, circular] in enumerate(loops):
-        # loop needs to have at least 3 vertices
-        if len(loop) < 3:
-            continue
-        # loop needs at least 1 vertex in the original, non-mirrored mesh
-        if mapping:
-            all_virtual = True
-            for vert in loop:
-                if mapping[vert] > -1:
-                    all_virtual = False
-                    break
-            if all_virtual:
-                continue
-        # loop has to be non-collinear
-        collinear = True
-        loc0 = mathutils.Vector(mesh_mod.vertices[loop[0]].co[:])
-        loc1 = mathutils.Vector(mesh_mod.vertices[loop[1]].co[:])
-        for v in loop[2:]:
-            locn = mathutils.Vector(mesh_mod.vertices[v].co[:])
-            if loc0 == loc1 or loc1 == locn:
-                loc0 = loc1
-                loc1 = locn
-                continue
-            d1 = loc1-loc0
-            d2 = locn-loc1
-            if -1e-6 < d1.angle(d2, 0) < 1e-6:
-                loc0 = loc1
-                loc1 = locn
-                continue
-            collinear = False
-            break
-        if collinear:
-            continue
-        # passed all tests, loop is valid
-        valid_loops.append([loop, circular])
-        valid_single_loops[len(valid_loops)-1] = single_loops[i]
-    
-    return(valid_single_loops, valid_loops)
-
-
-# calculate the location of single input vertices that need to be flattened
-def circle_flatten_singles(mesh_mod, com, p, q, normal, single_loop):
-    new_locs = []
-    for vert in single_loop:
-        loc = mathutils.Vector(mesh_mod.vertices[vert].co[:])
-        new_locs.append([vert,  loc - (loc-com).dot(normal)*normal])
-    
-    return(new_locs)
-
-
-# calculate input loops
-def circle_get_input(object, mesh, scene):
-    # get mesh with modifiers applied
-    derived, mesh_mod = get_derived_mesh(object, mesh, scene)
-    
-    # create list of edge-keys based on selection state
-    faces = False
-    for face in mesh.tessfaces:
-        if face.select and not face.hide:
-            faces = True
-            break
-    if faces:
-        # get selected, non-hidden , non-internal edge-keys
-        eks_selected = [key for keys in [face.edge_keys for face in \
-            mesh_mod.tessfaces if face.select and not face.hide] for key in keys]
-        edge_count = {}
-        for ek in eks_selected:
-            if ek in edge_count:
-                edge_count[ek] += 1
-            else:
-                edge_count[ek] = 1
-        edge_keys = [edge.key for edge in mesh_mod.edges if edge.select \
-            and not edge.hide and edge_count.get(edge.key, 1)==1]
-    else:
-        # no faces, so no internal edges either
-        edge_keys = [edge.key for edge in mesh_mod.edges if edge.select \
-            and not edge.hide]
-    
-    # add edge-keys around single vertices
-    verts_connected = dict([[vert, 1] for edge in [edge for edge in \
-        mesh_mod.edges if edge.select and not edge.hide] for vert in edge.key])
-    single_vertices = [vert.index for vert in mesh_mod.vertices if \
-        vert.select and not vert.hide and not \
-        verts_connected.get(vert.index, False)]
-    
-    if single_vertices and len(mesh.tessfaces)>0:
-        vert_to_single = dict([[v.index, []] for v in mesh_mod.vertices \
-            if not v.hide])
-        for face in [face for face in mesh_mod.tessfaces if not face.select \
-        and not face.hide]:
-            for vert in face.vertices:
-                if vert in single_vertices:
-                    for ek in face.edge_keys:
-                        if not vert in ek:
-                            edge_keys.append(ek)
-                            if vert not in vert_to_single[ek[0]]:
-                                vert_to_single[ek[0]].append(vert)
-                            if vert not in vert_to_single[ek[1]]:
-                                vert_to_single[ek[1]].append(vert)
-                    break
-    
-    # sort edge-keys into loops
-    loops = get_connected_selections(edge_keys)
-    
-    # find out to which loops the single vertices belong
-    single_loops = dict([[i, []] for i in range(len(loops))])
-    if single_vertices and len(mesh.tessfaces)>0:
-        for i, [loop, circular] in enumerate(loops):
-            for vert in loop:
-                if vert_to_single[vert]:
-                    for single in vert_to_single[vert]:
-                        if single not in single_loops[i]:
-                            single_loops[i].append(single)
-    
-    return(derived, mesh_mod, single_vertices, single_loops, loops)
-
-
-# recalculate positions based on the influence of the circle shape
-def circle_influence_locs(locs_2d, new_locs_2d, influence):
-    for i in range(len(locs_2d)):
-        oldx, oldy, j = locs_2d[i]
-        newx, newy, k = new_locs_2d[i]
-        altx = newx*(influence/100)+ oldx*((100-influence)/100)
-        alty = newy*(influence/100)+ oldy*((100-influence)/100)
-        locs_2d[i] = [altx, alty, j]
-    
-    return(locs_2d)
-
-
-# project 2d locations on circle, respecting distance relations between verts
-def circle_project_non_regular(locs_2d, x0, y0, r):
-    for i in range(len(locs_2d)):
-        x, y, j = locs_2d[i]
-        loc = mathutils.Vector([x-x0, y-y0])
-        loc.length = r
-        locs_2d[i] = [loc[0], loc[1], j]
-    
-    return(locs_2d)
-
-
-# project 2d locations on circle, with equal distance between all vertices
-def circle_project_regular(locs_2d, x0, y0, r):
-    # find offset angle and circling direction
-    x, y, i = locs_2d[0]
-    loc = mathutils.Vector([x-x0, y-y0])
-    loc.length = r
-    offset_angle = loc.angle(mathutils.Vector([1.0, 0.0]), 0.0)
-    loca = mathutils.Vector([x-x0, y-y0, 0.0])
-    if loc[1] < -1e-6:
-        offset_angle *= -1
-    x, y, j = locs_2d[1]
-    locb = mathutils.Vector([x-x0, y-y0, 0.0])
-    if loca.cross(locb)[2] >= 0:
-        ccw = 1
-    else:
-        ccw = -1
-    # distribute vertices along the circle
-    for i in range(len(locs_2d)):
-        t = offset_angle + ccw * (i / len(locs_2d) * 2 * math.pi)
-        x = math.cos(t) * r
-        y = math.sin(t) * r
-        locs_2d[i] = [x, y, locs_2d[i][2]]
-    
-    return(locs_2d)
-
-
-# shift loop, so the first vertex is closest to the center
-def circle_shift_loop(mesh_mod, loop, com):
-    verts, circular = loop
-    distances = [[(mesh_mod.vertices[vert].co - com).length, i] \
-        for i, vert in enumerate(verts)]
-    distances.sort()
-    shift = distances[0][1]
-    loop = [verts[shift:] + verts[:shift], circular]
-    
-    return(loop)
-
-
-##########################################
-####### Curve functions ##################
-##########################################
-
-# create lists with knots and points, all correctly sorted
-def curve_calculate_knots(loop, verts_selected):
-    knots = [v for v in loop[0] if v in verts_selected]
-    points = loop[0][:]
-    # circular loop, potential for weird splines
-    if loop[1]:
-        offset = int(len(loop[0]) / 4)
-        kpos = []
-        for k in knots:
-            kpos.append(loop[0].index(k))
-        kdif = []
-        for i in range(len(kpos) - 1):
-            kdif.append(kpos[i+1] - kpos[i])
-        kdif.append(len(loop[0]) - kpos[-1] + kpos[0])
-        kadd = []
-        for k in kdif:
-            if k > 2 * offset:
-                kadd.append([kdif.index(k), True])
-            # next 2 lines are optional, they insert
-            # an extra control point in small gaps
-            #elif k > offset:
-            #   kadd.append([kdif.index(k), False])
-        kins = []
-        krot = False
-        for k in kadd: # extra knots to be added
-            if k[1]: # big gap (break circular spline)
-                kpos = loop[0].index(knots[k[0]]) + offset
-                if kpos > len(loop[0]) - 1:
-                    kpos -= len(loop[0])
-                kins.append([knots[k[0]], loop[0][kpos]])
-                kpos2 = k[0] + 1
-                if kpos2 > len(knots)-1:
-                    kpos2 -= len(knots)
-                kpos2 = loop[0].index(knots[kpos2]) - offset
-                if kpos2 < 0:
-                    kpos2 += len(loop[0])
-                kins.append([loop[0][kpos], loop[0][kpos2]])
-                krot = loop[0][kpos2]
-            else: # small gap (keep circular spline)
-                k1 = loop[0].index(knots[k[0]])
-                k2 = k[0] + 1
-                if k2 > len(knots)-1:
-                    k2 -= len(knots)
-                k2 = loop[0].index(knots[k2])
-                if k2 < k1:
-                    dif = len(loop[0]) - 1 - k1 + k2
-                else:
-                    dif = k2 - k1
-                kn = k1 + int(dif/2)
-                if kn > len(loop[0]) - 1:
-                    kn -= len(loop[0])
-                kins.append([loop[0][k1], loop[0][kn]])
-        for j in kins: # insert new knots
-            knots.insert(knots.index(j[0]) + 1, j[1])
-        if not krot: # circular loop
-            knots.append(knots[0])
-            points = loop[0][loop[0].index(knots[0]):]
-            points += loop[0][0:loop[0].index(knots[0]) + 1]
-        else: # non-circular loop (broken by script)
-            krot = knots.index(krot)
-            knots = knots[krot:] + knots[0:krot]
-            if loop[0].index(knots[0]) > loop[0].index(knots[-1]):
-                points = loop[0][loop[0].index(knots[0]):]
-                points += loop[0][0:loop[0].index(knots[-1])+1]
-            else:
-                points = loop[0][loop[0].index(knots[0]):\
-                    loop[0].index(knots[-1]) + 1]
-    # non-circular loop, add first and last point as knots
-    else:
-        if loop[0][0] not in knots:
-            knots.insert(0, loop[0][0])
-        if loop[0][-1] not in knots:
-            knots.append(loop[0][-1])
-    
-    return(knots, points)
-
-
-# calculate relative positions compared to first knot
-def curve_calculate_t(mesh_mod, knots, points, pknots, regular, circular):
-    tpoints = []
-    loc_prev = False
-    len_total = 0
-    
-    for p in points:
-        if p in knots:
-            loc = pknots[knots.index(p)] # use projected knot location
-        else:
-            loc = mathutils.Vector(mesh_mod.vertices[p].co[:])
-        if not loc_prev:
-            loc_prev = loc
-        len_total += (loc-loc_prev).length
-        tpoints.append(len_total)
-        loc_prev = loc
-    tknots = []
-    for p in points:
-        if p in knots:
-            tknots.append(tpoints[points.index(p)])
-    if circular:
-        tknots[-1] = tpoints[-1]
-    
-    # regular option
-    if regular:
-        tpoints_average = tpoints[-1] / (len(tpoints) - 1)
-        for i in range(1, len(tpoints) - 1):
-            tpoints[i] = i * tpoints_average
-        for i in range(len(knots)):
-            tknots[i] = tpoints[points.index(knots[i])]
-        if circular:
-            tknots[-1] = tpoints[-1]
-    
-    
-    return(tknots, tpoints)
-
-
-# change the location of non-selected points to their place on the spline
-def curve_calculate_vertices(mesh_mod, knots, tknots, points, tpoints, splines,
-interpolation, restriction):
-    newlocs = {}
-    move = []
-    
-    for p in points:
-        if p in knots:
-            continue
-        m = tpoints[points.index(p)]
-        if m in tknots:
-            n = tknots.index(m)
-        else:
-            t = tknots[:]
-            t.append(m)
-            t.sort()
-            n = t.index(m) - 1
-        if n > len(splines) - 1:
-            n = len(splines) - 1
-        elif n < 0:
-            n = 0
-        
-        if interpolation == 'cubic':
-            ax, bx, cx, dx, tx = splines[n][0]
-            x = ax + bx*(m-tx) + cx*(m-tx)**2 + dx*(m-tx)**3
-            ay, by, cy, dy, ty = splines[n][1]
-            y = ay + by*(m-ty) + cy*(m-ty)**2 + dy*(m-ty)**3
-            az, bz, cz, dz, tz = splines[n][2]
-            z = az + bz*(m-tz) + cz*(m-tz)**2 + dz*(m-tz)**3
-            newloc = mathutils.Vector([x,y,z])
-        else: # interpolation == 'linear'
-            a, d, t, u = splines[n]
-            newloc = ((m-t)/u)*d + a
-
-        if restriction != 'none': # vertex movement is restricted
-            newlocs[p] = newloc
-        else: # set the vertex to its new location
-            move.append([p, newloc])
-        
-    if restriction != 'none': # vertex movement is restricted
-        for p in points:
-            if p in newlocs:
-                newloc = newlocs[p]
-            else:
-                move.append([p, mesh_mod.vertices[p].co])
-                continue
-            oldloc = mesh_mod.vertices[p].co
-            normal = mesh_mod.vertices[p].normal
-            dloc = newloc - oldloc
-            if dloc.length < 1e-6:
-                move.append([p, newloc])
-            elif restriction == 'extrude': # only extrusions
-                if dloc.angle(normal, 0) < 0.5 * math.pi + 1e-6:
-                    move.append([p, newloc])
-            else: # restriction == 'indent' only indentations
-                if dloc.angle(normal) > 0.5 * math.pi - 1e-6:
-                    move.append([p, newloc])
-
-    return(move)
-
-
-# trim loops to part between first and last selected vertices (including)
-def curve_cut_boundaries(mesh_mod, loops):
-    cut_loops = []
-    for loop, circular in loops:
-        if circular:
-            # don't cut
-            cut_loops.append([loop, circular])
-            continue
-        selected = [mesh_mod.vertices[v].select for v in loop]
-        first = selected.index(True)
-        selected.reverse()
-        last = -selected.index(True)
-        if last == 0:
-            cut_loops.append([loop[first:], circular])
-        else:
-            cut_loops.append([loop[first:last], circular])
-    
-    return(cut_loops)
-
-
-# calculate input loops
-def curve_get_input(object, mesh, boundaries, scene):
-    # get mesh with modifiers applied
-    derived, mesh_mod = get_derived_mesh(object, mesh, scene)
-    
-    # vertices that still need a loop to run through it
-    verts_unsorted = [v.index for v in mesh_mod.vertices if \
-        v.select and not v.hide]
-    # necessary dictionaries
-    vert_edges = dict_vert_edges(mesh_mod)
-    edge_faces = dict_edge_faces(mesh_mod)
-    correct_loops = []
-    
-    # find loops through each selected vertex
-    while len(verts_unsorted) > 0:
-        loops = curve_vertex_loops(mesh_mod, verts_unsorted[0], vert_edges,
-            edge_faces)
-        verts_unsorted.pop(0)
-        
-        # check if loop is fully selected
-        search_perpendicular = False
-        i = -1
-        for loop, circular in loops:
-            i += 1
-            selected = [v for v in loop if mesh_mod.vertices[v].select]
-            if len(selected) < 2:
-                # only one selected vertex on loop, don't use
-                loops.pop(i)
-                continue
-            elif len(selected) == len(loop):
-                search_perpendicular = loop
-                break
-        # entire loop is selected, find perpendicular loops
-        if search_perpendicular:
-            for vert in loop:
-                if vert in verts_unsorted:
-                    verts_unsorted.remove(vert)
-            perp_loops = curve_perpendicular_loops(mesh_mod, loop,
-                vert_edges, edge_faces)
-            for perp_loop in perp_loops:
-                correct_loops.append(perp_loop)
-        # normal input
-        else:
-            for loop, circular in loops:
-                correct_loops.append([loop, circular])
-    
-    # boundaries option
-    if boundaries:
-        correct_loops = curve_cut_boundaries(mesh_mod, correct_loops)
-    
-    return(derived, mesh_mod, correct_loops)
-
-
-# return all loops that are perpendicular to the given one
-def curve_perpendicular_loops(mesh_mod, start_loop, vert_edges, edge_faces):
-    # find perpendicular loops
-    perp_loops = []
-    for start_vert in start_loop:
-        loops = curve_vertex_loops(mesh_mod, start_vert, vert_edges,
-            edge_faces)
-        for loop, circular in loops:
-            selected = [v for v in loop if mesh_mod.vertices[v].select]
-            if len(selected) == len(loop):
-                continue
-            else:
-                perp_loops.append([loop, circular, loop.index(start_vert)])
-    
-    # trim loops to same lengths
-    shortest = [[len(loop[0]), i] for i, loop in enumerate(perp_loops)\
-        if not loop[1]]
-    if not shortest:
-        # all loops are circular, not trimming
-        return([[loop[0], loop[1]] for loop in perp_loops])
-    else:
-        shortest = min(shortest)
-    shortest_start = perp_loops[shortest[1]][2]
-    before_start = shortest_start
-    after_start = shortest[0] - shortest_start - 1
-    bigger_before = before_start > after_start
-    trimmed_loops = []
-    for loop in perp_loops:
-        # have the loop face the same direction as the shortest one
-        if bigger_before:
-            if loop[2] < len(loop[0]) / 2:
-                loop[0].reverse()
-                loop[2] = len(loop[0]) - loop[2] - 1
-        else:
-            if loop[2] > len(loop[0]) / 2:
-                loop[0].reverse()
-                loop[2] = len(loop[0]) - loop[2] - 1
-        # circular loops can shift, to prevent wrong trimming
-        if loop[1]:
-            shift = shortest_start - loop[2]
-            if loop[2] + shift > 0 and loop[2] + shift < len(loop[0]):
-                loop[0] = loop[0][-shift:] + loop[0][:-shift]
-            loop[2] += shift
-            if loop[2] < 0:
-                loop[2] += len(loop[0])
-            elif loop[2] > len(loop[0]) -1:
-                loop[2] -= len(loop[0])
-        # trim
-        start = max(0, loop[2] - before_start)
-        end = min(len(loop[0]), loop[2] + after_start + 1)
-        trimmed_loops.append([loop[0][start:end], False])
-    
-    return(trimmed_loops)
-
-
-# project knots on non-selected geometry
-def curve_project_knots(mesh_mod, verts_selected, knots, points, circular):
-    # function to project vertex on edge
-    def project(v1, v2, v3):
-        # v1 and v2 are part of a line
-        # v3 is projected onto it
-        v2 -= v1
-        v3 -= v1
-        p = v3.project(v2)
-        return(p + v1)
-    
-    if circular: # project all knots
-        start = 0
-        end = len(knots)
-        pknots = []
-    else: # first and last knot shouldn't be projected
-        start = 1
-        end = -1
-        pknots = [mathutils.Vector(mesh_mod.vertices[knots[0]].co[:])]
-    for knot in knots[start:end]:
-        if knot in verts_selected:
-            knot_left = knot_right = False
-            for i in range(points.index(knot)-1, -1*len(points), -1):
-                if points[i] not in knots:
-                    knot_left = points[i]
-                    break
-            for i in range(points.index(knot)+1, 2*len(points)):
-                if i > len(points) - 1:
-                    i -= len(points)
-                if points[i] not in knots:
-                    knot_right = points[i]
-                    break
-            if knot_left and knot_right and knot_left != knot_right:
-                knot_left = mathutils.Vector(\
-                    mesh_mod.vertices[knot_left].co[:])
-                knot_right = mathutils.Vector(\
-                    mesh_mod.vertices[knot_right].co[:])
-                knot = mathutils.Vector(mesh_mod.vertices[knot].co[:])
-                pknots.append(project(knot_left, knot_right, knot))
-            else:
-                pknots.append(mathutils.Vector(mesh_mod.vertices[knot].co[:]))
-        else: # knot isn't selected, so shouldn't be changed
-            pknots.append(mathutils.Vector(mesh_mod.vertices[knot].co[:]))
-    if not circular:
-        pknots.append(mathutils.Vector(mesh_mod.vertices[knots[-1]].co[:]))
-    
-    return(pknots)
-
-
-# find all loops through a given vertex
-def curve_vertex_loops(mesh_mod, start_vert, vert_edges, edge_faces):
-    edges_used = []
-    loops = []
-        
-    for edge in vert_edges[start_vert]:
-        if edge in edges_used:
-            continue
-        loop = []
-        circular = False
-        for vert in edge:
-            active_faces = edge_faces[edge]
-            new_vert = vert
-            growing = True
-            while growing:
-                growing = False
-                new_edges = vert_edges[new_vert]
-                loop.append(new_vert)
-                if len(loop) > 1:
-                    edges_used.append(tuple(sorted([loop[-1], loop[-2]])))
-                if len(new_edges) < 3 or len(new_edges) > 4:
-                    # pole
-                    break
-                else:
-                    # find next edge
-                    for new_edge in new_edges:
-                        if new_edge in edges_used:
-                            continue
-                        eliminate = False
-                        for new_face in edge_faces[new_edge]:
-                            if new_face in active_faces:
-                                eliminate = True
-                                break
-                        if eliminate:
-                            continue
-                        # found correct new edge
-                        active_faces = edge_faces[new_edge]
-                        v1, v2 = new_edge
-                        if v1 != new_vert:
-                            new_vert = v1
-                        else:
-                            new_vert = v2
-                        if new_vert == loop[0]:
-                            circular = True
-                        else:
-                            growing = True
-                        break
-            if circular:
-                break
-            loop.reverse()
-        loops.append([loop, circular])
-    
-    return(loops)
-
-
-##########################################
-####### Flatten functions ################
-##########################################
-
-# sort input into loops
-def flatten_get_input(mesh):
-    vert_verts = dict_vert_verts([edge.key for edge in mesh.edges \
-        if edge.select and not edge.hide])
-    verts = [v.index for v in mesh.vertices if v.select and not v.hide]
-    
-    # no connected verts, consider all selected verts as a single input
-    if not vert_verts:
-        return([[verts, False]])
-    
-    loops = []
-    while len(verts) > 0:
-        # start of loop
-        loop = [verts[0]]
-        verts.pop(0)
-        if loop[-1] in vert_verts:
-            to_grow = vert_verts[loop[-1]]
-        else:
-            to_grow = []
-        # grow loop
-        while len(to_grow) > 0:
-            new_vert = to_grow[0]
-            to_grow.pop(0)
-            if new_vert in loop:
-                continue
-            loop.append(new_vert)
-            verts.remove(new_vert)
-            to_grow += vert_verts[new_vert]
-        # add loop to loops
-        loops.append([loop, False])
-    
-    return(loops)
-
-
-# calculate position of vertex projections on plane
-def flatten_project(mesh, loop, com, normal):
-    verts = [mesh.vertices[v] for v in loop[0]]
-    verts_projected = [[v.index, mathutils.Vector(v.co[:]) - \
-        (mathutils.Vector(v.co[:])-com).dot(normal)*normal] for v in verts]
-    
-    return(verts_projected)
-
-
-##########################################
-####### Relax functions ##################
-##########################################
-
-# create lists with knots and points, all correctly sorted
-def relax_calculate_knots(loops):
-    all_knots = []
-    all_points = []
-    for loop, circular in loops:
-        knots = [[], []]
-        points = [[], []]
-        if circular:
-            if len(loop)%2 == 1: # odd
-                extend = [False, True, 0, 1, 0, 1]
-            else: # even
-                extend = [True, False, 0, 1, 1, 2]
-        else:
-            if len(loop)%2 == 1: # odd
-                extend = [False, False, 0, 1, 1, 2]
-            else: # even
-                extend = [False, False, 0, 1, 1, 2]
-        for j in range(2):
-            if extend[j]:
-                loop = [loop[-1]] + loop + [loop[0]]
-            for i in range(extend[2+2*j], len(loop), 2):
-                knots[j].append(loop[i])
-            for i in range(extend[3+2*j], len(loop), 2):
-                if loop[i] == loop[-1] and not circular:
-                    continue
-                if len(points[j]) == 0:
-                    points[j].append(loop[i])
-                elif loop[i] != points[j][0]:
-                    points[j].append(loop[i])
-            if circular:
-                if knots[j][0] != knots[j][-1]:
-                    knots[j].append(knots[j][0])
-        if len(points[1]) == 0:
-            knots.pop(1)
-            points.pop(1)
-        for k in knots:
-            all_knots.append(k)
-        for p in points:
-            all_points.append(p)
-    
-    return(all_knots, all_points)
-
-
-# calculate relative positions compared to first knot
-def relax_calculate_t(mesh_mod, knots, points, regular):
-    all_tknots = []
-    all_tpoints = []
-    for i in range(len(knots)):
-        amount = len(knots[i]) + len(points[i])
-        mix  = []
-        for j in range(amount):
-            if j%2 == 0:
-                mix.append([True, knots[i][round(j/2)]])
-            elif j == amount-1:
-                mix.append([True, knots[i][-1]])
-            else:
-                mix.append([False, points[i][int(j/2)]])
-        len_total = 0
-        loc_prev = False
-        tknots = []
-        tpoints = []
-        for m in mix:
-            loc = mathutils.Vector(mesh_mod.vertices[m[1]].co[:])
-            if not loc_prev:
-                loc_prev = loc
-            len_total += (loc - loc_prev).length
-            if m[0]:
-                tknots.append(len_total)
-            else:
-                tpoints.append(len_total)
-            loc_prev = loc
-        if regular:
-            tpoints = []
-            for p in range(len(points[i])):
-                tpoints.append((tknots[p] + tknots[p+1]) / 2)
-        all_tknots.append(tknots)
-        all_tpoints.append(tpoints)
-    
-    return(all_tknots, all_tpoints)
-
-
-# change the location of the points to their place on the spline
-def relax_calculate_verts(mesh_mod, interpolation, tknots, knots, tpoints,
-points, splines):
-    change = []
-    move = []
-    for i in range(len(knots)):
-        for p in points[i]:
-            m = tpoints[i][points[i].index(p)]
-            if m in tknots[i]:
-                n = tknots[i].index(m)
-            else:
-                t = tknots[i][:]
-                t.append(m)
-                t.sort()
-                n = t.index(m)-1
-            if n > len(splines[i]) - 1:
-                n = len(splines[i]) - 1
-            elif n < 0:
-                n = 0
-            
-            if interpolation == 'cubic':
-                ax, bx, cx, dx, tx = splines[i][n][0]
-                x = ax + bx*(m-tx) + cx*(m-tx)**2 + dx*(m-tx)**3
-                ay, by, cy, dy, ty = splines[i][n][1]
-                y = ay + by*(m-ty) + cy*(m-ty)**2 + dy*(m-ty)**3
-                az, bz, cz, dz, tz = splines[i][n][2]
-                z = az + bz*(m-tz) + cz*(m-tz)**2 + dz*(m-tz)**3
-                change.append([p, mathutils.Vector([x,y,z])])
-            else: # interpolation == 'linear'
-                a, d, t, u = splines[i][n]
-                if u == 0:
-                    u = 1e-8
-                change.append([p, ((m-t)/u)*d + a])
-    for c in change:
-        move.append([c[0], (mesh_mod.vertices[c[0]].co + c[1]) / 2])
-    
-    return(move)
-
-
-##########################################
-####### Space functions ##################
-##########################################
-
-# calculate relative positions compared to first knot
-def space_calculate_t(mesh_mod, knots):
-    tknots = []
-    loc_prev = False
-    len_total = 0
-    for k in knots:
-        loc = mathutils.Vector(mesh_mod.vertices[k].co[:])
-        if not loc_prev:
-            loc_prev = loc
-        len_total += (loc - loc_prev).length
-        tknots.append(len_total)
-        loc_prev = loc
-    amount = len(knots)
-    t_per_segment = len_total / (amount - 1)
-    tpoints = [i * t_per_segment for i in range(amount)]
-    
-    return(tknots, tpoints)
-
-
-# change the location of the points to their place on the spline
-def space_calculate_verts(mesh_mod, interpolation, tknots, tpoints, points,
-splines):
-    move = []
-    for p in points:
-        m = tpoints[points.index(p)]
-        if m in tknots:
-            n = tknots.index(m)
-        else:
-            t = tknots[:]
-            t.append(m)
-            t.sort()
-            n = t.index(m) - 1
-        if n > len(splines) - 1:
-            n = len(splines) - 1
-        elif n < 0:
-            n = 0
-        
-        if interpolation == 'cubic':
-            ax, bx, cx, dx, tx = splines[n][0]
-            x = ax + bx*(m-tx) + cx*(m-tx)**2 + dx*(m-tx)**3
-            ay, by, cy, dy, ty = splines[n][1]
-            y = ay + by*(m-ty) + cy*(m-ty)**2 + dy*(m-ty)**3
-            az, bz, cz, dz, tz = splines[n][2]
-            z = az + bz*(m-tz) + cz*(m-tz)**2 + dz*(m-tz)**3
-            move.append([p, mathutils.Vector([x,y,z])])
-        else: # interpolation == 'linear'
-            a, d, t, u = splines[n]
-            move.append([p, ((m-t)/u)*d + a])
-    
-    return(move)
-
-
-##########################################
-####### Operators ########################
-##########################################
-
-# bridge operator
-class Bridge(bpy.types.Operator):
-    bl_idname = 'mesh.looptools_bridge'
-    bl_label = "Bridge / Loft"
-    bl_description = "Bridge two, or loft several, loops of vertices"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    cubic_strength = bpy.props.FloatProperty(name = "Strength",
-        description = "Higher strength results in more fluid curves",
-        default = 1.0,
-        soft_min = -3.0,
-        soft_max = 3.0)
-    interpolation = bpy.props.EnumProperty(name = "Interpolation mode",
-        items = (('cubic', "Cubic", "Gives curved results"),
-            ('linear', "Linear", "Basic, fast, straight interpolation")),
-        description = "Interpolation mode: algorithm used when creating "\
-            "segments",
-        default = 'cubic')
-    loft = bpy.props.BoolProperty(name = "Loft",
-        description = "Loft multiple loops, instead of considering them as "\
-            "a multi-input for bridging",
-        default = False)
-    loft_loop = bpy.props.BoolProperty(name = "Loop",
-        description = "Connect the first and the last loop with each other",
-        default = False)
-    min_width = bpy.props.IntProperty(name = "Minimum width",
-        description = "Segments with an edge smaller than this are merged "\
-            "(compared to base edge)",
-        default = 0,
-        min = 0,
-        max = 100,
-        subtype = 'PERCENTAGE')
-    mode = bpy.props.EnumProperty(name = "Mode",
-        items = (('basic', "Basic", "Fast algorithm"), ('shortest',
-            "Shortest edge", "Slower algorithm with better vertex matching")),
-        description = "Algorithm used for bridging",
-        default = 'shortest')
-    remove_faces = bpy.props.BoolProperty(name = "Remove faces",
-        description = "Remove faces that are internal after bridging",
-        default = True)
-    reverse = bpy.props.BoolProperty(name = "Reverse",
-        description = "Manually override the direction in which the loops "\
-                      "are bridged. Only use if the tool gives the wrong " \
-                      "result",
-        default = False)
-    segments = bpy.props.IntProperty(name = "Segments",
-        description = "Number of segments used to bridge the gap "\
-            "(0 = automatic)",
-        default = 1,
-        min = 0,
-        soft_max = 20)
-    twist = bpy.props.IntProperty(name = "Twist",
-        description = "Twist what vertices are connected to each other",
-        default = 0)
-    
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return (ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-    
-    def draw(self, context):
-        layout = self.layout
-        #layout.prop(self, "mode") # no cases yet where 'basic' mode is needed
-        
-        # top row
-        col_top = layout.column(align=True)
-        row = col_top.row(align=True)
-        col_left = row.column(align=True)
-        col_right = row.column(align=True)
-        col_right.active = self.segments != 1
-        col_left.prop(self, "segments")
-        col_right.prop(self, "min_width", text="")
-        # bottom row
-        bottom_left = col_left.row()
-        bottom_left.active = self.segments != 1
-        bottom_left.prop(self, "interpolation", text="")
-        bottom_right = col_right.row()
-        bottom_right.active = self.interpolation == 'cubic'
-        bottom_right.prop(self, "cubic_strength")
-        # boolean properties
-        col_top.prop(self, "remove_faces")
-        if self.loft:
-            col_top.prop(self, "loft_loop")
-        
-        # override properties
-        col_top.separator()
-        row = layout.row(align = True)
-        row.prop(self, "twist")
-        row.prop(self, "reverse")
-    
-    def invoke(self, context, event):
-        # load custom settings
-        context.window_manager.looptools.bridge_loft = self.loft
-        settings_load(self)
-        return self.execute(context)
-    
-    def execute(self, context):
-        # initialise
-        global_undo, object, mesh = initialise()
-        edge_faces, edgekey_to_edge, old_selected_faces, smooth = \
-            bridge_initialise(mesh, self.interpolation)
-        settings_write(self)
-        
-        # check cache to see if we can save time
-        input_method = bridge_input_method(self.loft, self.loft_loop)
-        cached, single_loops, loops, derived, mapping = cache_read("Bridge",
-            object, mesh, input_method, False)
-        if not cached:
-            # get loops
-            loops = bridge_get_input(mesh)
-            if loops:
-                # reorder loops if there are more than 2
-                if len(loops) > 2:
-                    if self.loft:
-                        loops = bridge_sort_loops(mesh, loops, self.loft_loop)
-                    else:
-                        loops = bridge_match_loops(mesh, loops)
-        
-        # saving cache for faster execution next time
-        if not cached:
-            cache_write("Bridge", object, mesh, input_method, False, False,
-                loops, False, False)
-        
-        if loops:
-            # calculate new geometry
-            vertices = []
-            faces = []
-            max_vert_index = len(mesh.vertices)-1
-            for i in range(1, len(loops)):
-                if not self.loft and i%2 == 0:
-                    continue
-                lines = bridge_calculate_lines(mesh, loops[i-1:i+1],
-                    self.mode, self.twist, self.reverse)
-                vertex_normals = bridge_calculate_virtual_vertex_normals(mesh,
-                    lines, loops[i-1:i+1], edge_faces, edgekey_to_edge)
-                segments = bridge_calculate_segments(mesh, lines,
-                    loops[i-1:i+1], self.segments)
-                new_verts, new_faces, max_vert_index = \
-                    bridge_calculate_geometry(mesh, lines, vertex_normals,
-                    segments, self.interpolation, self.cubic_strength,
-                    self.min_width, max_vert_index)
-                if new_verts:
-                    vertices += new_verts
-                if new_faces:
-                    faces += new_faces
-            # make sure faces in loops that aren't used, aren't removed
-            if self.remove_faces and old_selected_faces:
-                bridge_save_unused_faces(mesh, old_selected_faces, loops)
-            # create vertices
-            if vertices:
-                bridge_create_vertices(mesh, vertices)
-            # create faces
-            if faces:
-                bridge_create_faces(mesh, faces, self.twist)
-                bridge_select_new_faces(mesh, len(faces), smooth)
-            # edge-data could have changed, can't use cache next run
-            if faces and not vertices:
-                cache_delete("Bridge")
-            # delete internal faces
-            if self.remove_faces and old_selected_faces:
-                bridge_remove_internal_faces(mesh, old_selected_faces)
-            # make sure normals are facing outside
-            bridge_recalculate_normals()
-        
-        terminate(global_undo)
-        return{'FINISHED'}
-
-
-# circle operator
-class Circle(bpy.types.Operator):
-    bl_idname = "mesh.looptools_circle"
-    bl_label = "Circle"
-    bl_description = "Move selected vertices into a circle shape"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    custom_radius = bpy.props.BoolProperty(name = "Radius",
-        description = "Force a custom radius",
-        default = False)
-    fit = bpy.props.EnumProperty(name = "Method",
-        items = (("best", "Best fit", "Non-linear least squares"),
-            ("inside", "Fit inside","Only move vertices towards the center")),
-        description = "Method used for fitting a circle to the vertices",
-        default = 'best')
-    flatten = bpy.props.BoolProperty(name = "Flatten",
-        description = "Flatten the circle, instead of projecting it on the " \
-            "mesh",
-        default = True)
-    influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    radius = bpy.props.FloatProperty(name = "Radius",
-        description = "Custom radius for circle",
-        default = 1.0,
-        min = 0.0,
-        soft_max = 1000.0)
-    regular = bpy.props.BoolProperty(name = "Regular",
-        description = "Distribute vertices at constant distances along the " \
-            "circle",
-        default = True)
-    
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        
-        col.prop(self, "fit")
-        col.separator()
-        
-        col.prop(self, "flatten")
-        row = col.row(align=True)
-        row.prop(self, "custom_radius")
-        row_right = row.row(align=True)
-        row_right.active = self.custom_radius
-        row_right.prop(self, "radius", text="")
-        col.prop(self, "regular")
-        col.separator()
-                
-        col.prop(self, "influence")
-    
-    def invoke(self, context, event):
-        # load custom settings
-        settings_load(self)
-        return self.execute(context)
-    
-    def execute(self, context):
-        # initialise
-        global_undo, object, mesh = initialise()
-        settings_write(self)
-        # check cache to see if we can save time
-        cached, single_loops, loops, derived, mapping = cache_read("Circle",
-            object, mesh, False, False)
-        if cached:
-            derived, mesh_mod = get_derived_mesh(object, mesh, context.scene)
-        else:
-            # find loops
-            derived, mesh_mod, single_vertices, single_loops, loops = \
-                circle_get_input(object, mesh, context.scene)
-            mapping = get_mapping(derived, mesh, mesh_mod, single_vertices,
-                False, loops)
-            single_loops, loops = circle_check_loops(single_loops, loops,
-                mapping, mesh_mod)
-        
-        # saving cache for faster execution next time
-        if not cached:
-            cache_write("Circle", object, mesh, False, False, single_loops,
-                loops, derived, mapping)
-        
-        move = []
-        for i, loop in enumerate(loops):
-            # best fitting flat plane
-            com, normal = calculate_plane(mesh_mod, loop)
-            # if circular, shift loop so we get a good starting vertex
-            if loop[1]:
-                loop = circle_shift_loop(mesh_mod, loop, com)
-            # flatten vertices on plane
-            locs_2d, p, q = circle_3d_to_2d(mesh_mod, loop, com, normal)
-            # calculate circle
-            if self.fit == 'best':
-                x0, y0, r = circle_calculate_best_fit(locs_2d)
-            else: # self.fit == 'inside'
-                x0, y0, r = circle_calculate_min_fit(locs_2d)
-            # radius override
-            if self.custom_radius:
-                r = self.radius / p.length
-            # calculate positions on circle
-            if self.regular:
-                new_locs_2d = circle_project_regular(locs_2d[:], x0, y0, r)
-            else:
-                new_locs_2d = circle_project_non_regular(locs_2d[:], x0, y0, r)
-            # take influence into account
-            locs_2d = circle_influence_locs(locs_2d, new_locs_2d,
-                self.influence)
-            # calculate 3d positions of the created 2d input
-            move.append(circle_calculate_verts(self.flatten, mesh_mod,
-                locs_2d, com, p, q, normal))
-            # flatten single input vertices on plane defined by loop
-            if self.flatten and single_loops:
-                move.append(circle_flatten_singles(mesh_mod, com, p, q,
-                    normal, single_loops[i]))
-        
-        # move vertices to new locations
-        move_verts(mesh, mapping, move, -1)
-        
-        # cleaning up 
-        if derived:
-            bpy.context.blend_data.meshes.remove(mesh_mod)
-        terminate(global_undo)
-        
-        return{'FINISHED'}
-
-
-# curve operator
-class Curve(bpy.types.Operator):
-    bl_idname = "mesh.looptools_curve"
-    bl_label = "Curve"
-    bl_description = "Turn a loop into a smooth curve"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    boundaries = bpy.props.BoolProperty(name = "Boundaries",
-        description = "Limit the tool to work within the boundaries of the "\
-            "selected vertices",
-        default = False)
-    influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    interpolation = bpy.props.EnumProperty(name = "Interpolation",
-        items = (("cubic", "Cubic", "Natural cubic spline, smooth results"),
-            ("linear", "Linear", "Simple and fast linear algorithm")),
-        description = "Algorithm used for interpolation",
-        default = 'cubic')
-    regular = bpy.props.BoolProperty(name = "Regular",
-        description = "Distribute vertices at constant distances along the" \
-            "curve",
-        default = True)
-    restriction = bpy.props.EnumProperty(name = "Restriction",
-        items = (("none", "None", "No restrictions on vertex movement"),
-            ("extrude", "Extrude only","Only allow extrusions (no "\
-                "indentations)"),
-            ("indent", "Indent only", "Only allow indentation (no "\
-                "extrusions)")),
-        description = "Restrictions on how the vertices can be moved",
-        default = 'none')
-    
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        
-        col.prop(self, "interpolation")
-        col.prop(self, "restriction")
-        col.prop(self, "boundaries")
-        col.prop(self, "regular")
-        col.separator()
-        
-        col.prop(self, "influence")
-    
-    def invoke(self, context, event):
-        # load custom settings
-        settings_load(self)
-        return self.execute(context)
-    
-    def execute(self, context):
-        # initialise
-        global_undo, object, mesh = initialise()
-        settings_write(self)
-        # check cache to see if we can save time
-        cached, single_loops, loops, derived, mapping = cache_read("Curve",
-            object, mesh, False, self.boundaries)
-        if cached:
-            derived, mesh_mod = get_derived_mesh(object, mesh, context.scene)
-        else:
-            # find loops
-            derived, mesh_mod, loops = curve_get_input(object, mesh,
-                self.boundaries, context.scene)
-            mapping = get_mapping(derived, mesh, mesh_mod, False, True, loops)
-            loops = check_loops(loops, mapping, mesh_mod)
-        verts_selected = [v.index for v in mesh_mod.vertices if v.select \
-            and not v.hide]
-        
-        # saving cache for faster execution next time
-        if not cached:
-            cache_write("Curve", object, mesh, False, self.boundaries, False,
-                loops, derived, mapping)
-        
-        move = []
-        for loop in loops:
-            knots, points = curve_calculate_knots(loop, verts_selected)
-            pknots = curve_project_knots(mesh_mod, verts_selected, knots,
-                points, loop[1])
-            tknots, tpoints = curve_calculate_t(mesh_mod, knots, points,
-                pknots, self.regular, loop[1])
-            splines = calculate_splines(self.interpolation, mesh_mod,
-                tknots, knots)
-            move.append(curve_calculate_vertices(mesh_mod, knots, tknots,
-                points, tpoints, splines, self.interpolation,
-                self.restriction))
-        
-        # move vertices to new locations
-        move_verts(mesh, mapping, move, self.influence)
-        
-        # cleaning up 
-        if derived:
-            bpy.context.blend_data.meshes.remove(mesh_mod)
-        
-        terminate(global_undo)
-        return{'FINISHED'}
-
-
-# flatten operator
-class Flatten(bpy.types.Operator):
-    bl_idname = "mesh.looptools_flatten"
-    bl_label = "Flatten"
-    bl_description = "Flatten vertices on a best-fitting plane"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    plane = bpy.props.EnumProperty(name = "Plane",
-        items = (("best_fit", "Best fit", "Calculate a best fitting plane"),
-            ("normal", "Normal", "Derive plane from averaging vertex "\
-            "normals"),
-            ("view", "View", "Flatten on a plane perpendicular to the "\
-            "viewing angle")),
-        description = "Plane on which vertices are flattened",
-        default = 'best_fit')
-    restriction = bpy.props.EnumProperty(name = "Restriction",
-        items = (("none", "None", "No restrictions on vertex movement"),
-            ("bounding_box", "Bounding box", "Vertices are restricted to "\
-            "movement inside the bounding box of the selection")),
-        description = "Restrictions on how the vertices can be moved",
-        default = 'none')
-    
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        
-        col.prop(self, "plane")
-        #col.prop(self, "restriction")
-        col.separator()
-        
-        col.prop(self, "influence")
-    
-    def invoke(self, context, event):
-        # load custom settings
-        settings_load(self)
-        return self.execute(context)
-    
-    def execute(self, context):
-        # initialise
-        global_undo, object, mesh = initialise()
-        settings_write(self)
-        # check cache to see if we can save time
-        cached, single_loops, loops, derived, mapping = cache_read("Flatten",
-            object, mesh, False, False)
-        if not cached:
-            # order input into virtual loops
-            loops = flatten_get_input(mesh)
-            loops = check_loops(loops, mapping, mesh)
-        
-        # saving cache for faster execution next time
-        if not cached:
-            cache_write("Flatten", object, mesh, False, False, False, loops,
-                False, False)
-        
-        move = []
-        for loop in loops:
-            # calculate plane and position of vertices on them
-            com, normal = calculate_plane(mesh, loop, method=self.plane,
-                object=object)
-            to_move = flatten_project(mesh, loop, com, normal)
-            if self.restriction == 'none':
-                move.append(to_move)
-            else:
-                move.append(to_move)
-        move_verts(mesh, False, move, self.influence)
-        
-        terminate(global_undo)
-        return{'FINISHED'}
-
-
-# relax operator
-class Relax(bpy.types.Operator):
-    bl_idname = "mesh.looptools_relax"
-    bl_label = "Relax"
-    bl_description = "Relax the loop, so it is smoother"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    input = bpy.props.EnumProperty(name = "Input",
-        items = (("all", "Parallel (all)", "Also use non-selected "\
-                "parallel loops as input"),
-            ("selected", "Selection","Only use selected vertices as input")),
-        description = "Loops that are relaxed",
-        default = 'selected')
-    interpolation = bpy.props.EnumProperty(name = "Interpolation",
-        items = (("cubic", "Cubic", "Natural cubic spline, smooth results"),
-            ("linear", "Linear", "Simple and fast linear algorithm")),
-        description = "Algorithm used for interpolation",
-        default = 'cubic')
-    iterations = bpy.props.EnumProperty(name = "Iterations",
-        items = (("1", "1", "One"),
-            ("3", "3", "Three"),
-            ("5", "5", "Five"),
-            ("10", "10", "Ten"),
-            ("25", "25", "Twenty-five")),
-        description = "Number of times the loop is relaxed",
-        default = "1")
-    regular = bpy.props.BoolProperty(name = "Regular",
-        description = "Distribute vertices at constant distances along the" \
-            "loop",
-        default = True)
-    
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        
-        col.prop(self, "interpolation")
-        col.prop(self, "input")
-        col.prop(self, "iterations")
-        col.prop(self, "regular")
-    
-    def invoke(self, context, event):
-        # load custom settings
-        settings_load(self)
-        return self.execute(context)
-    
-    def execute(self, context):
-        # initialise
-        global_undo, object, mesh = initialise()
-        settings_write(self)
-        # check cache to see if we can save time
-        cached, single_loops, loops, derived, mapping = cache_read("Relax",
-            object, mesh, self.input, False)
-        if cached:
-            derived, mesh_mod = get_derived_mesh(object, mesh, context.scene)
-        else:
-            # find loops
-            derived, mesh_mod, loops = get_connected_input(object, mesh,
-                context.scene, self.input)
-            mapping = get_mapping(derived, mesh, mesh_mod, False, False, loops)
-            loops = check_loops(loops, mapping, mesh_mod)
-        knots, points = relax_calculate_knots(loops)
-        
-        # saving cache for faster execution next time
-        if not cached:
-            cache_write("Relax", object, mesh, self.input, False, False, loops,
-                derived, mapping)
-        
-        for iteration in range(int(self.iterations)):
-            # calculate splines and new positions
-            tknots, tpoints = relax_calculate_t(mesh_mod, knots, points,
-                self.regular)
-            splines = []
-            for i in range(len(knots)):
-                splines.append(calculate_splines(self.interpolation, mesh_mod,
-                    tknots[i], knots[i]))
-            move = [relax_calculate_verts(mesh_mod, self.interpolation,
-                tknots, knots, tpoints, points, splines)]
-            move_verts(mesh, mapping, move, -1)
-        
-        # cleaning up 
-        if derived:
-            bpy.context.blend_data.meshes.remove(mesh_mod)
-        terminate(global_undo)
-        
-        return{'FINISHED'}
-
-
-# space operator
-class Space(bpy.types.Operator):
-    bl_idname = "mesh.looptools_space"
-    bl_label = "Space"
-    bl_description = "Space the vertices in a regular distrubtion on the loop"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    input = bpy.props.EnumProperty(name = "Input",
-        items = (("all", "Parallel (all)", "Also use non-selected "\
-                "parallel loops as input"),
-            ("selected", "Selection","Only use selected vertices as input")),
-        description = "Loops that are spaced",
-        default = 'selected')
-    interpolation = bpy.props.EnumProperty(name = "Interpolation",
-        items = (("cubic", "Cubic", "Natural cubic spline, smooth results"),
-            ("linear", "Linear", "Vertices are projected on existing edges")),
-        description = "Algorithm used for interpolation",
-        default = 'cubic')
-    
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-    
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        
-        col.prop(self, "interpolation")
-        col.prop(self, "input")
-        col.separator()
-        
-        col.prop(self, "influence")
-    
-    def invoke(self, context, event):
-        # load custom settings
-        settings_load(self)
-        return self.execute(context)
-    
-    def execute(self, context):
-        # initialise
-        global_undo, object, mesh = initialise()
-        settings_write(self)
-        # check cache to see if we can save time
-        cached, single_loops, loops, derived, mapping = cache_read("Space",
-            object, mesh, self.input, False)
-        if cached:
-            derived, mesh_mod = get_derived_mesh(object, mesh, context.scene)
-        else:
-            # find loops
-            derived, mesh_mod, loops = get_connected_input(object, mesh,
-                context.scene, self.input)
-            mapping = get_mapping(derived, mesh, mesh_mod, False, False, loops)
-            loops = check_loops(loops, mapping, mesh_mod)
-        
-        # saving cache for faster execution next time
-        if not cached:
-            cache_write("Space", object, mesh, self.input, False, False, loops,
-                derived, mapping)
-        
-        move = []
-        for loop in loops:
-            # calculate splines and new positions
-            if loop[1]: # circular
-                loop[0].append(loop[0][0])
-            tknots, tpoints = space_calculate_t(mesh_mod, loop[0][:])
-            splines = calculate_splines(self.interpolation, mesh_mod,
-                tknots, loop[0][:])
-            move.append(space_calculate_verts(mesh_mod, self.interpolation,
-                tknots, tpoints, loop[0][:-1], splines))
-        
-        # move vertices to new locations
-        move_verts(mesh, mapping, move, self.influence)
-        
-        # cleaning up 
-        if derived:
-            bpy.context.blend_data.meshes.remove(mesh_mod)
-        terminate(global_undo)
-        
-        return{'FINISHED'}
-
-
-##########################################
-####### GUI and registration #############
-##########################################
-
-# menu containing all tools
-class VIEW3D_MT_edit_mesh_looptools(bpy.types.Menu):
-    bl_label = "LoopTools"
-    
-    def draw(self, context):
-        layout = self.layout
-        
-#        layout.operator("mesh.looptools_bridge", text="Bridge").loft = False
-        layout.operator("mesh.looptools_circle")
-        layout.operator("mesh.looptools_curve")
-        layout.operator("mesh.looptools_flatten")
-#        layout.operator("mesh.looptools_bridge", text="Loft").loft = True
-        layout.operator("mesh.looptools_relax")
-        layout.operator("mesh.looptools_space")
-
-
-# panel containing all tools
-class VIEW3D_PT_tools_looptools(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_context = "mesh_edit"
-    bl_label = "LoopTools"
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-        lt = context.window_manager.looptools
-        
-        # bridge - first line
-#        split = col.split(percentage=0.15)
-#        if lt.display_bridge:
-#            split.prop(lt, "display_bridge", text="", icon='DOWNARROW_HLT')
-#        else:
-#            split.prop(lt, "display_bridge", text="", icon='RIGHTARROW')
-#        split.operator("mesh.looptools_bridge", text="Bridge").loft = False
-        # bridge - settings
-#        if lt.display_bridge:
-#            box = col.column(align=True).box().column()
-            #box.prop(self, "mode")
-            
-            # top row
-#            col_top = box.column(align=True)
-#            row = col_top.row(align=True)
-#            col_left = row.column(align=True)
-#            col_right = row.column(align=True)
-#            col_right.active = lt.bridge_segments != 1
-#            col_left.prop(lt, "bridge_segments")
-#            col_right.prop(lt, "bridge_min_width", text="")
-#            # bottom row
-#            bottom_left = col_left.row()
-#            bottom_left.active = lt.bridge_segments != 1
-#            bottom_left.prop(lt, "bridge_interpolation", text="")
-#            bottom_right = col_right.row()
-#            bottom_right.active = lt.bridge_interpolation == 'cubic'
-#            bottom_right.prop(lt, "bridge_cubic_strength")
-            # boolean properties
-#            col_top.prop(lt, "bridge_remove_faces")
-            
-            # override properties
-#            col_top.separator()
-#            row = box.row(align = True)
-#            row.prop(lt, "bridge_twist")
-#            row.prop(lt, "bridge_reverse")
-        
-        # circle - first line
-        split = col.split(percentage=0.15)
-        if lt.display_circle:
-            split.prop(lt, "display_circle", text="", icon='DOWNARROW_HLT')
-        else:
-            split.prop(lt, "display_circle", text="", icon='RIGHTARROW')
-        split.operator("mesh.looptools_circle")
-        # circle - settings
-        if lt.display_circle:
-            box = col.column(align=True).box().column()
-            box.prop(lt, "circle_fit")
-            box.separator()
-            
-            box.prop(lt, "circle_flatten")
-            row = box.row(align=True)
-            row.prop(lt, "circle_custom_radius")
-            row_right = row.row(align=True)
-            row_right.active = lt.circle_custom_radius
-            row_right.prop(lt, "circle_radius", text="")
-            box.prop(lt, "circle_regular")
-            box.separator()
-            
-            box.prop(lt, "circle_influence")
-        
-        # curve - first line
-        split = col.split(percentage=0.15)
-        if lt.display_curve:
-            split.prop(lt, "display_curve", text="", icon='DOWNARROW_HLT')
-        else:
-            split.prop(lt, "display_curve", text="", icon='RIGHTARROW')
-        split.operator("mesh.looptools_curve")
-        # curve - settings
-        if lt.display_curve:
-            box = col.column(align=True).box().column()
-            box.prop(lt, "curve_interpolation")
-            box.prop(lt, "curve_restriction")
-            box.prop(lt, "curve_boundaries")
-            box.prop(lt, "curve_regular")
-            box.separator()
-            
-            box.prop(lt, "curve_influence")
-        
-        # flatten - first line
-        split = col.split(percentage=0.15)
-        if lt.display_flatten:
-            split.prop(lt, "display_flatten", text="", icon='DOWNARROW_HLT')
-        else:
-            split.prop(lt, "display_flatten", text="", icon='RIGHTARROW')
-        split.operator("mesh.looptools_flatten")
-        # flatten - settings
-        if lt.display_flatten:
-            box = col.column(align=True).box().column()
-            box.prop(lt, "flatten_plane")
-            #box.prop(lt, "flatten_restriction")
-            box.separator()
-            
-            box.prop(lt, "flatten_influence")
-        
-        # loft - first line
-#        split = col.split(percentage=0.15)
-#        if lt.display_loft:
-#            split.prop(lt, "display_loft", text="", icon='DOWNARROW_HLT')
-#        else:
-#            split.prop(lt, "display_loft", text="", icon='RIGHTARROW')
-#        split.operator("mesh.looptools_bridge", text="Loft").loft = True
-#        # loft - settings
-#        if lt.display_loft:
-#            box = col.column(align=True).box().column()
-#            #box.prop(self, "mode")
-#            
-#            # top row
-#            col_top = box.column(align=True)
-#            row = col_top.row(align=True)
-#            col_left = row.column(align=True)
-#            col_right = row.column(align=True)
-#            col_right.active = lt.bridge_segments != 1
-#            col_left.prop(lt, "bridge_segments")
-#            col_right.prop(lt, "bridge_min_width", text="")
-#            # bottom row
-#            bottom_left = col_left.row()
-#            bottom_left.active = lt.bridge_segments != 1
-#            bottom_left.prop(lt, "bridge_interpolation", text="")
-#            bottom_right = col_right.row()
-#            bottom_right.active = lt.bridge_interpolation == 'cubic'
-#            bottom_right.prop(lt, "bridge_cubic_strength")
-#            # boolean properties
-#            col_top.prop(lt, "bridge_remove_faces")
-#            col_top.prop(lt, "bridge_loft_loop")
-#            
-#            # override properties
-#            col_top.separator()
-#            row = box.row(align = True)
-#            row.prop(lt, "bridge_twist")
-#            row.prop(lt, "bridge_reverse")
-        
-        # relax - first line
-        split = col.split(percentage=0.15)
-        if lt.display_relax:
-            split.prop(lt, "display_relax", text="", icon='DOWNARROW_HLT')
-        else:
-            split.prop(lt, "display_relax", text="", icon='RIGHTARROW')
-        split.operator("mesh.looptools_relax")
-        # relax - settings
-        if lt.display_relax:
-            box = col.column(align=True).box().column()
-            box.prop(lt, "relax_interpolation")
-            box.prop(lt, "relax_input")
-            box.prop(lt, "relax_iterations")
-            box.prop(lt, "relax_regular")
-        
-        # space - first line
-        split = col.split(percentage=0.15)
-        if lt.display_space:
-            split.prop(lt, "display_space", text="", icon='DOWNARROW_HLT')
-        else:
-            split.prop(lt, "display_space", text="", icon='RIGHTARROW')
-        split.operator("mesh.looptools_space")
-        # space - settings
-        if lt.display_space:
-            box = col.column(align=True).box().column()
-            box.prop(lt, "space_interpolation")
-            box.prop(lt, "space_input")
-            box.separator()
-            
-            box.prop(lt, "space_influence")
-
-
-# property group containing all properties for the gui in the panel
-class LoopToolsProps(bpy.types.PropertyGroup):
-    """
-    Fake module like class
-    bpy.context.window_manager.looptools
-    """
-    
-    # general display properties
-#    display_bridge = bpy.props.BoolProperty(name = "Bridge settings",
-#        description = "Display settings of the Bridge tool",
-#        default = False)
-    display_circle = bpy.props.BoolProperty(name = "Circle settings",
-        description = "Display settings of the Circle tool",
-        default = False)
-    display_curve = bpy.props.BoolProperty(name = "Curve settings",
-        description = "Display settings of the Curve tool",
-        default = False)
-    display_flatten = bpy.props.BoolProperty(name = "Flatten settings",
-        description = "Display settings of the Flatten tool",
-        default = False)
-#    display_loft = bpy.props.BoolProperty(name = "Loft settings",
-#        description = "Display settings of the Loft tool",
-#        default = False)
-    display_relax = bpy.props.BoolProperty(name = "Relax settings",
-        description = "Display settings of the Relax tool",
-        default = False)
-    display_space = bpy.props.BoolProperty(name = "Space settings",
-        description = "Display settings of the Space tool",
-        default = False)
-    
-    # bridge properties
-    bridge_cubic_strength = bpy.props.FloatProperty(name = "Strength",
-        description = "Higher strength results in more fluid curves",
-        default = 1.0,
-        soft_min = -3.0,
-        soft_max = 3.0)
-    bridge_interpolation = bpy.props.EnumProperty(name = "Interpolation mode",
-        items = (('cubic', "Cubic", "Gives curved results"),
-            ('linear', "Linear", "Basic, fast, straight interpolation")),
-        description = "Interpolation mode: algorithm used when creating "\
-            "segments",
-        default = 'cubic')
-    bridge_loft = bpy.props.BoolProperty(name = "Loft",
-        description = "Loft multiple loops, instead of considering them as "\
-            "a multi-input for bridging",
-        default = False)
-    bridge_loft_loop = bpy.props.BoolProperty(name = "Loop",
-        description = "Connect the first and the last loop with each other",
-        default = False)
-    bridge_min_width = bpy.props.IntProperty(name = "Minimum width",
-        description = "Segments with an edge smaller than this are merged "\
-            "(compared to base edge)",
-        default = 0,
-        min = 0,
-        max = 100,
-        subtype = 'PERCENTAGE')
-    bridge_mode = bpy.props.EnumProperty(name = "Mode",
-        items = (('basic', "Basic", "Fast algorithm"),
-                 ('shortest', "Shortest edge", "Slower algorithm with " \
-                                               "better vertex matching")),
-        description = "Algorithm used for bridging",
-        default = 'shortest')
-    bridge_remove_faces = bpy.props.BoolProperty(name = "Remove faces",
-        description = "Remove faces that are internal after bridging",
-        default = True)
-    bridge_reverse = bpy.props.BoolProperty(name = "Reverse",
-        description = "Manually override the direction in which the loops "\
-                      "are bridged. Only use if the tool gives the wrong " \
-                      "result",
-        default = False)
-    bridge_segments = bpy.props.IntProperty(name = "Segments",
-        description = "Number of segments used to bridge the gap "\
-            "(0 = automatic)",
-        default = 1,
-        min = 0,
-        soft_max = 20)
-    bridge_twist = bpy.props.IntProperty(name = "Twist",
-        description = "Twist what vertices are connected to each other",
-        default = 0)
-    
-    # circle properties
-    circle_custom_radius = bpy.props.BoolProperty(name = "Radius",
-        description = "Force a custom radius",
-        default = False)
-    circle_fit = bpy.props.EnumProperty(name = "Method",
-        items = (("best", "Best fit", "Non-linear least squares"),
-            ("inside", "Fit inside","Only move vertices towards the center")),
-        description = "Method used for fitting a circle to the vertices",
-        default = 'best')
-    circle_flatten = bpy.props.BoolProperty(name = "Flatten",
-        description = "Flatten the circle, instead of projecting it on the " \
-            "mesh",
-        default = True)
-    circle_influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    circle_radius = bpy.props.FloatProperty(name = "Radius",
-        description = "Custom radius for circle",
-        default = 1.0,
-        min = 0.0,
-        soft_max = 1000.0)
-    circle_regular = bpy.props.BoolProperty(name = "Regular",
-        description = "Distribute vertices at constant distances along the " \
-            "circle",
-        default = True)
-    
-    # curve properties
-    curve_boundaries = bpy.props.BoolProperty(name = "Boundaries",
-        description = "Limit the tool to work within the boundaries of the "\
-            "selected vertices",
-        default = False)
-    curve_influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    curve_interpolation = bpy.props.EnumProperty(name = "Interpolation",
-        items = (("cubic", "Cubic", "Natural cubic spline, smooth results"),
-            ("linear", "Linear", "Simple and fast linear algorithm")),
-        description = "Algorithm used for interpolation",
-        default = 'cubic')
-    curve_regular = bpy.props.BoolProperty(name = "Regular",
-        description = "Distribute vertices at constant distances along the" \
-            "curve",
-        default = True)
-    curve_restriction = bpy.props.EnumProperty(name = "Restriction",
-        items = (("none", "None", "No restrictions on vertex movement"),
-            ("extrude", "Extrude only","Only allow extrusions (no "\
-                "indentations)"),
-            ("indent", "Indent only", "Only allow indentation (no "\
-                "extrusions)")),
-        description = "Restrictions on how the vertices can be moved",
-        default = 'none')
-    
-    # flatten properties
-    flatten_influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    flatten_plane = bpy.props.EnumProperty(name = "Plane",
-        items = (("best_fit", "Best fit", "Calculate a best fitting plane"),
-            ("normal", "Normal", "Derive plane from averaging vertex "\
-            "normals"),
-            ("view", "View", "Flatten on a plane perpendicular to the "\
-            "viewing angle")),
-        description = "Plane on which vertices are flattened",
-        default = 'best_fit')
-    flatten_restriction = bpy.props.EnumProperty(name = "Restriction",
-        items = (("none", "None", "No restrictions on vertex movement"),
-            ("bounding_box", "Bounding box", "Vertices are restricted to "\
-            "movement inside the bounding box of the selection")),
-        description = "Restrictions on how the vertices can be moved",
-        default = 'none')
-    
-    # relax properties
-    relax_input = bpy.props.EnumProperty(name = "Input",
-        items = (("all", "Parallel (all)", "Also use non-selected "\
-                "parallel loops as input"),
-            ("selected", "Selection","Only use selected vertices as input")),
-        description = "Loops that are relaxed",
-        default = 'selected')
-    relax_interpolation = bpy.props.EnumProperty(name = "Interpolation",
-        items = (("cubic", "Cubic", "Natural cubic spline, smooth results"),
-            ("linear", "Linear", "Simple and fast linear algorithm")),
-        description = "Algorithm used for interpolation",
-        default = 'cubic')
-    relax_iterations = bpy.props.EnumProperty(name = "Iterations",
-        items = (("1", "1", "One"),
-            ("3", "3", "Three"),
-            ("5", "5", "Five"),
-            ("10", "10", "Ten"),
-            ("25", "25", "Twenty-five")),
-        description = "Number of times the loop is relaxed",
-        default = "1")
-    relax_regular = bpy.props.BoolProperty(name = "Regular",
-        description = "Distribute vertices at constant distances along the" \
-            "loop",
-        default = True)
-    
-    # space properties
-    space_influence = bpy.props.FloatProperty(name = "Influence",
-        description = "Force of the tool",
-        default = 100.0,
-        min = 0.0,
-        max = 100.0,
-        precision = 1,
-        subtype = 'PERCENTAGE')
-    space_input = bpy.props.EnumProperty(name = "Input",
-        items = (("all", "Parallel (all)", "Also use non-selected "\
-                "parallel loops as input"),
-            ("selected", "Selection","Only use selected vertices as input")),
-        description = "Loops that are spaced",
-        default = 'selected')
-    space_interpolation = bpy.props.EnumProperty(name = "Interpolation",
-        items = (("cubic", "Cubic", "Natural cubic spline, smooth results"),
-            ("linear", "Linear", "Vertices are projected on existing edges")),
-        description = "Algorithm used for interpolation",
-        default = 'cubic')
-
-
-# draw function for integration in menus
-def menu_func(self, context):
-    self.layout.menu("VIEW3D_MT_edit_mesh_looptools")
-    self.layout.separator()
-
-
-# define classes for registration
-classes = [VIEW3D_MT_edit_mesh_looptools,
-    VIEW3D_PT_tools_looptools,
-    LoopToolsProps,
-    Bridge,
-    Circle,
-    Curve,
-    Flatten,
-    Relax,
-    Space]
-
-
-# registering and menu integration
-def register():
-    for c in classes:
-        bpy.utils.register_class(c)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.prepend(menu_func)
-    bpy.types.WindowManager.looptools = bpy.props.PointerProperty(\
-        type = LoopToolsProps)
-
-
-# unregistering and removing menus
-def unregister():
-    for c in classes:
-        bpy.utils.unregister_class(c)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
-    try:
-        del bpy.types.WindowManager.looptools
-    except:
-        pass
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_mextrude.py b/release/scripts/addons_contrib/mesh_mextrude.py
deleted file mode 100644
index 586b601..0000000
--- a/release/scripts/addons_contrib/mesh_mextrude.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-################################################################################
-# Repeats extrusion + rotation + scale for one or more faces                   #
-
-################################################################################
-
-bl_info = {
-    "name": "MExtrude",
-    "author": "liero",
-    "version": (1, 2, 8),
-    "blender": (2, 6, 2),
-    "location": "View3D > Tool Shelf",
-    "description": "Repeat extrusions from faces to create organic shapes",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=28570",
-    "category": "Mesh"}
-
-import bpy, random
-from random import gauss
-from math import radians
-from mathutils import Euler
-from bpy.props import FloatProperty, IntProperty
-
-def vloc(self, r):
-    random.seed(self.ran + r)
-    return self.off * (1 + random.gauss(0, self.var1 / 3))
-
-def vrot(self,r):
-    random.seed(self.ran+r)
-    return Euler((radians(self.rotx) + random.gauss(0, self.var2 / 3), \
-        radians(self.roty) + random.gauss(0, self.var2 / 3), \
-        radians(self.rotz) + random.gauss(0,self.var2 / 3)), 'XYZ')
-
-def vsca(self, r):
-    random.seed(self.ran + r)
-    return [self.sca * (1 + random.gauss(0, self.var3 / 3))] * 3
-
-class MExtrude(bpy.types.Operator):
-    bl_idname = 'object.mextrude'
-    bl_label = 'MExtrude'
-    bl_description = 'Multi Extrude'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    off = FloatProperty(name='Offset', min=-2, soft_min=0.001, \
-        soft_max=2, max=5, default=.5, description='Translation')
-    rotx = FloatProperty(name='Rot X', min=-85, soft_min=-30, \
-        soft_max=30, max=85, default=0, description='X rotation')
-    roty = FloatProperty(name='Rot Y', min=-85, soft_min=-30, \
-        soft_max=30, max=85, default=0, description='Y rotation')
-    rotz = FloatProperty(name='Rot Z', min=-85, soft_min=-30, \
-        soft_max=30, max=85, default=-0, description='Z rotation')
-    sca = FloatProperty(name='Scale', min=0.1, soft_min=0.5, \
-        soft_max=1.2, max =2, default=.9, description='Scaling')
-    var1 = FloatProperty(name='Offset Var', min=-5, soft_min=-1, \
-        soft_max=1, max=5, default=0, description='Offset variation')
-    var2 = FloatProperty(name='Rotation Var', min=-5, soft_min=-1, \
-        soft_max=1, max=5, default=0, description='Rotation variation')
-    var3 = FloatProperty(name='Scale Noise', min=-5, soft_min=-1, \
-        soft_max=1, max=5, default=0, description='Scaling noise')
-    num = IntProperty(name='Repeat', min=1, max=50, soft_max=100, \
-        default=5, description='Repetitions')
-    ran = IntProperty(name='Seed', min=-9999, max=9999, default=0, \
-        description='Seed to feed random values')
-
-    @classmethod
-    def poll(cls, context):
-        return (context.object and context.object.type == 'MESH')
-
-    def draw(self, context):
-        layout = self.layout
-        column = layout.column(align=True)
-        column.label(text='Transformations:')
-        column.prop(self, 'off', slider=True)
-        column.prop(self, 'rotx', slider=True)
-        column.prop(self, 'roty', slider=True)
-        column.prop(self, 'rotz', slider=True)
-        column.prop(self, 'sca', slider=True)
-        column = layout.column(align=True)
-        column.label(text='Variation settings:')
-        column.prop(self, 'var1', slider=True)
-        column.prop(self, 'var2', slider=True)
-        column.prop(self, 'var3', slider=True)
-        column.prop(self, 'ran')
-        column = layout.column(align=False)
-        column.prop(self, 'num')
-
-    def execute(self, context):
-        obj = bpy.context.object
-        data, om, msv =  obj.data, obj.mode, []
-        msm = bpy.context.tool_settings.mesh_select_mode
-        bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-
-        # disable modifiers
-        for i in range(len(obj.modifiers)):
-            msv.append(obj.modifiers[i].show_viewport)
-            obj.modifiers[i].show_viewport = False
-
-        # isolate selection
-        bpy.ops.object.mode_set()
-        bpy.ops.object.mode_set(mode='EDIT')
-        total = data.total_face_sel
-        try: bpy.ops.mesh.select_inverse()
-        except: bpy.ops.mesh.select_all(action='INVERT')
-        bpy.ops.object.vertex_group_assign(new=True)
-        bpy.ops.mesh.hide()
-
-        # faces loop
-        for i in range(total):
-            bpy.ops.object.editmode_toggle()
-            # is bmesh..?
-            try:
-                faces = data.polygons
-            except:
-                faces = data.faces
-            for f in faces:
-                if not f.hide:
-                    f.select = True
-                    break
-            norm = f.normal.copy()
-            rot, loc = vrot(self, i), vloc(self, i)
-            norm.rotate(obj.matrix_world.to_quaternion())
-            bpy.ops.object.editmode_toggle()
-
-            # extrude loop
-            for a in range(self.num):
-                norm.rotate(rot)
-                r2q = rot.to_quaternion()
-                bpy.ops.mesh.extrude_faces_move()
-                bpy.ops.transform.translate(value = norm * loc)
-                bpy.ops.transform.rotate(value = [r2q.angle], axis = r2q.axis)
-                bpy.ops.transform.resize(value = vsca(self, i + a))
-            bpy.ops.object.vertex_group_remove_from()
-            bpy.ops.mesh.hide()
-
-        # keep just last faces selected
-        bpy.ops.mesh.reveal()
-        bpy.ops.object.vertex_group_deselect()
-        bpy.ops.object.vertex_group_remove()
-        bpy.ops.object.mode_set()
-
-
-        # restore user settings
-        for i in range(len(obj.modifiers)): 
-            obj.modifiers[i].show_viewport = msv[i]
-        bpy.context.tool_settings.mesh_select_mode = msm
-        bpy.ops.object.mode_set(mode=om)
-        if not total:
-            self.report({'INFO'}, 'Select one or more faces...')
-        return{'FINISHED'}
-
-class BotonME(bpy.types.Panel):
-    bl_label = 'Multi Extrude'
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator('object.mextrude')
-
-def register():
-    bpy.utils.register_class(MExtrude)
-    bpy.utils.register_class(BotonME)
-
-def unregister():
-    bpy.utils.unregister_class(MExtrude)
-    bpy.utils.unregister_class(BotonME)
-
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/mesh_normal_smooth.py b/release/scripts/addons_contrib/mesh_normal_smooth.py
deleted file mode 100644
index f5520ef..0000000
--- a/release/scripts/addons_contrib/mesh_normal_smooth.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# mesh_normalsmooth_7.py Copyright (C) 2010, Dolf Veenvliet
-#
-# Relaxes selected vertices while retaining the shape as much as possible
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    "name": "Normal Smooth",
-    "author": "Dolf Veenvliet",
-    "version": (7,),
-    "blender": (2, 5, 7),
-    "location": "View3D > Specials > Normal Smooth ",
-    "description": "Smooth the vertex position based on the normals",
-    "warning": "Broken",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Mesh"}
-    
-"""
-Usage:
-
-Launch from "W-menu" or from "Mesh -> Vertices -> Normal Smooth"
-
-Additional links:
-    Author Site: http://www.macouno.com
-    e-mail: dolf {at} macouno {dot} com
-"""
-
-import bpy, mathutils, math
-from bpy.props import IntProperty
-
-## Rotate one vector (vec1) towards another (vec2)
-## (rad = ammount of degrees to rotate in radians)
-def RotVtoV(vec1, vec2, rad):
-    cross = vec1.cross(vec2)
-    mat = mathutils.Matrix.Rotation(rad, 3, cross)
-    return (mat * vec1)
-
-
-# Find the new coordinate for this verticle
-def smoothVert(v1, v1in, me):
-    
-    v1co = v1.co
-    v1no = v1.normal
-    
-    # List of verts not to check (don't check against yourself)
-    chk = [v1in]
-    newCo = []
-    
-    # Make sure there's faces, otherwise we do nothing
-    if len(me.polygons):
-        
-        # Check every face
-        for f in me.polygons:
-            
-            # Only check faces that this vert is in
-            if v1in in f.vertices:
-                
-                # Loop through all the verts in the face
-                for v2in in f.vertices:
-                    
-                    # Make sure you check every vert only once
-                    if not v2in in chk:
-                        
-                        chk.append(v2in)
-                        
-                        v2 = me.vertices[v2in]
-                        
-                        v2co = v2.co
-                        
-                        # Get the vector from one vert to the other
-                        vTov = v2co - v1co
-                        
-                        vLen = vTov.length
-                        
-                        # Use half the distance (actually 0.514 seems to be the specific nr to multiply by... just by experience)
-                        vLen *= 0.514
-                        
-                        # Get the normal rotated 90 degrees (pi * 0.5 = 90 degrees in radians) towards the original vert
-                        vNor = RotVtoV(v2.normal, vTov.normalized(), (math.pi * 0.5))
-                        
-                        # Make the vector the correct length
-                        vNor = vNor.normalized() * vLen
-                        
-                        # Add the vector to the vert position to get the correct coord
-                        vNor = v2co + vNor
-                        
-                        newCo.append(vNor)
-                        
-    # Calculate the new coord only if there's a result
-    if len(newCo):
-        
-        nC = mathutils.Vector()
-        
-        # Add all the new coordinates together
-        for c in newCo:
-            nC = nC + c
-            
-        # Divide the resulting vector by the total to get the average
-        nC = nC / len(newCo)
-        
-    # If there's no result, just return the original coord
-    else:
-        nC = v1co
-                    
-    return nC
-                    
-
-# Base function
-def normal_smooth(context):
-
-    ob = context.active_object
-
-    bpy.ops.object.mode_set(mode='OBJECT')
-    
-    vNew = {}
-    me = ob.data
-    
-    # loop through all verts
-    for v1 in me.vertices:
-        
-        # only smooth selected verts
-        if v1.select:
-            
-            v1in = v1.index
-            
-            # Get the new coords for this vert
-            vNew[v1in] = smoothVert(v1, v1in, me)
-            
-    # Only if they're anything new, can we apply anything
-    if len(vNew):
-        
-        # Get the indexes for all verts to adapt
-        for k in vNew.keys():
-            
-            # Set the vert's new coords
-            me.vertices[k].co = vNew[k]
-            
-    bpy.ops.object.mode_set(mode='EDIT')
-
-    
-class NormalSmooth(bpy.types.Operator):
-    '''Smoothes verticle position based on vertex normals'''
-    bl_idname = 'normal.smooth'
-    bl_label = 'Normal Smooth'
-    bl_options = {'REGISTER', 'UNDO'}
-
-
-    iterations = IntProperty(name="Smoothing iterations",
-                default=1, min=0, max=100, soft_min=0, soft_max=10)
-    
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH')
-
-    def execute(self, context):
-        for i in range(0,self.iterations):
-            normal_smooth(context)
-        return {'FINISHED'}
-
-
-def menu_func(self, context):
-    self.layout.operator(NormalSmooth.bl_idname, text="Normal Smooth")
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.VIEW3D_MT_edit_mesh_specials.append(menu_func)
-    bpy.types.VIEW3D_MT_edit_mesh_vertices.append(menu_func)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
-    bpy.types.VIEW3D_MT_edit_mesh_vertices.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py b/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py
deleted file mode 100644
index 72aa08d..0000000
--- a/release/scripts/addons_contrib/mesh_seam_from_uv_isles.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Seam from uv isles",
-    "author": "Fredrik Hansson",
-    "version": (1,1),
-    "blender": (2, 5, 7),
-    "location": "UV/Image editor> UVs > Seam from UV isles",
-    "description": "Marks seams based on UV isles",
-    "warning": "", # used for warning icon and text in addons panel
-    "wiki_url": 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
-        'Scripts/Modeling/Seams_from_uv_isles',
-    "tracker_url": "https://projects.blender.org/tracker/index.php?" \
-        "func=detail&aid=22929",
-    "category": "Mesh"}
-
-import bpy
-
-def main(context):
-    obj = context.active_object
-    mesh = obj.data
-
-    if not obj or obj.type != 'MESH':
-        print("no active Mesh")
-        return
-    if not mesh.uv_textures.active:
-        print("no active UV Texture")
-        return
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-
-    uvtex=mesh.uv_textures.active.data
-
-    wrap_q = [1,2,3,0]
-    wrap_t = [1,2,0]
-    edge_uvs = {}
-
-    for i,uvface in enumerate(uvtex):
-        f=mesh.faces[i]
-        f_uv = [(round(uv[0], 6), round(uv[1], 6)) for uv in uvface.uv]
-        f_vi = [vertices for vertices in f.vertices]
-        for i, key in enumerate(f.edge_keys):
-            if len(f.vertices)==3:
-                uv1, uv2 = f_uv[i], f_uv[wrap_t[i]]
-                vi1, vi2 = f_vi[i], f_vi[wrap_t[i]]
-            else: # quad
-                uv1, uv2 = f_uv[i], f_uv[wrap_q[i]]
-                vi1, vi2 = f_vi[i], f_vi[wrap_q[i]]
-
-            if vi1 > vi2: vi1,uv1,uv2 = vi2,uv2,uv1
-
-            edge_uvs.setdefault(key, []).append((uv1, uv2))
-
-    for ed in mesh.edges:
-            if(len(set(edge_uvs[ed.key])) > 1):
-                ed.use_seam=1
-
-    bpy.ops.object.mode_set(mode='EDIT')
-
-class UvIsleSeamsOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "mesh.seam_from_uv_isles"
-    bl_label = "Seams from UV isles"
-    bl_options = {'REGISTER', 'UNDO'}
-
-#  def poll(self, context):
-#      obj = context.active_object
-#       return (obj and obj.type == 'MESH')
-
-    def execute(self, context):
-        main(context)
-        return {'FINISHED'}
-
-
-def menu_func(self, context):
-    self.layout.operator(UvIsleSeamsOperator.bl_idname)
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.IMAGE_MT_uvs.append(menu_func)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.IMAGE_MT_uvs.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_select_vertex_groups.py b/release/scripts/addons_contrib/mesh_select_vertex_groups.py
deleted file mode 100644
index 93a7db6..0000000
--- a/release/scripts/addons_contrib/mesh_select_vertex_groups.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    'name': 'Select Vertex Groups',
-    'author': 'Martin Ellison',
-    'version': (1, 0),
-    'blender': (2, 5, 9),
-    'location': 'Toolbox',
-    'description': 'Finds all the vertex groups that chosen verts are in, & any verts that are not in any group',
-    'warning': 'Broken', # used for warning icon and text in addons panel
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Modeling/Select_Vertex_Groups",
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
-        'func=detail&aid=22025',
-    'category': 'Mesh'}
-
-"""
-This script finds all the vertex groups that chosen vertexes are in, and any vertexes that are not in any vertex group.
-
-This is useful for cleaning up a mesh if vertex groups under animation go off to the wrong place (because they are in a vertex group that they should not be in, or not in the vertex group that they should be in).
-
-How to use:
-1. select a mesh and get into edit mode.
-2. by default it will use all vertexes; alternatively, select vertexes of interest and click on 'use selected vertexes'. Note that subsequent selections and deselections of vertexes will not change the set of vertexes to be used, you need to click on these buttons again to do that.
-3. click on 'select' and 'deselect' buttons for listed vertex groups, and for no vertex group, to select and deselect vertexes.
-
-This only lists vertex groups that have used vertexes.
-
-You may want to use the mesh select/deselect all (keyboard A) operator to start.
-
-Once you have the right vertexes selected, you can use the standard vertex groups property editor to add them to or remove them from the desired vertex groups.
-"""
-
-
-import bpy
-from bpy.props import *
-
-global use_selected_only, used_vertexes, the_mesh, vertex_usage
-use_selected_only = False
-used_vertexes = set()
-the_mesh = None
-vertex_usage = ''
-
-class UseAll(bpy.types.Operator):
-    bl_idname = "mesh.primitive_fvg_useall"
-    bl_label = "Use all Vertexes"
-    bl_register = True
-    bl_undo = True
-    #limit = FloatProperty(name="limit", description="Ignore weights under this limit.", default= 0.01, min = 0.0, max = 1.0, soft_min=0.0, soft_max=1.0)
-
-    def execute(self, context):
-        global use_selected_only
-        use_selected_only = False
-        bpy.ops.object.editmode_toggle()
-        set_used()
-        bpy.ops.object.editmode_toggle()
-        return {'FINISHED'}
-
-class UseSelected(bpy.types.Operator):
-    bl_idname = "mesh.primitive_fvg_useselected"
-    bl_label = "Use Selected Vertexes"
-    bl_register = True
-    bl_undo = True
-
-    def execute(self, context):
-        global use_selected_only
-        use_selected_only = True
-        bpy.ops.object.editmode_toggle()
-        set_used()
-        bpy.ops.object.editmode_toggle()
-        return {'FINISHED'}
-
-class SelectFound(bpy.types.Operator):
-    bl_idname = "mesh.primitive_fvg_selfound"
-    bl_label = "Select"
-    bl_register = True
-    bl_undo = True
-    vertexgroup = bpy.props.StringProperty(name = 'vertexgroup', description = 'vertexgroup', default = '', options = set())
-
-    def execute(self, context):
-        global the_mesh
-        bpy.ops.object.editmode_toggle()
-        vertexgroup = self.properties.vertexgroup
-        fv = found_verts(vertexgroup)
-        for v in fv: v.select = True
-        bpy.ops.object.editmode_toggle()
-        return {'FINISHED'}
-
-class DeselectFound(bpy.types.Operator):
-    bl_idname = "mesh.primitive_fvg_deselfound"
-    bl_label = "Deselect"
-    bl_register = True
-    bl_undo = True
-    vertexgroup = bpy.props.StringProperty(name = 'vertexgroup', description = 'vertexgroup', default = '', options = set())
-
-    def execute(self, context):
-        global the_mesh
-        bpy.ops.object.editmode_toggle()
-        vertexgroup = self.properties.vertexgroup
-        fv = found_verts(vertexgroup)
-        for v in fv: v.select = False
-        bpy.ops.object.editmode_toggle()
-        return {'FINISHED'}
-
-def set_used():
-    global use_selected_only, used_vertexes, the_mesh, vertex_usage
-    obj = bpy.context.active_object
-    used_vertexes = set()
-    if use_selected_only:
-        for v in obj.data.vertices:
-            if v.select: used_vertexes.add(v.index)
-    else:
-        for v in obj.data.vertices: used_vertexes.add(v.index)
-    the_mesh = obj
-    vertex_usage = '%d vertexes used' % (len(used_vertexes))
-
-
-def make_groups(limit):
-    global used_vertexes
-    vgp = []
-    vgdict = {}
-    vgused = {}
-    obj = bpy.context.active_object
-    all_in_group = True
-    for vg in obj.vertex_groups:
-        vgdict[vg.index] = vg.name
-    for v in obj.data.vertices:
-        in_group = False
-        if v.index in used_vertexes:
-            for g in v.groups:
-                gr = g.group
-                w = g.weight
-                if w > limit:
-                    if not gr in vgused: vgused[gr] = 0
-                    vgused[gr] += 1
-                    in_group = True
-        if not in_group: all_in_group = False
-    if not all_in_group:
-        vgp.append(("no group", "(No group)"))
-    for gn in vgused.keys():
-        name = vgdict[gn]
-        vgp.append((name, '%s has %d vertexes' % (name, vgused[gn]) ))
-    print("%d groups found\n" % len(vgp))
-    return vgp
-
-def found_verts(vertex_group):
-    global used_vertexes
-    vgfound = []
-    obj = bpy.context.active_object
-    if vertex_group == 'no group':
-        for v in obj.data.vertices:
-            if v.index in used_vertexes and len(v.groups) == 0:
-                gfound.append(v)
-    else:
-        vgnum = -1
-        for vg in obj.vertex_groups:
-            if vg.name == vertex_group: vgnum = vg.index
-        for v in obj.data.vertices:
-            if v.index in used_vertexes:
-                found = False
-                for g in v.groups:
-                        if g.group == vgnum: found = True
-                if found: vgfound.append(v)
-    print('%d vertexes found for %s' % (len(vgfound), vertex_group))
-    return vgfound
-
-
-class VIEW3D_PT_FixVertexGroups(bpy.types.Panel):
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_label = "Select Vertex Groups"
-
-    @classmethod
-    def poll(self, context):
-        if bpy.context.active_object:
-            obj = bpy.context.active_object
-            if obj.type == 'MESH' and obj.mode == 'EDIT': return True
-        return False
-
-    def draw(self, context):
-        global use_selected_only, used_vertexes, the_mesh, vertex_usage
-
-        if bpy.context.active_object:
-            obj = bpy.context.active_object
-            if obj.type == 'MESH' and obj.mode == 'EDIT':
-                layout = self.layout
-                use_all = layout.operator("mesh.primitive_fvg_useall", "Use all vertexes")
-                layout.operator("mesh.primitive_fvg_useselected", "Use selected vertexes")
-                if use_selected_only:
-                    layout.label(text = 'Using selected vertexes.')
-                else:
-                    layout.label(text = 'Using all vertexes.')
-                layout.label(vertex_usage)
-                if len(used_vertexes) == 0 or obj is not the_mesh: set_used()
-                #layout.prop(use_all, 'limit', slider = True)
-                #groups = make_groups(use_all.limitval)
-                groups = make_groups(0.01)
-                for gp in groups:
-                    layout.label(text = gp[1])
-                    row = layout.row()
-                    sel_op = row.operator("mesh.primitive_fvg_selfound", "Select")
-                    sel_op.vertexgroup = gp[0]
-                    desel_op = row.operator("mesh.primitive_fvg_deselfound", "Deselect")
-                    desel_op.vertexgroup = gp[0]
-
-classes = [UseAll, UseSelected, SelectFound, DeselectFound]
-
-def register():
-    bpy.utils.register_module(__name__)
-    pass
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    pass
-
-if __name__ == "__main__":
-    print('------ executing --------')
-    register()
diff --git a/release/scripts/addons_contrib/mesh_show_vgroup_weights.py b/release/scripts/addons_contrib/mesh_show_vgroup_weights.py
deleted file mode 100644
index d077a49..0000000
--- a/release/scripts/addons_contrib/mesh_show_vgroup_weights.py
+++ /dev/null
@@ -1,468 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-# <pep8 compliant> (Thanks to CodemanX on IRC)
-
-bl_info = {
-    "name": "Show Vertex Groups/Weights",
-    "author": "Jason van Gumster (Fweeb), Bartius Crouch",
-    "version": (0, 7, 1),
-    "blender": (2, 62, 3),
-    "location": "3D View > Properties Region > Show Weights",
-    "description": "Finds the vertex groups of a selected vertex and displays the corresponding weights",
-    "warning": "Requires bmesh",
-    "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/Py/Scripts/Modeling/Show_Vertex_Group_Weights",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=30609&group_id=153&atid=467",
-    "category": "Mesh"}
-
-#TODO - Add button for selecting vertices with no groups
-
-
-import bpy, bmesh, bgl, blf, mathutils
-
-
-# Borrowed/Modified from Bart Crouch's old Index Visualiser add-on
-def calc_callback(self, context):
-    #polling
-    if context.mode != "EDIT_MESH" or len(context.active_object.vertex_groups) == 0:
-        return
-
-    # get color info from theme
-    acol = context.user_preferences.themes[0].view_3d.editmesh_active
-    tcol = (acol[0] * 0.85, acol[1] * 0.85, acol[2] * 0.85)
-    
-    # get screen information
-    mid_x = context.region.width / 2.0
-    mid_y = context.region.height / 2.0
-    width = context.region.width
-    height = context.region.height
-    
-    # get matrices
-    view_mat = context.space_data.region_3d.perspective_matrix
-    ob_mat = context.active_object.matrix_world
-    total_mat = view_mat * ob_mat
-    
-    # calculate location info
-    texts = []
-    locs = []
-    weights  = []
-    me = context.active_object.data
-    bm = bmesh.from_edit_mesh(me)
-    dvert_lay = bm.verts.layers.deform.active
-
-    for v in bm.verts:
-        if v.select: #XXX Should check v.hide here, but it doesn't work
-            if bm.select_mode == {'VERT'} and bm.select_history.active is not None and bm.select_history.active.index == v.index:
-                locs.append([acol[0], acol[1], acol[2], v.index, v.co.to_4d()])
-            else:
-                locs.append([tcol[0], tcol[1], tcol[2], v.index, v.co.to_4d()])
-            dvert = v[dvert_lay]
-            for vgroup in context.active_object.vertex_groups:
-                if vgroup.index in dvert.keys():
-                    weights += [v.index, vgroup.index, dvert[vgroup.index]]
-
-    for loc in locs:
-        vec = total_mat * loc[4] # order is important
-        # dehomogenise
-        vec = mathutils.Vector((vec[0] / vec[3], vec[1] / vec[3], vec[2] / vec[3]))
-        x = int(mid_x + vec[0] * width / 2.0)
-        y = int(mid_y + vec[1] * height / 2.0)
-        texts += [loc[0], loc[1], loc[2], loc[3], x, y, 0]
-
-    # store as ID property in mesh
-    context.active_object.data["show_vgroup_verts"] = texts
-    context.active_object.data["show_vgroup_weights"] = weights
-
-
-# draw in 3d-view
-def draw_callback(self, context):
-    # polling
-    if context.mode != "EDIT_MESH" or len(context.active_object.vertex_groups) == 0:
-        return
-    # retrieving ID property data
-    try:
-        texts = context.active_object.data["show_vgroup_verts"]
-        weights = context.active_object.data["show_vgroup_weights"]
-    except:
-        return
-    if not texts:
-        return
-
-    bm = bmesh.from_edit_mesh(context.active_object.data)
-
-    if bm.select_mode == {'VERT'} and bm.select_history.active is not None:
-        active_vert = bm.select_history.active
-    else:
-        active_vert = None
-
-    # draw
-    blf.size(0, 13, 72)
-    blf.enable(0, blf.SHADOW)
-    blf.shadow(0, 3, 0.0, 0.0, 0.0, 1.0)
-    blf.shadow_offset(0, 2, -2)
-    for i in range(0, len(texts), 7):
-        bgl.glColor3f(texts[i], texts[i+1], texts[i+2])
-        blf.position(0, texts[i+4], texts[i+5], texts[i+6])
-        blf.draw(0, "Vertex " + str(int(texts[i+3])) + ":")
-        font_y = texts[i+5]
-        group_name = ""
-        for j in range(0, len(weights), 3):
-            if int(weights[j]) == int(texts[i+3]):
-                font_y -= 13
-                blf.position(0, texts[i+4] + 10, font_y, texts[i+6])
-                for group in context.active_object.vertex_groups:
-                    if group.index == int(weights[j+1]):
-                        group_name = group.name
-                        break
-                blf.draw(0, group_name + ": %.3f" % weights[j+2])
-        if group_name == "":
-            font_y -= 13
-            blf.position(0, texts[i+4] + 10, font_y, texts[i+6])
-            blf.draw(0, "No Groups")
-
-    # restore defaults
-    blf.disable(0, blf.SHADOW)
-
-
-# operator
-class ShowVGroupWeights(bpy.types.Operator):
-    bl_idname = "view3d.show_vgroup_weights"
-    bl_label = "Show Vertex Group Weights"
-    bl_description = "Toggle the display of the vertex groups and weights for selected vertices"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-    
-    def __del__(self):
-        bpy.context.scene.display_indices = -1
-        clear_properties(full=False)
-    
-    def modal(self, context, event):
-        if context.area:
-            context.area.tag_redraw()
-
-        # removal of callbacks when operator is called again
-        if context.scene.display_indices == -1:
-            context.region.callback_remove(self.handle1)
-            context.region.callback_remove(self.handle2)
-            context.scene.display_indices = 0
-            return {'CANCELLED'}
-        
-        return {'PASS_THROUGH'}
-    
-    def invoke(self, context, event):
-        if context.area.type == 'VIEW_3D':
-            if context.scene.display_indices < 1:
-                # operator is called for the first time, start everything
-                context.scene.display_indices = 1
-                context.window_manager.modal_handler_add(self)
-                self.handle1 = context.region.callback_add(calc_callback,
-                    (self, context), 'POST_VIEW')
-                self.handle2 = context.region.callback_add(draw_callback,
-                    (self, context), 'POST_PIXEL')
-                return {'RUNNING_MODAL'}
-            else:
-                # operator is called again, stop displaying
-                context.scene.display_indices = -1
-                clear_properties(full=False)
-                return {'RUNNING_MODAL'}
-        else:
-            self.report({"WARNING"}, "View3D not found, can't run operator")
-            return {'CANCELLED'}
-
-
-# properties used by the script
-class InitProperties(bpy.types.Operator):
-    bl_idname = "view3d.init_find_weights"
-    bl_label = "Initialize properties for vgroup weights finder"
-    
-    def execute(self, context):
-        bpy.types.Scene.display_indices = bpy.props.IntProperty(
-            name="Display indices",
-            default=0)
-        context.scene.display_indices = 0
-        return {'FINISHED'}
-
-
-# removal of ID-properties when script is disabled
-def clear_properties(full=True):
-    # can happen on reload
-    if bpy.context.scene is None:
-        return
-    
-    if "show_vgroup_verts" in bpy.context.active_object.data.keys():
-        del bpy.context.active_object.data["show_vgroup_verts"]
-    if "show_vgroup_weights" in bpy.context.active_object.data.keys():
-        del bpy.context.active_object.data["show_vgroup_weights"]
-    if full:
-        props = ["display_indices"]
-        for p in props:
-            if p in bpy.types.Scene.bl_rna.properties:
-                exec("del bpy.types.Scene." + p)
-            if p in bpy.context.scene.keys():
-                del bpy.context.scene[p]
-
-
-class AssignVertexWeight(bpy.types.Operator):
-    bl_idname = "mesh.vertex_group_assign"
-    bl_label = "Assign Weights"
-    bl_description = "Assign weights for all of the groups on a specific vertex"
-
-    vgroup_weights = bpy.props.StringProperty(name = "Vertex Group Weights")
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-
-    def execute(self, context):
-        me = context.active_object.data
-        bm = bmesh.from_edit_mesh(me)
-        dvert_lay = bm.verts.layers.deform.active
-        weights = eval(self.vgroup_weights) #XXX Would be nice if I didn't have to use an eval
-
-        for v in bm.verts:
-            if v.index == weights["__index__"]:
-                del weights["__index__"]
-                dvert = v[dvert_lay]
-                for vgroup in dvert.keys():
-                    dvert[vgroup] = weights[vgroup]
-                break
-
-        return {'FINISHED'}
-
-
-class RemoveFromVertexGroup(bpy.types.Operator):
-    bl_idname = "mesh.vertex_group_remove"
-    bl_label = "Remove Vertex from Group"
-    bl_description = "Remove a specific vertex from a specific vertex group"
-
-    #XXX abusing vector props here a bit; the first element is the vert index and the second is the group index
-    vert_and_group = bpy.props.IntVectorProperty(name = "Vertex and Group to remove", size = 2)
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-
-    def execute(self, context):
-        ob = context.active_object
-        me = ob.data
-        bm = bmesh.from_edit_mesh(me)
-
-        # Save current selection
-        selected_verts = []
-        for v in bm.verts:
-            if v.select == True:
-                selected_verts.append(v.index)
-                if v.index != self.vert_and_group[0]:
-                    v.select = False
-
-        ob.vertex_groups.active_index = self.vert_and_group[1]
-        bpy.ops.object.vertex_group_remove_from()
-
-        # Re-select vertices
-        for v in bm.verts:
-            if v.index in selected_verts:
-                v.select = True
-
-        #XXX Hacky, but there's no other way to update the UI panels
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.object.editmode_toggle()
-        return {'FINISHED'}
-
-
-class AddToVertexGroup(bpy.types.Operator):
-    bl_idname = "mesh.vertex_group_add"
-    bl_label = "Add Vertex to Group"
-    bl_description = "Add a specific vertex to a specific vertex group"
-
-    def avail_vgroups(self, context):
-        ob = context.active_object
-        bm = bmesh.from_edit_mesh(ob.data)
-        dvert_lay = bm.verts.layers.deform.active
-        items = []
-        self.vertex = bm.select_history.active.index
-
-        dvert = bm.select_history.active[dvert_lay]
-
-        items.append(("-1", "New Vertex Group", "-1", -1))
-
-        for i in ob.vertex_groups:
-            if i.index not in dvert.keys():
-                items.append((i.name, i.name, str(i.index), i.index))
-
-        return items
-
-    vertex = bpy.props.IntProperty()
-    available_vgroups = bpy.props.EnumProperty(items = avail_vgroups, name = "Available Groups")
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-
-    def execute(self, context):
-        ob = context.active_object
-        me = ob.data
-        bm = bmesh.from_edit_mesh(me)
-        #print(self.available_vgroups)
-
-        # Save current selection
-        selected_verts = []
-        for v in bm.verts:
-            if v.select == True:
-                selected_verts.append(v.index)
-                if v.index != self.vertex:
-                    v.select = False
-
-        weight = context.tool_settings.vertex_group_weight
-        context.tool_settings.vertex_group_weight = 1.0
-        if self.available_vgroups == "-1":
-            bpy.ops.object.vertex_group_assign(new = True) #XXX Assumes self.vertex is the active vertex
-        else:
-            bpy.ops.object.vertex_group_set_active(group = self.available_vgroups)
-            bpy.ops.object.vertex_group_assign() #XXX Assumes self.vertex is the active vertex
-        context.tool_settings.vertex_group_weight = weight
-
-        # Re-select vertices
-        for v in bm.verts:
-            if v.index in selected_verts:
-                v.select = True
-
-        #XXX Hacky, but there's no other way to update the UI panels
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.object.editmode_toggle()
-        return {'FINISHED'}
-
-
-class PanelShowWeights(bpy.types.Panel):
-    bl_label = "Show Weights"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "UI"
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-
-    def draw(self, context):
-        layout = self.layout
-        ob = context.active_object
-        me = ob.data
-        bm = bmesh.from_edit_mesh(me)
-        dvert_lay = bm.verts.layers.deform.active
-
-        if context.scene.display_indices < 1:
-            layout.operator(ShowVGroupWeights.bl_idname, text = "Show Weights Overlay")
-        else:
-            layout.operator(ShowVGroupWeights.bl_idname, text = "Hide Weights Overlay")
-
-        if len(ob.vertex_groups) > 0:
-            # Active vertex
-            active_vert = bm.select_history.active
-            sub = layout.box()
-            col = sub.column(align = True)
-            if bm.select_mode == {'VERT'} and active_vert is not None:
-                col.label(text = "Active Vertex")
-                row = col.row()
-                row.label(text = "Vertex " + str(active_vert.index) + ":")
-                row.operator_menu_enum("mesh.vertex_group_add", "available_vgroups", text = "Add Group", icon = 'GROUP_VERTEX')
-                has_groups = False
-                vgroup_weights = {}
-
-                for i in me.vertices:
-                    if i.index == active_vert.index:
-                        vgroup_weights["__index__"] = i.index
-                        for j in range(len(i.groups)):
-                            for k in ob.vertex_groups:
-                                if k.index == i.groups[j].group:
-                                    has_groups = True
-                                    split = col.split(percentage = 0.90, align = True)
-                                    vgroup_weights[k.index] = i.groups[j].weight
-                                    row = split.row(align = True)
-                                    row.prop(i.groups[j], "weight", text = k.name, slider = True, emboss = not k.lock_weight)
-                                    row = split.row(align = True)
-                                    row.operator("mesh.vertex_group_remove", text = "R").vert_and_group = (i.index, k.index)
-                
-                if not has_groups:
-                    col.label(text = "    No Groups")
-                else:
-                    col.operator("mesh.vertex_group_assign").vgroup_weights = str(vgroup_weights)
-                layout.separator()
-            else:
-                col.label(text = "No Active Vertex")
-            layout.prop(context.window_manager, "show_vgroups_show_all", toggle = True)
-            # All selected vertices (except for the active vertex)
-            if context.window_manager.show_vgroups_show_all:
-                for v in bm.verts:
-                    if v.select:
-                        if active_vert is not None and v.index == active_vert.index:
-                            continue
-                        sub = layout.box()
-                        col = sub.column(align = True)
-                        col.label(text = "Vertex " + str(v.index) + ":")
-                        has_groups = False
-                        vgroup_weights = {}
-                        for i in me.vertices:
-                            if i.index == v.index:
-                                vgroup_weights["__index__"] = i.index
-                                for j in range(len(i.groups)):
-                                    for k in ob.vertex_groups:
-                                        if k.index == i.groups[j].group:
-                                            has_groups = True
-                                            split = col.split(percentage = 0.90, align = True)
-                                            vgroup_weights[k.index] = i.groups[j].weight
-                                            row = split.row(align = True)
-                                            row.prop(i.groups[j], "weight", text = k.name, slider = True, emboss = not k.lock_weight)
-                                            row = split.row(align = True)
-                                            row.operator("mesh.vertex_group_remove", text = "R").vert_and_group = (i.index, k.index)
-                        if not has_groups:
-                            col.label(text = "    No Groups")
-                        else:
-                            col.operator("mesh.vertex_group_assign").vgroup_weights = str(vgroup_weights)
-        else:
-            layout.label(text = "No Groups")
-
-
-def register():
-    bpy.types.WindowManager.show_vgroups_show_all = bpy.props.BoolProperty(
-        name = "Show All Selected Vertices",
-        description = "Show all vertices with vertex groups assigned to them",
-        default = False)
-    bpy.types.Mesh.assign_vgroup = bpy.props.StringProperty()
-    bpy.utils.register_class(ShowVGroupWeights)
-    bpy.utils.register_class(InitProperties)
-    bpy.ops.view3d.init_find_weights()
-    bpy.utils.register_class(AssignVertexWeight)
-    bpy.utils.register_class(RemoveFromVertexGroup)
-    bpy.utils.register_class(AddToVertexGroup)
-    bpy.utils.register_class(PanelShowWeights)
-    
-
-def unregister():
-    bpy.utils.unregister_class(ShowVGroupWeights)
-    bpy.utils.unregister_class(InitProperties)
-    clear_properties()
-    bpy.utils.unregister_class(AssignVertexWeight)
-    bpy.utils.unregister_class(RemoveFromVertexGroup)
-    bpy.utils.unregister_class(AddToVertexGroup)
-    bpy.utils.unregister_class(PanelShowWeights)
-    del bpy.types.WindowManager.show_vgroups_show_all
-    del bpy.types.Mesh.assign_vgroup
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_solidify_wireframe.py b/release/scripts/addons_contrib/mesh_solidify_wireframe.py
deleted file mode 100644
index 0fd787d..0000000
--- a/release/scripts/addons_contrib/mesh_solidify_wireframe.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Solid Wire Frame ALT",
-    "author": "Campbell Barton",
-    "version": (1, 0),
-    "blender": (2, 6, 2),
-    "location": "3D View Toolbar",
-    "description": "Make solid wire",
-    "warning": "",  # used for warning icon and text in addons panel
-    # "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
-    #             "Scripts/Modeling/Mesh_WireFrane',
-    # "tracker_url": "https://projects.blender.org/tracker/index.php?"
-    #                "func=detail&aid=22929",
-    "category": "Mesh"}
-
-
-import bmesh
-import bpy
-
-
-def add_nor(no_a, no_b):
-    if no_a.dot(no_b) > 0.0:
-        return no_a + no_b
-    else:
-        return no_a - no_b
-
-
-def calc_boundary_tangent(v):
-    e_a, e_b = [e for e in v.link_edges if e.is_boundary][0:2]
-
-    l_a = e_a.link_loops[0]
-    l_b = e_b.link_loops[0]
-
-    # average edge face normal
-    no_face = add_nor(l_a.face.normal, l_b.face.normal)
-
-    # average edge direction
-    v_a = e_a.other_vert(v)
-    v_b = e_b.other_vert(v)
-
-    no_edge = (v_a.co - v.co).normalized() + (v.co - v_b.co).normalized()
-
-    # find the normal
-    no = no_edge.cross(no_face).normalized()
-
-    # check are we flipped the right way
-    ta = e_a.calc_tangent(l_a) + e_b.calc_tangent(l_b)
-    if no.dot(ta) < 0.0:
-        no.negate()
-
-    return no
-
-
-import math
-
-
-def shell_angle_to_dist(angle):
-    return 1.0 if angle < 0.000001 else abs(1.0 / math.cos(angle))
-
-
-# first make 2 verts per vert
-def solid_wire(bm_src, depth=0.01, use_boundary=True, use_even_offset=True):
-    bm_dst = bmesh.new()
-
-    bm_src.verts.index_update()
-
-    inset = depth
-
-    verts_neg = []
-    verts_pos = []
-
-    is_boundary = False
-
-    if use_boundary:
-        verts_boundary = [None] * len(bm_src.verts)
-
-    for v in bm_src.verts:
-        co = v.co
-        no_scale = v.normal * depth
-        verts_neg.append(bm_dst.verts.new(co - no_scale))
-        verts_pos.append(bm_dst.verts.new(co + no_scale))
-
-        if use_boundary:
-            v.tag = False
-            v.select = False
-
-    verts_loop = []
-
-    for f in bm_src.faces:
-        for l in f.loops:
-            l.index = len(verts_loop)
-            in_scale = l.calc_tangent() * inset
-
-            if use_even_offset:
-                in_scale *= shell_angle_to_dist((math.pi - l.calc_angle()) * 0.5)
-
-            verts_loop.append(bm_dst.verts.new(l.vert.co + in_scale))
-
-            # boundary
-            if use_boundary:
-                if l.edge.is_boundary:
-                    for v in (l.vert, l.link_loop_next.vert):
-                        if not v.tag:
-                            is_boundary = True
-                            v.tag = True             # don't copy the vert again
-                            l.edge.tag = False  # we didn't make a face yet
-
-                            v_boundary_tangent = calc_boundary_tangent(v)
-
-                            in_scale = v_boundary_tangent * inset
-
-                            if use_even_offset:
-                                in_scale *= shell_angle_to_dist((math.pi - l.calc_angle()) * 0.5)
-
-                            v_boundary = verts_boundary[v.index] = bm_dst.verts.new(v.co + in_scale)
-
-                            # TODO, make into generic function
-
-    # build faces
-    for f in bm_src.faces:
-        for l in f.loops:
-            l_next = l.link_loop_next
-            v_l1 = verts_loop[l.index]
-            v_l2 = verts_loop[l_next.index]
-
-            v_src_l1 = l.vert
-            v_src_l2 = l_next.vert
-
-            i_1 = v_src_l1.index
-            i_2 = v_src_l2.index
-
-            v_neg1 = verts_neg[i_1]
-            v_neg2 = verts_neg[i_2]
-
-            v_pos1 = verts_pos[i_1]
-            v_pos2 = verts_pos[i_2]
-
-            bm_dst.faces.new((v_l1, v_l2, v_neg2, v_neg1), f)
-            bm_dst.faces.new((v_l2, v_l1, v_pos1, v_pos2), f)
-
-            #
-            if use_boundary:
-
-                if v_src_l1.tag and v_src_l2.tag:
-                    # paranoid check, probably not needed
-                    assert(l.edge.is_boundary)
-
-                    # we know we only touch this edge/face once
-                    v_b1 = verts_boundary[i_1]
-                    v_b2 = verts_boundary[i_2]
-                    bm_dst.faces.new((v_b2, v_b1, v_neg1, v_neg2), f)
-                    bm_dst.faces.new((v_b1, v_b2, v_pos2, v_pos1), f)
-
-    return bm_dst
-
-
-def main(context, kw):
-    scene = bpy.context.scene
-    obact = scene.objects.active
-    me = bpy.data.meshes.new(name=obact.name)
-    ob = bpy.data.objects.new(me.name, me)
-    scene.objects.link(ob)
-    # scene.objects.active = ob
-
-    # can work but messes with undo
-    '''
-    if ob.mode == 'EDIT':
-        bm_src = bmesh.from_edit_mesh(obact.data)
-    else:
-    '''
-    if 1:
-        bm_src = bmesh.new()
-        bm_src.from_mesh(obact.data)
-
-    bm_dst = solid_wire(bm_src,
-                        depth=kw["thickness"],
-                        use_boundary=kw["use_boundary"],
-                        use_even_offset=kw["use_even_offset"])
-    bm_src.free()
-
-    bm_dst.to_mesh(me)
-
-    # copy some settings.
-    ob.matrix_world = obact.matrix_world
-    ob.layers = obact.layers
-    scene.objects.active = ob
-    ob.select = True
-    obact.select = False
-
-
-# ----------------------------------------------------------------------------
-# boiler plate code from here on
-
-from bpy.types import Operator, Panel
-from bpy.props import BoolProperty, FloatProperty
-
-
-class SolidWireFrameOperator(Operator):
-    ''''''
-    bl_idname = "mesh.solid_wire_frame"
-    bl_label = "Solid Wireframe"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    thickness = FloatProperty(
-            name="Value",
-            description="Assignment value",
-            default=0.05,
-            min=0.0, max=100.0,
-            soft_min=0.0, soft_max=1.0,
-            )
-
-    use_boundary = BoolProperty(
-            description="Add wire to boundary faces",
-            default=True,
-            )
-
-    use_even_offset = BoolProperty(
-            description="Use even calculations",
-            default=True,
-            )
-
-    def execute(self, context):
-        main(context, self.as_keywords())
-        return {'FINISHED'}
-
-
-class VIEW3D_PT_solid_wire(Panel):
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_label = "Solid Wire"
-
-    def draw(self, context):
-        self.layout.operator(SolidWireFrameOperator.bl_idname)
-
-
-'''
-def menu_func(self, context):
-    self.layout.operator(SolidWireFrameOperator.bl_idname)
-'''
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    # bpy.types.VIEW3D_MT_edit_mesh_faces.append(menu_func)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    # bpy.types.VIEW3D_MT_edit_mesh_faces.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/mesh_vertex_slide.py b/release/scripts/addons_contrib/mesh_vertex_slide.py
deleted file mode 100644
index 796d302..0000000
--- a/release/scripts/addons_contrib/mesh_vertex_slide.py
+++ /dev/null
@@ -1,472 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-    "name": "Vertex slide for Bmesh",
-    "author": "Valter Battioli (ValterVB) and PKHG",
-    "version": (2, 0, 0),
-    "blender": (2, 6, 2),
-    "location": "View3D > Mesh > Vertices (CTRL V-key)",
-    "description": "Slide a vertex along an edge or a line",
-    "warning": "Work only with Blender 2.62 or higher",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Modeling/Vertex_Slide2",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=27561",
-    "category": "Mesh"}
-
-#***********************************************************************
-#ver. 1.0.0: -First version
-#ver. 1.0.1: -Now the mouse wheel select in continuos mode the next vertex
-#            -Add a marker for the vertex to move
-#ver. 1.0.2: -Add check for vertices not selected
-#            -Some cleanup
-#ver. 1.0.3: -Now the movement is proportional to the mouse movement
-#             1/10 of the distance between 2 points for every pixel
-#             mouse movement (1/100 with SHIFT)
-#ver. 1.0.4: all coordinate as far as possible replaced by vectors
-#            view3d_utils are used to define length of an edge on screen!
-#            partial simplified logic by PKHG
-#ver. 1.0.6: Restore continuous slide, code cleanup
-#            Correct the crash with not linked vertex
-#ver. 1.0.7: Restore shift, and some code cleanup
-#ver. 1.0.8: Restore 2 type of sliding with 2 vertex selected
-#ver. 1.0.9: Fix for reverse vector multiplication
-#ver. 1.1.0: Delete debug info, some cleanup and add some comments
-#ver. 1.1.1: Now UNDO work properly
-#ver. 1.1.2: Refactory and some clean of the code.
-#            Add edge drawing (from chromoly vertex slide)
-#            Add help on screen (from chromooly vertex slide)
-#ver. 1.1.3: Now work also with Continuos Grab, some clean on code
-#ver. 1.1.4: Remove a lot of mode switching in Invoke. It was too slow 
-#            with big mesh.
-#ver. 1.1.5: Changed Lay out of the Help and the Key for reverse the 
-#            movement. Left/Right arrow rather than Pus/Minus numpad
-#ver. 1.1.6: Now the vertex movement is always coherent with Mouse movement
-#ver. 2.0.0: Update to Bmesh and remove all mode switching
-#ver. 2.0.1: Replaced Conv3DtoScreen2D function with location_3d_to_region_2d
-#ver. 2.0.2: Fix crash if there are some duplicate vertices
-#***********************************************************************
-
-import bpy
-import bmesh
-import bgl
-import blf
-from mathutils import Vector
-from bpy_extras.view3d_utils import location_3d_to_region_2d as loc3d2d
-
-# Equation of the line
-# Changing t we have a new point coordinate on the line along v0 v1
-# With t from 0 to 1  I move from v0 to v1
-def NewCoordinate(v0, v1, t):
-    return v0 + t * (v1 - v0)
-    
-#  This class store Vertex data
-class Point():
-    def __init__(self):
-        self.original = self.Vertex()  # Original position
-        self.new = self.Vertex()  # New position
-        self.t = 0  # Used for move the vertex
-        self.x2D = 0  # Screen 2D cooord of the point
-        self.y2D = 0  # Screen 2D cooord of the point
-        self.selected = False
-
-    class Vertex():
-        def __init__(self):
-            self.co = None
-            self.idx = None
-            
-class BVertexSlideOperator(bpy.types.Operator):
-    bl_idname = "vertex.slide"
-    bl_label = "Vertex Slide"
-    bl_options = {'REGISTER', 'UNDO', 'GRAB_POINTER', 'BLOCKING', 'INTERNAL'}
-
-    Vertex1 = Point()  # First selected vertex data
-    LinkedVertices1 = []  # List of index of linked verts of Vertex1
-    Vertex2 = Point()  # Second selected vertex data
-    LinkedVertices2 = []  # List of index of linked verts of Vertex2
-    ActiveVertex = None  # Index of vertex to be moved
-    tmpMouse_x = 0
-    tmpMouse = Vector((0, 0))
-    Direction = 1.0  # Used for direction and precision of the movement
-    FirstVertexMove = True  # If true move the first vertex
-    VertLinkedIdx = 0  # Index of LinkedVertices1. Used only for 1 vertex select case
-    LeftAltPress = False  # Flag to know if ALT is hold on
-    LeftShiftPress = False  # Flag to know if SHIFT is hold on
-    obj = None  # Object
-    mesh = None  # Mesh
-    bm = None  # BMesh
-
-    # OpenGL Function to draw on the screen help and pointer *
-    def draw_callback_px(self, context):
-        x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[self.ActiveVertex].co)
-
-        # Draw an * at the active vertex
-        blf.position(0, x, y, 0)
-        blf.size(0, 26, 72)
-        blf.draw(0, "*")
-
-        #Draw Help
-        yPos=30
-        blf.size(0, 11, context.user_preferences.system.dpi)
-        txtHelp1 = "{SHIFT}:Precision"
-        txtHelp2 = "{WHEEL}:Change the vertex/edge"
-        txtHelp3 = "{ALT}:Continuos slide"
-        txtHelp4 = "{LEFT ARROW}:Reverse the movement"
-        txtHelp5 = "{RIGHT ARROW}:Restore the movement"
-        blf.position(0, 70, yPos, 0)
-        blf.draw(0, txtHelp5)
-        yPos += (int(blf.dimensions(0, txtHelp4)[1]*2))
-        blf.position(0 , 70, yPos, 0)
-        blf.draw(0, txtHelp4)
-        yPos += (int(blf.dimensions(0, txtHelp3)[1]*2))
-        blf.position(0 , 70, yPos, 0)
-        blf.draw(0, txtHelp3)
-        yPos += (int(blf.dimensions(0, txtHelp2)[1]*2))
-        blf.position(0 , 70, yPos, 0)
-        blf.draw(0, txtHelp2)
-        yPos += (int(blf.dimensions(0, txtHelp1)[1]*2))
-        blf.position(0 , 70, yPos, 0)
-        blf.draw(0, txtHelp1)
-
-        # Draw edge
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glColor4f(1.0, 0.1, 0.8, 1.0)
-        bgl.glBegin(bgl.GL_LINES)
-        for p in self.LinkedVertices1:
-            bgl.glVertex2f(self.Vertex1.x2D, self.Vertex1.y2D)
-            bgl.glVertex2f(p.x2D, p.y2D)
-        for p in self.LinkedVertices2:
-            bgl.glVertex2f(self.Vertex2.x2D, self.Vertex2.y2D)
-            bgl.glVertex2f(p.x2D, p.y2D)
-        bgl.glEnd()
-
-    # Compute the screen distance of two vertices
-    def ScreenDistance(self, vertex_zero_co, vertex_one_co):
-        matw = bpy.context.active_object.matrix_world
-        V0 = matw * vertex_zero_co
-        res0 = loc3d2d(bpy.context.region, bpy.context.space_data.region_3d, V0)
-        V1 = matw * vertex_one_co
-        res1 = loc3d2d(bpy.context.region, bpy.context.space_data.region_3d, V1)
-        result = (res0 - res1).length
-        return result
-
-    def modal(self, context, event):
-        if event.type == 'MOUSEMOVE':
-            Vertices = self.bm.verts
-            # Calculate the temp t value. Stored in td
-            tmpMouse = Vector((event.mouse_x, event.mouse_y))
-            t_diff = (tmpMouse - self.tmpMouse).length
-            self.tmpMouse = tmpMouse
-            if self.Vertex2.original.idx is not None: # 2 vertex selected
-                td = t_diff * self.Direction / self.ScreenDistance(self.Vertex1.original.co,
-                                                                   self.Vertex2.original.co)
-            else:  # 1 vertex selected
-                td = t_diff * self.Direction / self.ScreenDistance(self.Vertex1.original.co,
-                                                                   self.LinkedVertices1[self.VertLinkedIdx].original.co)
-            if event.mouse_x < self.tmpMouse_x:
-                td = -td
-
-            if self.Vertex2.original.idx is not None: # 2 vertex selected
-                # Calculate the t valuse
-                if self.FirstVertexMove:
-                    self.Vertex1.t = self.Vertex1.t + td
-                else:
-                    self.Vertex2.t = self.Vertex2.t + td
-                # Move the vertex
-                Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex1.original.co,
-                                                                       self.Vertex2.original.co,
-                                                                       self.Vertex1.t)
-                Vertices[self.Vertex2.original.idx].co = NewCoordinate(self.Vertex2.original.co,
-                                                                       self.Vertex1.original.co,
-                                                                       self.Vertex2.t)
-            else:  # 1 vertex selected
-                if self.LeftAltPress:  # Continuous slide
-                    # Calculate the t valuse
-                    self.Vertex2.t = self.Vertex2.t + td
-                    # Move the vertex
-                    Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex2.original.co,
-                                                                           self.LinkedVertices1[self.VertLinkedIdx].original.co,
-                                                                           self.Vertex2.t)
-                else:
-                    # Calculate the t valuse
-                    self.LinkedVertices1[self.VertLinkedIdx].t = self.LinkedVertices1[self.VertLinkedIdx].t + td
-                    # Move the vertex
-                    Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex1.original.co,
-                                                                           self.LinkedVertices1[self.VertLinkedIdx].original.co,
-                                                                           self.LinkedVertices1[self.VertLinkedIdx].t)
-                self.ActiveVertex = self.Vertex1.original.idx
-            self.tmpMouse_x = event.mouse_x
-            context.area.tag_redraw()
-
-        elif event.type == 'LEFT_SHIFT':  # Hold left SHIFT for precision
-            self.LeftShiftPress = not self.LeftShiftPress
-            if self.LeftShiftPress:
-                self.Direction *= 0.1
-            else:
-                if self.Direction < 0:
-                    self.Direction = -1
-                else:
-                    self.Direction = 1
-
-        elif event.type == 'LEFT_ALT':  # Hold ALT to use continuous slide
-            self.LeftAltPress = not self.LeftAltPress
-            if self.LeftAltPress and self.Vertex2.original.idx is None:
-                vert = self.bm.verts[self.Vertex1.original.idx]
-                self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z))
-                self.Vertex2.t = 0
-
-        elif event.type == 'LEFT_ARROW':  # Reverse direction
-            if self.Direction < 0.0:
-                self.Direction = - self.Direction
-
-        elif event.type == 'RIGHT_ARROW':  # Restore direction
-            if self.Direction > 0.0:
-                self.Direction = - self.Direction
-
-        elif event.type == 'WHEELDOWNMOUSE':  # Change the vertex to be moved
-            if self.Vertex2.original.idx is None:
-                if self.LeftAltPress:
-                    vert=self.bm.verts[self.Vertex1.original.idx]
-                    self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z))
-                    self.Vertex2.t = 0
-                self.VertLinkedIdx = self.VertLinkedIdx + 1
-                if self.VertLinkedIdx > len(self.LinkedVertices1) - 1:
-                    self.VertLinkedIdx = 0
-                bpy.ops.mesh.select_all(action='DESELECT')
-                self.bm.verts[self.Vertex1.original.idx].select = True
-                self.bm.verts[self.LinkedVertices1[self.VertLinkedIdx].original.idx].select = True
-            else:
-                self.FirstVertexMove = not self.FirstVertexMove
-                if self.LeftAltPress == False:
-                    self.Vertex1.t = 0
-                    self.Vertex2.t = 0
-                if self.FirstVertexMove:
-                    self.ActiveVertex = self.Vertex1.original.idx
-                else:
-                    self.ActiveVertex = self.Vertex2.original.idx
-            # Keep Vertex movement coherent with Mouse movement
-            if self.Vertex2.original.idx is not None:
-                if self.FirstVertexMove: 
-                    tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-                    tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
-                    if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction >= 0)):
-                        self.Direction = -self.Direction
-                else:
-                    tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
-                    tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-                    if (tmpX1 < tmpX2 and self.Direction < 0) or (tmpX2 < tmpX1 and self.Direction >= 0):
-                        self.Direction = -self.Direction
-            else:
-                tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-                tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[self.VertLinkedIdx].original.co)
-                if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction < 0)):
-                    self.Direction = -self.Direction
-            context.area.tag_redraw()
-
-        elif event.type == 'WHEELUPMOUSE':  # Change the vertex to be moved
-            if self.Vertex2.original.idx is None:
-                if self.LeftAltPress:
-                    vert = self.bm.verts[self.Vertex1.original.idx]
-                    self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z))
-                    self.Vertex2.t = 0
-                self.VertLinkedIdx = self.VertLinkedIdx - 1
-                if self.VertLinkedIdx < 0:
-                    self.VertLinkedIdx = len(self.LinkedVertices1) - 1
-                bpy.ops.mesh.select_all(action='DESELECT')
-                self.bm.verts[self.Vertex1.original.idx].select = True
-                self.bm.verts[self.LinkedVertices1[self.VertLinkedIdx].original.idx].select = True
-            else:
-                self.FirstVertexMove = not self.FirstVertexMove
-                if self.LeftAltPress == False:
-                    self.Vertex1.t = 0
-                    self.Vertex2.t = 0
-                if self.FirstVertexMove:
-                    self.ActiveVertex = self.Vertex1.original.idx
-                else:
-                    self.ActiveVertex = self.Vertex2.original.idx
-            # Keep Vertex movement coherent with Mouse movement
-            if self.Vertex2.original.idx is not None:
-                if self.FirstVertexMove: 
-                    tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-                    tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
-                    if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction >= 0)):
-                        self.Direction = -self.Direction
-                else:
-                    tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
-                    tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-                    if (tmpX1 < tmpX2 and self.Direction < 0) or (tmpX2 < tmpX1 and self.Direction >= 0):
-                        self.Direction = -self.Direction
-            else:
-                tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-                tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[self.VertLinkedIdx].original.co)
-                if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction < 0)):
-                    self.Direction = -self.Direction
-            context.area.tag_redraw()
-
-        elif event.type == 'LEFTMOUSE':  # Confirm and exit
-            Vertices = self.bm.verts
-            bpy.ops.mesh.select_all(action='DESELECT')
-            Vertices[self.Vertex1.original.idx].select = True
-            if self.Vertex2.original.idx is not None:
-                Vertices[self.Vertex2.original.idx].select = True
-            context.region.callback_remove(self._handle)
-            context.area.tag_redraw()
-            return {'FINISHED'}
-
-        elif event.type in {'RIGHTMOUSE', 'ESC'}:  # Restore and exit
-            Vertices = self.bm.verts
-            bpy.ops.mesh.select_all(action='DESELECT')
-            Vertices[self.Vertex1.original.idx].co = self.Vertex1.original.co
-            Vertices[self.Vertex1.original.idx].select = True
-            if self.Vertex2.original.idx is not None:
-                Vertices[self.Vertex2.original.idx].co = self.Vertex2.original.co
-                Vertices[self.Vertex2.original.idx].select = True
-            context.region.callback_remove(self._handle)
-            context.area.tag_redraw()
-            return {'CANCELLED'}
-
-        return {'RUNNING_MODAL'}
-
-    def invoke(self, context, event):
-        if context.active_object == None or context.active_object.type != "MESH":
-            self.report({'WARNING'}, "Not any active object or not an mesh object:")
-            return {'CANCELLED'}
-
-        if context.active_object.mode != 'EDIT':
-            self.report({'WARNING'}, "Mesh isn't in Edit Mode")
-            return {'CANCELLED'}
-        
-        self.obj = bpy.context.object
-        self.mesh = self.obj.data
-        self.bm = bmesh.from_edit_mesh(self.mesh)
-
-        Count=0
-        Selected=False
-        SelectedVertices = []  # Index of selected vertices
-        for i, v in enumerate(self.bm.verts):
-            if v.select and v.is_valid:
-                SelectedVertices.append(v.index)
-                Selected = True
-                Count += 1 
-                if (Count > 2):  # More than 2 vertices selected
-                    Selected = False
-                    break
-
-        if Selected == False:
-            self.report({'WARNING'}, "0 or more then 2 vertices selected, could not start")
-            return {'CANCELLED'}
-
-        self.tmpMouse[0], self.tmpMouse[1] = (event.mouse_x, event.mouse_y)
-        self.tmpMouse_x = self.tmpMouse[0]
-
-        self.Vertex1 = Point()
-        self.Vertex2 = Point()
-        self.LinkedVertices1 = []
-        self.LinkedVertices2 = []
-
-        # Store selected vertices data. To move in the first Loop
-        self.Vertex1.original.idx = SelectedVertices[0]
-        self.Vertex1.original.co = self.bm.verts[SelectedVertices[0]].co.copy()
-        self.Vertex1.new = self.Vertex1.original
-        x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[SelectedVertices[0]].co)  # For draw edge
-        self.Vertex1.x2D = x
-        self.Vertex1.y2D = y
-        if len(SelectedVertices) == 2:
-            self.Vertex2.original.idx = SelectedVertices[1]
-            self.Vertex2.original.co = self.bm.verts[SelectedVertices[1]].co.copy()
-            self.Vertex2.new = self.Vertex2.original
-            x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[SelectedVertices[1]].co)  # For draw edge
-            self.Vertex2.x2D = x
-            self.Vertex2.y2D = y
-
-        if len(SelectedVertices) == 2:
-            self.bm.verts[self.Vertex2.original.idx].select = False  # Unselect the second selected vertex
-
-        # Store linked vertices data, except the selected vertices
-        for i, vert in enumerate(self.bm.verts[self.Vertex1.original.idx].link_edges):
-            self.LinkedVertices1.append(Point())
-            self.LinkedVertices1[-1].original.idx = vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).index   #e_0.other_vert(v_0).index
-            self.LinkedVertices1[-1].original.co = vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).co.copy()
-            self.LinkedVertices1[-1].new = self.LinkedVertices1[-1].original
-            x, y = loc3d2d(context.region, context.space_data.region_3d, vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).co)  # For draw edge
-            self.LinkedVertices1[-1].x2D = x
-            self.LinkedVertices1[-1].y2D = y
-        if len(SelectedVertices) == 2:
-            for i, vert in enumerate(self.bm.verts[self.Vertex2.original.idx].link_edges):
-                self.LinkedVertices2.append(Point())
-                self.LinkedVertices2[-1].original.idx = vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).index
-                self.LinkedVertices2[-1].original.co = vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).co.copy()
-                self.LinkedVertices2[-1].new = self.LinkedVertices1[-1].original
-                x, y = loc3d2d(context.region, context.space_data.region_3d, vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).co)  # For draw edge
-                self.LinkedVertices2[-1].x2D = x
-                self.LinkedVertices2[-1].y2D = y
-
-        # Check for no linked vertex. Can be happen also with a mix of Select Mode
-        # Need only with 1 vertex selected
-        if len(SelectedVertices) == 1 and len(self.LinkedVertices1) == 0:
-            self.report({'WARNING'}, "Isolated vertex or mixed Select Mode!")
-            return {'CANCELLED'}
-        # Check for duplicate vertices. If some linked vertice have the same coords of selected vertice
-        # we have the error "division by 0
-        if self.Vertex1.original.co == self.Vertex2.original.co:
-            self.report({'WARNING'}, "At least one duplicate vertex")
-            return {'CANCELLED'}
-            
-        self.bm.verts[self.Vertex1.original.idx].select = True  # Select the first selected vertex
-        if len(SelectedVertices) == 2:
-            self.bm.verts[self.Vertex2.original.idx].select = True  # Select the second selected vertex
-        else:
-            self.bm.verts[self.LinkedVertices1[0].original.idx].select = True  # Select the first linked vertex
-        self.ActiveVertex = self.Vertex1.original.idx
-
-        # Keep Vertex movement coherent with Mouse movement
-        tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
-        if len(SelectedVertices) == 2:
-            tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
-        else:
-            tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[0].original.co)
-        if tmpX2 - tmpX1 < 0:
-            self.Direction = -self.Direction
-
-        # Add the region OpenGL drawing callback
-        # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
-        context.window_manager.modal_handler_add(self)
-        self._handle = context.region.callback_add(self.__class__.draw_callback_px, (self, context), 'POST_PIXEL')
-        context.area.tag_redraw()  # Force the redraw of the 3D View
-        return {'RUNNING_MODAL'}
-
-def menu_func(self, context):
-    self.layout.operator_context = "INVOKE_DEFAULT"
-    self.layout.operator(BVertexSlideOperator.bl_idname, text="Vertex Slide Bmesh")
-
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.VIEW3D_MT_edit_mesh_vertices.prepend(menu_func)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.VIEW3D_MT_edit_mesh_vertices.remove(menu_func)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/object_batch_rename_datablocks.py b/release/scripts/addons_contrib/object_batch_rename_datablocks.py
deleted file mode 100644
index fb8e9da..0000000
--- a/release/scripts/addons_contrib/object_batch_rename_datablocks.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Batch Rename Datablocks",
-    "author": "tstscr",
-    "version": (1, 0),
-    "blender": (2, 5, 9),
-    "location": "Search > (rename)",
-    "description": "Batch renaming of datablocks (e.g. rename materials after objectnames)",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Object/Batch_Rename_Datablocks",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=25242",
-    "category": "Object"}
-
-
-import bpy
-from bpy.props import *
-
-def get_first_material_name(ob):
-    for m_slot in ob.material_slots:
-        if m_slot.material:
-            material_name = m_slot.material.name
-            return material_name
-
-def get_name(self, ob):
-    if self.naming_base == 'Object':
-        return ob.name
-    
-    if self.naming_base == 'Mesh':
-        if ob.data: return ob.data.name
-        else: return ob.name
-    
-    if self.naming_base == 'Material':
-        material_name = get_first_material_name(ob)
-        if not material_name: return ob.name
-        else: return material_name
-
-    if self.naming_base == 'Custom':
-        return self.rename_custom
-    
-    
-def rename_datablocks_main(self, context):
-    obs = context.selected_editable_objects
-    for ob in obs:
-        name = get_name(self, ob)
-        
-        if self.rename_object:
-            if (self.rename_use_prefix
-            and self.prefix_object):
-                ob.name = self.rename_prefix + name
-            else:
-                ob.name = name
-        
-        if self.rename_data:
-            if (ob.data
-            and ob.data.users == 1):
-                if (self.rename_use_prefix
-                and self.prefix_data):
-                    ob.data.name = self.rename_prefix + name
-                else:
-                    ob.data.name = name
-        
-        if self.rename_material:
-            if ob.material_slots:
-                for m_slot in ob.material_slots:
-                    if m_slot.material:
-                        if m_slot.material.users == 1:
-                            if (self.rename_use_prefix
-                            and self.prefix_material):
-                                m_slot.material.name = self.rename_prefix + name
-                            else:
-                                m_slot.material.name = name
-
-class OBJECT_OT_batch_rename_datablocks(bpy.types.Operator):
-    '''Batch rename Datablocks'''
-    bl_idname = "object.batch_rename_datablocks"
-    bl_label = "Batch Rename Datablocks"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    name_origins = [
-                    ('Object', 'Object', 'Object'),
-                    ('Mesh', 'Mesh', 'Mesh'),
-                    ('Material', 'Material', 'Material'),
-                    ('Custom', 'Custom', 'Custom')
-                    ]
-    naming_base = EnumProperty(name='Name after:',
-                                items=name_origins)
-    rename_custom = StringProperty(name='Custom Name',
-                                default='New Name',
-                                description='Rename all with this String')
-    rename_object = BoolProperty(name='Rename Objects',
-                                default=False,
-                                description='Rename Objects')
-    rename_data = BoolProperty(name='Rename Data',
-                                default=True,
-                                description='Rename Object\'s Data')
-    rename_material = BoolProperty(name='Rename Materials',
-                                default=True,
-                                description='Rename Objects\' Materials')
-    rename_use_prefix = BoolProperty(name='Add Prefix',
-                                default=False,
-                                description='Prefix Objectnames with first Groups name')
-    rename_prefix = StringProperty(name='Prefix',
-                                default='',
-                                description='Prefix name with this string')
-    prefix_object = BoolProperty(name='Object',
-                                default=True,
-                                description='Prefix Object Names')
-    prefix_data = BoolProperty(name='Data',
-                                default=True,
-                                description='Prefix Data Names')
-    prefix_material = BoolProperty(name='Material',
-                                default=True,
-                                description='Prefix Material Names')
-
-    dialog_width = 260
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        col.label(text='Rename after:')
-        
-        row = layout.row()
-        row.prop(self.properties, 'naming_base', expand=True)
-        
-        col = layout.column()
-        col.prop(self.properties, 'rename_custom')
-
-        col.separator()
-        col.label('Datablocks to rename:')
-        col.prop(self.properties, 'rename_object')
-        col.prop(self.properties, 'rename_data')
-        col.prop(self.properties, 'rename_material')
-        
-        col.separator()
-        col.prop(self.properties, 'rename_use_prefix')
-        col.prop(self.properties, 'rename_prefix')
-        
-        row = layout.row()
-        row.prop(self.properties, 'prefix_object')
-        row.prop(self.properties, 'prefix_data')
-        row.prop(self.properties, 'prefix_material')
-        
-        col = layout.column()
-        
-    @classmethod
-    def poll(cls, context):
-        return context.selected_objects != None
-
-    def execute(self, context):
-
-        rename_datablocks_main(self, context)
-        
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        wm = context.window_manager
-        wm.invoke_props_dialog(self, self.dialog_width)
-        return {'RUNNING_MODAL'}
-        
-        
-def register():
-    bpy.utils.register_module(__name__)
-    pass
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    pass
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/object_drop_to_ground.py b/release/scripts/addons_contrib/object_drop_to_ground.py
deleted file mode 100644
index 471a0a6..0000000
--- a/release/scripts/addons_contrib/object_drop_to_ground.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-bl_info = {
-    'name': 'Drop to Ground',
-    'author': 'Unnikrishnan(kodemax), Florian Meyer(testscreenings)',
-    'version': (1,2),
-    "blender": (2, 6, 3),
-    'location': '3D View -> Tool Shelf -> Object Tools Panel (at the bottom)',
-    'description': 'Drop selected objects on active object',
-    'warning': '',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Object/Drop_to_ground',
-    "tracker_url": "http://projects.blender.org/tracker/?func=detail&atid=467&aid=25349",
-    'category': 'Object'}
-#################################################################
-import bpy, bmesh
-from mathutils import *
-from bpy.types import Operator
-from bpy.props import *
-#################################################################
-def get_align_matrix(location, normal):
-    up = Vector((0,0,1))                      
-    angle = normal.angle(up)
-    axis = up.cross(normal)                            
-    mat_rot = Matrix.Rotation(angle, 4, axis) 
-    mat_loc = Matrix.Translation(location)
-    mat_align = mat_rot * mat_loc                      
-    return mat_align
-
-def transform_ground_to_world(sc, ground):
-    tmpMesh = ground.to_mesh(sc, True, 'PREVIEW')
-    tmpMesh.transform(ground.matrix_world)
-    tmp_ground = bpy.data.objects.new('tmpGround', tmpMesh)
-    sc.objects.link(tmp_ground)
-    sc.update()
-    return tmp_ground
-
-def get_lowest_world_co_from_mesh(ob, mat_parent=None):
-    bme = bmesh.new()
-    bme.from_object(ob)
-    mat_to_world = ob.matrix_world.copy()
-    if mat_parent:
-        mat_to_world = mat_parent * mat_to_world
-    lowest=None
-    #bme.verts.index_update() #probably not needed
-    for v in bme.verts:
-        if not lowest:
-            lowest = v
-        if (mat_to_world * v.co).z < (mat_to_world * lowest.co).z:
-            lowest = v
-    lowest_co = mat_to_world * lowest.co
-    bme.free()
-    return lowest_co
-
-def get_lowest_world_co(context, ob, mat_parent=None):
-    if ob.type == 'MESH':
-        return get_lowest_world_co_from_mesh(ob)
-    
-    elif ob.type == 'EMPTY' and ob.dupli_type == 'GROUP':
-        if not ob.dupli_group:
-            return None
-        
-        else:
-            lowest_co = None
-            for ob_l in ob.dupli_group.objects:
-                if ob_l.type == 'MESH':
-                    lowest_ob_l = get_lowest_world_co_from_mesh(ob_l, ob.matrix_world)
-                    if not lowest_co:
-                        lowest_co = lowest_ob_l
-                    if lowest_ob_l.z < lowest_co.z:
-                        lowest_co = lowest_ob_l
-                        
-            return lowest_co
-
-def drop_objects(self, context):
-    ground = context.object
-    obs = context.selected_objects
-    obs.remove(ground)
-    tmp_ground = transform_ground_to_world(context.scene, ground)
-    down = Vector((0, 0, -10000))
-    
-    for ob in obs:
-        if self.use_origin:
-            lowest_world_co = ob.location
-        else:
-            lowest_world_co = get_lowest_world_co(context, ob)
-        if not lowest_world_co:
-            print(ob.type, 'is not supported. Failed to drop', ob.name)
-            continue
-        hit_location, hit_normal, hit_index = tmp_ground.ray_cast(lowest_world_co,
-                                                                  lowest_world_co + down)
-        if hit_index == -1:
-            print(ob.name, 'didn\'t hit the ground')
-            continue
-        
-        # simple drop down
-        to_ground_vec =  hit_location - lowest_world_co
-        ob.location += to_ground_vec
-        
-        # drop with align to hit normal
-        if self.align:
-            to_center_vec = ob.location - hit_location #vec: hit_loc to origin
-            # rotate object to align with face normal
-            mat_normal = get_align_matrix(hit_location, hit_normal)
-            rot_euler = mat_normal.to_euler()
-            mat_ob_tmp = ob.matrix_world.copy().to_3x3()
-            mat_ob_tmp.rotate(rot_euler)
-            mat_ob_tmp = mat_ob_tmp.to_4x4()
-            ob.matrix_world = mat_ob_tmp
-            # move_object to hit_location
-            ob.location = hit_location
-            # move object above surface again
-            to_center_vec.rotate(rot_euler)
-            ob.location += to_center_vec
-        
-
-    #cleanup
-    bpy.ops.object.select_all(action='DESELECT')
-    tmp_ground.select = True
-    bpy.ops.object.delete('EXEC_DEFAULT')
-    for ob in obs:
-        ob.select = True
-    ground.select = True
-    
-#################################################################
-class OBJECT_OT_drop_to_ground(Operator):
-    '''Drop selected objects on active object'''
-    bl_idname = "object.drop_on_active"
-    bl_label = "Drop to Ground"
-    bl_options = {'REGISTER', 'UNDO'}
-    bl_description = "Drop selected objects on active object"
-
-    align = BoolProperty(
-            name="Align to ground",
-            description="Aligns the object to the ground",
-            default=True)
-    use_origin = BoolProperty(
-            name="Use Center",
-            description="Drop to objects origins",
-            default=False)
-
-    ##### POLL #####
-    @classmethod
-    def poll(cls, context):
-        return len(context.selected_objects) >= 2
-    
-    ##### EXECUTE #####
-    def execute(self, context):
-        print('\nDropping Objects')
-        drop_objects(self, context)
-        return {'FINISHED'}
-
-#################################################################
-def drop_to_ground_button(self, context):
-    self.layout.operator(OBJECT_OT_drop_to_ground.bl_idname,
-                         text="Drop to Ground")
-    
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.VIEW3D_PT_tools_objectmode.append(drop_to_ground_button)
-    
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.types.VIEW3D_PT_tools_objectmode.remove(drop_to_ground_button)
-
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/object_edit_linked.py b/release/scripts/addons_contrib/object_edit_linked.py
deleted file mode 100644
index db3b181..0000000
--- a/release/scripts/addons_contrib/object_edit_linked.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    "name": "Edit Linked Library",
-    "author": "Jason van Gumster (Fweeb)",
-    "version": (0, 7, 0),
-    "blender": (2, 6, 0),
-    "location": "View3D > Toolshelf > Edit Linked Library",
-    "description": "Allows editing of objects linked from a .blend library.",
-    "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.5/Py/Scripts/Object/Edit_Linked_Library",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=29630&group_id=153&atid=467",
-    "category": "Object"}
-    
-
-import bpy
-from bpy.app.handlers import persistent
-
-settings = {
-    "original_file": "",
-    "linked_file": "",
-    "linked_objects": [],
-    }
-
- at persistent
-def linked_file_check(context):
-    if settings["linked_file"] != "":
-        if settings["linked_file"] in {bpy.data.filepath, bpy.path.abspath(bpy.data.filepath)}:
-            print("Editing a linked library.")
-            bpy.ops.object.select_all(action = 'DESELECT')
-            for ob_name in settings["linked_objects"]:
-                bpy.data.objects[ob_name].select = True
-            if len(settings["linked_objects"]) == 1:
-                bpy.context.scene.objects.active = bpy.data.objects[settings["linked_objects"][0]]
-        else:
-            # For some reason, the linked editing session ended (failed to find a file or opened a different file before returning to the originating .blend)
-            settings["original_file"] = ""
-            settings["linked_file"] = ""
-
-
-
-class EditLinked(bpy.types.Operator):
-    '''Edit Linked Library'''
-    bl_idname = "object.edit_linked"
-    bl_label = "Edit Linked Library"
-
-    autosave = bpy.props.BoolProperty(name = "Autosave", description = "Automatically save the current file before opening the linked library", default = True)
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        #print(bpy.context.active_object.library)
-        target = context.active_object
-
-        if target.dupli_group and target.dupli_group.library:
-            targetpath = target.dupli_group.library.filepath
-            settings["linked_objects"].extend([ob.name for ob in target.dupli_group.objects])
-        elif target.library:
-            targetpath = target.library.filepath
-            settings["linked_objects"].append(target.name)
-
-        if targetpath:
-            print(target.name + " is linked to " + targetpath)
-
-            if self.properties.autosave == True:
-                bpy.ops.wm.save_mainfile()
-
-            settings["original_file"] = bpy.data.filepath
-
-            # XXX: need to test for proxied rigs
-            settings["linked_file"] = bpy.path.abspath(targetpath)
-
-            bpy.ops.wm.open_mainfile(filepath=settings["linked_file"])
-            print("Opened linked file!")
-        else:
-            self.report({'WARNING'}, target.name + " is not linked")
-            print(target.name + " is not linked")
-
-        return {'FINISHED'}
-
-
-class ReturnToOriginal(bpy.types.Operator):
-    '''Return to the original file after editing the linked library .blend'''
-    bl_idname = "wm.return_to_original"
-    bl_label = "Return to Original File"
-
-    autosave = bpy.props.BoolProperty(name = "Autosave", description = "Automatically save the current file before opening original file", default = True)
-
-    @classmethod
-    def poll(cls, context):
-        # Probably the wrong context to check for here...
-        return context.active_object is not None
-    
-    def execute(self, context):
-        if self.properties.autosave == True:
-            bpy.ops.wm.save_mainfile()
-        bpy.ops.wm.open_mainfile(filepath=settings["original_file"])
-        settings["original_file"] = ""
-        settings["linked_objects"] = []
-        print("Back to the original!")
-        return {'FINISHED'}
-
-
-# UI
-# TODO: Add operators to the File menu? Hide the entire panel for non-linked objects?
-class PanelLinkedEdit(bpy.types.Panel):
-    bl_label = "Edit Linked Library"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-
-
-    def draw(self, context):
-        kc = bpy.context.window_manager.keyconfigs.addon
-        km = kc.keymaps["3D View"]
-        kmi_edit = km.keymap_items["object.edit_linked"]
-        kmi_return = km.keymap_items["wm.return_to_original"]
-
-        if settings["original_file"] == "" and ((context.active_object.dupli_group and context.active_object.dupli_group.library is not None) or context.active_object.library is not None):
-            kmi_edit.active = True
-            kmi_return.active = False
-            self.layout.operator("object.edit_linked").autosave = context.scene.edit_linked_autosave
-            self.layout.prop(context.scene, "edit_linked_autosave")
-        elif settings["original_file"] != "":
-            kmi_edit.active = False
-            kmi_return.active = True
-            self.layout.operator("wm.return_to_original").autosave = context.scene.edit_linked_autosave
-            self.layout.prop(context.scene, "edit_linked_autosave")
-        else:
-            kmi_edit.active = False
-            kmi_return.active = False
-            self.layout.label(text = "Active object is not linked")
-
-
-bpy.app.handlers.load_post.append(linked_file_check)
-
-
-def register():
-    bpy.utils.register_class(EditLinked)
-    bpy.utils.register_class(ReturnToOriginal)
-    bpy.utils.register_class(PanelLinkedEdit)
-
-    # Is there a better place to store this property?
-    bpy.types.Scene.edit_linked_autosave = bpy.props.BoolProperty(name = "Autosave", description = "Automatically save the current file before opening a linked file", default = True)
-
-    # Keymapping (deactivated by default; activated when a library object is selected)
-    kc = bpy.context.window_manager.keyconfigs.addon
-    km = kc.keymaps.new(name = "3D View", space_type='VIEW_3D')
-    kmi = km.keymap_items.new("object.edit_linked", 'NUMPAD_SLASH', 'PRESS', shift = True)
-    kmi.active = False
-    kmi = km.keymap_items.new("wm.return_to_original", 'NUMPAD_SLASH', 'PRESS', shift = True)
-    kmi.active = False
-
-
-def unregister():
-    bpy.utils.unregister_class(EditLinked)
-    bpy.utils.unregister_class(SaveAndResume)
-    bpy.utils.unregister_class(PanelLinkedEdit)
-
-    del bpy.types.Scene.edit_linked_autosave
-
-    kc = bpy.context.window_manager.keyconfigs.addon
-    km = kc.keymaps["3D View"]
-    km.keymap_items.remove(km.keymap_items["object.edit_linked"])
-    km.keymap_items.remove(km.keymap_items["wm.return_to_original"])
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/object_laplace_lightning.py b/release/scripts/addons_contrib/object_laplace_lightning.py
deleted file mode 100644
index d658df4..0000000
--- a/release/scripts/addons_contrib/object_laplace_lightning.py
+++ /dev/null
@@ -1,1243 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-bl_info = {
-    "name": "Laplacian Lightning",
-    "author": "teldredge",
-    "version": (0, 2, 6),
-    "blender": (2, 6, 1),
-    "location": "View3D > ToolShelf > Laplacian Lightning",
-    "description": "Lightning mesh generator using laplacian growth algorithm",
-    "warning": "Beta/Buggy.",
-    "wiki_url": "http://www.funkboxing.com/wordpress/?p=301",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"
-                   "func=detail&aid=27189",
-    "category": "Object"}
-        
-######################################################################
-######################################################################
-##################### BLENDER LAPLACIAN LIGHTNING ####################
-############################ teldredge ###############################
-######################## www.funkboxing.com ##########################
-######################################################################
-######################## using algorithm from ########################
-######################################################################
-############## FAST SIMULATION OF LAPLACIAN GROWTH (FSLG) ############
-#################### http://gamma.cs.unc.edu/FRAC/ ###################
-######################################################################
-###################### and a few ideas ideas from ####################
-######################################################################
-##### FAST ANIMATION OF LIGHTNING USING AN ADAPTIVE MESH (FALUAM) ####
-################ http://gamma.cs.unc.edu/FAST_LIGHTNING/ #############
-######################################################################
-######################################################################
-"""           -----RELEASE LOG/NOTES/PONTIFICATIONS-----
-v0.1.0 - 04.11.11
-    basic generate functions and UI
-    object creation report (Custom Properties: FSLG_REPORT)
-v0.2.0 - 04.15.11
-    started spelling laplacian right.
-    add curve function (not in UI) ...twisting problem
-    classify stroke by MAIN path, h-ORDER paths, TIP paths
-    jitter cells for mesh creation
-    add materials if present
-v0.2.1 - 04.16.11
-    mesh classification speedup
-v0.2.2 - 04.21.11
-    fxns to write/read array to file 
-    restrict growth to insulator cells (object bounding box)
-    origin/ground defineable by object
-    gridunit more like 'resolution'
-v0.2.3 - 04.24.11
-    cloud attractor object (termintates loop if hit)
-    secondary path orders (hOrder) disabled in UI (set to 1)
-v0.2.4 - 04.26.11
-    fixed object selection in UI
-    will not run if required object not selected   
-    moved to view 3d > toolbox
-v0.2.5 - 05.08.11
-    testing for 2.57b
-    single mesh output (for build modifier)
-    speedups (dist fxn)
-v0.2.6 - 06.20.11
-    scale/pos on 'write to cubes' works now
-    if origin obj is mesh, uses all verts as initial charges
-    semi-helpful tooltips
-    speedups, faster dedupe fxn, faster classification
-    use any shape mesh obj as insulator mesh
-        must have rot=0, scale=1, origin set to geometry
-        often fails to block bolt with curved/complex shapes
-    separate single and multi mesh creation
-
-v0.x -
-    -fix vis fxn to only buildCPGraph once for VM or VS
-    -improve list fxns (rid of ((x,y,z),w) and use (x,y,z,w)), use 'sets'
-    -create python cmodule for a few of most costly fxns
-        i have pretty much no idea how to do this yet
-    -cloud and insulator can be groups of MESH objs
-    -?text output, possibly to save on interrupt, allow continue from text
-    -?hook modifiers from tips->sides->main, weight w/ vert groups
-    -user defined 'attractor' path
-    -fix add curve function
-    -animated arcs via. ionization path    
-    -environment map boundary conditions - requires Eqn. 15 from FSLG...
-    -?assign wattage at each segment for HDRI
-    -?default settings for -lightning, -teslacoil, -spark/arc
-    -fix hOrder functionality
-    -multiple 'MAIN' brances for non-lightning discharges
-    -n-symmetry option, create mirror images, snowflakes, etc...
-"""
-
-######################################################################
-######################################################################
-######################################################################
-import bpy
-import time
-import random
-from math import sqrt
-from mathutils import Vector
-import struct
-import bisect
-import os.path
-notZero = 0.0000000001
-scn = bpy.context.scene
-
-######################################################################
-########################### UTILITY FXNS #############################
-######################################################################
-def within(x,y,d):
-###---CHECK IF x-d <= y <= x+d
-    if x-d <= y and x + d >= y:
-        return True
-    else: return False
-
-def dist(ax, ay, az ,bx, by, bz):
-    dv = Vector((ax,ay,az)) - Vector((bx,by,bz))
-    d = dv.length
-    return d
-
-def splitList(aList, idx):
-    ll = []
-    for x in aList:
-        ll.append(x[idx])
-    return ll
-
-def splitListCo(aList):
-    ll = []
-    for p in aList:
-        ll.append((p[0], p[1], p[2]))
-    return ll
-
-def getLowHigh(aList):
-    tLow = aList[0]; tHigh = aList[0]
-    for a in aList:
-        if a < tLow: tLow = a
-        if a > tHigh: tHigh = a
-    return tLow, tHigh
-
-def weightedRandomChoice(aList):
-    tL = []
-    tweight = 0
-    for a in range(len(aList)):
-        idex = a; weight = aList[a]
-        if weight > 0.0:
-            tweight += weight
-            tL.append((tweight, idex))
-    i = bisect.bisect(tL, (random.uniform(0, tweight), None))    
-    r = tL[i][1]
-    return r
-
-def getStencil3D_26(x,y,z):
-    nL = []
-    for xT in range(x-1, x+2):
-        for yT in range(y-1, y+2):
-            for zT in range(z-1, z+2):
-                nL.append((xT, yT, zT))
-    nL.remove((x,y,z))
-    return nL
-
-def jitterCells(aList, jit):
-    j = jit/2
-    bList = []
-    for a in aList:
-        ax = a[0] + random.uniform(-j, j)
-        ay = a[1] + random.uniform(-j, j)
-        az = a[2] + random.uniform(-j, j)
-        bList.append((ax, ay, az))
-    return bList
-
-def deDupe(seq, idfun=None): 
-###---THANKS TO THIS GUY - http://www.peterbe.com/plog/uniqifiers-benchmark
-    if idfun is None:
-        def idfun(x): return x
-    seen = {}
-    result = []
-    for item in seq:
-        marker = idfun(item)
-        if marker in seen: continue
-        seen[marker] = 1
-        result.append(item)
-    return result
-
-######################################################################
-######################## VISUALIZATION FXNS ##########################
-######################################################################
-def writeArrayToVoxel(arr, filename):
-    gridS = 64
-    half = int(gridS/2)
-    bitOn = 255
-    aGrid = [[[0 for z in range(gridS)] for y in range(gridS)] for x in range(gridS)]
-    for a in arr:
-        try:
-            aGrid[a[0]+half][a[1]+half][a[2]+half] = bitOn
-        except:
-            print('Particle beyond voxel domain')
-    file = open(filename, "wb")
-    for z in range(gridS):
-        for y in range(gridS):
-            for x in range(gridS):
-                file.write(struct.pack('B', aGrid[x][y][z]))
-    file.flush()
-    file.close()
-        
-def writeArrayToFile(arr, filename):
-    file = open(filename, "w")
-    for a in arr:
-        tstr = str(a[0]) + ',' + str(a[1]) + ',' + str(a[2]) + '\n'
-        file.write(tstr)
-    file.close
-
-def readArrayFromFile(filename):
-    file = open(filename, "r")
-    arr = []
-    for f in file:
-        pt = f[0:-1].split(',')
-        arr.append((int(pt[0]), int(pt[1]), int(pt[2])))
-    return arr
-
-def makeMeshCube(msize):
-    msize = msize/2
-    mmesh = bpy.data.meshes.new('q')
-    mmesh.vertices.add(8)
-    mmesh.vertices[0].co = [-msize, -msize, -msize]
-    mmesh.vertices[1].co = [-msize,  msize, -msize]
-    mmesh.vertices[2].co = [ msize,  msize, -msize]
-    mmesh.vertices[3].co = [ msize, -msize, -msize]
-    mmesh.vertices[4].co = [-msize, -msize,  msize]
-    mmesh.vertices[5].co = [-msize,  msize,  msize]
-    mmesh.vertices[6].co = [ msize,  msize,  msize]
-    mmesh.vertices[7].co = [ msize, -msize,  msize]
-    mmesh.faces.add(6)
-    mmesh.faces[0].vertices_raw = [0,1,2,3]
-    mmesh.faces[1].vertices_raw = [0,4,5,1]
-    mmesh.faces[2].vertices_raw = [2,1,5,6]
-    mmesh.faces[3].vertices_raw = [3,2,6,7]
-    mmesh.faces[4].vertices_raw = [0,3,7,4]
-    mmesh.faces[5].vertices_raw = [5,4,7,6]
-    mmesh.update(calc_edges=True)
-    return(mmesh)
-
-def writeArrayToCubes(arr, gridBU, orig, cBOOL = False, jBOOL = True):
-    for a in arr:
-        x = a[0]; y = a[1]; z = a[2]
-        me = makeMeshCube(gridBU)
-        ob = bpy.data.objects.new('xCUBE', me)
-        ob.location.x = (x*gridBU) + orig[0]
-        ob.location.y = (y*gridBU) + orig[1]
-        ob.location.z = (z*gridBU) + orig[2]
-        if cBOOL: ###---!!!MOSTLY UNUSED
-            ###   POS+BLUE, NEG-RED, ZERO:BLACK
-            col = (1.0, 1.0, 1.0, 1.0)
-            if a[3] == 0: col = (0.0, 0.0, 0.0, 1.0)
-            if a[3] < 0: col = (-a[3], 0.0, 0.0, 1.0)
-            if a[3] > 0: col = (0.0, 0.0, a[3], 1.0)                
-            ob.color = col
-        bpy.context.scene.objects.link(ob)
-        bpy.context.scene.update()
-    if jBOOL:
-        ###---SELECTS ALL CUBES w/ ?bpy.ops.object.join() b/c
-        ###   CAN'T JOIN ALL CUBES TO A SINGLE MESH RIGHT... ARGH...
-        for q in bpy.context.scene.objects:
-            q.select = False
-            if q.name[0:5] == 'xCUBE':
-                q.select = True
-                bpy.context.scene.objects.active = q
-
-def addVert(ob, pt, conni = -1):
-    mmesh = ob.data
-    mmesh.vertices.add(1)
-    vcounti = len(mmesh.vertices)-1
-    mmesh.vertices[vcounti].co = [pt[0], pt[1], pt[2]]
-    if conni > -1:
-        mmesh.edges.add(1)
-        ecounti = len(mmesh.edges)-1
-        mmesh.edges[ecounti].vertices = [conni, vcounti]
-        mmesh.update()
-
-def addEdge(ob, va, vb):
-    mmesh = ob.data
-    mmesh.edges.add(1)
-    ecounti = len(mmesh.edges)-1
-    mmesh.edges[ecounti].vertices = [va, vb]
-    mmesh.update()    
-
-def newMesh(mname):
-    mmesh = bpy.data.meshes.new(mname)
-    omesh = bpy.data.objects.new(mname, mmesh)
-    bpy.context.scene.objects.link(omesh)
-    return omesh      
-
-def writeArrayToMesh(mname, arr, gridBU, rpt = None):
-    mob = newMesh(mname)
-    mob.scale = (gridBU, gridBU, gridBU)
-    if rpt: addReportProp(mob, rpt)
-    addVert(mob, arr[0], -1)
-    for ai in range(1, len(arr)):
-        a = arr[ai]
-        addVert(mob, a, ai-1)
-    return mob        
-
-###---!!!OUT OF ORDER - SOME PROBLEM WITH IT ADDING (0,0,0)
-def writeArrayToCurves(cname, arr, gridBU, bd = .05, rpt = None):
-    cur = bpy.data.curves.new('fslg_curve', 'CURVE')
-    cur.use_fill_front = False
-    cur.use_fill_back = False    
-    cur.bevel_depth = bd
-    cur.bevel_resolution = 2    
-    cob = bpy.data.objects.new(cname, cur)
-    cob.scale = (gridBU, gridBU, gridBU)
-    if rpt: addReportProp(cob, rpt)
-    bpy.context.scene.objects.link(cob)
-    cur.splines.new('BEZIER')
-    cspline = cur.splines[0]
-    div = 1 ###   SPACING FOR HANDLES (2 - 1/2 WAY, 1 - NEXT BEZIER)
-    for a in range(len(arr)):
-        cspline.bezier_points.add(1)
-        bp = cspline.bezier_points[len(cspline.bezier_points)-1]
-        if a-1 < 0: hL = arr[a]
-        else:
-            hx = arr[a][0] - ((arr[a][0]-arr[a-1][0]) / div)
-            hy = arr[a][1] - ((arr[a][1]-arr[a-1][1]) / div)
-            hz = arr[a][2] - ((arr[a][2]-arr[a-1][2]) / div)
-            hL = (hx,hy,hz)
-        
-        if a+1 > len(arr)-1: hR = arr[a]
-        else:
-            hx = arr[a][0] + ((arr[a+1][0]-arr[a][0]) / div)
-            hy = arr[a][1] + ((arr[a+1][1]-arr[a][1]) / div)
-            hz = arr[a][2] + ((arr[a+1][2]-arr[a][2]) / div)
-            hR = (hx,hy,hz)
-        bp.co = arr[a]
-        bp.handle_left = hL
-        bp.handle_right = hR
-
-def addArrayToMesh(mob, arr):
-    addVert(mob, arr[0], -1)
-    mmesh = mob.data
-    vcounti = len(mmesh.vertices)-1
-    for ai in range(1, len(arr)):
-        a = arr[ai]
-        addVert(mob, a, len(mmesh.vertices)-1)
-
-def addMaterial(ob, matname):
-    mat = bpy.data.materials[matname]
-    ob.active_material = mat
-
-def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None):
-    ###---MAIN BRANCH
-    print('   WRITING MAIN BRANCH')
-    llmain = []
-    for x in MAINi:
-        llmain.append(jarr[x])
-    mob = writeArrayToMesh('la0MAIN', llmain, gs)
-    mob.location = orig       
-
-    ###---hORDER BRANCHES
-    for hOi in range(len(HORDERi)):
-        print('   WRITING ORDER', hOi)        
-        hO = HORDERi[hOi]
-        hob = newMesh('la1H'+str(hOi))
-
-        for y in hO:
-            llHO = []
-            for x in y:
-                llHO.append(jarr[x])
-            addArrayToMesh(hob, llHO)
-        hob.scale = (gs, gs, gs)
-        hob.location = orig
-
-    ###---TIPS
-    print('   WRITING TIP PATHS')    
-    tob = newMesh('la2TIPS')
-    for y in  TIPSi:
-        llt = []        
-        for x in y:
-            llt.append(jarr[x])
-        addArrayToMesh(tob, llt)
-    tob.scale = (gs, gs, gs)
-    tob.location = orig
-
-    ###---ADD MATERIALS TO OBJECTS (IF THEY EXIST)    
-    try:
-        addMaterial(mob, 'edgeMAT-h0')
-        addMaterial(hob, 'edgeMAT-h1')
-        addMaterial(tob, 'edgeMAT-h2')
-        print('   ADDED MATERIALS')
-    except: print('   MATERIALS NOT FOUND')
-    ###---ADD GENERATION REPORT TO ALL MESHES
-    if rpt:
-        addReportProp(mob, rpt)
-        addReportProp(hob, rpt)
-        addReportProp(tob, rpt)                
-
-def writeStokeToSingleMesh(arr, jarr, orig, gs, mct, rpt=None): 
-    sgarr = buildCPGraph(arr, mct)
-    llALL = []
-
-    Aob = newMesh('laALL')
-    for pt in jarr:
-        addVert(Aob, pt)
-    for cpi in range(len(sgarr)):
-        ci = sgarr[cpi][0]
-        pi = sgarr[cpi][1]
-        addEdge(Aob, pi, ci)
-    Aob.location = orig
-    Aob.scale = ((gs,gs,gs))
-
-    if rpt:
-        addReportProp(Aob, rpt)
-
-def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst):
-###---IN: (cellgrid, origin, gridscale,
-###   mulimesh, single mesh, cubes, voxels, report sting)
-    origin = oob.location
-
-    ###---DEAL WITH VERT MULTI-ORIGINS
-    oct = 2
-    if oob.type == 'MESH': oct = len(oob.data.vertices)
-
-    ###---JITTER CELLS
-    if vm or vs: cjarr = jitterCells(cg, 1)
-
-
-    if vm:  ###---WRITE ARRAY TO MULTI MESH
-        
-        aMi, aHi, aTi = classifyStroke(cg, oct, scn.HORDER)
-        print(':::WRITING TO MULTI-MESH')        
-        writeStokeToMesh(cg, cjarr, aMi, aHi, aTi, origin, gs, rst)
-        print(':::MULTI-MESH WRITTEN')
-
-    if vs:  ###---WRITE TO SINGLE MESH
-        print(':::WRITING TO SINGLE MESH')         
-        writeStokeToSingleMesh(cg, cjarr, origin, gs, oct, rst)
-        print(':::SINGLE MESH WRITTEN')
-        
-    if vc:  ###---WRITE ARRAY TO CUBE OBJECTS
-        print(':::WRITING TO CUBES')
-        writeArrayToCubes(cg, gs, origin)
-        print(':::CUBES WRITTEN')
-
-    if vv:  ###---WRITE ARRAY TO VOXEL DATA FILE
-        print(':::WRITING TO VOXELS')
-        fname = "FSLGvoxels.raw"
-        path = os.path.dirname(bpy.data.filepath)
-        writeArrayToVoxel(cg, path + "\\" + fname)
-        print(':::VOXEL DATA WRITTEN TO - ', path + "\\" + fname)
-
-    ###---READ/WRITE ARRAY TO FILE (MIGHT NOT BE NECESSARY)
-    #tfile = 'c:\\testarr.txt'
-    #writeArrayToFile(cg, tfile)
-    #cg = readArrayFromFile(tfile)
-
-    ###---READ/WRITE ARRAY TO CURVES (OUT OF ORDER)
-    #writeArrayToCurves('laMAIN', llmain, .10, .25)        
-
-######################################################################
-########################### ALGORITHM FXNS ###########################
-########################## FROM FALUAM PAPER #########################
-###################### PLUS SOME STUFF I MADE UP #####################
-######################################################################
-def buildCPGraph(arr, sti = 2):
-###---IN -XYZ ARRAY AS BUILT BY GENERATOR
-###---OUT -[(CHILDindex, PARENTindex)]
-###   sti - start index, 2 for Empty, len(me.vertices) for Mesh
-    sgarr = []
-    sgarr.append((1, 0)) #
-    for ai in range(sti, len(arr)):
-        cs = arr[ai]
-        cpts = arr[0:ai]
-        cslap = getStencil3D_26(cs[0], cs[1], cs[2])
-
-        for nc in cslap:
-            ct = cpts.count(nc)
-            if ct>0:
-                cti = cpts.index(nc)
-        sgarr.append((ai, cti))
-    return sgarr
-
-def buildCPGraph_WORKINPROGRESS(arr, sti = 2):
-###---IN -XYZ ARRAY AS BUILT BY GENERATOR
-###---OUT -[(CHILDindex, PARENTindex)]
-###   sti - start index, 2 for Empty, len(me.vertices) for Mesh
-    sgarr = []
-    sgarr.append((1, 0)) #
-    ctix = 0
-    for ai in range(sti, len(arr)):		
-        cs = arr[ai]
-        #cpts = arr[0:ai]
-        cpts = arr[ctix:ai]
-        cslap = getStencil3D_26(cs[0], cs[1], cs[2])
-        for nc in cslap:
-            ct = cpts.count(nc)
-            if ct>0:
-                #cti = cpts.index(nc)
-                cti = ctix + cpts.index(nc)
-                ctix = cpts.index(nc)
-				
-        sgarr.append((ai, cti))
-    return sgarr
-
-def findChargePath(oc, fc, ngraph, restrict = [], partial = True):
-    ###---oc -ORIGIN CHARGE INDEX, fc -FINAL CHARGE INDEX
-    ###---ngraph -NODE GRAPH, restrict- INDEX OF SITES CANNOT TRAVERSE
-    ###---partial -RETURN PARTIAL PATH IF RESTRICTION ENCOUNTERD
-    cList = splitList(ngraph, 0)
-    pList = splitList(ngraph, 1)
-    aRi = []
-    cNODE = fc
-    for x in range(len(ngraph)):
-        pNODE = pList[cList.index(cNODE)]
-        aRi.append(cNODE)
-        cNODE = pNODE
-        npNODECOUNT = cList.count(pNODE)
-        if cNODE == oc:             ###   STOP IF ORIGIN FOUND
-            aRi.append(cNODE)       ###   RETURN PATH
-            return aRi
-        if npNODECOUNT == 0:        ###   STOP IF NO PARENTS
-            return []               ###   RETURN []
-        if pNODE in restrict:       ###   STOP IF PARENT IS IN RESTRICTION
-            if partial:             ###   RETURN PARTIAL OR []
-                aRi.append(cNODE)
-                return aRi
-            else: return []
-
-def findTips(arr):
-    lt = []
-    for ai in arr[0:len(arr)-1]:
-        a = ai[0]
-        cCOUNT = 0
-        for bi in arr:
-            b = bi[1]
-            if a == b:
-                cCOUNT += 1
-        if cCOUNT == 0:
-            lt.append(a)
-    return lt
-
-def findChannelRoots(path, ngraph, restrict = []):
-    roots = []
-    for ai in range(len(ngraph)):
-        chi = ngraph[ai][0]
-        par = ngraph[ai][1]
-        if par in path and not chi in path and \
-            not chi in restrict:        
-            roots.append(par)
-    droots = deDupe(roots)
-    return droots
-
-def findChannels(roots, tips, ngraph, restrict):
-    cPATHS = []
-    for ri in range(len(roots)):
-        r = roots[ri]
-        sL = 1
-        sPATHi = []
-        for ti in range(len(tips)):
-            t = tips[ti]
-            if t < r: continue
-            tPATHi = findChargePath(r, t, ngraph, restrict, False)
-            tL = len(tPATHi)
-            if tL > sL:
-                if countChildrenOnPath(tPATHi, ngraph) > 1:
-                    sL = tL
-                    sPATHi = tPATHi
-                    tTEMP = t; tiTEMP = ti
-        if len(sPATHi) > 0:
-            print('   found path/idex from', ri, 'of', 
-                  len(roots), 'possible | tips:', tTEMP, tiTEMP)
-            cPATHS.append(sPATHi)
-            tips.remove(tTEMP)
-    return cPATHS
-
-def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict):
-    cPATHS = []
-    tips = list(ttips)
-    for ri in range(len(roots)):
-        r = roots[ri]
-        sL = 1
-        sPATHi = []
-        tipREMOVE = [] ###---CHECKED TIP INDEXES, TO BE REMOVED FOR NEXT LOOP
-        for ti in range(len(tips)):
-            t = tips[ti]            
-            #print('-CHECKING RT/IDEX:', r, ri, 'AGAINST TIP', t, ti)
-            #if t < r: continue
-            if ti < ri: continue
-            tPATHi = findChargePath(r, t, ngraph, restrict, False)
-            tL = len(tPATHi)
-            if tL > sL:
-                if countChildrenOnPath(tPATHi, ngraph) > 1:
-                    sL = tL
-                    sPATHi = tPATHi
-                    tTEMP = t; tiTEMP = ti
-            if tL > 0:
-                tipREMOVE.append(t)                    
-        if len(sPATHi) > 0:
-            print('   found path from root idex', ri, 'of', 
-                   len(roots), 'possible roots | #oftips=', len(tips))
-            cPATHS.append(sPATHi)
-        for q in tipREMOVE:  tips.remove(q)
-
-    return cPATHS
-
-def countChildrenOnPath(aPath, ngraph, quick = True):
-    ###---RETURN HOW MANY BRANCHES 
-    ###   COUNT WHEN NODE IS A PARENT >1 TIMES
-    ###   quick -STOP AND RETURN AFTER FIRST
-    cCOUNT = 0
-    pList = splitList(ngraph,1)
-    for ai in range(len(aPath)-1):
-        ap = aPath[ai]
-        pc = pList.count(ap)
-        if quick and pc > 1: 
-            return pc
-    return cCOUNT
-
-###---CLASSIFY CHANNELS INTO 'MAIN', 'hORDER/SECONDARY' and 'SIDE'
-def classifyStroke(sarr, mct, hORDER = 1):
-    print(':::CLASSIFYING STROKE')
-    ###---BUILD CHILD/PARENT GRAPH (INDEXES OF sarr)  
-    sgarr = buildCPGraph(sarr, mct)
-
-    ###---FIND MAIN CHANNEL 
-    print('   finding MAIN')
-    oCharge = sgarr[0][1]
-    fCharge = sgarr[len(sgarr)-1][0]
-    aMAINi = findChargePath(oCharge, fCharge, sgarr)
-    
-    ###---FIND TIPS
-    print('   finding TIPS')
-    aTIPSi = findTips(sgarr)
-
-    ###---FIND hORDER CHANNEL ROOTS
-    ###   hCOUNT = ORDERS BEWTEEN MAIN and SIDE/TIPS
-    ###   !!!STILL BUGGY!!!
-    hRESTRICT = list(aMAINi)    ### ADD TO THIS AFTER EACH TIME
-    allHPATHSi = []             ### ALL hO PATHS: [[h0], [h1]...]
-    curPATHSi = [aMAINi]        ### LIST OF PATHS FIND ROOTS ON
-    for h in range(hORDER):
-        allHPATHSi.append([])
-        for pi in range(len(curPATHSi)):     ###   LOOP THROUGH ALL PATHS IN THIS ORDER
-            p = curPATHSi[pi]
-            ###   GET ROOTS FOR THIS PATH
-            aHROOTSi = findChannelRoots(p, sgarr, hRESTRICT)
-            print('   found', len(aHROOTSi), 'roots in ORDER', h, ':#paths:', len(curPATHSi))
-            ### GET CHANNELS FOR THESE ROOTS
-            if len(aHROOTSi) == 0:
-                print('NO ROOTS FOR FOUND FOR CHANNEL')
-                aHPATHSi = []
-                continue
-            else:
-                aHPATHSiD = findChannels(aHROOTSi, aTIPSi, sgarr, hRESTRICT)
-                aHPATHSi = aHPATHSiD
-                allHPATHSi[h] += aHPATHSi
-                ###   SET THESE CHANNELS AS RESTRICTIONS FOR NEXT ITERATIONS
-                for hri in aHPATHSi:
-                    hRESTRICT += hri
-        curPATHSi = aHPATHSi
-    
-    ###---SIDE BRANCHES, FINAL ORDER OF HEIRARCHY
-    ###   FROM TIPS THAT ARE NOT IN AN EXISTING PATH
-    ###   BACK TO ANY OTHER POINT THAT IS ALREADY ON A PATH
-    aDRAWNi = []
-    aDRAWNi += aMAINi
-    for oH in allHPATHSi:
-        for o in oH:
-            aDRAWNi += o
-    aTPATHSi = []
-    for a in aTIPSi:
-        if not a in aDRAWNi:
-            aPATHi = findChargePath(oCharge, a, sgarr, aDRAWNi)
-            aDRAWNi += aPATHi
-            aTPATHSi.append(aPATHi)
-            
-    return aMAINi, allHPATHSi, aTPATHSi
-
-def voxelByVertex(ob, gs):
-###---'VOXELIZES' VERTS IN A MESH TO LIST [(x,y,z),(x,y,z)]
-###   W/ RESPECT GSCALE AND OB ORIGIN (B/C SHOULD BE ORIGIN OBJ)
-    orig = ob.location
-    ll = []
-    for v in ob.data.vertices:
-        x = int( v.co.x / gs )
-        y = int( v.co.y / gs )
-        z = int( v.co.z / gs )      
-        ll.append((x,y,z))
-    return ll
-    
-def voxelByRays(ob, orig, gs):
-###--- MESH INTO A 3DGRID W/ RESPECT GSCALE AND BOLT ORIGIN
-###   -DOES NOT TAKE OBJECT ROTATION/SCALE INTO ACCOUNT
-###   -THIS IS A HORRIBLE, INEFFICIENT FUNCTION
-###    MAYBE THE RAYCAST/GRID THING ARE A BAD IDEA. BUT I 
-###    HAVE TO 'VOXELIZE THE OBJECT W/ RESCT TO GSCALE/ORIGIN
-    bbox = ob.bound_box
-    bbxL = bbox[0][0]; bbxR = bbox[4][0]
-    bbyL = bbox[0][1]; bbyR = bbox[2][1]
-    bbzL = bbox[0][2]; bbzR = bbox[1][2]
-    xct = int((bbxR - bbxL) / gs)
-    yct = int((bbyR - bbyL) / gs)
-    zct = int((bbzR - bbzL) / gs)
-    xs = int(xct/2); ys = int(yct/2); zs = int(zct/2)
-    print('  CASTING', xct, '/', yct, '/', zct, 'cells, total:', xct*yct*zct, 'in obj-', ob.name)    
-    ll = []
-    rc = 100    ###---DISTANCE TO CAST FROM
-    ###---RAYCAST TOP/BOTTOM
-    print('  RAYCASTING TOP/BOTTOM')
-    for x in range(xct):
-        for y in range(yct):
-            xco = bbxL + (x*gs);  yco = bbyL + (y*gs)
-            v1 = ((xco, yco,  rc));    v2 = ((xco, yco, -rc))            
-            vz1 = ob.ray_cast(v1,v2);   vz2 = ob.ray_cast(v2,v1)            
-            if vz1[2] != -1: ll.append((x-xs, y-ys, int(vz1[0][2] * (1/gs)) ))
-            if vz2[2] != -1: ll.append((x-xs, y-ys, int(vz2[0][2] * (1/gs)) ))
-    ###---RAYCAST FRONT/BACK
-    print('  RAYCASTING FRONT/BACK')    
-    for x in range(xct):
-        for z in range(zct):
-            xco = bbxL + (x*gs);  zco = bbzL + (z*gs)
-            v1 = ((xco, rc,  zco));    v2 = ((xco, -rc, zco))            
-            vy1 = ob.ray_cast(v1,v2);   vy2 = ob.ray_cast(v2,v1)            
-            if vy1[2] != -1: ll.append((x-xs, int(vy1[0][1] * (1/gs)), z-zs))
-            if vy2[2] != -1: ll.append((x-xs, int(vy2[0][1] * (1/gs)), z-zs))
-    ###---RAYCAST LEFT/RIGHT
-    print('  RAYCASTING LEFT/RIGHT')
-    for y in range(yct):
-        for z in range(zct):
-            yco = bbyL + (y*gs);  zco = bbzL + (z*gs)
-            v1 = ((rc, yco,  zco));    v2 = ((-rc, yco, zco))            
-            vx1 = ob.ray_cast(v1,v2);   vx2 = ob.ray_cast(v2,v1)            
-            if vx1[2] != -1: ll.append((int(vx1[0][0] * (1/gs)), y-ys, z-zs))            
-            if vx2[2] != -1: ll.append((int(vx2[0][0] * (1/gs)), y-ys, z-zs))
-
-    ###---ADD IN NEIGHBORS SO BOLT WONT GO THRU
-    nlist = []
-    for l in ll:
-        nl = getStencil3D_26(l[0], l[1], l[2])
-        nlist += nl
-
-    ###---DEDUPE
-    print('  ADDED NEIGHBORS, DEDUPING...')    
-    rlist = deDupe(ll+nlist)
-    qlist = []
-    
-    ###---RELOCATE GRID W/ RESPECT GSCALE AND BOLT ORIGIN
-    ###   !!!NEED TO ADD IN OBJ ROT/SCALE HERE SOMEHOW...
-    od = Vector(( (ob.location[0] - orig[0]) / gs,
-                  (ob.location[1] - orig[1]) / gs,
-                  (ob.location[2] - orig[2]) / gs ))
-    for r in rlist:
-        qlist.append((r[0]+int(od[0]), r[1]+int(od[1]), r[2]+int(od[2]) ))
-
-    return qlist
-
-def fakeGroundChargePlane(z, charge):
-    eCL = []
-    xy = abs(z)/2
-    eCL += [(0, 0, z, charge)]    
-    eCL += [(xy, 0, z, charge)]
-    eCL += [(0, xy, z, charge)]
-    eCL += [(-xy, 0, z, charge)]
-    eCL += [(0, -xy, z, charge)]
-    return eCL
-
-def addCharges(ll, charge):
-###---IN: ll - [(x,y,z), (x,y,z)], charge - w
-###   OUT clist - [(x,y,z,w), (x,y,z,w)]
-    clist = []
-    for l in ll:
-        clist.append((l[0], l[1], l[2], charge))
-    return clist
-        
-######################################################################
-########################### ALGORITHM FXNS ###########################
-############################## FROM FSLG #############################
-######################################################################
-def getGrowthProbability_KEEPFORREFERENCE(uN, aList):
-    ###---IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES
-    ###   OUT: LIST OF [(XYZ), POT, PROB]
-    cList = splitList(aList, 0)
-    oList = splitList(aList, 1)
-    Omin, Omax = getLowHigh(oList)
-    if Omin == Omax: Omax += notZero; Omin -= notZero
-    PdL = []
-    E = 0
-    E = notZero   ###===DIVISOR FOR (FSLG - Eqn. 12)
-    for o in oList:
-        Uj = (o - Omin) / (Omax - Omin) ###===(FSLG - Eqn. 13)
-        E += pow(Uj, uN)
-    for oi in range(len(oList)):
-        o = oList[oi]
-        Ui = (o - Omin) / (Omax - Omin)
-        Pd = (pow(Ui, uN)) / E ###===(FSLG - Eqn. 12)
-        PdINT = Pd * 100
-        PdL.append(Pd)
-    return PdL 
-
-###---WORK IN PROGRESS, TRYING TO SPEED THESE UP
-def fslg_e13(x, min, max, u): return pow((x - min) / (max - min), u)
-def addit(x,y):return x+y
-def fslg_e12(x, min, max, u, e): return (fslg_e13(x, min, max, u) / e) * 100
-
-def getGrowthProbability(uN, aList):
-    ###---IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES
-    ###   OUT: LIST OF PROB
-    cList = splitList(aList, 0)
-    oList = splitList(aList, 1)
-    Omin, Omax = getLowHigh(oList)
-    if Omin == Omax: Omax += notZero; Omin -= notZero
-    PdL = []
-    E = notZero
-    minL = [Omin for q in range(len(oList))]
-    maxL = [Omax for q in range(len(oList))]
-    uNL =  [uN   for q in range(len(oList))]
-    E = sum(map(fslg_e13, oList, minL, maxL, uNL))
-    EL = [E for q in range(len(oList))]
-    mp = map(fslg_e12, oList, minL, maxL, uNL, EL)
-    for m in mp: PdL.append(m)
-    return PdL 
-
-def updatePointCharges(p, cList, eList = []):
-    ###---IN: pNew -NEW GROWTH CELL
-    ###       cList -OLD CANDIDATE SITES, eList -SAME
-    ###   OUT: LIST OF NEW CHARGE AT CANDIDATE SITES
-    r1 = 1/2        ###===(FSLG - Eqn. 10)
-    nOiL = []    
-    for oi in range(len(cList)):
-        o = cList[oi][1]
-        c = cList[oi][0]
-        iOe = 0
-        rit = dist(c[0], c[1], c[2], p[0], p[1], p[2])        
-        iOe += (1 - (r1/rit))
-        Oit =  o + iOe            
-        nOiL.append((c, Oit))
-    return nOiL
-
-def initialPointCharges(pList, cList, eList = []):
-    ###---IN: p -CHARGED CELL (XYZ), cList -CANDIDATE SITES (XYZ, POT, PROB)
-    ###   OUT: cList -WITH POTENTIAL CALCULATED 
-    r1 = 1/2        ###===(FSLG - Eqn. 10)
-    npList = []
-    for p in pList:
-        npList.append(((p[0], p[1], p[2]), 1.0))
-    for e in eList:
-        npList.append(((e[0], e[1], e[2]), e[3]))
-    OiL = []
-    for i in cList:
-        Oi = 0
-        for j in npList:
-            if i != j[0]:
-                rij = dist(i[0], i[1], i[2], j[0][0], j[0][1], j[0][2])
-                Oi += (1 - (r1 / rij)) * j[1] ### CHARGE INFLUENCE
-        OiL.append(((i[0], i[1], i[2]), Oi))
-    return OiL
-
-def getCandidateSites(aList, iList = []):
-    ###---IN: aList -(X,Y,Z) OF CHARGED CELL SITES, iList -insulator sites
-    ###   OUT: CANDIDATE LIST OF GROWTH SITES [(X,Y,Z)]
-    tt1 = time.clock()    
-    cList = []
-    for c in aList:
-        tempList = getStencil3D_26(c[0], c[1], c[2])
-        for t in tempList:
-            if not t in aList and not t in iList:
-                cList.append(t)
-    ncList = deDupe(cList)
-    tt2 = time.clock()	
-    #print('FXNTIMER:getCandidateSites:', tt2-tt1, 'check 26 against:', len(aList)+len(iList))    
-    return ncList
-
-######################################################################
-############################# SETUP FXNS #############################
-######################################################################
-def setupObjects():
-    oOB = bpy.data.objects.new('ELorigin', None)
-    oOB.location = ((0,0,10))
-    bpy.context.scene.objects.link(oOB)
-
-    gOB = bpy.data.objects.new('ELground', None)
-    gOB.empty_draw_type = 'ARROWS'
-    bpy.context.scene.objects.link(gOB)
-    
-    cME = makeMeshCube(1)
-    cOB = bpy.data.objects.new('ELcloud', cME)
-    cOB.location = ((-2,8,12))
-    cOB.hide_render = True    
-    bpy.context.scene.objects.link(cOB)
-    
-    iME = makeMeshCube(1)
-    for v in iME.vertices: 
-        xyl = 6.5; zl = .5
-        v.co[0] = v.co[0] * xyl
-        v.co[1] = v.co[1] * xyl
-        v.co[2] = v.co[2] * zl
-    iOB = bpy.data.objects.new('ELinsulator', iME)    
-    iOB.location = ((0,0,5))
-    iOB.hide_render = True
-    bpy.context.scene.objects.link(iOB)
-
-    try:
-        scn.OOB = 'ELorigin'
-        scn.GOB = 'ELground'
-        scn.COB = 'ELcloud'
-        scn.IOB = 'ELinsulator'
-    except: pass
-
-def checkSettings():
-    check = True
-    if scn.OOB == "": 
-        print('ERROR: NO ORIGIN OBJECT SELECTED')
-        check = False
-    if scn.GROUNDBOOL and scn.GOB == "":
-        print('ERROR: NO GROUND OBJECT SELECTED')
-        check = False
-    if scn.CLOUDBOOL and scn.COB == "":
-        print('ERROR: NO CLOUD OBJECT SELECTED')        
-        check = False
-    if scn.IBOOL and scn.IOB == "":
-        print('ERROR: NO INSULATOR OBJECT SELECTED')        
-        check = False
-    #should make a popup here
-    return check
-
-
-######################################################################
-############################### MAIN #################################
-######################################################################
-def FSLG():
-###======FAST SIMULATION OF LAPLACIAN GROWTH======###
-    print('\n<<<<<<------GO GO GADGET: FAST SIMULATION OF LAPLACIAN GROWTH!')
-    tc1 = time.clock()
-    TSTEPS = scn.TSTEPS
-
-    obORIGIN = scn.objects[scn.OOB]
-    obGROUND = scn.objects[scn.GOB]    
-    scn.ORIGIN = obORIGIN.location
-    scn.GROUNDZ = int((obGROUND.location[2] - scn.ORIGIN[2]) / scn.GSCALE)
-    
-    ###====== 1) INSERT INTIAL CHARGE(S) POINT (USES VERTS IF MESH)
-    cgrid = [(0, 0, 0)]
-    if obORIGIN.type == 'MESH':
-        print("<<<<<<------ORIGIN OBJECT IS MESH, 'VOXELIZING' INTIAL CHARGES FROM VERTS")
-        cgrid = voxelByVertex(obORIGIN, scn.GSCALE)
-        if scn.VMMESH:
-            print("<<<<<<------CANNOT CLASSIFY STROKE FROM VERT ORIGINS YET, NO MULTI-MESH OUTPUT")
-            scn.VMMESH = False; scn.VSMESH = True
-
-    ###---GROUND CHARGE CELL / INSULATOR LISTS (eChargeList/icList)
-    eChargeList = []; icList = []
-    if scn.GROUNDBOOL:
-        eChargeList = fakeGroundChargePlane(scn.GROUNDZ, scn.GROUNDC)
-    if scn.CLOUDBOOL:
-        print("<<<<<<------'VOXELIZING' CLOUD OBJECT (COULD TAKE SOME TIME)")
-        obCLOUD = scn.objects[scn.COB]
-        eChargeListQ = voxelByRays(obCLOUD, scn.ORIGIN, scn.GSCALE)
-        eChargeList = addCharges(eChargeListQ, scn.CLOUDC)
-        print('<<<<<<------CLOUD OBJECT CELL COUNT = ', len(eChargeList) )        
-    if scn.IBOOL:
-        print("<<<<<<------'VOXELIZING' INSULATOR OBJECT (COULD TAKE SOME TIME)")
-        obINSULATOR = scn.objects[scn.IOB]
-        icList = voxelByRays(obINSULATOR, scn.ORIGIN, scn.GSCALE)
-        print('<<<<<<------INSULATOR OBJECT CELL COUNT = ', len(icList) )
-        #writeArrayToCubes(icList, scn.GSCALE, scn.ORIGIN)
-        #return 'THEEND'
-        
-    ###====== 2) LOCATE CANDIDATE SITES AROUND CHARGE
-    cSites = getCandidateSites(cgrid, icList)
-    
-    ###====== 3) CALC POTENTIAL AT EACH SITE (Eqn. 10)
-    cSites = initialPointCharges(cgrid, cSites, eChargeList)
-    
-    ts = 1
-    while ts <= TSTEPS:
-        ###====== 1) SELECT NEW GROWTH SITE (Eqn. 12)
-        ###===GET PROBABILITIES AT CANDIDATE SITES
-        gProbs = getGrowthProbability(scn.BIGVAR, cSites)
-        ###===CHOOSE NEW GROWTH SITE BASED ON PROBABILITIES
-        gSitei = weightedRandomChoice(gProbs)
-        gsite  = cSites[gSitei][0]
-
-        ###====== 2) ADD NEW POINT CHARGE AT GROWTH SITE
-        ###===ADD NEW GROWTH CELL TO GRID
-        cgrid.append(gsite)
-        ###===REMOVE NEW GROWTH CELL FROM CANDIDATE SITES
-        cSites.remove(cSites[gSitei])
-
-        ###====== 3) UPDATE POTENTIAL AT CANDIDATE SITES (Eqn. 11)
-        cSites = updatePointCharges(gsite, cSites, eChargeList)        
-
-        ###====== 4) ADD NEW CANDIDATES SURROUNDING GROWTH SITE
-        ###===GET CANDIDATE 'STENCIL'
-        ncSitesT = getCandidateSites([gsite], icList)
-        ###===REMOVE CANDIDATES ALREADY IN CANDIDATE LIST OR CHARGE GRID
-        ncSites = []
-        cSplit = splitList(cSites, 0)
-        for cn in ncSitesT:
-            if not cn in cSplit and \
-            not cn in cgrid:
-                ncSites.append((cn, 0))
-
-        ###====== 5) CALC POTENTIAL AT NEW CANDIDATE SITES (Eqn. 10)
-        ncSplit = splitList(ncSites, 0)        
-        ncSites = initialPointCharges(cgrid, ncSplit, eChargeList)
-
-        ###===ADD NEW CANDIDATE SITES TO CANDIDATE LIST
-        for ncs in ncSites:
-            cSites.append(ncs)
-
-        ###===ITERATION COMPLETE
-        istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS) 
-        istr12 = ' | GROUNDZ: ' + str(scn.GROUNDZ) + ' | '
-        istr2 = 'CANDS: ' + str(len(cSites)) + ' | '
-        istr3 = 'GSITE: ' + str(gsite)
-        print(istr1 + istr12 + istr2 + istr3)        
-        ts += 1
-        
-        ###---EARLY TERMINATION FOR GROUND/CLOUD STRIKE
-        if scn.GROUNDBOOL:
-            if gsite[2] == scn.GROUNDZ:
-                ts = TSTEPS+1
-                print('<<<<<<------EARLY TERMINATION DUE TO GROUNDSTRIKE')
-                continue
-        if scn.CLOUDBOOL:
-            #if gsite in cloudList:
-            if gsite in splitListCo(eChargeList):
-                ts = TSTEPS+1
-                print('<<<<<<------EARLY TERMINATION DUE TO CLOUDSTRIKE')
-                continue            
-
-    tc2 = time.clock()
-    tcRUN = tc2 - tc1
-    print('<<<<<<------LAPLACIAN GROWTH LOOP COMPLETED: ' + str(len(cgrid)) + ' / ' + str(tcRUN)[0:5] + ' SECONDS')
-    print('<<<<<<------VISUALIZING DATA')
-
-    reportSTRING = getReportString(tcRUN)    
-    ###---VISUALIZE ARRAY
-    visualizeArray(cgrid, obORIGIN, scn.GSCALE, scn.VMMESH, scn.VSMESH, scn.VCUBE, scn.VVOX, reportSTRING)
-    print('<<<<<<------COMPLETE')
-
-######################################################################
-################################ GUI #################################
-######################################################################
-###---NOT IN UI
-bpy.types.Scene.ORIGIN = bpy.props.FloatVectorProperty(name = "origin charge")
-bpy.types.Scene.GROUNDZ = bpy.props.IntProperty(name = "ground Z coordinate")
-bpy.types.Scene.HORDER = bpy.props.IntProperty(name = "secondary paths orders")
-###---IN UI
-bpy.types.Scene.TSTEPS = bpy.props.IntProperty(
-    name = "iterations", description = "number of cells to create, will end early if hits ground plane or cloud")
-bpy.types.Scene.GSCALE = bpy.props.FloatProperty(
-    name = "grid unit size", description = "scale of cells, .25 = 4 cells per blenderUnit")
-bpy.types.Scene.BIGVAR = bpy.props.FloatProperty(
-    name = "straightness", description = "straightness/branchiness of bolt, <2 is mush, >12 is staight line, 6.3 is good")
-bpy.types.Scene.GROUNDBOOL = bpy.props.BoolProperty(
-    name = "use ground object", description = "use ground plane or not")
-bpy.types.Scene.GROUNDC = bpy.props.IntProperty(
-    name = "ground charge", description = "charge of ground plane")
-bpy.types.Scene.CLOUDBOOL = bpy.props.BoolProperty(
-    name = "use cloud object", description = "use cloud obj, attracts and terminates like ground but any obj instead of z plane, can slow down loop if obj is large, overrides ground")
-bpy.types.Scene.CLOUDC = bpy.props.IntProperty(
-    name = "cloud charge", description = "charge of a cell in cloud object (so total charge also depends on obj size)")
-
-bpy.types.Scene.VMMESH = bpy.props.BoolProperty(
-    name = "multi mesh", description = "output to multi-meshes for different materials on main/sec/side branches")
-bpy.types.Scene.VSMESH = bpy.props.BoolProperty(
-    name = "single mesh", description = "output to single mesh for using build modifier and particles for effects")
-bpy.types.Scene.VCUBE = bpy.props.BoolProperty(
-    name = "cubes", description = "CTRL-J after run to JOIN, outputs a bunch of cube objest, mostly for testing")
-bpy.types.Scene.VVOX = bpy.props.BoolProperty(        
-    name = "voxel (experimental)", description = "output to a voxel file to bpy.data.filepath\FSLGvoxels.raw - doesn't work well right now")
-bpy.types.Scene.IBOOL = bpy.props.BoolProperty(
-    name = "use insulator object", description = "use insulator mesh object to prevent growth of bolt in areas")
-bpy.types.Scene.OOB = bpy.props.StringProperty(description = "origin of bolt, can be an Empty, if obj is mesh will use all verts as charges")
-bpy.types.Scene.GOB = bpy.props.StringProperty(description = "object to use as ground plane, uses z coord only")
-bpy.types.Scene.COB = bpy.props.StringProperty(description = "object to use as cloud, best to use a cube")
-bpy.types.Scene.IOB = bpy.props.StringProperty(description = "object to use as insulator, 'voxelized' before generating bolt, can be slow")
-
-###---DEFAULT USER SETTINGS
-scn.TSTEPS = 350
-scn.HORDER = 1
-scn.GSCALE = 0.12
-scn.BIGVAR = 6.3
-scn.GROUNDBOOL = True
-scn.GROUNDC = -250
-scn.CLOUDBOOL = False
-scn.CLOUDC = -1
-scn.VMMESH = True
-scn.VSMESH = False
-scn.VCUBE = False
-scn.VVOX = False
-scn.IBOOL = False
-try:
-    scn.OOB = "ELorigin"
-    scn.GOB = "ELground"
-    scn.COB = "ELcloud"
-    scn.IOB = "ELinsulator"    
-except: pass
-### TESTING
-if False:
-#if True:
-    #scn.BIGVAR = 6.3
-    #scn.VSMESH = True
-    #scn.VMMESH = False
-    #scn.VCUBE = True
-    #scn.TSTEPS = 7500
-    scn.TSTEPS = 100
-    #scn.GROUNDC = -500
-    #scn.CLOUDC = -5
-    #scn.GROUNDBOOL = False
-    #scn.CLOUDBOOL = True
-    
-    #scn.IBOOL = True
-
-class runFSLGLoopOperator(bpy.types.Operator):
-    '''By The Mighty Hammer Of Thor!!!'''
-    bl_idname = "object.runfslg_operator"
-    bl_label = "run FSLG Loop Operator"
-
-    def execute(self, context):
-        if checkSettings():
-            FSLG()
-        else: pass
-        return {'FINISHED'}
-    
-class setupObjectsOperator(bpy.types.Operator):
-    '''create origin/ground/cloud/insulator objects'''
-    bl_idname = "object.setup_objects_operator"
-    bl_label = "Setup Objects Operator"
-
-    def execute(self, context):
-        setupObjects()        
-        return {'FINISHED'}    
-
-class OBJECT_PT_fslg(bpy.types.Panel):
-    bl_label = "Laplacian Lightning - v0.2.6"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_context = "objectmode"
-
-    def draw(self, context):
-        scn = context.scene
-        layout = self.layout
-        colR = layout.column()        
-        #row1 = layout.row()
-        #colL = row1.column()
-        #colR = row1.column()
-        colR.label('-for progress open console-')
-        colR.label('Help > Toggle System Console')        
-        colR.prop(scn, 'TSTEPS')
-        colR.prop(scn, 'GSCALE')        
-        colR.prop(scn, 'BIGVAR')
-        colR.operator('object.setup_objects_operator', text = 'create setup objects')        
-        colR.label('origin object')
-        colR.prop_search(scn, "OOB",  context.scene, "objects")        
-        colR.prop(scn, 'GROUNDBOOL')
-        colR.prop_search(scn, "GOB",  context.scene, "objects")        
-        colR.prop(scn, 'GROUNDC') 
-        colR.prop(scn, 'CLOUDBOOL')
-        colR.prop_search(scn, "COB",  context.scene, "objects")        
-        colR.prop(scn, 'CLOUDC')
-        colR.prop(scn, 'IBOOL')
-        colR.prop_search(scn, "IOB",  context.scene, "objects")
-        colR.operator('object.runfslg_operator', text = 'generate lightning')
-        #col.prop(scn, 'HORDER')
-        colR.prop(scn, 'VMMESH')
-        colR.prop(scn, 'VSMESH')        
-        colR.prop(scn, 'VCUBE')
-        colR.prop(scn, 'VVOX')
-
-def getReportString(rtime):
-    rSTRING1 = 't:' + str(scn.TSTEPS) + ',sc:' + str(scn.GSCALE)[0:4] + ',uv:' + str(scn.BIGVAR)[0:4] + ',' 
-    rSTRING2 = 'ori:' + str(scn. ORIGIN[0]) + '/' + str(scn. ORIGIN[1]) + '/' + str(scn. ORIGIN[2]) + ','
-    rSTRING3 = 'gz:' + str(scn.GROUNDZ) + ',gc:' + str(scn.GROUNDC) + ',rtime:' + str(int(rtime))
-    return rSTRING1 + rSTRING2 + rSTRING3
-
-def addReportProp(ob, str):
-    bpy.types.Object.FSLG_REPORT = bpy.props.StringProperty(
-	   name = 'fslg_report', default = '')
-    ob.FSLG_REPORT = str
-        
-def register():
-    bpy.utils.register_class(runFSLGLoopOperator)    
-    bpy.utils.register_class(setupObjectsOperator)
-    bpy.utils.register_class(OBJECT_PT_fslg)
-
-def unregister():
-    bpy.utils.unregister_class(runFSLGLoopOperator)    
-    bpy.utils.unregister_class(setupObjectsOperator)    
-    bpy.utils.unregister_class(OBJECT_PT_fslg)
-
-if __name__ == "__main__":
-    ### RUN FOR TESTING
-    #FSLG()
-    
-    ### UI
-    register()
-    pass
-
-###########################
-##### FXN BENCHMARKS ######
-###########################
-def BENCH():
-    print('\n\n\n--->BEGIN BENCHMARK')
-    bt0 = time.clock()
-    ###---MAKE A BIG LIST
-    tsize = 25
-    tlist = []
-    for x in range(tsize):
-        for y in range(tsize):
-            for z in range(tsize):
-                tlist.append((x,y,z))
-                tlist.append((x,y,z))
-
-    ###---FUNCTION TO TEST
-    bt1 = time.clock()
-
-    #ll = deDupe(tlist)
-    #ll = f5(tlist)
-    print('LENS - ', len(tlist), len(ll) )
-
-    bt2 = time.clock()
-    btRUNb = bt2 - bt1
-    btRUNa = bt1 - bt0
-    print('--->SETUP TIME    : ', btRUNa)
-    print('--->BENCHMARK TIME: ', btRUNb)
-    print('--->GRIDSIZE: ', tsize, ' - ', tsize*tsize*tsize)
-    
-#BENCH()    
-
-
-##################################
-################################
diff --git a/release/scripts/addons_contrib/object_mangle_tools.py b/release/scripts/addons_contrib/object_mangle_tools.py
deleted file mode 100644
index a0e13e1..0000000
--- a/release/scripts/addons_contrib/object_mangle_tools.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# mangle_tools.py (c) 2011 Phil Cote (cotejrp1)
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-bl_info = {
-    "name": "Mangle Tools",
-    "author": "Phil Cote",
-    "version": (0, 2),
-    "blender": (2, 6, 3),
-    "location": "View3D > Tools",
-    "description": "Set of tools to mangle curves, meshes, and shape keys",
-    "warning": "", # used for warning icon and text in addons panel
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=29071",
-    "category": "Object"}
-
-import bpy
-import random
-import time
-from math import pi
-import bmesh
-
-def move_coordinate(context, co, is_curve=False):
-    xyz_const = context.scene.constraint_vector
-    random.seed(time.time())
-    multiplier = 1
-
-    # For curves, we base the multiplier on the circumference formula.
-    # This helps make curve changes more noticable.
-    if is_curve:
-        multiplier = 2 * pi
-    random_mag = context.scene.random_magnitude
-    if xyz_const[0]:    
-        co.x += .01 * random.randrange( -random_mag, random_mag ) * multiplier
-    if xyz_const[1]:
-        co.y += .01 * random.randrange( -random_mag, random_mag )  * multiplier
-    if xyz_const[2]:
-        co.z += .01 * random.randrange( -random_mag, random_mag ) * multiplier
-
-
-class MeshManglerOperator(bpy.types.Operator):
-    '''push vertices on the selected object around in random directions to 
-    create a crumpled look'''
-    bl_idname = "ba.mesh_mangler"
-    bl_label = "Mangle Mesh"
-    bl_options = { "REGISTER", "UNDO" }
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob != None and ob.type == 'MESH'
-
-    def execute(self, context):
-        mesh = context.active_object.data
-        bm = bmesh.new()
-        bm.from_mesh(mesh)
-        verts, faces = bm.verts, bm.faces
-        randomMag = context.scene.random_magnitude
-        random.seed( time.time() )
-
-        if mesh.shape_keys != None:
-            self.report( {"INFO"}, "Cannot mangle mesh: Shape keys present" )
-            return {'CANCELLED'}
-        
-        for vert in verts:
-            xVal = .01 * random.randrange( -randomMag, randomMag )
-            yVal = .01 * random.randrange( -randomMag, randomMag)
-            zVal = .01 * random.randrange( -randomMag, randomMag )
-            vert.co.x = vert.co.x + xVal
-            vert.co.y = vert.co.y + yVal
-            vert.co.z = vert.co.z + zVal
-                
-        bm.to_mesh(mesh)   
-        mesh.update()
-        return {'FINISHED'}
-
-
-class AnimanglerOperator(bpy.types.Operator):
-    '''makes a shape key and pushes the verts around on it to set up for random pulsating animation'''
-    bl_idname = "ba.ani_mangler"
-    bl_label = "Mangle Shape Key"
-
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob != None and ob.type in [ 'MESH', 'CURVE' ]
-
-    def execute(self, context):
-        scn = context.scene
-        mangleName = scn.mangle_name
-        ob = context.object
-        shapeKey = ob.shape_key_add( name=mangleName )
-        verts = shapeKey.data
-        
-        for vert in verts:
-            move_coordinate(context, vert.co, is_curve=ob.type=='CURVE')
-            
-        return {'FINISHED'}
-
-
-class CurveManglerOp(bpy.types.Operator):
-    '''Mangles a curve to the degree the user specifies'''
-    bl_idname = "ba.curve_mangler"
-    bl_label = "Mangle Curve"
-    bl_options = { 'REGISTER', 'UNDO' }
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob != None and ob.type == "CURVE"
-
-
-    def execute(self, context):
-
-        ob = context.active_object
-        if ob.data.shape_keys != None:
-            self.report({"INFO"}, "Cannot mangle curve.  Shape keys present")
-            return {'CANCELLED'}
-        splines = context.object.data.splines
-        
-        for spline in splines:
-            if spline.type == 'BEZIER':
-                points = spline.bezier_points
-            elif spline.type in ('POLY', 'NURBS'):
-                points = spline.points
-
-            for point in points:
-                move_coordinate(context, point.co, is_curve=True)
-
-        return {'FINISHED'}
-
-
-class MangleToolsPanel(bpy.types.Panel):
-    bl_label = "Mangle Tools"
-    bl_space_type = "VIEW_3D"
-    bl_region_type="TOOLS"
-    bl_context = "objectmode"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    def draw(self, context):
-        scn = context.scene
-        layout = self.layout
-        col = layout.column()
-        col.prop(scn, "constraint_vector")
-        col.prop(scn, "random_magnitude")
-
-        col.operator("ba.curve_mangler")
-        col.operator("ba.mesh_mangler")
-        col.separator()
-        col.prop(scn, "mangle_name")
-        col.operator("ba.ani_mangler")
-
-
-IntProperty = bpy.props.IntProperty
-StringProperty = bpy.props.StringProperty
-BoolVectorProperty = bpy.props.BoolVectorProperty
-
-def register():
-    bpy.utils.register_class(AnimanglerOperator)
-    bpy.utils.register_class(MeshManglerOperator)
-    bpy.utils.register_class(CurveManglerOp)
-    bpy.utils.register_class(MangleToolsPanel)
-    scnType = bpy.types.Scene
-    
-                                    
-    scnType.constraint_vector = BoolVectorProperty(name="Mangle Constraint", 
-                                default=(True,True,True),
-                                subtype='XYZ',
-                                description="Constrains Mangle Direction")
-                                
-    scnType.random_magnitude = IntProperty( name = "Mangle Severity", 
-                              default = 10, min = 1, max = 30, 
-                              description = "Severity of mangling")
-    
-    scnType.mangle_name = StringProperty(name="Shape Key Name",
-                             default="mangle",
-                             description="Name given for mangled shape keys")
-def unregister():
-    bpy.utils.unregister_class(AnimanglerOperator)
-    bpy.utils.unregister_class(MeshManglerOperator)
-    bpy.utils.unregister_class(MangleToolsPanel)
-    bpy.utils.unregister_class(CurveManglerOp)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/object_render_wire.py b/release/scripts/addons_contrib/object_render_wire.py
deleted file mode 100644
index c8d60ac..0000000
--- a/release/scripts/addons_contrib/object_render_wire.py
+++ /dev/null
@@ -1,424 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See th
-# 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.
-#
-# object_render_wire.py liero, meta-androcto,
-# Yorik van Havre, Alejandro Sierra, Howard Trickey
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    "name": "Render Wireframe",
-    "author": "Community",
-    "description": " WireRender & WireSoild modes",
-    "version": (2, 3),
-    "blender": (2, 6, 3),
-    "location": "Object > Render Wireframe",
-    "warning": '',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts',
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
-                   'func=detail&aid=26997',
-    'category': 'Object'}
-
-import bpy, mathutils
-
-cube_faces = [ [0,3,2,1], [5,6,7,4], [0,1,5,4],
-               [7,6,2,3], [2,6,5,1], [0,4,7,3] ]
-cube_normals = [ mathutils.Vector((0,0,-1)),
-                 mathutils.Vector((0,0,1)),
-                 mathutils.Vector((0,-1,0)),
-                 mathutils.Vector((0,1,0)),
-                 mathutils.Vector((1,0,0)),
-                 mathutils.Vector((-1,0,0)) ]
-
-def create_cube(me, v, d):
-    x = v.co.x
-    y = v.co.y
-    z = v.co.z
-    coords=[ [x-d,y-d,z-d], [x+d,y-d,z-d], [x+d,y+d,z-d], [x-d,y+d,z-d],
-         [x-d,y-d,z+d], [x+d,y-d,z+d], [x+d,y+d,z+d], [x-d,y+d,z+d] ]
-    for coord in coords:
-        me.vertices.add(1)
-        me.vertices[-1].co = mathutils.Vector(coord)
-
-def norm_dot(e, k, fnorm, me):
-    v = me.vertices[e[1]].co - me.vertices[e[0]].co
-    if k == 1:
-        v = -v
-    v.normalize()
-    return v * fnorm
-
-def fill_cube_face(me, index, f):
-    return [index + cube_faces[f][i] for i in range(4)]
-
-# Coords of jth point of face f in cube instance i
-def cube_face_v(me, f, i, j):
-    return me.vertices[i + cube_faces[f][j]].co
-
-def cube_face_center(me, f, i):
-    return 0.5 * (cube_face_v(me, f, i, 0) + \
-                  cube_face_v(me, f, i, 2))
-
-# Return distance between points on two faces when
-# each point is projected onto the plane that goes through
-# the face center and is perpendicular to the line
-# through the face centers.
-def projected_dist(me, i1, i2, f1, f2, j1, j2):
-    f1center = cube_face_center(me, f1, i1)
-    f2center = cube_face_center(me, f2, i2)
-    axis_norm = (f2center - f1center).normalized()
-    v1 = cube_face_v(me, f1, i1, j1)
-    v2 = cube_face_v(me, f2, i2, j2)
-    v1proj = v1 - (axis_norm * (v1 - f1center)) * axis_norm
-    v2proj = v2 - (axis_norm * (v2 - f2center)) * axis_norm
-    return (v2proj - v1proj).length
-
-def skin_edges(me, i1, i2, f1, f2):
-    # Connect verts starting at i1 forming cube face f1
-    # to those starting at i2 forming cube face f2.
-    # Need to find best alignment to avoid a twist.
-    shortest_length = 1e6
-    f2_start_index = 0
-    for i in range(4):
-        x = projected_dist(me, i1, i2, f1, f2, 0, i)
-        if x < shortest_length:
-            shortest_length = x
-            f2_start_index = i
-    ans = []
-    j = f2_start_index
-    for i in range(4):
-        fdata = [i1 + cube_faces[f1][i],
-                 i2 + cube_faces[f2][j],
-                 i2 + cube_faces[f2][(j + 1) % 4],
-                 i1 + cube_faces[f1][(i - 1) % 4]]
-        if fdata[3] == 0:
-            fdata = [fdata[3]] + fdata[0:3]
-        ans.extend(fdata)
-        j = (j - 1) % 4
-    return ans
-            
-
-# Return map: v -> list of length len(node_normals) where
-# each element of the list is either None (no assignment)
-# or ((v0, v1), 0 or 1) giving an edge and direction that face is assigned to.
-def find_assignment(me, edges, vert_edges, node_normals):
-    nf = len(node_normals)
-    feasible = {}
-    for e in edges:
-        for k in (0, 1):
-            fds = [(f, norm_dot(e, k, node_normals[f], me)) for f in range(nf)]
-            feasible[(e, k)] = [fd for fd in fds if fd[1] > 0.01]
-    assignment = {}
-    for v, ves in vert_edges.items():
-        assignment[v] = best_assignment(ves, feasible, nf)
-    return assignment
-
-def best_assignment(ves, feasible, nf):
-    apartial = [ None ] * nf
-    return best_assign_help(ves, feasible, apartial, 0.0)[0]
-
-def best_assign_help(ves, feasible, apartial, sumpartial):
-    if len(ves) == 0:
-        return (apartial, sumpartial)
-    else:
-        ek0 = ves[0]
-        vesrest = ves[1:]
-        feas = feasible[ek0]
-        bestsum = 0
-        besta = None
-        for (f, d) in feas:
-            if apartial[f] is None:
-                ap = apartial[:]
-                ap[f] = ek0
-                # sum up d**2 to penalize smaller d's more
-                sp = sumpartial + d*d
-                (a, s) = best_assign_help(vesrest, feasible, ap, sp)
-                if s > bestsum:
-                    bestsum = s
-                    besta = a
-        if besta:
-            return (besta, bestsum)
-        else:
-            # not feasible to assign e0, k0; try to assign rest
-            return best_assign_help(vesrest, feasible, apartial, sumpartial)
-
-def assigned_face(e, assignment):
-    (v0, v1), dir = e
-    a = assignment[v1]
-    for j, ee in enumerate(a):
-        if e == ee:
-            return j
-    return -1
-
-def create_wired_mesh(me2, me, thick):
-    edges = []
-    vert_edges = {}
-    for be in me.edges:
-        if be.select and not be.hide:
-            e = (be.key[0], be.key[1])
-            edges.append(e)
-            for k in (0, 1):
-                if e[k] not in vert_edges:
-                    vert_edges[e[k]] = []
-                vert_edges[e[k]].append((e, k))
-
-    assignment = find_assignment(me, edges, vert_edges, cube_normals)
-
-    # Create the geometry
-    n_idx = {}   
-    for v in assignment:
-        vpos = me.vertices[v]
-        index = len(me2.vertices)
-        # We need to associate each node with the new geometry
-        n_idx[v] = index   
-        # Geometry for the nodes, each one a cube
-        create_cube(me2, vpos, thick)
-
-    # Skin using the new geometry 
-    cfaces = []  
-    for k, f in assignment.items():
-        # Skin the nodes
-        for i in range(len(cube_faces)):
-            if f[i] is None:
-                cfaces.extend(fill_cube_face(me2, n_idx[k], i))
-            else:
-                (v0, v1), dir = f[i]
-                # only skin between edges in forward direction
-                # to avoid making doubles
-                if dir == 1:
-                    # but first make sure other end actually assigned
-                    i2 = assigned_face(((v0, v1), 0), assignment)
-                    if i2 == -1:
-                        cfaces.extend(fill_cube_face(me2, n_idx[k], i))
-                    continue
-                i2 = assigned_face(((v0, v1), 1), assignment)
-                if i2 != -1:
-                    cfaces.extend(skin_edges(me2, n_idx[v0], n_idx[v1], i, i2))
-                else:
-                    # assignment failed for this edge
-                    cfaces.extend(fill_cube_face(me2, n_idx[k], i))
-
-    # adding faces to the mesh
-    me2.tessfaces.add(len(cfaces) // 4)
-    me2.tessfaces.foreach_set("vertices_raw", cfaces)
-    me2.update(calc_edges=True)
-
-# panel containing tools
-def wire_add(mallas):
-    if mallas:
-        bpy.ops.object.select_all(action='DESELECT')
-        bpy.context.scene.objects.active = mallas[0]
-        for o in mallas: o.select = True
-        bpy.ops.object.duplicate()
-        obj, sce = bpy.context.object, bpy.context.scene
-        for mod in obj.modifiers: obj.modifiers.remove(mod)
-        bpy.ops.object.join()
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.select_all(action='SELECT')
-        bpy.ops.mesh.delete(type='ONLY_FACE')
-        bpy.ops.object.mode_set()
-        bpy.ops.object.convert(target='CURVE')
-        if 'wire_object' in sce.objects.keys():
-            sce.objects.get('wire_object').data = obj.data
-            sce.objects.get('wire_object').matrix_world = mallas[0].matrix_world
-            sce.objects.unlink(obj)
-        else:
-            obj.name = 'wire_object'
-        obj.data.resolution_u = 1
-        obj.data.bevel_depth = 0.005
-        obj.data.fill_mode = 'FULL'
-        obj.data.materials.append(bpy.data.materials.get('mat_wireobj'))
-
-    return{'FINISHED'}
-'''
-class VIEW3D_PT_tools_SolidifyWireframe(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_context = "mesh_edit"
-    bl_label = "Solidify Wireframe"
-
-    def draw(self, context):
-        active_obj = context.active_object
-        layout = self.layout
-        col = layout.column(align=True)
-        col.operator("mesh.solidify_wireframe", text="Solidify")
-        col.prop(context.scene, "swThickness")
-        col.prop(context.scene, "swSelectNew")
-'''
-# a class for your operator
-class SolidifyWireframe(bpy.types.Operator):
-    '''Turns the selected edges of a mesh into solid objects'''
-    bl_idname = "mesh.solidify_wireframe"
-    bl_label = "Solidify Wireframe"
-    bl_options = {'REGISTER', 'UNDO'}
-    
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob and ob.type == 'MESH'
-
-    def execute(self, context):
-        # Get the active object
-        ob_act = context.active_object
-        # getting current edit mode
-        currMode = ob_act.mode
-        # switching to object mode
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.select_all(action='DESELECT')
-        # getting mesh data
-        mymesh = ob_act.data
-        #getting new mesh
-        newmesh = bpy.data.meshes.new(mymesh.name + " wire")
-        obj = bpy.data.objects.new(newmesh.name,newmesh)
-        obj.location = ob_act.location
-        obj.rotation_euler = ob_act.rotation_euler
-        obj.scale = ob_act.scale
-        context.scene.objects.link(obj)
-        create_wired_mesh(newmesh, mymesh, context.scene.swThickness)
-
-        # restoring original editmode if needed
-        if context.scene.swSelectNew:
-            obj.select = True
-            context.scene.objects.active = obj
-        else:
-            bpy.ops.object.mode_set(mode=currMode)
-
-        # returning after everything is done
-        return {'FINISHED'}
-		
-class WireMaterials(bpy.types.Operator):
-    bl_idname = 'scene.wire_render'
-    bl_label = 'Create Materials'
-    bl_description = 'Set Up Materials for a Wire Render'
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def execute(self, context):
-        wm = bpy.context.window_manager
-        scn = bpy.context.scene
-
-        if 'mat_clay' not in bpy.data.materials:
-            mat = bpy.data.materials.new('mat_clay')
-            mat.specular_intensity = 0
-        else: mat = bpy.data.materials.get('mat_clay')
-        mat.diffuse_color = wm.col_clay
-        mat.use_shadeless = wm.shadeless_mat
-
-        if 'mat_wire' not in bpy.data.materials:
-            mat = bpy.data.materials.new('mat_wire')
-            mat.specular_intensity = 0
-            mat.use_transparency = True
-            mat.type = 'WIRE'
-            mat.offset_z = 0.1
-        else: mat = bpy.data.materials.get('mat_wire')
-        mat.diffuse_color = wm.col_wire
-        mat.use_shadeless = wm.shadeless_mat
-
-        try: bpy.ops.object.mode_set()
-        except: pass
-
-        if wm.selected_meshes: objetos = bpy.context.selected_objects
-        else: objetos = bpy.data.objects
-
-        mallas = [o for o in objetos if o.type == 'MESH' and o.is_visible(scn)]
-
-        for obj in mallas:
-            scn.objects.active = obj
-            print ('procesando >', obj.name)
-            obj.show_wire = wm.wire_view
-            for mat in obj.material_slots:
-                bpy.ops.object.material_slot_remove()
-            obj.data.materials.append(bpy.data.materials.get('mat_wire'))
-            obj.data.materials.append(bpy.data.materials.get('mat_clay'))
-            obj.material_slots.data.active_material_index = 1
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.mesh.select_all(action='SELECT')
-            bpy.ops.object.material_slot_assign()
-            bpy.ops.object.mode_set()
-
-        if wm.wire_object:
-            if 'mat_wireobj' not in bpy.data.materials:
-                mat = bpy.data.materials.new('mat_wireobj')
-                mat.specular_intensity = 0
-            else: mat = bpy.data.materials.get('mat_wireobj')
-            mat.diffuse_color = wm.col_wire
-            mat.use_shadeless = wm.shadeless_mat
-            wire_add(mallas)
-
-        return{'FINISHED'}
-
-class PanelWMat(bpy.types.Panel):
-    bl_label = 'Setup Wire Render'
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    def draw(self, context):
-        wm = bpy.context.window_manager
-        active_obj = context.active_object
-        layout = self.layout
-
-        column = layout.column(align=True)
-        column.prop(wm, 'col_clay')
-        column.prop(wm, 'col_wire')
-        column = layout.column(align=True)
-        column.prop(wm, 'selected_meshes')
-        column.prop(wm, 'shadeless_mat')
-        column.prop(wm, 'wire_view')
-        column.prop(wm, 'wire_object')
-        column.separator()
-        column.operator('scene.wire_render')
-        column.label(text='- - - - - - - - - - - - - - - - - - - - - -')
-        col = layout.column(align=True)
-        column.label(text='Solid WireFrame')
-        layout.operator("mesh.solidify_wireframe", text="Create Mesh Object")
-        col.prop(context.scene, "swThickness")
-        col.prop(context.scene, "swSelectNew")
-bpy.types.WindowManager.selected_meshes = bpy.props.BoolProperty(name='Selected Meshes', default=False, description='Apply materials to Selected Meshes / All Visible Meshes')
-bpy.types.WindowManager.shadeless_mat = bpy.props.BoolProperty(name='Shadeless', default=False, description='Generate Shadeless Materials')
-bpy.types.WindowManager.col_clay = bpy.props.FloatVectorProperty(name='', description='Clay Color', default=(1.0, 0.9, 0.8), min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
-bpy.types.WindowManager.col_wire = bpy.props.FloatVectorProperty(name='', description='Wire Color', default=(0.1 ,0.0 ,0.0), min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
-bpy.types.WindowManager.wire_view = bpy.props.BoolProperty(name='Viewport Wires', default=False, description='Overlay wires display over solid in Viewports')
-bpy.types.WindowManager.wire_object = bpy.props.BoolProperty(name='Create Curve Object', default=False, description='Very slow! - Add a Wire Object to scene to be able to render wires in Cycles')
-bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness", description="Thickness of the skinned edges", default=0.01)
-bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire", description="If checked, the wire object will be selected after creation", default=True)
-
-# Register the operator
-def solidifyWireframe_menu_func(self, context):
-        self.layout.operator(SolidifyWireframe.bl_idname, text="Solidify Wireframe", icon='PLUGIN')
-
-# Add "Solidify Wireframe" menu to the "Mesh" menu.
-def register():
-        bpy.utils.register_class(WireMaterials)
-        bpy.utils.register_class(PanelWMat)
-        bpy.utils.register_module(__name__)
-        bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness",
-                                                              description="Thickness of the skinned edges",
-                                                              default=0.01)
-        bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire",
-                                                             description="If checked, the wire object will be selected after creation",
-                                                             default=True)
-        bpy.types.VIEW3D_MT_edit_mesh_edges.append(solidifyWireframe_menu_func)
-
-# Remove "Solidify Wireframe" menu entry from the "Mesh" menu.
-def unregister():
-        bpy.utils.unregister_class(WireMaterials)
-        bpy.utils.unregister_class(PanelWMat)
-        bpy.utils.unregister_module(__name__)
-        del bpy.types.Scene.swThickness
-        bpy.types.VIEW3D_MT_edit_mesh_edges.remove(solidifyWireframe_menu_func)
-
-if __name__ == "__main__":
-        register()
diff --git a/release/scripts/addons_contrib/oscurart_futurism.py b/release/scripts/addons_contrib/oscurart_futurism.py
deleted file mode 100644
index 683ff13..0000000
--- a/release/scripts/addons_contrib/oscurart_futurism.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Futurism",
-    "author": "Oscurart",
-    "version": (1, 1),
-    "blender": (2, 5, 9),
-    "location": "Object > Futurism",
-    "description": "Adds a new Mesh Object",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Add Mesh"}
-
-
-import bpy
-
-def object_osc_futurism (self, context,STEP, HOLD):
-    ACTOBJ=bpy.context.active_object # OBJETO ACTIVO
-    FS=bpy.context.scene.frame_start # FRAME START
-    FE=bpy.context.scene.frame_end # FRAME END
-    OBJLIST=[] # LISTA PARA OBJETOS ????
-    FC=FS # FRAME CURRENT
-    OBJNUMBER=1 # SUFIJO DE NUMERO PARA OBJETOS
-    STEPINC=0 # NUMERO PARA EVALUAR LOS PASOS    
-    # SETEO EL FRAME CURRENT
-    bpy.context.scene.frame_set(FS)  
-    
-    OBACT = bpy.context.active_object
-    
-    ## CREO EMPTY
-    bpy.ops.object.add()
-    bpy.context.active_object.name = "FuturismContainer"
-    EMPTY = bpy.context.active_object
-    
-    bpy.context.scene.objects.active = OBACT  
-    
-    for OBJETO in range((FE+1)-FS):
-        if STEPINC == STEP:
-            # CREO UN MESH A PARTIR DE OBJETO
-            MESH=ACTOBJ.to_mesh(bpy.context.scene, True, 'PREVIEW')
-            # CREO OBJETO
-            OBJECT=bpy.data.objects.new(ACTOBJ.name[:3]+str(FC), MESH)
-            # CONECTO A LA ESCENA
-            bpy.context.scene.objects.link(OBJECT)
-            # SETEO FRAME CURRENT
-            bpy.context.scene.frame_set(FC)
-            # MARCO EXPRESIONES PARA VIEW
-            OBJECT.driver_add("hide")
-            OBJECT.animation_data.drivers[0].driver.variables.new()
-            OBJECT.animation_data.drivers[0].driver.expression= "False if frame >= "+str(FC)+" and frame <= "+str(FC+HOLD)+" else True"
-            OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].id_type = 'SCENE'
-            OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].id= bpy.context.scene
-            OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].data_path = "current_frame"
-            # MARCO EXPRESIONES PARA RENDER
-            OBJECT.driver_add("hide_render")
-            OBJECT.animation_data.drivers[1].driver.variables.new()
-            OBJECT.animation_data.drivers[1].driver.expression= "False if frame >= "+str(FC)+" and frame <= "+str(FC+HOLD)+" else True"
-            OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].id_type = 'SCENE'
-            OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].id= bpy.context.scene
-            OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].data_path = "current_frame"            
-            # RESETEO STEPINC
-            STEPINC=0
-            # COPIAMOS S R T
-            OBJECT.matrix_world=ACTOBJ.matrix_world
-            #EMPARENTO
-            OBJECT.parent=EMPTY
-        # AVANZO STEP Y FRAME
-        FC+=1
-        STEPINC+=1
-        
-    
-
-# CLASE PARA OPERADOR
-class Oscurart_futurism (bpy.types.Operator):
-    bl_idname = "object.duplicate_futurism"
-    bl_label = "Duplicate Futurism"
-    bl_description = "Duplicate object per frame"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    scale = bpy.props.IntProperty(name='Step',default=1, min=1, max=1000)
-    
-    hold = bpy.props.IntProperty(name='Hold', default=0, min=0)
-
-    def execute(self, context):
-        object_osc_futurism(self, context, self.scale, self.hold)
-
-        return {'FINISHED'}
-
-
-# Registration
-
-def add_osc_futurism_button(self, context):
-    self.layout.operator(
-        Oscurart_futurism.bl_idname,
-        text="Futurism",
-        icon="PLUGIN")
-
-
-def register():
-    bpy.utils.register_class(Oscurart_futurism)
-    bpy.types.VIEW3D_MT_object.append(add_osc_futurism_button)
-
-
-def unregister():
-    bpy.utils.unregister_class(Oscurart_futurism)
-    bpy.types.VIEW3D_MT_object.remove(add_osc_futurism_button)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/oscurart_mesh_thread.py b/release/scripts/addons_contrib/oscurart_mesh_thread.py
deleted file mode 100644
index c82dfda..0000000
--- a/release/scripts/addons_contrib/oscurart_mesh_thread.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Make Thread Mesh",
-    "author": "Oscurart",
-    "version": (1,0),
-    "blender": (2, 5, 9),
-    "api": 4000,
-    "location": "Add > Mesh > Thread",
-    "description": "Make a thread.",
-    "warning": "",
-    "wiki_url": "oscurart.blogspot.com",
-    "tracker_url": "",
-    "category": "Object"}
-
-
-
-import math
-import bpy
-
-
-def func_osc_screw(self, STRETCH,TURNS,DIAMETER,RESOLUTION):
-    # DATA PARA EL MESH
-    me = bpy.data.meshes.new("threadData")
-    obj = bpy.data.objects.new("Thread", me)     
-    bpy.context.scene.objects.link(obj)  
-      
-    # VARIABLES
-    vertexlist=[]
-    facelist=[]
-    facereset=0     
-    CANTDIV=360/RESOLUTION
-    ESPACIODIV=STRETCH/(TURNS+2+RESOLUTION)
-
-    # PARA CADA VERTICE EN EL RANGO DESDE CERO A LENGTH 
-    for vertice in range(0,TURNS+2+RESOLUTION):        
-        # SUMA EN LA LISTA UN VERTICE       
-        vertexlist.append((math.sin(math.radians(vertice*CANTDIV))*DIAMETER,vertice*ESPACIODIV,math.cos(math.radians(vertice*CANTDIV))*DIAMETER))
-        if vertice > RESOLUTION:
-            facelist.append((vertice-(RESOLUTION),vertice-((RESOLUTION)+1),vertice-1,vertice))    
-
-    # CONECTO OBJETO    
-    me.from_pydata(vertexlist,[],facelist)
-    me.update()
-    
-
-
-class oscMakeScrew (bpy.types.Operator):
-
-    bl_idname = "mesh.primitive_thread_oscurart"
-    bl_label = "Add Mesh Thread"
-    bl_description = "Create a Thread"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    resolution = bpy.props.IntProperty (name="Resolution",default=10,min=3,max=1000)
-    stretch = bpy.props.FloatProperty (name="Stretch",default=1,min=0.000001,max=1000)
-    turns = bpy.props.IntProperty (name="Turns Steps",default=19,min=0)
-    diameter = bpy.props.FloatProperty (name="Diameter",default=1,min=0,max=1000)
-  
-    
-    
-    def execute(self, context):
-        func_osc_screw(self, self.stretch,self.turns,self.diameter,self.resolution)
-        return {'FINISHED'}
-
-
-# Registration
-
-def add_screw_list(self, context):
-    self.layout.operator(
-        "mesh.primitive_thread_oscurart",
-        text="Thread",
-        icon="PLUGIN")
-
-def register():
-    bpy.types.INFO_MT_mesh_add.append(add_screw_list)
-    bpy.utils.register_class(oscMakeScrew)
-
-
-def unregister():
-    bpy.types.INFO_MT_mesh_add.remove(add_screw_list)
-    bpy.utils.unregister_class(oscMakeScrew)
-
-
-if __name__ == '__main__':
-    register()
-
diff --git a/release/scripts/addons_contrib/oscurart_tools.py b/release/scripts/addons_contrib/oscurart_tools.py
deleted file mode 100644
index b491cee..0000000
--- a/release/scripts/addons_contrib/oscurart_tools.py
+++ /dev/null
@@ -1,2669 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Oscurart Tools",
-    "author": "Oscurart",
-    "version": (2,9),
-    "blender": (2, 6, 2),
-    "location": "View3D > Tools > Oscurart Tools",
-    "description": "Tools for objects, render, shapes, and files.",
-    "warning": "",
-    "wiki_url": "oscurart.blogspot.com",
-    "tracker_url": "",
-    "category": "Object"}
-
-
-
-import bpy
-import math
-import sys
-import os
-import stat
-import bmesh
-
-## CREA PANELES EN TOOLS
-
-# VARIABLES DE ENTORNO
-bpy.types.Scene.osc_object_tools=bpy.props.BoolProperty(default=False)
-bpy.types.Scene.osc_mesh_tools=bpy.props.BoolProperty(default=False)
-bpy.types.Scene.osc_shapes_tools=bpy.props.BoolProperty(default=False)
-bpy.types.Scene.osc_render_tools=bpy.props.BoolProperty(default=False)
-bpy.types.Scene.osc_files_tools=bpy.props.BoolProperty(default=False)
-bpy.types.Scene.osc_overrides_tools=bpy.props.BoolProperty(default=False)
-
-# PANEL DE CONTROL
-class OscPanelControl(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_label = "Oscurart Tools"
-    def draw(self,context):
-        active_obj = context.active_object
-        layout = self.layout             
-  
-        col = layout.column(align=1)         
-        col.prop(bpy.context.scene,"osc_object_tools",text="Object",icon="OBJECT_DATAMODE")
-        col.prop(bpy.context.scene,"osc_mesh_tools",text="Mesh",icon="EDITMODE_HLT")
-        col.prop(bpy.context.scene,"osc_shapes_tools",text="Shapes",icon="SHAPEKEY_DATA")
-        col.prop(bpy.context.scene,"osc_render_tools",text="Render",icon="SCENE")
-        col.prop(bpy.context.scene,"osc_files_tools",text="Files",icon="IMASEL")
-        col.prop(bpy.context.scene,"osc_overrides_tools",text="Overrides",icon="GREASEPENCIL")
-
-# POLLS
-class OscPollObject():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-    @classmethod
-    def poll(cls, context):
-        return(context.scene.osc_object_tools == True)
-    
-
-class OscPollMesh():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-    @classmethod
-    def poll(cls, context):
-        return(context.scene.osc_mesh_tools == True)    
-
-
-class OscPollShapes():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-    @classmethod
-    def poll(cls, context):
-        return(context.scene.osc_shapes_tools == True)
-
-class OscPollRender():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-    @classmethod
-    def poll(cls, context):
-        return(context.scene.osc_render_tools == True)
-    
-class OscPollFiles():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-    @classmethod
-    def poll(cls, context):
-        return(context.scene.osc_files_tools == True)  
-    
-class OscPollOverrides():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-    @classmethod
-    def poll(cls, context):
-        return(context.scene.osc_overrides_tools == True)       
-
-
-
-## PANELES    
-class OscPanelObject(OscPollObject, bpy.types.Panel):
-    bl_idname = "Oscurart Object Tools"
-    bl_label = "Object Tools"
-        
-    def draw(self, context):
-        active_obj = context.active_object
-        layout = self.layout        
-        col = layout.column(align=1)
-        row = col.row()           
-        
-        colrow = col.row(align=1)  
-        colrow.operator("objects.relink_objects_between_scenes",icon="LINKED")     
-        colrow.operator("objects.copy_objects_groups_layers",icon="LINKED")      
-        col.operator("object.distribute_apply_osc",icon="OBJECT_DATAMODE") 
-        colrow = col.row(align=1)
-        colrow.prop(bpy.context.scene,"SearchAndSelectOt",text="")
-        colrow.operator("object.search_and_select_osc",icon="ZOOM_SELECTED")       
-        colrow = col.row(align=1)
-        colrow.prop(bpy.context.scene,"RenameObjectOt",text="")
-        colrow.operator("object.rename_objects_osc",icon="SHORTDISPLAY")  
-        col.operator("object.duplicate_object_symmetry_osc",icon="OBJECT_DATAMODE", text="Duplicate Object Symmetry")      
-        colrow = col.row(align=1)
-        colrow.operator("object.modifiers_remove_osc",icon="MODIFIER", text="Remove Modifiers")
-        colrow.operator("object.modifiers_apply_osc",icon="MODIFIER", text="Apply Modifiers")
-        
-
-class OscPanelMesh(OscPollMesh, bpy.types.Panel):
-    bl_idname = "Oscurart Mesh Tools"
-    bl_label = "Mesh Tools"
-        
-    def draw(self, context):
-        active_obj = context.active_object
-        layout = self.layout        
-        col = layout.column(align=1)
-        row = col.row()           
-        
-        col.operator("mesh.select_side_osc",icon="VERTEXSEL")  
-        col.operator("mesh.normals_outside_osc",icon="SNAP_NORMAL")       
-        colrow=col.row(align=1)
-        colrow.operator("mesh.resym_osc",icon="UV_SYNC_SELECT") 
-        colrow.operator("mesh.resym_vertex_weights_osc",icon="UV_SYNC_SELECT") 
-        colrow=col.row(align=1)        
-        colrow.operator("file.export_groups_osc", icon='GROUP_VCOL')
-        colrow.operator("file.import_groups_osc", icon='GROUP_VCOL')        
-
-        
-class OscPanelShapes(OscPollShapes, bpy.types.Panel):
-    bl_idname = "Oscurart Shapes Tools"
-    bl_label = "Shapes Tools"
-        
-    def draw(self, context):
-        active_obj = context.active_object
-        layout = self.layout        
-        col = layout.column(align=1)
-        row = col.row()           
-
-        col.operator("object.shape_key_to_objects_osc",icon="OBJECT_DATAMODE")
-        col.operator("mesh.create_lmr_groups_osc",icon="GROUP_VERTEX")
-        col.operator("mesh.split_lr_shapes_osc",icon="SHAPEKEY_DATA")
-        colrow=col.row()
-        colrow.operator("mesh.create_symmetrical_layout_osc",icon="SETTINGS")         
-        colrow.operator("mesh.create_asymmetrical_layout_osc",icon="SETTINGS") 
-        
-class OscPanelRender(OscPollRender, bpy.types.Panel):
-    bl_idname = "Oscurart Render Tools"
-    bl_label = "Render Tools"
-        
-    def draw(self, context):
-        active_obj = context.active_object
-        layout = self.layout        
-        col = layout.column(align=1)
-        row = col.row() 
-
-        col.operator("file.create_batch_maker_osc", icon="LINENUMBERS_ON", text="Make Render Batch") 
-        colrow = col.row()
-        colrow.operator("render.render_layers_at_time_osc",icon="RENDER_STILL", text="All Scenes")  
-        colrow.operator("render.render_layers_at_time_osc_cf",icon="RENDER_STILL", text="> Frame")
-        colrow = col.row()
-        colrow.operator("render.render_current_scene_osc",icon="RENDER_STILL", text="Active Scene")
-        colrow.operator("render.render_current_scene_osc_cf",icon="RENDER_STILL", text="> Frame")
-        colrow = col.row(align=1) 
-        colrow.prop(bpy.context.scene,"OscSelScenes",text="")
-        colrow.operator("render.render_selected_scenes_osc",icon="RENDER_STILL", text="Selected Scenes") 
-        colrow.operator("render.render_selected_scenes_osc_cf",icon="RENDER_STILL", text="> Fame")       
-             
-        colrow = col.row(align=1)
-        colrow.prop(bpy.context.scene,"rcPARTS",text="Render Crop Parts") 
-        colrow.operator("render.render_crop_osc",icon="RENDER_REGION")  
-
-
-class OscPanelFiles(OscPollFiles, bpy.types.Panel):
-    bl_idname = "Oscurart Files Tools"
-    bl_label = "Files Tools"
-        
-    def draw(self, context):
-        active_obj = context.active_object
-        layout = self.layout        
-        col = layout.column(align=1)
-      
-        colrow = col.row()
-        colrow.operator("file.save_incremental_osc",icon="NEW")
-        colrow.operator("image.reload_images_osc",icon="IMAGE_COL")  
-        colrow = col.row(align=1)
-        colrow.prop(bpy.context.scene,"oscSearchText",text="")               
-        colrow.prop(bpy.context.scene,"oscReplaceText",text="")         
-        col.operator("file.replace_file_path_osc",icon="SHORTDISPLAY") 
-        
-        
-class OscPanelOverrides(OscPollOverrides, bpy.types.Panel):
-    bl_idname = "Oscurart Overrides"
-    bl_label = "Overrides Tools"
-        
-    def draw(self, context):
-        layout = self.layout
-
-        obj = context.object
-        
-        col = layout.box().column(align=1)
-
-        colrow = col.row()
-        col.operator("render.overrides_set_list", text="Create Override List",icon="GREASEPENCIL")
-        col.label(text="Active Scene: " + bpy.context.scene.name)
-        col.label(text="Example: [[Group,Material]]")        
-        col.prop(bpy.context.scene, '["OVERRIDE"]', text="")
-        col.operator("render.check_overrides", text="Check List",icon="ZOOM_ALL")
-        
-        boxcol=layout.box().column(align=1)
-        boxcol.label(text="Danger Zone")
-        boxcolrow=boxcol.row()
-        boxcolrow.operator("render.apply_overrides", text="Apply Overrides",icon="ERROR")
-        boxcolrow.operator("render.restore_overrides", text="Restore Overrides",icon="ERROR")        
-
-
-        
-##---------------------------RELOAD IMAGES------------------
-
-class reloadImages (bpy.types.Operator):
-    bl_idname = "image.reload_images_osc"
-    bl_label = "Reload Images" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-        for imgs in bpy.data.images:
-            imgs.reload()
-        return{"FINISHED"}
-
-##-----------------------------RESYM---------------------------
-
-def defResym(self, OFFSET, SUBD):
-    
-    ##EDIT    
-    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-    
-    ##SETEO VERTEX MODE        
-    bpy.context.tool_settings.mesh_select_mode[0]=1
-    bpy.context.tool_settings.mesh_select_mode[1]=0
-    bpy.context.tool_settings.mesh_select_mode[2]=0
-    
-    OBJETO = bpy.context.active_object
-    OBDATA = bmesh.from_edit_mesh(OBJETO.data)
-    OBDATA.select_flush(False)
-
-    if SUBD > 0:
-        USESUB=True
-        SUBLEV=SUBD
-    else:
-        USESUB=False
-        SUBLEV=1
-    
-    ## IGUALO VERTICES CERCANOS A CERO      
-    for vertice in OBDATA.verts[:]:
-        if abs(vertice.co[0]) < OFFSET  : 
-            vertice.co[0] = 0              
-            
-    ##BORRA IZQUIERDA
-    bpy.ops.mesh.select_all(action="DESELECT")
-       
-    for vertices in OBDATA.verts[:]:
-      if vertices.co[0] < 0:
-        vertices.select = 1
-    
-    ## BORRA COMPONENTES
-    bpy.ops.mesh.delete()
-    ## SUMA MIRROR
-    bpy.ops.object.modifier_add(type='MIRROR')    
-    ## SELECCIONO TODOS LOS COMPONENTES
-    bpy.ops.mesh.select_all(action="SELECT")
-    ## CREO UV TEXTURE DEL SIMETRICO
-    bpy.ops.mesh.uv_texture_add()
-    ## SETEO VARIABLE CON LA CANTIDAD DE UVS, RESTO UNO Y LE DOY UN NOMBRE
-    LENUVLISTSIM = len(bpy.data.objects[OBJETO.name].data.uv_textures)
-    LENUVLISTSIM = LENUVLISTSIM - 1
-    OBJETO.data.uv_textures[LENUVLISTSIM:][0].name = "SYMMETRICAL"
-    ## UNWRAP
-    bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=USESUB, uv_subsurf_level=SUBLEV)
-    ## MODO OBJETO
-    bpy.ops.object.mode_set(mode="OBJECT", toggle= False) 
-    ## APLICO MIRROR
-    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Mirror")
-    ## VUELVO A EDIT MODE
-    bpy.ops.object.mode_set(mode="EDIT", toggle= False)
-    OBDATA = bmesh.from_edit_mesh(OBJETO.data)
-    OBDATA.select_flush(0)
-    ## CREO UV TEXTURE DEL ASIMETRICO
-    bpy.ops.mesh.uv_texture_add()
-    ## SETEO VARIABLE CON LA CANTIDAD DE UVS, RESTO UNO Y LE DOY UN NOMBRE
-    LENUVLISTASIM = len(OBJETO.data.uv_textures)
-    LENUVLISTASIM = LENUVLISTASIM  - 1
-    OBJETO.data.uv_textures[LENUVLISTASIM:][0].name = "ASYMMETRICAL"
-    ## SETEO UV ACTIVO
-    OBJETO.data.uv_textures.active = OBJETO.data.uv_textures["ASYMMETRICAL"]
-    ## UNWRAP
-    bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=USESUB, uv_subsurf_level=SUBLEV)
-    
-
-class resym (bpy.types.Operator):
-    bl_idname = "mesh.resym_osc"
-    bl_label = "ReSym Mesh" 
-    bl_options =  {"REGISTER","UNDO"}
-    OFFSET=bpy.props.FloatProperty(name="Offset", default=0.001, min=-0, max=0.1)
-    SUBD=bpy.props.IntProperty(name="Subdivisions Levels", default=0, min=0, max=4) 
-    def execute(self,context):
-        defResym(self, self.OFFSET, self.SUBD)
-        return{"FINISHED"}     
-        
-## -----------------------------------SELECT LEFT---------------------
-def side (self, nombre, offset): 
-    
-    bpy.ops.object.mode_set(mode="EDIT", toggle=0)
-    
-    OBJECT=bpy.context.active_object        
-    ODATA = bmesh.from_edit_mesh(OBJECT.data)
-    MODE=bpy.context.mode
-
-    
-    
-    ##SETEO VERTEX MODE
-    
-    bpy.context.tool_settings.mesh_select_mode[0]=1
-    bpy.context.tool_settings.mesh_select_mode[1]=0
-    bpy.context.tool_settings.mesh_select_mode[2]=0
-    
-    ## DESELECCIONA TODO
-    for VERTICE in ODATA.verts[:]:
-        VERTICE.select = False
-    
-    if nombre == False:
-        ## CONDICION QUE SI EL VERTICE ES MENOR A 0 LO SELECCIONA  
-        for VERTICES in ODATA.verts[:]:
-            if VERTICES.co[0] < (offset):
-                VERTICES.select = 1  
-    else:
-        ## CONDICION QUE SI EL VERTICE ES MENOR A 0 LO SELECCIONA        
-        for VERTICES in ODATA.verts[:]:
-            if VERTICES.co[0] > (offset):
-                VERTICES.select = 1                              
-
-    ODATA.select_flush(False)
-    
-    bpy.ops.object.mode_set(mode="EDIT", toggle=0)    
-
-
-class SelectMenor (bpy.types.Operator):
-    bl_idname = "mesh.select_side_osc"
-    bl_label = "Select Side" 
-    bl_options =  {"REGISTER","UNDO"}
-    
-    side = bpy.props.BoolProperty(name="Greater than zero", default=False)
-    offset = bpy.props.FloatProperty(name="Offset", default=0)
-    def execute(self,context):  
-        
-        side(self, self.side, self.offset)
-               
-        return{"FINISHED"}        
-           
-    
-    
-    
-
-##-----------------------------------CREATE SHAPES----------------       
-class CreaShapes(bpy.types.Operator):
-    bl_idname = "mesh.split_lr_shapes_osc"
-    bl_label = "Split LR Shapes"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context):
-        ## VARIABLES
-        ACTOBJ=bpy.context.active_object
-        LENKB=len(ACTOBJ.data.shape_keys.key_blocks)
-        
-        ## RECORTO NOMBRES
-        for SHAPE in ACTOBJ.data.shape_keys.key_blocks:
-            if len(SHAPE.name) > 7:
-                SHAPE.name=SHAPE.name[:8]
-                
-        ## DUPLICO SHAPES Y CONECTO GRUPO
-        for SHAPE in ACTOBJ.data.shape_keys.key_blocks[1:]:
-            SHAPE.value=1
-            bpy.ops.object.shape_key_add(from_mix=True)
-            ACTOBJ.data.shape_keys.key_blocks[-1].name=SHAPE.name[:8]+"_L"
-            ACTOBJ.data.shape_keys.key_blocks[-1].vertex_group="_L"
-            bpy.ops.object.shape_key_add(from_mix=True)
-            ACTOBJ.data.shape_keys.key_blocks[-1].name=SHAPE.name[:8]+"_R"
-            ACTOBJ.data.shape_keys.key_blocks[-1].vertex_group="_R"
-            bpy.ops.object.shape_key_clear() 
-        
-        print ("OPERACION TERMINADA")        
-        return{"FINISHED"}
-    
-    
-##----------------------------SHAPES LAYOUT-----------------------
-
-class CreaShapesLayout(bpy.types.Operator):
-    bl_idname = "mesh.create_symmetrical_layout_osc"
-    bl_label = "Symmetrical Layout"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context):
-        
-  
-        SEL_OBJ= bpy.context.active_object
-        LISTA_KEYS = bpy.context.active_object.data.shape_keys.key_blocks[:]
-        
-        ##MODOS
-        EDITMODE = "bpy.ops.object.mode_set(mode='EDIT')"
-        OBJECTMODE = "bpy.ops.object.mode_set(mode='OBJECT')"
-        POSEMODE = "bpy.ops.object.mode_set(mode='POSE')"
-        
-        ##INDICE DE DRIVERS
-        varindex = 0
-        
-        ##CREA NOMBRES A LA ARMATURE
-        amt = bpy.data.armatures.new("ArmatureData")
-        ob = bpy.data.objects.new("RIG_LAYOUT_"+SEL_OBJ.name, amt)
-        
-        ##LINK A LA ESCENA
-        scn = bpy.context.scene
-        scn.objects.link(ob)
-        scn.objects.active = ob
-        ob.select = True
-        
-        
-        
-        
-        
-        eval(EDITMODE)
-        gx = 0
-        gy = 0
-        
-        
-        
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK EN CREACION DE HUESOS "+keyblock.name)
-        
-                
-            if keyblock.name[-2:] != "_L":
-                if keyblock.name[-2:] != "_R":
-        
-                    ##CREA HUESOS
-                
-                    bone = amt.edit_bones.new(keyblock.name)
-                    bone.head = (gx,0,0)
-                    bone.tail = (gx,0,1)
-                    gx = gx+2.2
-                    bone = amt.edit_bones.new(keyblock.name+"_CTRL")
-                    bone.head = (gy,0,0)
-                    bone.tail = (gy,0,0.2)
-                    gy = gy+2.2     
-                  
-                    ##SETEA ARMATURE ACTIVA
-                    bpy.context.scene.objects.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].select = 1
-                    ##DESELECCIONA (modo edit)
-                    eval(EDITMODE)
-                    bpy.ops.armature.select_all(action="DESELECT")
-                    
-                    ##EMPARENTA HUESOS
-                
-                    ##HUESO ACTIVO
-                    eval(OBJECTMODE)
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name] 
-                    ##MODO EDIT
-                    eval(EDITMODE)       
-                    ##DESELECCIONA (modo edit)
-                    bpy.ops.armature.select_all(action="DESELECT")    
-                    ##MODO OBJECT  
-                    eval(OBJECTMODE)    
-                    ##SELECCIONA UN HUESO
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name+"_CTRL"].select = 1
-                    eval(EDITMODE)    
-                    ##EMPARENTA
-                    bpy.ops.armature.parent_set(type="OFFSET")
-                    ##DESELECCIONA (modo edit)
-                    bpy.ops.armature.select_all(action="DESELECT")      
-                     
-                    ##LE HAGO UNA VARIABLE DE PLACEBO
-                    keyblock.driver_add("value") 
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.expression = "var+var_001"
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()           
-                      
-                    
-                    varindex = varindex + 1 
-        
-        
-        
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK SEGUNDA VUELTA :"+keyblock.name)    
-            
-            if keyblock.name[-2:] == "_L":
-                print("igual a L") 
-        
-                ##CREA DRIVERS Y LOS CONECTA
-                keyblock.driver_add("value")
-                keyblock.driver_add("value")
-                
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.expression = "var+var_001"
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].id  = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name] 
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].bone_target   = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[(keyblock.name[:-2])+"_CTRL"].name
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].type = 'TRANSFORMS' 
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].transform_space= "LOCAL_SPACE"        
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].transform_type= "LOC_X"  
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].id = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].bone_target   = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[(keyblock.name[:-2])+"_CTRL"].name    
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].type = 'TRANSFORMS'            
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].transform_space= "LOCAL_SPACE"        
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].transform_type= "LOC_Y"    
-                        
-                             
-                varindex = varindex + 1
-            
-                
-        
-          
-            if keyblock.name[-2:] == "_R":
-                print("igual a R") 
-                
-                ##CREA DRIVERS Y LOS CONECTA
-                keyblock.driver_add("value")
-                keyblock.driver_add("value")        
-                
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.expression = "-var+var_001"
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].id  = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name] 
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].bone_target   = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[(keyblock.name[:-2])+"_CTRL"].name      
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].type = 'TRANSFORMS' 
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].transform_space= "LOCAL_SPACE"                 
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].transform_type= "LOC_X"  
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].id = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].bone_target   = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[(keyblock.name[:-2])+"_CTRL"].name    
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].type = 'TRANSFORMS'            
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].transform_space= "LOCAL_SPACE"        
-                SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].transform_type= "LOC_Y" 
-                        
-                varindex = varindex + 1       
-                
-                
-                
-                
-        ## CREO DATA PARA SLIDERS
-        
-        ## creo data para los contenedores
-        verticess = [(-1,1,0),(1,1,0),(1,-1,0),(-1,-1,0)]
-        edgess = [(0,1),(1,2),(2,3),(3,0)]
-        
-        mesh = bpy.data.meshes.new(keyblock.name+"_data_container")
-        object = bpy.data.objects.new("GRAPHIC_CONTAINER", mesh)
-        bpy.context.scene.objects.link(object)
-        mesh.from_pydata(verticess,edgess,[])
-        
-        ## PONGO LOS LIMITES Y SETEO ICONOS
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK EN CREACION DE HUESOS "+keyblock.name)
-        
-                
-            if keyblock.name[-2:] != "_L":
-                if keyblock.name[-2:] != "_R":
-                    ## SETEO ICONOS
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name].custom_shape = bpy.data.objects['GRAPHIC_CONTAINER']
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].custom_shape = bpy.data.objects['GRAPHIC_CONTAINER']
-                    ## SETEO CONSTRAINTS
-                    eval(OBJECTMODE)
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name+"_CTRL"]
-                    ## SUMO CONSTRAINT
-                    eval(POSEMODE)
-                    bpy.ops.pose.constraint_add(type="LIMIT_LOCATION")
-                    
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].min_x = -1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_min_x = 1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].min_z = 0
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_min_z = 1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].min_y = -1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_min_y = 1
-                    
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].max_x =  1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_max_x = 1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].max_z =  0
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_max_z = 1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].max_y =  1
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_max_y = 1
-                    
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].owner_space  = "LOCAL"
-                    
-        ## PARA QUE EL TEXTO FUNCIONE PASAMOS A OBJECT MODE
-        eval(OBJECTMODE)
-        
-        ## TEXTOS
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK EN TEXTOS "+keyblock.name)
-        
-                
-            if keyblock.name[-2:] != "_L":
-                if keyblock.name[-2:] != "_R":            
-                    ## creo tipografias
-                    bpy.ops.object.text_add(location=(0,0,0))
-                    bpy.data.objects['Text'].data.body = keyblock.name
-                    bpy.data.objects['Text'].name = "TEXTO_"+keyblock.name
-                    bpy.data.objects["TEXTO_"+keyblock.name].rotation_euler[0] = math.pi/2
-                    bpy.data.objects["TEXTO_"+keyblock.name].location.x = -1
-                    bpy.data.objects["TEXTO_"+keyblock.name].location.z = -1
-                    bpy.data.objects["TEXTO_"+keyblock.name].data.size = .2
-                    ## SETEO OBJETO ACTIVO
-                    bpy.context.scene.objects.active = bpy.data.objects["TEXTO_"+keyblock.name]
-                    bpy.ops.object.constraint_add(type="COPY_LOCATION")
-                    bpy.data.objects["TEXTO_"+keyblock.name].constraints['Copy Location'].target = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                    bpy.data.objects["TEXTO_"+keyblock.name].constraints['Copy Location'].subtarget = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name].name
-                    
-                    bpy.ops.object.select_all(action="DESELECT")
-                    bpy.data.objects["TEXTO_"+keyblock.name].select = 1 
-                    bpy.context.scene.objects.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                    bpy.ops.object.parent_set(type="OBJECT") 
-                    
-        
-        ## EMPARENTA ICONO
-        
-        bpy.ops.object.select_all(action="DESELECT")
-        bpy.data.objects["GRAPHIC_CONTAINER"].select = 1 
-        bpy.context.scene.objects.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-        bpy.ops.object.parent_set(type="OBJECT")
-        
-        eval(POSEMODE)  
-  
-        ## BORRA DRIVERS DE QUE NO SEAN LEFT O RIGHT
-        for driver in SEL_OBJ.data.shape_keys.animation_data.drivers:
-            if driver.data_path.count("_L") == False and driver.data_path.count("_R") == False :
-                SEL_OBJ.data.shape_keys.driver_remove(driver.data_path) 
-  
-  
-  
-  
-              
-        return{"FINISHED"}    
-        
-##----------------------------CREATE LMR GROUPS-------------------
-def createLMRGroups(self, FACTORVG, ADDVG):
-    ## SETEO VERTEX MODE EDIT
-    bpy.context.window.screen.scene.tool_settings.mesh_select_mode[0] = 1
-    bpy.context.window.screen.scene.tool_settings.mesh_select_mode[1] = 0
-    bpy.context.window.screen.scene.tool_settings.mesh_select_mode[2] = 0
-    
-    ## VARIABLES
-    ACTOBJ=bpy.context.active_object
-    bpy.ops.object.mode_set(mode="EDIT", toggle=False)
-    bpy.ops.mesh.select_all(action='DESELECT')
-    bpy.ops.object.mode_set(mode="OBJECT")
-    GRUPOS=["_L","_R"]
-    MIRRORINDEX=0      
-            
-    for LADO in GRUPOS:
-        if MIRRORINDEX == 0:
-            ## SUMO DOS VG
-            bpy.ops.object.vertex_group_add()        
-            ## ASIGNO TODOS LOS VERTICES AL GRUPO
-            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-            bpy.ops.mesh.select_all(action='SELECT')
-            bpy.ops.object.vertex_group_assign(new=False)
-            bpy.ops.mesh.select_all(action='DESELECT')
-            bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False)        
-            ## SETEO VALORES
-            for VERTICE in ACTOBJ.data.vertices:
-                VERTICE.groups[-1].weight=(VERTICE.co[0]*FACTORVG)+ADDVG    
-            ## RENOMBRO
-            ACTOBJ.vertex_groups[-1].name=LADO    
-    
-        else:
-            ## SUMO DOS VG
-            bpy.ops.object.vertex_group_add()        
-            ## ASIGNO TODOS LOS VERTICES AL GRUPO
-            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-            bpy.ops.mesh.select_all(action='SELECT')
-            bpy.ops.object.vertex_group_assign(new=False)
-            bpy.ops.mesh.select_all(action='DESELECT')
-            bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False)       
-            ## SETEO VALORES
-            for VERTICE in ACTOBJ.data.vertices:
-                VERTICE.groups[-1].weight=(-VERTICE.co[0]*FACTORVG)+ADDVG         
-            ## RENOMBRO
-            ACTOBJ.vertex_groups[-1].name=LADO
-        ## CAMBIO MIRROR INDEX
-        MIRRORINDEX+=1
-        
-    ## SETEO GRUPO ACTIVO   
-    ACTOBJ.vertex_groups.active_index=len(ACTOBJ.vertex_groups)       
-
-
-class CreaGrupos(bpy.types.Operator):
-    bl_idname = "mesh.create_lmr_groups_osc"
-    bl_label = "Create LM groups"
-    bl_description = "Create LM groups"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    FACTORVG= bpy.props.FloatProperty(name="Factor", default=1, min=0, max=1000)
-    ADDVG= bpy.props.FloatProperty(name="Addition", default=.5, min=0, max=1000)
-    
-    def execute(self, context):
-
-        createLMRGroups(self, self.FACTORVG, self.ADDVG)
-
-        return {'FINISHED'}
-    
-##------------------------------NORMALS OUTSIDE--------------------    
-class normalsOutside(bpy.types.Operator):  
-    bl_idname = "mesh.normals_outside_osc"
-    bl_label = "Normals Outside"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context):
-        for OBJETO in bpy.context.selected_objects:
-            ## SETEA OBJETO ACTIVO
-            bpy.data.scenes[0].objects.active = bpy.data.objects[OBJETO.name]
-            ## EDICION
-            bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-            ## SELECCIONA TODOS LOS COMPONENTES 
-            bpy.ops.mesh.select_all(action="SELECT")
-            ## EXPULSA NORMALES
-            bpy.ops.mesh.normals_make_consistent(inside=False)
-            ## EDICION
-            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-        return{"FINISHED"}
-
-
-##------------------------------DISTRIBUTE---------------------------
-
- 
-
-def distributeDef(self, context, X, Y, Z):    
-
-    ## LISTA DE OBJETOS
-    OBJETOS = list(bpy.context.selected_objects)
-
-    if X == True:
-        ## LISTA VACIA
-        LISTOBJ=[]
-        
-        ## LISTA DE OBJETOS Y NOMBRES
-        for OBJETO in OBJETOS:
-            LISTOBJ.append((OBJETO.location[0],OBJETO.name))
-        
-        ## REORDENO
-        LISTOBJ.sort()
-        
-        ## AVERIGUO MINIMO Y MAXIMO
-        MIN = min(LISTOBJ)[0]
-        MAX = max(LISTOBJ)[0]
-        DIF = (MAX - MIN) / (len(OBJETOS)-1)
-        TEMPDIF = 0
-        
-        print(MIN,MAX,DIF,TEMPDIF)
-        
-        ## ORDENO
-        for OBJETO in LISTOBJ:
-            bpy.data.objects[OBJETO[1]].location[0]= MIN+TEMPDIF
-            TEMPDIF+=DIF
-    
-
-    if Y == True:
-        ## LISTA VACIA
-        LISTOBJ=[]
-        
-        ## LISTA DE OBJETOS Y NOMBRES
-        for OBJETO in OBJETOS:
-            LISTOBJ.append((OBJETO.location[1],OBJETO.name))
-        
-        ## REORDENO
-        LISTOBJ.sort()
-        
-        ## AVERIGUO MINIMO Y MAXIMO
-        MIN = min(LISTOBJ)[0]
-        MAX = max(LISTOBJ)[0]
-        DIF = (MAX - MIN) / (len(OBJETOS)-1)
-        TEMPDIF = 0
-        
-        print(MIN,MAX,DIF,TEMPDIF)
-        
-        ## ORDENO
-        for OBJETO in LISTOBJ:
-            bpy.data.objects[OBJETO[1]].location[1]= MIN+TEMPDIF
-            TEMPDIF+=DIF
-    
-    if Z == True:
-        ## LISTA VACIA
-        LISTOBJ=[]
-        
-        ## LISTA DE OBJETOS Y NOMBRES
-        for OBJETO in OBJETOS:
-            LISTOBJ.append((OBJETO.location[2],OBJETO.name))
-        
-        ## REORDENO
-        LISTOBJ.sort()
-        
-        ## AVERIGUO MINIMO Y MAXIMO
-        MIN = min(LISTOBJ)[0]
-        MAX = max(LISTOBJ)[0]
-        DIF = (MAX - MIN) / (len(OBJETOS)-1)
-        TEMPDIF = 0
-        
-        print(MIN,MAX,DIF,TEMPDIF)
-        
-        ## ORDENO
-        for OBJETO in LISTOBJ:
-            bpy.data.objects[OBJETO[1]].location[2]= MIN+TEMPDIF
-            TEMPDIF+=DIF
-    
-
-
-
-      
-class DistributeMinMaxApply (bpy.types.Operator):
-    bl_idname = "object.distribute_apply_osc"
-    bl_label = "Distribute Objects" 
-    bl_options =  {"REGISTER","UNDO"}
-        
-    X=bpy.props.BoolProperty(default=False, name="X")
-    Y=bpy.props.BoolProperty(default=False, name="Y")
-    Z=bpy.props.BoolProperty(default=False, name="Z")
-
-    def execute(self, context):
-
-        distributeDef(self, context, self.X, self.Y, self.Z)
-        
-        return{"FINISHED"}            
-          
-
-
-##--------------------------------RENDER LAYER AT TIME----------------------------
-
-
-def defRenderAll (FRAMETYPE):
-        
-    LISTMAT=[]
-    SCENES=bpy.data.scenes[:]
-    ACTSCENE=bpy.context.scene
-    FC=bpy.context.scene.frame_current 
-    FS=bpy.context.scene.frame_start
-    FE=bpy.context.scene.frame_end
-
-    print("---------------------")
-           
-    ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
-    for OBJECT in bpy.data.objects[:]:
-        SLOTLIST=[]
-        try:
-            if OBJECT.type=="MESH" or OBJECT.type == "META":
-                for SLOT in OBJECT.material_slots[:]:
-                    SLOTLIST.append(SLOT.material)
-               
-                LISTMAT.append((OBJECT,SLOTLIST))
-
-        except:
-            pass
-        
-  
-    for SCENE in SCENES:
-        PROPTOLIST=list(eval(SCENE['OVERRIDE']))
-        CURSC= SCENE.name 
-        PATH = SCENE.render.filepath
-        ENDPATH = PATH
-        FILEPATH=bpy.data.filepath
-        
-
-
-        
-        # CAMBIO SCENE
-        bpy.context.window.screen.scene=SCENE
-        
-        if FRAMETYPE == True:
-            bpy.context.scene.frame_start=FC
-            bpy.context.scene.frame_end=FC   
-            bpy.context.scene.frame_end=FC 
-            bpy.context.scene.frame_start=FC
-        
-
-        ## SETEO MATERIALES  DE OVERRIDES
-        try:
-            for OVERRIDE in PROPTOLIST:
-                for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
-                    if OBJECT.type == "MESH" or OBJECT.type == "META":
-                        for SLOT in OBJECT.material_slots[:]:
-                            SLOT.material=bpy.data.materials[OVERRIDE[1]]             
-        except:
-            pass
-         
-        if sys.platform.startswith("w"):
-            print ("PLATFORM: WINDOWS")
-            SCENENAME=(FILEPATH.rsplit("\\")[-1])[:-6]            
-        else:
-            print ("PLATFORM:LINUX")    
-            SCENENAME=(FILEPATH.rsplit("/")[-1])[:-6]
-
-        LAYERLIST=[]
-        for layer in SCENE.render.layers:
-            if layer.use == 1:
-                LAYERLIST.append(layer)
-            
-        for layers in LAYERLIST:
-            for rl in LAYERLIST:
-                rl.use= 0
-
-            print("SCENE: "+CURSC)    
-            print ("LAYER: "+layers.name)
-            print("OVERRIDE: "+str(PROPTOLIST))            
-            
-            SCENE.render.filepath = PATH+"/"+SCENENAME+"/"+CURSC+"/"+layers.name+"/"+SCENENAME+"_"+SCENE.name+"_"+layers.name+"_"
-            SCENE.render.layers[layers.name].use = 1
-            bpy.ops.render.render(animation=True, write_still=True, layer=layers.name, scene= SCENE.name)
-
-            print ("DONE")
-            print("---------------------")
-        
-        ## REESTABLECE LOS LAYERS
-        for layer in LAYERLIST:
-            layer.use = 1
-        
-        ## RESTAURA EL PATH FINAL
-        SCENE.render.filepath = ENDPATH
-       
-        #RESTAURO MATERIALES  DE OVERRIDES  
-        for OBJECT in LISTMAT:
-            SLOTIND=0
-            try:
-                for SLOT in OBJECT[1]:
-                    OBJECT[0].material_slots[SLOTIND].material=SLOT
-                    SLOTIND+=1
-            except:
-                print("OUT OF RANGE")
-        # RESTAURO FRAMES
-        if FRAMETYPE == True:
-            SCENE.frame_start=FS
-            SCENE.frame_end=FE
-            SCENE.frame_end=FE
-            SCENE.frame_start=FS
-    # RESTAURO SCENE
-    bpy.context.window.screen.scene=ACTSCENE      
-
-
-class renderAll (bpy.types.Operator):
-    bl_idname="render.render_layers_at_time_osc"
-    bl_label="Render layers at time"
-    
-    FRAMETYPE=bpy.props.BoolProperty(default=False)
-
-    
-    def execute(self,context):
-        defRenderAll(self.FRAMETYPE)
-        return{"FINISHED"}
-
-class renderAllCF (bpy.types.Operator):
-    bl_idname="render.render_layers_at_time_osc_cf"
-    bl_label="Render layers at time Current Frame"
-    
-    FRAMETYPE=bpy.props.BoolProperty(default=True)
-
-    
-    def execute(self,context):
-        defRenderAll(self.FRAMETYPE)
-        return{"FINISHED"}
-
-
-
-##--------------------------------RENDER SELECTED SCENES----------------------------
-
-
-bpy.types.Scene.OscSelScenes = bpy.props.StringProperty(default="[]")
-
-
-def defRenderSelected(FRAMETYPE):    
-        
-    ACTSCENE=bpy.context.scene
-    LISTMAT=[]
-    SCENES=bpy.data.scenes[:]
-    SCENELIST=bpy.context.scene.OscSelScenes
-    FC=bpy.context.scene.frame_current    
-    FS=bpy.context.scene.frame_start
-    FE=bpy.context.scene.frame_end    
-    ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
-    for OBJECT in bpy.data.objects[:]:
-        SLOTLIST=[]
-        try:
-            if OBJECT.type=="MESH" or OBJECT.type == "META":
-                for SLOT in OBJECT.material_slots[:]:
-                    SLOTLIST.append(SLOT.material)
-               
-                LISTMAT.append((OBJECT,SLOTLIST))
-        except:
-            pass
-        
-  
-    for SCENE in SCENES:
-        if SCENE.name in SCENELIST:
-            PROPTOLIST=list(eval(SCENE['OVERRIDE']))
-            CURSC= SCENE.name 
-            PATH = SCENE.render.filepath
-            ENDPATH = PATH
-            FILEPATH=bpy.data.filepath
-
-            print("---------------------")
-
-            # CAMBIO SCENE
-            bpy.context.window.screen.scene=SCENE
-            
-            if FRAMETYPE == True:
-                bpy.context.scene.frame_start=FC
-                bpy.context.scene.frame_end=FC   
-                bpy.context.scene.frame_end=FC 
-                bpy.context.scene.frame_start=FC
-        
-            ## SETEO MATERIALES  DE OVERRIDES
-            try:
-                for OVERRIDE in PROPTOLIST:
-                    for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
-                        if OBJECT.type == "MESH" or OBJECT.type == "META":
-                            for SLOT in OBJECT.material_slots[:]:
-                                SLOT.material=bpy.data.materials[OVERRIDE[1]]             
-            except:
-                pass
-             
-            if sys.platform.startswith("w"):
-                print ("PLATFORM: WINDOWS")
-                SCENENAME=(FILEPATH.rsplit("\\")[-1])[:-6]            
-            else:
-                print ("PLATFORM:LINUX")    
-                SCENENAME=(FILEPATH.rsplit("/")[-1])[:-6]
-
-            LAYERLIST=[]
-            for layer in SCENE.render.layers:
-                if layer.use == 1:
-                    LAYERLIST.append(layer)
-                
-            for layers in LAYERLIST:
-                for rl in LAYERLIST:
-                    rl.use= 0
-                    
-                print("SCENE: "+CURSC)    
-                print ("LAYER: "+layers.name)
-                print("OVERRIDE: "+str(PROPTOLIST))  
-            
-                SCENE.render.filepath = PATH+"/"+SCENENAME+"/"+CURSC+"/"+layers.name+"/"+SCENENAME+"_"+SCENE.name+"_"+layers.name+"_"
-                SCENE.render.layers[layers.name].use = 1
-                bpy.ops.render.render(animation=True, layer=layers.name, write_still=True, scene= SCENE.name)
-
-                print ("DONE")
-                print("---------------------")
-                
-            ## REESTABLECE LOS LAYERS
-            for layer in LAYERLIST:
-                layer.use = 1
-            
-            ## RESTAURA EL PATH FINAL
-            SCENE.render.filepath = ENDPATH
-           
-            #RESTAURO MATERIALES  DE OVERRIDES  
-            for OBJECT in LISTMAT:
-                SLOTIND=0
-                try:
-                    for SLOT in OBJECT[1]:
-                        OBJECT[0].material_slots[SLOTIND].material=SLOT
-                        SLOTIND+=1
-                except:
-                    print("OUT OF RANGE")
-                    
-            # RESTAURO FRAMES
-            if FRAMETYPE == True:
-                SCENE.frame_start=FS
-                SCENE.frame_end=FE
-                SCENE.frame_end=FE
-                SCENE.frame_start=FS                    
-                    
-                    
-    # RESTAURO SCENE
-    bpy.context.window.screen.scene=ACTSCENE
-
-
-class renderSelected (bpy.types.Operator):
-    bl_idname="render.render_selected_scenes_osc"
-    bl_label="Render Selected Scenes"
-
-    FRAMETYPE=bpy.props.BoolProperty(default=False)
- 
-    def execute(self,context):
-        defRenderSelected(self.FRAMETYPE)
-        return{"FINISHED"}
-    
-class renderSelectedCF (bpy.types.Operator):
-    bl_idname="render.render_selected_scenes_osc_cf"
-    bl_label="Render Selected Scenes Curent Frame"
-
-    FRAMETYPE=bpy.props.BoolProperty(default=True)
-
-    def execute(self,context):
-        defRenderSelected(self.FRAMETYPE)
-        return{"FINISHED"}
-
-
-
-##--------------------------------RENDER CURRENT SCENE----------------------------
-
-
-def defRenderCurrent (FRAMETYPE):
-    LISTMAT=[]
-    SCENE=bpy.context.scene
-    FC=bpy.context.scene.frame_current    
-    FS=bpy.context.scene.frame_start
-    FE=bpy.context.scene.frame_end 
-    
-    print("---------------------")
-        
-    ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
-    for OBJECT in bpy.data.objects[:]:
-        SLOTLIST=[]
-        try:
-            if OBJECT.type=="MESH" or OBJECT.type == "META":
-                for SLOT in OBJECT.material_slots[:]:
-                    SLOTLIST.append(SLOT.material)               
-                LISTMAT.append((OBJECT,SLOTLIST))
-        except:
-            pass        
-
-
-    PROPTOLIST=list(eval(SCENE['OVERRIDE']))
-    CURSC= SCENE.name 
-    PATH = SCENE.render.filepath
-    ENDPATH = PATH
-    FILEPATH=bpy.data.filepath
-
-
-    if FRAMETYPE == True:
-        bpy.context.scene.frame_start=FC
-        bpy.context.scene.frame_end=FC   
-        bpy.context.scene.frame_end=FC 
-        bpy.context.scene.frame_start=FC  
-    
-    ## SETEO MATERIALES  DE OVERRIDES
-    try:
-        for OVERRIDE in PROPTOLIST:
-            for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
-                if OBJECT.type == "MESH" or OBJECT.type == "META":
-                    for SLOT in OBJECT.material_slots[:]:
-                        SLOT.material=bpy.data.materials[OVERRIDE[1]]             
-    except:
-        pass
-     
-    if sys.platform.startswith("w"):
-        print ("PLATFORM: WINDOWS")
-        SCENENAME=(FILEPATH.rsplit("\\")[-1])[:-6]            
-    else:
-        print ("PLATFORM:LINUX")    
-        SCENENAME=(FILEPATH.rsplit("/")[-1])[:-6]
-
-    LAYERLIST=[]
-    for layer in SCENE.render.layers:
-        if layer.use == 1:
-            LAYERLIST.append(layer)
-        
-    for layers in LAYERLIST:
-        for rl in LAYERLIST:
-            rl.use= 0
-
-        print("SCENE: "+CURSC)    
-        print ("LAYER: "+layers.name)
-        print("OVERRIDE: "+str(PROPTOLIST))
-
-
-        SCENE.render.filepath = PATH+"/"+SCENENAME+"/"+CURSC+"/"+layers.name+"/"+SCENENAME+"_"+SCENE.name+"_"+layers.name+"_"
-        SCENE.render.layers[layers.name].use = 1
-        bpy.ops.render.render(animation=True, layer=layers.name, write_still=1, scene= SCENE.name)
-        
-        print ("DONE")
-        print("---------------------")
-    
-    ## REESTABLECE LOS LAYERS
-    for layer in LAYERLIST:
-        layer.use = 1
-    
-    ## RESTAURA EL PATH FINAL
-    SCENE.render.filepath = ENDPATH
-   
-    #RESTAURO MATERIALES  DE OVERRIDES  
-    for OBJECT in LISTMAT:
-        SLOTIND=0
-        try:
-            for SLOT in OBJECT[1]:
-                OBJECT[0].material_slots[SLOTIND].material=SLOT
-                SLOTIND+=1
-        except:
-            print("FUERA DE RANGO")    
-
-    # RESTAURO FRAMES
-    if FRAMETYPE == True:
-        SCENE.frame_start=FS
-        SCENE.frame_end=FE
-        SCENE.frame_end=FE
-        SCENE.frame_start=FS 
-
-
-class renderCurrent (bpy.types.Operator):
-    bl_idname="render.render_current_scene_osc"
-    bl_label="Render Current Scene"
-
-    FRAMETYPE=bpy.props.BoolProperty(default=False)
-
-    def execute(self,context):
-        
-        defRenderCurrent(self.FRAMETYPE)
-        
-        return{"FINISHED"}
-
-
-class renderCurrentCF (bpy.types.Operator):
-    bl_idname="render.render_current_scene_osc_cf"
-    bl_label="Render Current Scene Current Frame"
-
-    FRAMETYPE=bpy.props.BoolProperty(default=True)
-
-    def execute(self,context):
-               
-        defRenderCurrent(self.FRAMETYPE)
-        
-        return{"FINISHED"}
-
-   
-##--------------------------RENDER CROP----------------------
-## SETEO EL STATUS DEL PANEL PARA EL IF 
-bpy.types.Scene.RcropStatus = bpy.props.BoolProperty(default=0)
-
-## CREO DATA PARA EL SLIDER
-bpy.types.Scene.rcPARTS = bpy.props.IntProperty(default=0,min=2,max=50,step=1) 
-
-
-class renderCrop (bpy.types.Operator):
-    bl_idname="render.render_crop_osc"
-    bl_label="Render Crop: Render!"
-    def execute(self,context):
-
-        ##AVERIGUO EL SISTEMA
-        if sys.platform.startswith("w"):
-            print ("PLATFORM: WINDOWS")
-            VARSYSTEM= "\\"          
-        else:
-            print ("PLATFORM:LINUX")    
-            VARSYSTEM= "/"
-
-        
-        ## NOMBRE DE LA ESCENA
-        SCENENAME=(bpy.data.filepath.rsplit(VARSYSTEM)[-1]).rsplit(".")[0]        
-        
-        ## CREA ARRAY
-        PARTES=[]
-        START=1
-        PARTS=bpy.context.scene.rcPARTS
-        PARTS=PARTS+1
-        while START < PARTS:
-            PARTES.append(START)
-            START=START+1
-        print(PARTES)
-        
-
-        
-        ##SETEO VARIABLE PARA LA FUNCION DE RENDER
-        NUMERODECORTE=1
-        
-        ##ESCENA ACTIVA
-        SCACT = bpy.context.scene
-        
-        ## SETEO CROP
-        bpy.data.scenes[SCACT.name].render.use_crop_to_border = 1
-        bpy.data.scenes[SCACT.name].render.use_border = 1
-        
-        ##A VERIGUO RES EN Y
-        RESY=bpy.data.scenes[SCACT.name].render.resolution_y
-        
-        ## AVERIGUO EL PATH DE LA ESCENA
-        OUTPUTFILEPATH=bpy.data.scenes[SCACT.name].render.filepath
-        bpy.context.scene.render.filepath = OUTPUTFILEPATH+bpy.context.scene.name
-        
-
-        
-        ## CUANTAS PARTES HARA
-        LENPARTES=len(PARTES)
-        
-        ## DIVIDE 1 SOBRE LA CANTIDAD DE PARTES
-        DIVISOR=1/PARTES[LENPARTES-1]
-        
-        ## SETEA VARIABLE DEL MARCO MINIMO Y MAXIMO
-        CMIN=0
-        CMAX=DIVISOR
-        
-        ## REMUEVE EL ULTIMO OBJETO DEL ARRAY PARTES
-        PARTESRESTADA = PARTES.pop(LENPARTES-1)
-        
-        ## SETEA EL MINIMO Y EL MAXIMO CON LOS VALORES DE ARRIBA
-        bpy.data.scenes[SCACT.name].render.border_min_y = CMIN
-        bpy.data.scenes[SCACT.name].render.border_max_y = CMAX
-
-        
-        ##SETEA EL OUTPUT PARA LA PRIMERA PARTE
-        OUTPUTFILEPATH+bpy.context.scene.name
-        bpy.context.scene.render.filepath = OUTPUTFILEPATH+SCENENAME+VARSYSTEM+SCENENAME+"_PART"+str(PARTES[0])+"_"
-        
-        ##RENDER PRIMERA PARTE
-        bpy.ops.render.render(animation=True)
-        bpy.context.scene.render.filepath
-        
-        ##SUMO UN NUMERO AL CORTE
-        NUMERODECORTE = NUMERODECORTE+1      
-        
-        
-        ## RENDER!
-        for PARTE in PARTES:
-            ## SUMA A LOS VALORES DEL CROP
-            CMIN = CMIN + DIVISOR
-            CMAX = CMAX + DIVISOR
-            print ("EL CROP ES DE "+str(CMIN)+" A "+str(CMAX))
-            ## SETEA BORDE
-            bpy.data.scenes[SCACT.name].render.border_min_y = CMIN
-            bpy.data.scenes[SCACT.name].render.border_max_y = CMAX
-            ## SETEA EL OUTPUT
-            bpy.context.scene.render.filepath = OUTPUTFILEPATH+SCENENAME+VARSYSTEM+SCENENAME+"_PART"+str(NUMERODECORTE)+"_"
-            print ("EL OUTPUT DE LA FUNCION ES " +bpy.context.scene.render.filepath)
-            ## PRINTEA EL NUMERO DE CORTE
-            print (PARTE)
-            ## RENDER
-            bpy.ops.render.render(animation=True)
-            ## SUMO NUMERO DE CORTE
-            NUMERODECORTE = NUMERODECORTE+1    
-        
-        
-        ## REESTABLEZCO EL FILEPATH
-        bpy.context.scene.render.filepath = OUTPUTFILEPATH  
-        
-        
-        print ("RENDER TERMINADO")
-                
-        return{"FINISHED"}
-
-
-    
-##------------------------ SEARCH AND SELECT ------------------------
-
-## SETEO VARIABLE DE ENTORNO
-bpy.types.Scene.SearchAndSelectOt = bpy.props.StringProperty(default="Object name initials")
-
-
-class SearchAndSelectOt(bpy.types.Operator):
-    bl_idname = "object.search_and_select_osc"
-    bl_label = "Search And Select"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context): 
-        for objeto in bpy.context.scene.objects:
-            variableNombre = bpy.context.scene.SearchAndSelectOt
-            if objeto.name.startswith(variableNombre) == True :
-                objeto.select = 1
-                print("Selecciona:" + str(objeto.name))
-        return{"FINISHED"}
-
-##-------------------------RENAME OBJECTS----------------------------------    
-
-## CREO VARIABLE
-bpy.types.Scene.RenameObjectOt = bpy.props.StringProperty(default="Type here")
-
-class renameObjectsOt (bpy.types.Operator):
-    bl_idname = "object.rename_objects_osc"
-    bl_label = "Rename Objects" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-
-        ## LISTA
-        listaObj = bpy.context.selected_objects
-        
-        
-        
-        for objeto in listaObj:
-            print (objeto.name)
-            objeto.name = bpy.context.scene.RenameObjectOt
-        return{"FINISHED"}
-
-
-
-##-------------------------RESYM VG---------------------------------- 
-
-
-
-
-class resymVertexGroups (bpy.types.Operator):
-    bl_idname = "mesh.resym_vertex_weights_osc"
-    bl_label = "Resym Vertex Weights" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-        
-        OBACTIVO=bpy.context.active_object
-        VGACTIVO=OBACTIVO.vertex_groups.active.index
-        MENORESACERO=[]
-        MAYORESACERO=[]
-        MENORESACEROYSG=[]
-        
-        
-        ## LISTA DE LOS VERTICES QUE ESTAN EN GRUPOS
-        VERTICESENGRUPOS=[0]
-        for vertice in OBACTIVO.data.vertices:
-            if len(vertice.groups.items()) > 0:
-                VERTICESENGRUPOS.append(vertice.index)  
-                
-                
-                
-        ## VERTICES MENORES A CERO
-        for verticeindex in VERTICESENGRUPOS:
-            for indices in OBACTIVO.data.vertices[verticeindex].groups:
-                if indices.group == VGACTIVO:     
-                    if bpy.context.active_object.data.vertices[verticeindex].co[0] < 0:
-                        MENORESACERO.append(bpy.context.active_object.data.vertices[verticeindex].index)
-                        
-        ## VERTICES MENORES A CERO Y SIN GRUPO
-        for vertice in OBACTIVO.data.vertices:
-            if vertice.co[0] < 0:
-                MENORESACEROYSG.append(vertice.index)               
-                
-        
-        ## VERTICES MAYORES A CERO
-        for verticeindex in VERTICESENGRUPOS:
-            for indices in OBACTIVO.data.vertices[verticeindex].groups:
-                if indices.group == VGACTIVO:     
-                    if bpy.context.active_object.data.vertices[verticeindex].co[0] > 0:
-                        MAYORESACERO.append(bpy.context.active_object.data.vertices[verticeindex].index)
-        
-        ## TE MUESTRA LAS LISTAS
-        print("-------------VERTICES EN GRUPOS-----------")        
-        print (VERTICESENGRUPOS)
-        print("-------------MENORES A CERO-----------")
-        print (MENORESACERO)
-        print("-------------MENORES A CERO SIN GRUPO-----------")
-        print (MENORESACEROYSG)
-        print("-------------MAYORES A CERO-----------")
-        print (MAYORESACERO)
-        
-        
-        ## SETEA WORK INDEX      
-        for vertices in MAYORESACERO:
-            for indices in OBACTIVO.data.vertices[vertices].groups:
-                if indices.group == VGACTIVO: 
-                    WORKINDEX = indices.group  
-        
-        ## DESELECCIONO COMPONENTES
-        bpy.ops.object.mode_set(mode="EDIT",toggle=0)
-        bpy.ops.mesh.select_all(action="DESELECT")
-        bpy.ops.object.mode_set(mode="OBJECT",toggle=0)
-        
-        
-        ## SETEO GRUPO
-        for verticemenor in MENORESACEROYSG:
-            for verticemayor in MAYORESACERO:
-                if OBACTIVO.data.vertices[verticemenor].co[0] == -OBACTIVO.data.vertices[verticemayor].co[0]:
-                    if OBACTIVO.data.vertices[verticemenor].co[1] == OBACTIVO.data.vertices[verticemayor].co[1]:   
-                        if OBACTIVO.data.vertices[verticemenor].co[2] == OBACTIVO.data.vertices[verticemayor].co[2]: 
-                            OBACTIVO.data.vertices[verticemenor].select = 1    
-        
-        ## ASSIGNO AL GRUPO
-        bpy.ops.object.mode_set(mode="EDIT",toggle=0)
-        bpy.ops.object.vertex_group_assign(new=False)
-        bpy.ops.mesh.select_all(action="DESELECT")
-        bpy.ops.object.mode_set(mode="OBJECT",toggle=0)
-        
-        ## MODO PINTURA
-        bpy.ops.object.mode_set(mode="WEIGHT_PAINT",toggle=0)
-        
-        
-        ##--------->> VUELVO A CREAR GRUPOS YA QUE LOS INDICES CAMBIARON
-        MENORESACERO=[]
-        MAYORESACERO=[]
-        
-        
-        ## LISTA DE LOS VERTICES QUE ESTAN EN GRUPOS
-        VERTICESENGRUPOS=[0]
-        for vertice in OBACTIVO.data.vertices:
-            if len(vertice.groups.items()) > 0:
-                VERTICESENGRUPOS.append(vertice.index)  
-                
-                
-                
-        ## VERTICES MENORES A CERO
-        for verticeindex in VERTICESENGRUPOS:
-            for indices in OBACTIVO.data.vertices[verticeindex].groups:
-                if indices.group == VGACTIVO:     
-                    if bpy.context.active_object.data.vertices[verticeindex].co[0] < 0:
-                        MENORESACERO.append(bpy.context.active_object.data.vertices[verticeindex].index)
-        
-        
-        
-        
-        ## VERTICES MAYORES A CERO
-        for verticeindex in VERTICESENGRUPOS:
-            for indices in OBACTIVO.data.vertices[verticeindex].groups:
-                if indices.group == VGACTIVO:     
-                    if bpy.context.active_object.data.vertices[verticeindex].co[0] > 0:
-                        MAYORESACERO.append(bpy.context.active_object.data.vertices[verticeindex].index)
-        
-        
-        ## SETEO WEIGHT     
-        for verticemenor in MENORESACERO:
-            for verticemayor in MAYORESACERO:
-                if OBACTIVO.data.vertices[verticemenor].co[0] == -OBACTIVO.data.vertices[verticemayor].co[0]:
-                    if OBACTIVO.data.vertices[verticemenor].co[1] == OBACTIVO.data.vertices[verticemayor].co[1]:   
-                        if OBACTIVO.data.vertices[verticemenor].co[2] == OBACTIVO.data.vertices[verticemayor].co[2]: 
-                            VARINMAY = 0
-                            VARINMEN = 0
-                            while  OBACTIVO.data.vertices[verticemayor].groups[VARINMAY].group != VGACTIVO:
-                                VARINMAY = VARINMAY+1
-                            while  OBACTIVO.data.vertices[verticemenor].groups[VARINMEN].group != VGACTIVO:
-                                VARINMEN = VARINMEN+1
-                            ##print("Varinmay: "+str(VARINMAY)+" .Varinmen "+str(VARINMEN))  
-                            OBACTIVO.data.vertices[verticemenor].groups[VARINMEN].weight = OBACTIVO.data.vertices[verticemayor].groups[VARINMAY].weight
-                            
-        
-                          
-        print("===============(TERMINADO)=============")       
-        return{"FINISHED"}
-
-
-
-##------------------------ SHAPES LAYOUT SYMMETRICA ------------------------
-
-
-
-class CreateLayoutAsymmetrical(bpy.types.Operator):
-    bl_idname = "mesh.create_asymmetrical_layout_osc"
-    bl_label = "Asymmetrical Layout"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context): 
-                
-        SEL_OBJ= bpy.context.active_object
-        LISTA_KEYS = bpy.context.active_object.data.shape_keys.key_blocks
-        
-        ##MODOS
-        EDITMODE = "bpy.ops.object.mode_set(mode='EDIT')"
-        OBJECTMODE = "bpy.ops.object.mode_set(mode='OBJECT')"
-        POSEMODE = "bpy.ops.object.mode_set(mode='POSE')"
-        
-        ##INDICE DE DRIVERS
-        varindex = 0
-        
-        ##CREA NOMBRES A LA ARMATURE
-        amtas = bpy.data.armatures.new("ArmatureData")
-        obas = bpy.data.objects.new("RIG_LAYOUT_"+SEL_OBJ.name, amtas)
-        
-        ##LINK A LA ESCENA
-        scn = bpy.context.scene
-        scn.objects.link(obas)
-        scn.objects.active = obas
-        obas.select = True
-        
-        
-        
-        
-        
-        eval(EDITMODE)
-        gx = 0
-        gy = 0
-        
-        
-        
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK EN CREACION DE HUESOS "+keyblock.name)
-        
-                
-            if keyblock.name[-2:] != "_L":
-                if keyblock.name[-2:] != "_R":
-        
-                    ##CREA HUESOS
-                
-                    bone = amtas.edit_bones.new(keyblock.name)
-                    bone.head = (gx,0,0)
-                    bone.tail = (gx,0,1)
-                    gx = gx+2.2
-                    bone = amtas.edit_bones.new(keyblock.name+"_CTRL")
-                    bone.head = (gy,0,0)
-                    bone.tail = (gy,0,0.2)
-                    gy = gy+2.2     
-                  
-                    ##SETEA ARMATURE ACTIVA
-                    bpy.context.scene.objects.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].select = 1
-                    ##DESELECCIONA (modo edit)
-                    eval(EDITMODE)
-                    bpy.ops.armature.select_all(action="DESELECT")
-                    
-                    ##EMPARENTA HUESOS
-                
-                    ##HUESO ACTIVO
-                    eval(OBJECTMODE)
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name] 
-                    ##MODO EDIT
-                    eval(EDITMODE)       
-                    ##DESELECCIONA (modo edit)
-                    bpy.ops.armature.select_all(action="DESELECT")    
-                    ##MODO OBJECT  
-                    eval(OBJECTMODE)    
-                    ##SELECCIONA UN HUESO
-                    bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name+"_CTRL"].select = 1
-                    eval(EDITMODE)    
-                    ##EMPARENTA
-                    bpy.ops.armature.parent_set(type="OFFSET")
-                    ##DESELECCIONA (modo edit)
-                    bpy.ops.armature.select_all(action="DESELECT")      
-                     
-                    ##CREA DRIVERS Y LOS CONECTA
-                    keyblock.driver_add("value")
-                    keyblock.driver_add("value")        
-                    
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.expression = "-var+var_001"
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables.new()
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].id  = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name] 
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].bone_target   = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[(keyblock.name)+"_CTRL"].name      
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].type = 'TRANSFORMS' 
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].transform_space= "LOCAL_SPACE"                 
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var'].targets[0].transform_type= "LOC_X"  
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].id = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].bone_target   = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[(keyblock.name)+"_CTRL"].name    
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].type = 'TRANSFORMS'            
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].transform_space= "LOCAL_SPACE"        
-                    SEL_OBJ.data.shape_keys.animation_data.drivers[varindex].driver.variables['var_001'].targets[0].transform_type= "LOC_Y" 
-                          
-                    
-                    varindex = varindex + 1 
-        
-        
-        
-             
-                
-                
-                
-                
-        ## CREO DATA PARA SLIDERS
-        
-        ## creo data para los contenedores
-        verticess = [(-.1,1,0),(.1,1,0),(.1,0,0),(-.1,0,0)]
-        edgess = [(0,1),(1,2),(2,3),(3,0)]
-        
-        mesh = bpy.data.meshes.new(keyblock.name+"_data_container")
-        object = bpy.data.objects.new("GRAPHIC_CONTAINER_AS", mesh)
-        bpy.context.scene.objects.link(object)
-        mesh.from_pydata(verticess,edgess,[])
-        
-        ## PONGO LOS LIMITES Y SETEO ICONOS
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK EN CREACION DE HUESOS "+keyblock.name)
-            ## SETEO ICONOS
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name].custom_shape = bpy.data.objects['GRAPHIC_CONTAINER_AS']
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].custom_shape = bpy.data.objects['GRAPHIC_CONTAINER_AS']
-            ## SETEO CONSTRAINTS
-            eval(OBJECTMODE)
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name+"_CTRL"]
-            ## SUMO CONSTRAINT
-            eval(POSEMODE)
-            bpy.ops.pose.constraint_add(type="LIMIT_LOCATION")
-            
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].min_x = 0
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_min_x = 1
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].min_z = 0
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_min_z = 1
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].min_y = 0
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_min_y = 1
-            
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].max_x =  0
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_max_x = 1
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].max_z =  0
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_max_z = 1
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].max_y =  1
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].use_max_y = 1
-            
-            bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].pose.bones[keyblock.name+"_CTRL"].constraints['Limit Location'].owner_space  = "LOCAL"
-                    
-        ## PARA QUE EL TEXTO FUNCIONE PASAMOS A OBJECT MODE
-        eval(OBJECTMODE)
-        
-        ## TEXTOS
-        for keyblock in LISTA_KEYS:
-            print ("KEYBLOCK EN TEXTOS "+keyblock.name)            
-            ## creo tipografias
-            bpy.ops.object.text_add(location=(0,0,0))
-            bpy.data.objects['Text'].data.body = keyblock.name
-            bpy.data.objects['Text'].name = "TEXTO_"+keyblock.name
-            bpy.data.objects["TEXTO_"+keyblock.name].rotation_euler[0] = math.pi/2
-            bpy.data.objects["TEXTO_"+keyblock.name].location.x = -1
-            bpy.data.objects["TEXTO_"+keyblock.name].location.z = -1
-            bpy.data.objects["TEXTO_"+keyblock.name].data.size = .2
-            ## SETEO OBJETO ACTIVO
-            bpy.context.scene.objects.active = bpy.data.objects["TEXTO_"+keyblock.name]
-            bpy.ops.object.constraint_add(type="COPY_LOCATION")
-            bpy.data.objects["TEXTO_"+keyblock.name].constraints['Copy Location'].target = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-            bpy.data.objects["TEXTO_"+keyblock.name].constraints['Copy Location'].subtarget = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name].name
-            
-            bpy.ops.object.select_all(action="DESELECT")
-            bpy.data.objects["TEXTO_"+keyblock.name].select = 1 
-            bpy.context.scene.objects.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-            bpy.ops.object.parent_set(type="OBJECT") 
-            
-        
-        ## EMPARENTA ICONO
-        
-        bpy.ops.object.select_all(action="DESELECT")
-        bpy.data.objects["GRAPHIC_CONTAINER_AS"].select = 1 
-        bpy.context.scene.objects.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name]
-        bpy.ops.object.parent_set(type="OBJECT")
-        
-        eval(POSEMODE)  
-                  
-        
-
-        return{"FINISHED"}
-
-
-##------------------------ SHAPES LAYOUT SYMMETRICA ------------------------
-
-class saveIncremental(bpy.types.Operator):
-    bl_idname = "file.save_incremental_osc"
-    bl_label = "Save Incremental File"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context):     
-        ##SETEO VARIABLES
-        filepath=bpy.data.filepath
-        
-        ##SI LA RUTA CONTIENE _V
-        if filepath.count("_v") == 0:
-            print("La escena no tiene numero")
-            stpath=filepath.rsplit(".blend")
-            incrementalValue=1
-            print("El output es: "+ stpath[0]+"_v0"+str(incrementalValue)+".blend")
-            output=stpath[0]+"_v0"+str(incrementalValue)+".blend"
-            bpy.ops.wm.save_as_mainfile(filepath=output)  
-            
-            
-        else:    
-            sfilepath=filepath.split("_v")[0]
-            idfilepath=(filepath.split("_v")[1])[:-6]
-            stpath=sfilepath+"_v"
-            incrementalValue=int(idfilepath)    
-            
-            if len(idfilepath) > 1 :
-                if idfilepath[0] == "0":
-                    print("El primer valor es cero")
-                    incrementalValue+=1
-                    print("El output es: "+ sfilepath+"_v0"+str(incrementalValue)+".blend")
-                    output=sfilepath+"_v0"+str(incrementalValue)+".blend"
-                    bpy.ops.wm.save_as_mainfile(filepath=output)
-                else:
-                    print("El primer valor no es cero")
-                    incrementalValue+=1
-                    print("El output es: "+ sfilepath+"_v"+str(incrementalValue)+".blend")  
-                    output=sfilepath+"_v0"+str(incrementalValue)+".blend"
-                    bpy.ops.wm.save_as_mainfile(filepath=output)              
-            
-            if len(idfilepath) <= 1 :
-                print("No tiene primer valor")  
-                incrementalValue+=1
-                print("El output es: "+ sfilepath+"_v0"+str(incrementalValue)+".blend")  
-                output=sfilepath+"_v0"+str(incrementalValue)+".blend"
-                bpy.ops.wm.save_as_mainfile(filepath=output)      
-        return{"FINISHED"}  
-    
-##------------------------ REPLACE FILE PATHS ------------------------ 
-
-bpy.types.Scene.oscSearchText = bpy.props.StringProperty(default="Search Text")
-bpy.types.Scene.oscReplaceText = bpy.props.StringProperty(default="Replace Text")
-
-class replaceFilePath(bpy.types.Operator):
-    bl_idname = "file.replace_file_path_osc"
-    bl_label = "Replace File Path"
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self, context):    
-        TEXTSEARCH=bpy.context.scene.oscSearchText
-        TEXTREPLACE=bpy.context.scene.oscReplaceText
-        
-        for image in bpy.data.images:
-            if image.filepath != '':
-                if image.filepath.count(TEXTSEARCH) == 2:
-                    FILEPATH=image.filepath
-                    FOLDER=FILEPATH.partition(TEXTSEARCH)[0]+TEXTREPLACE
-                    PREFIX=FILEPATH.partition(TEXTSEARCH)[-1].partition(TEXTSEARCH)[0]+TEXTREPLACE+FILEPATH.partition(TEXTSEARCH)[-1].partition(TEXTSEARCH)[2]        
-                    print("Reemplazo el path de: "+image.name)
-                    image.filepath=FOLDER+PREFIX   
-
-                if image.filepath.count(TEXTSEARCH) == 1:
-                    FILEPATH=image.filepath
-                    FOLDER=FILEPATH.partition(TEXTSEARCH)[0]+TEXTREPLACE+FILEPATH.partition(TEXTSEARCH)[-1]
-                        
-                    print("Reemplazo el path de: "+image.name)
-                    image.filepath= FOLDER
-
-                     
-        return{"FINISHED"}
-
-
-
-##------------------------ DUPLICATE OBJECTS SYMMETRY ------------------------ 
-
-def duplicateSymmetrical (self, disconect):
-    for objeto in bpy.context.selected_objects:
-                
-        OBSEL=objeto 
-        
-        #DESELECT AND SELECT OBJETO
-        bpy.ops.object.select_all(action='DESELECT') 
-        objeto.select = 1   
-        bpy.context.scene.objects.active=objeto
-        
-        #DUPLICA
-        bpy.ops.object.duplicate(linked=1)
-        
-        #OBJETO ACTIVO
-        OBDUP=bpy.context.active_object 
-           
-        print(OBDUP)
-        
-        #SUMA DRIVER
-        OBDUP.driver_add("location")
-        
-        ## LOCATIONS
-        
-        #EXPRESION
-        OBDUP.animation_data.drivers[0].driver.expression = "-var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[0].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[0].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[0].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[0].driver.variables[0].targets[0].transform_type = 'LOC_X'
-        
-        #EXPRESION
-        OBDUP.animation_data.drivers[1].driver.expression = "var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[1].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[1].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[1].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[1].driver.variables[0].targets[0].transform_type = 'LOC_Y'
-        
-        #EXPRESION
-        OBDUP.animation_data.drivers[2].driver.expression = "var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[2].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[2].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[2].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[2].driver.variables[0].targets[0].transform_type = 'LOC_Z'
-        
-        ## SCALE
-        OBDUP.driver_add("scale")
-        
-        
-        #EXPRESION
-        OBDUP.animation_data.drivers[3].driver.expression = "-var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[3].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[3].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[3].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[3].driver.variables[0].targets[0].transform_type = 'SCALE_X'
-                        
-        #EXPRESION
-        OBDUP.animation_data.drivers[4].driver.expression = "var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[4].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[4].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[4].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[4].driver.variables[0].targets[0].transform_type = 'SCALE_Y'
-                        
-                        
-        #EXPRESION
-        OBDUP.animation_data.drivers[5].driver.expression = "var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[5].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[5].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[5].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[5].driver.variables[0].targets[0].transform_type = 'SCALE_Z'
-                                                                                                      
-
-        ## ROTATION
-        OBDUP.driver_add("rotation_euler")
-        
-        
-        #EXPRESION
-        OBDUP.animation_data.drivers[6].driver.expression = "var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[6].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[6].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[6].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[6].driver.variables[0].targets[0].transform_type = 'ROT_X'
-                        
-        #EXPRESION
-        OBDUP.animation_data.drivers[7].driver.expression = "-var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[7].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[7].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[7].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[7].driver.variables[0].targets[0].transform_type = 'ROT_Y'
-                        
-                        
-        #EXPRESION
-        OBDUP.animation_data.drivers[8].driver.expression = "-var"
-        #CREA VARIABLE
-        OBDUP.animation_data.drivers[8].driver.variables.new()
-        #MODIFICO VARIABLE
-        OBDUP.animation_data.drivers[8].driver.variables[0].type = "TRANSFORMS"
-        OBDUP.animation_data.drivers[8].driver.variables[0].targets[0].id = objeto
-        OBDUP.animation_data.drivers[8].driver.variables[0].targets[0].transform_type = 'ROT_Z'               
-
-        if disconect != True:
-            bpy.ops.object.make_single_user(obdata=True, object=True) 
-            bpy.context.active_object.driver_remove("location") 
-            bpy.context.active_object.driver_remove("rotation_euler") 
-            bpy.context.active_object.driver_remove("scale")     
-
-
-class oscDuplicateSymmetricalOp (bpy.types.Operator):
-    bl_idname = "object.duplicate_object_symmetry_osc"
-    bl_label = "Oscurart Duplicate Symmetrical"  
-    bl_options =  {"REGISTER","UNDO"}
-    
-    desconecta = bpy.props.BoolProperty(name="Keep Connection", default=True)
-    
-    def execute(self,context):
-        
-        duplicateSymmetrical(self, self.desconecta)  
-                      
-        return{"FINISHED"}  
-        
-
-##---------------------------BATCH MAKER------------------
-
-
-def defoscBatchMaker(TYPE):
-    # REVISO SISTEMA
-    if sys.platform.startswith("w"):
-        print ("PLATFORM: WINDOWS")
-        SYSBAR="\\" 
-        EXTSYS=".bat" 
-        QUOTES='"'          
-    else:
-        print ("PLATFORM:LINUX")    
-        SYSBAR="/"
-        EXTSYS=".sh"
-        QUOTES=''
-    
-    print(TYPE)
-    
-    # CREO VARIABLES
-    FILENAME=bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0]
-    BINDIR=bpy.app[4]
-    SHFILE= bpy.data.filepath.rpartition(SYSBAR)[0]+SYSBAR+FILENAME+EXTSYS
-    FILEBATCH=open(SHFILE,"w")
-    FILESC=open(bpy.data.filepath.rpartition(SYSBAR)[0]+SYSBAR+"osRlat.py","w")
-    FILESSC=open(bpy.data.filepath.rpartition(SYSBAR)[0]+SYSBAR+"osRSlat.py","w")
-
-    
-    # DEFINO ARCHIVO DE BATCH
-    FILEBATCH.writelines("%s%s%s -b %s -x 1 -o %s -P %s%s.py  -s %s -e %s -a" % (QUOTES,BINDIR,QUOTES,bpy.data.filepath,bpy.context.scene.render.filepath,bpy.data.filepath.rpartition(SYSBAR)[0]+SYSBAR,TYPE,str(bpy.context.scene.frame_start),str(bpy.context.scene.frame_end)) )
-    FILEBATCH.close()        
-    
-    # SI ES LINUX LE DOY PERMISOS CHMOD
-    if EXTSYS == ".sh":
-        os.chmod(SHFILE, stat.S_IRWXU)
-        
-    
-    
-    # DEFINO LOS ARCHIVOS DE SCRIPT
-    FILESC.writelines("import bpy \nbpy.ops.render.render_layers_at_time_osc()\nbpy.ops.wm.quit_blender()" )
-    FILESC.close()    
-    FILESSC.writelines("import bpy \nbpy.ops.render.render_selected_scenes_osc()\nbpy.ops.wm.quit_blender()" )
-    FILESSC.close() 
-
-class oscBatchMaker (bpy.types.Operator):
-    bl_idname = "file.create_batch_maker_osc"
-    bl_label = "Make render batch" 
-    bl_options = {'REGISTER', 'UNDO'}
-        
-
-    type = bpy.props.EnumProperty(
-            name="Render Mode",
-            description="Select Render Mode.",
-            items=(('osRlat', "All Scenes", "Render All Layers At Time"),
-                   ('osRSlat', "Selected Scenes", "Render Only The Selected Scenes")),
-            default='osRlat',
-            )
-   
-    
-    def execute(self,context):
-        defoscBatchMaker(self.type)
-        return{"FINISHED"}
-
-
-##---------------------------REMOVE MODIFIERS Y APPLY MODIFIERS------------------
-
-class oscRemModifiers (bpy.types.Operator):
-    bl_idname = "object.modifiers_remove_osc"
-    bl_label = "Remove modifiers" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-        for objeto in bpy.context.selected_objects:
-            for modificador in objeto.modifiers:
-                print(modificador.type)
-                bpy.context.scene.objects.active=objeto
-                bpy.ops.object.modifier_remove(modifier=modificador.name)
-        return{"FINISHED"}
-
-class oscApplyModifiers (bpy.types.Operator):
-    bl_idname = "object.modifiers_apply_osc"
-    bl_label = "Apply modifiers" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-        for objeto in bpy.context.selected_objects:
-            bpy.ops.object.select_all(action='DESELECT')
-            bpy.context.scene.objects.active=objeto
-            objeto.select=True            
-            bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', object=True, obdata=True, material=False, texture=False, animation=False)
-            for modificador in objeto.modifiers:
-                print(modificador.type)
-                # SUBSURF
-                if modificador.type == 'SUBSURF':
-                    if modificador.levels > 0:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)          
-                # MESH DEFORM
-                if modificador.type == 'MESH_DEFORM':
-                    if modificador.object != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)      
-                # ARRAY 
-                if modificador.type == 'ARRAY':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                # BEVEL 
-                if modificador.type == 'BEVEL':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name) 
-                # BOOLEAN
-                if modificador.type == 'BOOLEAN':
-                    if modificador.object != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                      
-                # BUILD
-                if modificador.type == 'BUILD':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)            
-                # DECIMATE
-                if modificador.type == 'DECIMATE':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name) 
-                # EDGE SPLIT
-                if modificador.type == 'EDGE_SPLIT':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)             
-                # MASK
-                if modificador.type == 'MASK':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)              
-                # MIRROR
-                if modificador.type == 'MIRROR':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name) 
-                # MULTIRESOLUTION
-                if modificador.type == 'MULTIRES':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                # SCREW
-                if modificador.type == 'SCREW':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                # SOLIDIFY
-                if modificador.type == 'SOLIDIFY':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)     
-                # UV_PROJECT
-                if modificador.type == 'UV_PROJECT':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)              
-                # ARMATURE
-                if modificador.type == 'ARMATURE':
-                    if modificador.object != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name) 
-                # CAST
-                if modificador.type == 'CAST':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name) 
-                # CURVE
-                if modificador.type == 'CURVE':
-                    if modificador.object != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                              
-                # DISPLACE
-                if modificador.type == 'DISPLACE':
-                    if modificador.texture != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                  
-                # HOOK
-                if modificador.type == 'HOOK':
-                    if modificador.object != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                   
-                # LATTICE
-                if modificador.type == 'LATTICE':
-                    if modificador.object != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                
-                # SHRINK WRAP
-                if modificador.type == 'SHRINKWRAP':
-                    if modificador.target != None:
-                        bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                  
-                # SIMPLE DEFORM
-                if modificador.type == 'SIMPLE_DEFORM':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)                
-                # SMOOTH
-                if modificador.type == 'SMOOTH':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)                  
-                # WARP
-                if modificador.type == 'WARP':
-                    if modificador.object_from != None:
-                        if modificador.object_to != None:
-                            bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name)
-                    else:
-                        bpy.ops.object.modifier_remove(modifier=modificador.name)                 
-                # WAVE
-                if modificador.type == 'WAVE':
-                    bpy.ops.object.modifier_apply(apply_as="DATA",modifier=modificador.name) 
-        return{"FINISHED"}
-
-
-        
-##---------------------------SHAPES TO OBJECTS------------------
-
-class ShapeToObjects (bpy.types.Operator):
-    bl_idname = "object.shape_key_to_objects_osc"
-    bl_label = "Shapes To Objects" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-        OBJACT=bpy.context.active_object    
-        for SHAPE in OBJACT.data.shape_keys.key_blocks[:]:
-            print(SHAPE.name)
-            bpy.ops.object.shape_key_clear()
-            SHAPE.value=1
-            mesh=OBJACT.to_mesh(bpy.context.scene, True, 'PREVIEW')
-            object=bpy.data.objects.new(SHAPE.name, mesh)
-            bpy.context.scene.objects.link(object)
-        return{"FINISHED"}
-    
-    
-
-##--------------------------OVERRIDES-----------------------------
-
-## PARA ESCENAS NUEVAS
-
-for scene in bpy.data.scenes[:]:
-    try:
-        scene['OVERRIDE']
-    except:
-        scene['OVERRIDE']="[]"
-
-
-
-class OverridesOp (bpy.types.Operator):
-    bl_idname = "render.overrides_set_list"
-    bl_label = "Overrides set list" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-        for scene in bpy.data.scenes[:]:
-            try:
-                scene['OVERRIDE']
-            except:
-                scene['OVERRIDE']="[]"
-        return{"FINISHED"}        
-
-
-###------------------------IMPORT EXPORT GROUPS--------------------
-
-class OscExportVG (bpy.types.Operator):
-    bl_idname = "file.export_groups_osc"
-    bl_label = "Export Groups" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-
-        OBSEL=bpy.context.active_object
-        
-        if os.sys.platform.count("win"):
-            print("WINDOWS")
-            BAR = "\\"
-        else:
-            print("LINUX")
-            BAR = "/"  
-        # VARIABLES
-        FILEPATH=bpy.data.filepath        
-        FILE=open(FILEPATH.rpartition(BAR)[0]+BAR+OBSEL.name+".xml", mode="w")
-        VERTLIST=[]
-
-        LENVER=len(OBSEL.data.vertices)        
-        
-        for VG in OBSEL.vertex_groups:
-            BONELIST=[]
-            for VERTICE in range(0,LENVER):
-                try:
-                    BONELIST.append((VERTICE,VG.weight(VERTICE),VG.name,))
-                except:
-                    pass
-            VERTLIST.append(BONELIST)
-        
-        ## CREO LA LISTA CON LOS NOMBRES DE LOS GRUPOS
-        NAMEGROUPLIST=[]
-        for VG in OBSEL.vertex_groups:
-            NAMEGROUPLIST.append(VG.name)
-        
-        ## AGREGO LOS NOMBRES A LA LISTA
-        VERTLIST.append(NAMEGROUPLIST)
-        
-        ## GUARDO Y CIERRO
-        FILE.writelines(str(VERTLIST))
-        FILE.close()
-        
-        ## ---- CREO OTRO ARCHIVO PARA LA DATA ----
-        # VARIABLES
-        FILEPATH=bpy.data.filepath        
-        FILE=open(FILEPATH.rpartition(BAR)[0]+BAR+OBSEL.name+"_DATA.xml", mode="w")        
-        
-        DATAVER=[]
-        
-        for VERT in OBSEL.data.vertices[:]:
-            TEMP=0
-            VGTEMP=0
-            LISTVGTEMP=[]            
-            
-            for GROUP in VERT.groups[:]:
-                LISTVGTEMP.append((GROUP.group,VGTEMP))
-                VGTEMP+=1
-            
-            LISTVGTEMP=sorted(LISTVGTEMP)
-            for GROUP in VERT.groups[:]:
-                DATAVER.append((VERT.index,TEMP,VERT.groups[LISTVGTEMP[TEMP][1]].weight))
-                TEMP+=1
-
-        
-        ## GUARDO Y CIERRO
-        FILE.writelines(str(DATAVER))
-        FILE.close()        
-        
-        return{"FINISHED"}
-        
-class OscImportVG (bpy.types.Operator):
-    bl_idname = "file.import_groups_osc"
-    bl_label = "Import Groups" 
-    bl_options =  {"REGISTER","UNDO"}
-    def execute(self,context):
-
-        OBSEL=bpy.context.active_object
-	# AVERIGUO EL SISTEMA
-        if os.sys.platform.count("win"):
-            print("WINDOWS")
-            BAR = "\\"
-        else:
-            print("LINUX")
-            BAR = "/" 
-        # VARIABLES 
-        FILEPATH=bpy.data.filepath
-        FILE=open(FILEPATH.rpartition(BAR)[0]+BAR+OBSEL.name+".xml", mode="r")
-        VERTLIST=FILE.readlines(0)
-        VERTLIST=eval(VERTLIST[0])
-        VERTLISTR=VERTLIST[:-1]
-        GROUPLIST=VERTLIST[-1:]
-        VGINDEX=0      
-        
-        ## MODO OBJECT
-        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-        
-        for GROUP in GROUPLIST[0]:
-            #CREO GRUPO
-            bpy.ops.object.vertex_group_add()
-            #CAMBIO NOMBRE
-            OBSEL.vertex_groups[-1].name=GROUP 
-         
-             
-       
-        
-        for VG in OBSEL.vertex_groups[:]:            
-            # SETEO VG
-            bpy.ops.object.vertex_group_set_active(group=VG.name)            
-            # EDIT    
-            bpy.ops.object.mode_set(mode='EDIT')               
-            # DESELECT
-            bpy.ops.mesh.select_all(action='DESELECT')                          
-            # OBJECT   
-            bpy.ops.object.mode_set(mode='OBJECT')              
-            # SELECCIONO LOS VERTICES             
-            for VERTI in VERTLISTR[VG.index]:
-                OBSEL.data.vertices[VERTI[0]].select=1                   
-            ## SETEO EL VALOR DEL PESO
-            bpy.context.tool_settings.vertex_group_weight=1                                  
-            # EDIT    
-            bpy.ops.object.mode_set(mode='EDIT')         
-            ## ASIGNO
-            bpy.ops.object.vertex_group_assign(new=False)
-
-        # CIERRO
-        FILE.close()
-        
-        
-        ## ----------- LEVANTO DATA ----
-        # VARIABLES 
-        FILEPATH=bpy.data.filepath
-        FILE=open(FILEPATH.rpartition(BAR)[0]+BAR+OBSEL.name+"_DATA.xml", mode="r")
-        DATAPVER=FILE.readlines(0)
-        DATAPVER=eval(DATAPVER[0])
-        
-        # PASO A MODO OBJECT      
-        bpy.ops.object.mode_set(mode='OBJECT')        
-        
-        #for VERT in DATAPVER:
-        for VERT in DATAPVER:
-            OBSEL.data.vertices[VERT[0]].groups[VERT[1]].weight=VERT[2]       
-        
-        # CIERRO
-        FILE.close()
-        
-   
-        # PASO A MODO PINTURA DE PESO       
-        bpy.ops.object.mode_set(mode='WEIGHT_PAINT')
-        return{"FINISHED"}
-
-
-## ------------------------------------ RELINK OBJECTS--------------------------------------   
-
-
-def relinkObjects (self):  
-    
-    LISTSCENE=[]
-    
-    for SCENE in bpy.data.scenes[:]:
-        if bpy.selection[-1] in SCENE.objects[:]:
-            LISTSCENE.append(SCENE)    
-
-    OBJECTS = bpy.selection[:-1]
-    
-    ## REMUEVO ESCENA ACTIVA
-    LISTSCENE.remove(bpy.context.scene)
-    
-    ## DESELECT
-    bpy.ops.object.select_all(action='DESELECT')
-    
-    ## SELECT
-    for OBJETO in OBJECTS:
-        if OBJETO.users != len(bpy.data.scenes):
-            print(OBJETO.name)
-            OBJETO.select = True
-        
-    ## LINK
-    for SCENE in LISTSCENE:
-        bpy.ops.object.make_links_scene(scene=SCENE.name)           
-    
-
-class OscRelinkObjectsBetween (bpy.types.Operator):
-    bl_idname = "objects.relink_objects_between_scenes"
-    bl_label = "Relink Objects Between Scenes" 
-    bl_options =  {"REGISTER","UNDO"}  
-    
-   
-      
-    def execute (self, context):
-        relinkObjects(self)        
-        return {'FINISHED'}
-    
-
-
-## ------------------------------------ COPY GROUPS AND LAYERS--------------------------------------   
-
-
-def CopyObjectGroupsAndLayers (self): 
-              
-    OBSEL=bpy.selection[:]
-    GLOBALLAYERS=str(OBSEL[-1].layers[:])
-    ACTSCENE=bpy.context.scene
-    GROUPS=OBSEL[-1].users_group
-    ERROR=False    
-    
-    for OBJECT in OBSEL[:-1]:
-        for scene in bpy.data.scenes[:]:
-            try:
-                ISINLAYER=False
-                bpy.context.window.screen.scene=scene
-                
-                if OBSEL[-1] in bpy.context.scene.objects[:]:
-                    scene.objects[OBJECT.name].layers=OBSEL[-1].layers
-                else:
-                    scene.objects[OBJECT.name].layers=list(eval(GLOBALLAYERS))
-                    ISINLAYER=True
-                    
-                
-                scene.objects.active=OBJECT
-                
-                for GROUP in GROUPS:
-                    bpy.ops.object.group_link(group=GROUP.name)      
-                
-                if ISINLAYER == False:                          
-                    print("-- %s was successfully copied in %s" % (OBJECT.name,scene.name))
-                else:
-                    print("++ %s copy data from %s in %s" % (OBJECT.name,ACTSCENE.name,scene.name))    
-            except:
-                print ("** %s was not copied in %s" % (OBJECT.name,scene.name))  
-                ERROR = True 
-    bpy.context.window.screen.scene=ACTSCENE 
-    
-    if ERROR == False:
-        self.report({'INFO'}, "All Objects were Successfully Copied")
-    else:
-        self.report({'WARNING'}, "Some Objects Could not be Copied")    
-           
-
-class OscCopyObjectGAL (bpy.types.Operator):
-    bl_idname = "objects.copy_objects_groups_layers"
-    bl_label = "Copy Groups And Layers" 
-    bl_options =  {"REGISTER","UNDO"}  
-   
-      
-    def execute (self, context):
-        CopyObjectGroupsAndLayers (self)        
-        return {'FINISHED'}
-    
-    
-## ------------------------------------ APPLY AND RESTORE OVERRIDES --------------------------------------   
-
-   
-
-class OscApplyOverrides(bpy.types.Operator):
-    bl_idname = "render.apply_overrides"
-    bl_label = "Apply Overrides in this Scene" 
-    bl_options =  {"REGISTER","UNDO"}  
-   
-      
-    def execute (self, context):
-        LISTMAT=[]
-        PROPTOLIST=list(eval(bpy.context.scene['OVERRIDE']))        
-        # REVISO SISTEMA
-        if sys.platform.startswith("w"):
-            print ("PLATFORM: WINDOWS")
-            SYSBAR="\\"           
-        else:
-            print ("PLATFORM:LINUX")    
-            SYSBAR="/"        
-        FILEPATH=bpy.data.filepath
-        ACTIVEFOLDER=FILEPATH.rpartition(SYSBAR)[0]
-        ENTFILEPATH= "%s%s%s_OVERRIDE.xml" %  (ACTIVEFOLDER,SYSBAR,bpy.context.scene.name)
-        XML=open(ENTFILEPATH ,mode="w")        
-        ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
-        for OBJECT in bpy.data.objects[:]:
-            SLOTLIST=[]
-            try:
-                if OBJECT.type=="MESH" or OBJECT.type == "META":
-                    for SLOT in OBJECT.material_slots[:]:
-                        SLOTLIST.append(SLOT.material)                   
-                    LISTMAT.append((OBJECT,SLOTLIST))        
-            except:
-                pass        
-        try:
-            for OVERRIDE in PROPTOLIST:
-                for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
-                    if OBJECT.type == "MESH" or OBJECT.type == "META":
-                        for SLOT in OBJECT.material_slots[:]:
-                            SLOT.material=bpy.data.materials[OVERRIDE[1]]             
-        except:
-            pass
-        
-        XML.writelines(str(LISTMAT))
-        XML.close()       
-        return {'FINISHED'}   
-    
-class OscRestoreOverrides(bpy.types.Operator):
-    bl_idname = "render.restore_overrides"
-    bl_label = "Restore Overrides in this Scene" 
-    bl_options =  {"REGISTER","UNDO"}  
-   
-      
-    def execute (self, context):
-        # REVISO SISTEMA
-        if sys.platform.startswith("w"):
-            print ("PLATFORM: WINDOWS")
-            SYSBAR="\\"           
-        else:
-            print ("PLATFORM:LINUX")    
-            SYSBAR="/"   
-        
-        FILEPATH=bpy.data.filepath
-        ACTIVEFOLDER=FILEPATH.rpartition(SYSBAR)[0]
-        ENTFILEPATH= "%s%s%s_OVERRIDE.xml" %  (ACTIVEFOLDER,SYSBAR,bpy.context.scene.name)
-        XML=open(ENTFILEPATH,mode="r")
-        RXML=XML.readlines(0)
-        
-        LISTMAT=list(eval(RXML[0]))     
-        
-        # RESTAURO MATERIALES  DE OVERRIDES  
-        for OBJECT in LISTMAT:
-            SLOTIND=0
-            try:
-                for SLOT in OBJECT[1]:
-                    OBJECT[0].material_slots[SLOTIND].material=SLOT
-                    SLOTIND+=1
-            except:
-                print("OUT OF RANGE")
-        # CIERRO
-        XML.close()
-       
-        return {'FINISHED'}     
-    
-    
-## ------------------------------------ CHECK OVERRIDES --------------------------------------   
-
-class OscCheckOverrides (bpy.types.Operator):
-    bl_idname = "render.check_overrides"
-    bl_label = "Check Overrides" 
-    bl_options =  {"REGISTER","UNDO"}  
-   
-      
-    def execute (self, context):
-        GROUPI=False
-        GLOBAL=0
-        GLOBALERROR=0
-        
-        print("==== STARTING CHECKING ====")
-        print("")
-        
-        for SCENE in bpy.data.scenes[:]:            
-            MATLIST=[]
-            MATI=False       
-                 
-            for MATERIAL in bpy.data.materials[:]:
-                MATLIST.append(MATERIAL.name)
-                
-            GROUPLIST=[]
-            for GROUP in bpy.data.groups[:]:
-                if GROUP.users > 0:
-                    GROUPLIST.append(GROUP.name)
-                
-            print("   %s Scene is checking" % (SCENE.name))
-            
-            for OVERRIDE in list(eval(SCENE['OVERRIDE'])):
-                # REVISO OVERRIDES EN GRUPOS
-                if OVERRIDE[0] in GROUPLIST:
-                    pass
-                else:                    
-                    print("** %s group are in conflict." % (OVERRIDE[0]))
-                    GROUPI=True
-                    GLOBALERROR+=1
-                # REVISO OVERRIDES EN GRUPOS    
-                if OVERRIDE[1] in MATLIST:
-                    pass
-                else:                 
-                    print("** %s material are in conflict." % (OVERRIDE[1]))
-                    MATI=True
-                    GLOBALERROR+=1
-            
-            if MATI is False:
-                print("-- Materials are ok.") 
-            else:    
-                GLOBAL+=1
-            if GROUPI is False:
-                print("-- Groups are ok.")   
-            else:    
-                GLOBAL+=1
-      
-        if GLOBAL < 1:     
-            self.report({'INFO'}, "Materials And Groups are Ok")     
-        if GLOBALERROR > 0:
-            self.report({'WARNING'}, "Override Error: Look in the Console")    
-        print("")
-
-        return {'FINISHED'}
-          
-     
-   
-##======================================================================================FIN DE SCRIPTS    
-    
-    
-def register():
-    pass
-
-def unregister():
-    pass
-
-if __name__ == "__main__":
-    register()
-
-
-
-## REGISTRA CLASSES
-bpy.utils.register_class(OscPanelControl)
-bpy.utils.register_class(OscPanelObject)
-bpy.utils.register_class(OscPanelMesh)
-bpy.utils.register_class(OscPanelShapes)
-bpy.utils.register_class(OscPanelRender)
-bpy.utils.register_class(OscPanelFiles)
-bpy.utils.register_class(OscPanelOverrides)
-bpy.utils.register_class(SelectMenor)
-bpy.utils.register_class(CreaGrupos)
-bpy.utils.register_class(CreaShapes)
-bpy.utils.register_class(normalsOutside)
-bpy.utils.register_class(resym)
-bpy.utils.register_class(reloadImages)
-bpy.utils.register_class(renderAll)
-bpy.utils.register_class(renderAllCF)
-bpy.utils.register_class(renderCrop)
-bpy.utils.register_class(SearchAndSelectOt)
-bpy.utils.register_class(CreaShapesLayout)
-bpy.utils.register_class(renameObjectsOt)
-bpy.utils.register_class(resymVertexGroups)
-bpy.utils.register_class(CreateLayoutAsymmetrical)
-bpy.utils.register_class(DistributeMinMaxApply)
-bpy.utils.register_class(saveIncremental)
-bpy.utils.register_class(replaceFilePath)
-bpy.utils.register_class(oscDuplicateSymmetricalOp)
-bpy.utils.register_class(oscBatchMaker)
-bpy.utils.register_class(oscRemModifiers)
-bpy.utils.register_class(oscApplyModifiers)
-bpy.utils.register_class(ShapeToObjects)
-bpy.utils.register_class(OverridesOp)
-bpy.utils.register_class(OscExportVG )
-bpy.utils.register_class(OscImportVG )
-bpy.utils.register_class(renderCurrent)
-bpy.utils.register_class(renderCurrentCF)
-bpy.utils.register_class(renderSelected)
-bpy.utils.register_class(renderSelectedCF)
-bpy.utils.register_class(OscRelinkObjectsBetween)
-bpy.utils.register_class(OscCopyObjectGAL) 
-bpy.utils.register_class(OscApplyOverrides)
-bpy.utils.register_class(OscRestoreOverrides)
-bpy.utils.register_class(OscCheckOverrides)
diff --git a/release/scripts/addons_contrib/particle_hair_lab.py b/release/scripts/addons_contrib/particle_hair_lab.py
deleted file mode 100644
index d05f04b..0000000
--- a/release/scripts/addons_contrib/particle_hair_lab.py
+++ /dev/null
@@ -1,1505 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Grass Lab",
-    "author": "Ondrej Raha(lokhorn), meta-androcto",
-    "version": (0,5),
-    "blender": (2, 6, 0),
-    "location": "View3D > Tool Shelf > Grass Preset Panel",
-    "description": "Creates particle grass with material",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Object/grass_Lab",
-    "tracker_url": "",
-    "category": "Object"}
-
-
-import bpy
-from bpy.props import *
-
-# Returns the action we want to take
-def getActionToDo(obj):
-    if not obj or obj.type != 'MESH':
-        return 'NOT_OBJ_DO_NOTHING'
-    elif obj.type == 'MESH':
-        return 'GENERATE'
-    else:
-        return "DO_NOTHING"
-
-# TO DO
-"""
-class saveSelectionPanel(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    bl_label = "Selection Save"
-    bl_options = {"DEFAULT_CLOSED"}
-    bl_context = "particlemode"
-    
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-        
-        col.operator("save.selection", text="Save Selection 1")
-"""
-######GRASS########################
-class grassLabPanel(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    bl_label = "Grass Lab"
-    bl_context = "objectmode"
-    
-
-    def draw(self, context):
-        active_obj = bpy.context.active_object
-        active_scn = bpy.context.scene.name
-        layout = self.layout
-        col = layout.column(align=True)
-        
-        WhatToDo = getActionToDo(active_obj)
-      
-        
-        if WhatToDo == "GENERATE":
-            col.operator("grass.generate_grass", text="Create grass")
-
-            col.prop(context.scene, "grass_type")
-        else:
-            col.label(text="Select mesh object")
-        
-        if active_scn == "TestgrassScene":
-            col.operator("grass.switch_back", text="Switch back to scene")
-        else:
-            col.operator("grass.test_scene", text="Create Test Scene")
-
-# TO DO
-"""
-class saveSelection(bpy.types.Operator):
-    bl_idname = "save.selection"
-    bl_label = "Save Selection"
-    bl_description = "Save selected particles"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-        
-        return {"FINISHED"}
-"""
-class testScene1(bpy.types.Operator):
-    bl_idname = "grass.switch_back"
-    bl_label = "Switch back to scene"
-    bl_description = "If you want keep this scene, switch scene in info window"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-        scene = bpy.context.scene
-        bpy.data.scenes.remove(scene)
-        
-        return {"FINISHED"}
-        
-        
-class testScene2(bpy.types.Operator):
-    bl_idname = "grass.test_scene"
-    bl_label = "Create test scene"
-    bl_description = "You can switch scene in info panel"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-# add new scene
-        bpy.ops.scene.new(type="NEW")
-        scene = bpy.context.scene
-        scene.name = "TestgrassScene"
-# render settings
-        render = scene.render
-        render.resolution_x = 1920
-        render.resolution_y = 1080
-        render.resolution_percentage = 50
-# add new world
-        world = bpy.data.worlds.new("grassWorld")
-        scene.world = world
-        world.use_sky_blend = True
-        world.use_sky_paper = True
-        world.horizon_color = (0.004393,0.02121,0.050)
-        world.zenith_color = (0.03335,0.227,0.359)
-       
-# add text
-        bpy.ops.object.text_add(location=(-0.292,0,-0.152), rotation =(1.571,0,0))
-        text = bpy.context.active_object
-        text.scale = (0.05,0.05,0.05)
-        text.data.body = "Grass Lab"
-        
-# add material to text
-        textMaterial = bpy.data.materials.new('textMaterial')
-        text.data.materials.append(textMaterial)
-        textMaterial.use_shadeless = True
-        
-# add camera
-        bpy.ops.object.camera_add(location = (0,-1,0),rotation = (1.571,0,0))
-        cam = bpy.context.active_object.data
-        cam.lens = 50
-        cam.draw_size = 0.1
-        
-# add spot lamp
-        bpy.ops.object.lamp_add(type="SPOT", location = (-0.7,-0.5,0.3), rotation =(1.223,0,-0.960))
-        lamp1 = bpy.context.active_object.data
-        lamp1.name = "Key Light"
-        lamp1.energy = 1.5
-        lamp1.distance = 1.5
-        lamp1.shadow_buffer_soft = 5
-        lamp1.shadow_buffer_size = 8192
-        lamp1.shadow_buffer_clip_end = 1.5
-        lamp1.spot_blend = 0.5
-        
-# add spot lamp2
-        bpy.ops.object.lamp_add(type="SPOT", location = (0.7,-0.6,0.1), rotation =(1.571,0,0.785))
-        lamp2 = bpy.context.active_object.data
-        lamp2.name = "Fill Light"
-        lamp2.color = (0.874,0.874,1)
-        lamp2.energy = 0.5
-        lamp2.distance = 1.5
-        lamp2.shadow_buffer_soft = 5
-        lamp2.shadow_buffer_size = 4096
-        lamp2.shadow_buffer_clip_end = 1.5
-        lamp2.spot_blend = 0.5
-        
-# light Rim
-        """
-        # add spot lamp3
-        bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
-        lamp3 = bpy.context.active_object.data
-        lamp3.name = "Rim Light"
-        lamp3.color = (0.194,0.477,1)
-        lamp3.energy = 3
-        lamp3.distance = 1.5
-        lamp3.shadow_buffer_soft = 5
-        lamp3.shadow_buffer_size = 4096
-        lamp3.shadow_buffer_clip_end = 1.5
-        lamp3.spot_blend = 0.5
-        """
-# add sphere
-# add sphere
-        bpy.ops.mesh.primitive_uv_sphere_add(size=0.1)
-        bpy.ops.object.shade_smooth()
-		
-        return {"FINISHED"}
-
-
-class Generategrass(bpy.types.Operator):
-    bl_idname = "grass.generate_grass"
-    bl_label = "Generate grass"
-    bl_description = "Create a grass"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-# Make variable that is the current .blend file main data blocks
-        blend_data = context.blend_data
-        ob = bpy.context.active_object
-        scene = context.scene
-
-######################################################################
-########################Test screen grass########################
-        if scene.grass_type == '0':              
-            
-###############Create New Material##################
-# add new material
-            grassMaterial = bpy.data.materials.new('greengrassMat')
-            ob.data.materials.append(grassMaterial)
-            
-#Material settings
-            grassMaterial.preview_render_type = "HAIR"
-            grassMaterial.diffuse_color = (0.09710, 0.288, 0.01687)
-            grassMaterial.specular_color = (0.604, 0.465, 0.136)
-            grassMaterial.specular_intensity = 0.3
-            grassMaterial.ambient = 0
-            grassMaterial.use_cubic = True
-            grassMaterial.use_transparency = True
-            grassMaterial.alpha = 0
-            grassMaterial.use_transparent_shadows = True
-            #strand
-            grassMaterial.strand.use_blender_units = True
-            grassMaterial.strand.root_size = 0.00030
-            grassMaterial.strand.tip_size = 0.00010
-            grassMaterial.strand.size_min = 0.7
-            grassMaterial.strand.width_fade = 0.1
-            grassMaterial.strand.shape = 0.061
-            grassMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            grassTex = bpy.data.textures.new("greengrassTex", type='BLEND')
-            grassTex.use_preview_alpha = True
-            grassTex.use_color_ramp = True
-            ramp = grassTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.114,0.375,0.004025,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.267,0.155,0.02687,0]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.281,0.598,0.03157,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.119,0.528,0.136,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.247,0.713,0.006472,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.01943,0.163,0.01242,0.64]
-    
-# add texture to material
-            MTex = grassMaterial.texture_slots.add()
-            MTex.texture = grassTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-            
-            
-            
-###############  Create Particles  ##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            grassParticles = bpy.context.object.particle_systems.active
-            grassParticles.name = "greengrassPar"
-            grassParticles.settings.type = "HAIR"
-            grassParticles.settings.use_advanced_hair = True
-            grassParticles.settings.count = 500
-            grassParticles.settings.normal_factor = 0.05
-            grassParticles.settings.factor_random = 0.001
-            grassParticles.settings.use_dynamic_rotation = True
-            
-            grassParticles.settings.material = NumberOfMaterials
-            
-            grassParticles.settings.use_strand_primitive = True
-            grassParticles.settings.use_hair_bspline = True
-            grassParticles.settings.render_step = 5
-            grassParticles.settings.length_random = 0.5
-            grassParticles.settings.draw_step = 5
-# children
-            grassParticles.settings.rendered_child_count = 50
-            grassParticles.settings.child_type = "INTERPOLATED"
-            grassParticles.settings.child_length = 0.250
-            grassParticles.settings.create_long_hair_children = True
-            grassParticles.settings.clump_shape = 0.074
-            grassParticles.settings.clump_factor = 0.55
-            grassParticles.settings.roughness_endpoint = 0.080
-            grassParticles.settings.roughness_end_shape = 0.80
-            grassParticles.settings.roughness_2 = 0.043
-            grassParticles.settings.roughness_2_size = 0.230
-        
-        
-######################################################################
-######################  Field Grass  ########################
-        if scene.grass_type == '1':
-###############Create New Material##################
-# add new material
-            grassMaterial = bpy.data.materials.new('fieldgrassMat')
-            ob.data.materials.append(grassMaterial)
-            
-#Material settings
-            grassMaterial.preview_render_type = "HAIR"
-            grassMaterial.diffuse_color = (0.229, 0.800, 0.010)
-            grassMaterial.specular_color = (0.010, 0.06072, 0.000825)
-            grassMaterial.specular_intensity = 0.3
-            grassMaterial.specular_hardness = 100
-            grassMaterial.use_specular_ramp = True
-            
-            ramp = grassMaterial.specular_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.0356,0.0652,0.009134,0]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.352,0.750,0.231,1]
-            rampElement1 = rampElements.new(0.255)
-            rampElement1.color = [0.214,0.342,0.0578,0.31]
-            rampElement2 = rampElements.new(0.594)
-            rampElement2.color = [0.096,0.643,0.0861,0.72]
-            
-            grassMaterial.ambient = 0
-            grassMaterial.use_cubic = True
-            grassMaterial.use_transparency = True
-            grassMaterial.alpha = 0
-            grassMaterial.use_transparent_shadows = True
-            #strand
-            grassMaterial.strand.use_blender_units = True
-            grassMaterial.strand.root_size = 0.00030
-            grassMaterial.strand.tip_size = 0.00015
-            grassMaterial.strand.size_min = 0.450
-            grassMaterial.strand.width_fade = 0.1
-            grassMaterial.strand.shape = 0.02
-            grassMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            grassTex = bpy.data.textures.new("feildgrassTex", type='BLEND')
-            grassTex.name = "feildgrassTex"
-            grassTex.use_preview_alpha = True
-            grassTex.use_color_ramp = True
-            ramp = grassTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.01467,0.005307,0.00316,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.0272,0.01364,0.01013,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.04445,0.02294,0.01729,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.04092,0.0185,0.01161,0.64]
-            
-# add texture to material
-            MTex = grassMaterial.texture_slots.add()
-            MTex.texture = grassTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-            
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            grassParticles = bpy.context.object.particle_systems.active
-            grassParticles.name = "fieldgrassPar"
-            grassParticles.settings.type = "HAIR"
-            grassParticles.settings.use_emit_random = True
-            grassParticles.settings.use_even_distribution = True
-            grassParticles.settings.use_advanced_hair = True
-            grassParticles.settings.count = 2000
-#Particle settings Velocity
-            grassParticles.settings.normal_factor = 0.060
-            grassParticles.settings.factor_random = 0.045
-            grassParticles.settings.use_dynamic_rotation = False
-            grassParticles.settings.brownian_factor = 0.070
-            grassParticles.settings.damping = 0.160
-            grassParticles.settings.material = NumberOfMaterials
- # strands           
-            grassParticles.settings.use_strand_primitive = True
-            grassParticles.settings.use_hair_bspline = True
-            grassParticles.settings.render_step = 7
-            grassParticles.settings.length_random = 1.0
-            grassParticles.settings.draw_step = 2
-# children
-            grassParticles.settings.child_type = "INTERPOLATED"
-            grassParticles.settings.child_length = 0.160
-            grassParticles.settings.create_long_hair_children = False
-            grassParticles.settings.clump_factor = 0.000
-            grassParticles.settings.clump_shape = 0.000
-            grassParticles.settings.roughness_endpoint = 0.000
-            grassParticles.settings.roughness_end_shape = 1
-            grassParticles.settings.roughness_2 = 0.200
-            grassParticles.settings.roughness_2_size = 0.230
-        
-        
-######################################################################
-########################Short Clumpped grass##########################
-        elif scene.grass_type == '2':
-###############Create New Material##################
-# add new material
-            grassMaterial = bpy.data.materials.new('clumpygrassMat')
-            ob.data.materials.append(grassMaterial)
-            
-#Material settings
-            grassMaterial.preview_render_type = "HAIR"
-            grassMaterial.diffuse_color = (0.01504, 0.05222, 0.007724)
-            grassMaterial.specular_color = (0.02610, 0.196, 0.04444)
-            grassMaterial.specular_intensity = 0.5
-            grassMaterial.specular_hardness = 100
-            grassMaterial.ambient = 0
-            grassMaterial.use_cubic = True
-            grassMaterial.use_transparency = True
-            grassMaterial.alpha = 0
-            grassMaterial.use_transparent_shadows = True
-#strand
-            grassMaterial.strand.use_blender_units = True
-            grassMaterial.strand.root_size = 0.000315
-            grassMaterial.strand.tip_size = 0.00020
-            grassMaterial.strand.size_min = 0.2
-            grassMaterial.strand.width_fade = 0.1
-            grassMaterial.strand.shape = -0.900
-            grassMaterial.strand.blend_distance = 0.001
-            
-# add texture
-            grassTex = bpy.data.textures.new("clumpygrasstex", type='BLEND')
-            grassTex.use_preview_alpha = True
-            grassTex.use_color_ramp = True
-            ramp = grassTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.004025,0.002732,0.002428,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.141,0.622,0.107,0.2]
-            rampElement1 = rampElements.new(0.202)
-            rampElement1.color = [0.01885,0.2177,0.01827,0.65]
-            rampElement2 = rampElements.new(0.499)
-            rampElement2.color = [0.114,0.309,0.09822,0.87]
-            rampElement3 = rampElements.new(0.828)
-            rampElement3.color = [0.141,0.427,0.117,0.64]
-            
-# add texture to material
-            MTex = grassMaterial.texture_slots.add()
-            MTex.texture = grassTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-            
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            grassParticles = bpy.context.object.particle_systems.active
-            grassParticles.name = "clumpygrass"
-            grassParticles.settings.type = "HAIR"
-            grassParticles.settings.use_advanced_hair = True
-            grassParticles.settings.hair_step = 2
-            grassParticles.settings.count = 250
-            grassParticles.settings.normal_factor = 0.0082
-            grassParticles.settings.tangent_factor = 0.001
-            grassParticles.settings.tangent_phase = 0.250
-            grassParticles.settings.factor_random = 0.001
-            grassParticles.settings.use_dynamic_rotation = True
-            
-            grassParticles.settings.material = NumberOfMaterials
-            
-            grassParticles.settings.use_strand_primitive = True
-            grassParticles.settings.use_hair_bspline = True
-            grassParticles.settings.render_step = 3
-            grassParticles.settings.length_random = 0.3
-            grassParticles.settings.draw_step = 3
-# children
-            grassParticles.settings.child_type = "INTERPOLATED"
-            grassParticles.settings.child_length = 0.667
-            grassParticles.settings.child_length_threshold = 0.111
-            grassParticles.settings.rendered_child_count = 200
-            grassParticles.settings.virtual_parents = 1
-            grassParticles.settings.clump_factor = 0.425
-            grassParticles.settings.clump_shape = -0.999
-            grassParticles.settings.roughness_endpoint = 0.003
-            grassParticles.settings.roughness_end_shape = 5
-            
-            
-        
-        return {'FINISHED'}
-		
-####
-######### HAIR LAB ##########
-####
-class HairLabPanel(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    bl_label = "Hair Lab"
-    bl_context = "objectmode"
-    
-
-    def draw(self, context):
-        active_obj = bpy.context.active_object
-        active_scn = bpy.context.scene.name
-        layout = self.layout
-        col = layout.column(align=True)
-        
-        WhatToDo = getActionToDo(active_obj)
-      
-        
-        if WhatToDo == "GENERATE":
-            col.operator("hair.generate_hair", text="Create Hair")
-
-            col.prop(context.scene, "hair_type")
-        else:
-            col.label(text="Select mesh object")
-        
-        if active_scn == "TestHairScene":
-            col.operator("hair.switch_back", text="Switch back to scene")
-        else:
-            col.operator("hair.test_scene", text="Create Test Scene")
-
-# TO DO
-"""
-class saveSelection(bpy.types.Operator):
-    bl_idname = "save.selection"
-    bl_label = "Save Selection"
-    bl_description = "Save selected particles"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-        
-        return {"FINISHED"}
-"""
-class testScene3(bpy.types.Operator):
-    bl_idname = "hair.switch_back"
-    bl_label = "Switch back to scene"
-    bl_description = "If you want keep this scene, switch scene in info window"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-        scene = bpy.context.scene
-        bpy.data.scenes.remove(scene)
-        
-        return {"FINISHED"}
-        
-        
-class testScene4(bpy.types.Operator):
-    bl_idname = "hair.test_scene"
-    bl_label = "Create test scene"
-    bl_description = "You can switch scene in info panel"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-# add new scene
-        bpy.ops.scene.new(type="NEW")
-        scene = bpy.context.scene
-        scene.name = "TestHairScene"
-# render settings
-        render = scene.render
-        render.resolution_x = 1920
-        render.resolution_y = 1080
-        render.resolution_percentage = 50
-# add new world
-        world = bpy.data.worlds.new("HairWorld")
-        scene.world = world
-        world.use_sky_blend = True
-        world.use_sky_paper = True
-        world.horizon_color = (0.004393,0.02121,0.050)
-        world.zenith_color = (0.03335,0.227,0.359)
-        
-# add text
-        bpy.ops.object.text_add(location=(-0.292,0,-0.152), rotation =(1.571,0,0))
-        text = bpy.context.active_object
-        text.scale = (0.05,0.05,0.05)
-        text.data.body = "Hair Lab"
-        
-# add material to text
-        textMaterial = bpy.data.materials.new('textMaterial')
-        text.data.materials.append(textMaterial)
-        textMaterial.use_shadeless = True
-        
-# add camera
-        bpy.ops.object.camera_add(location = (0,-1,0),rotation = (1.571,0,0))
-        cam = bpy.context.active_object.data
-        cam.lens = 50
-        cam.draw_size = 0.1
-        
-# add spot lamp
-        bpy.ops.object.lamp_add(type="SPOT", location = (-0.7,-0.5,0.3), rotation =(1.223,0,-0.960))
-        lamp1 = bpy.context.active_object.data
-        lamp1.name = "Key Light"
-        lamp1.energy = 1.5
-        lamp1.distance = 1.5
-        lamp1.shadow_buffer_soft = 5
-        lamp1.shadow_buffer_size = 8192
-        lamp1.shadow_buffer_clip_end = 1.5
-        lamp1.spot_blend = 0.5
-        
-# add spot lamp2
-        bpy.ops.object.lamp_add(type="SPOT", location = (0.7,-0.6,0.1), rotation =(1.571,0,0.785))
-        lamp2 = bpy.context.active_object.data
-        lamp2.name = "Fill Light"
-        lamp2.color = (0.874,0.874,1)
-        lamp2.energy = 0.5
-        lamp2.distance = 1.5
-        lamp2.shadow_buffer_soft = 5
-        lamp2.shadow_buffer_size = 4096
-        lamp2.shadow_buffer_clip_end = 1.5
-        lamp2.spot_blend = 0.5
-        
-# light Rim
-        """
-        # add spot lamp3
-        bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
-        lamp3 = bpy.context.active_object.data
-        lamp3.name = "Rim Light"
-        lamp3.color = (0.194,0.477,1)
-        lamp3.energy = 3
-        lamp3.distance = 1.5
-        lamp3.shadow_buffer_soft = 5
-        lamp3.shadow_buffer_size = 4096
-        lamp3.shadow_buffer_clip_end = 1.5
-        lamp3.spot_blend = 0.5
-        """
-# add sphere
-        bpy.ops.mesh.primitive_uv_sphere_add(size=0.1)
-        bpy.ops.object.shade_smooth()       
-        return {"FINISHED"}
-
-
-class GenerateHair(bpy.types.Operator):
-    bl_idname = "hair.generate_hair"
-    bl_label = "Generate Hair"
-    bl_description = "Create a Hair"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-# Make variable that is the current .blend file main data blocks
-        blend_data = context.blend_data
-        ob = bpy.context.active_object
-        scene = context.scene
-
-######################################################################
-########################Long Red Straight Hair########################
-        if scene.hair_type == '0':              
-            
-###############Create New Material##################
-# add new material
-            hairMaterial = bpy.data.materials.new('LongRedStraightHairMat')
-            ob.data.materials.append(hairMaterial)
-            
-#Material settings
-            hairMaterial.preview_render_type = "HAIR"
-            hairMaterial.diffuse_color = (0.287, 0.216, 0.04667)
-            hairMaterial.specular_color = (0.604, 0.465, 0.136)
-            hairMaterial.specular_intensity = 0.3
-            hairMaterial.ambient = 0
-            hairMaterial.use_cubic = True
-            hairMaterial.use_transparency = True
-            hairMaterial.alpha = 0
-            hairMaterial.use_transparent_shadows = True
-#strand
-            hairMaterial.strand.use_blender_units = True
-            hairMaterial.strand.root_size = 0.00030
-            hairMaterial.strand.tip_size = 0.00010
-            hairMaterial.strand.size_min = 0.7
-            hairMaterial.strand.width_fade = 0.1
-            hairMaterial.strand.shape = 0.061
-            hairMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            hairTex = bpy.data.textures.new("LongRedStraightHairTex", type='BLEND')
-            hairTex.use_preview_alpha = True
-            hairTex.use_color_ramp = True
-            ramp = hairTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.114,0.05613,0.004025,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.267,0.155,0.02687,0]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.281,0.168,0.03157,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.288,0.135,0.006242,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.247,0.113,0.006472,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.253,0.09919,0.01242,0.64]
-    
-# add texture to material
-            MTex = hairMaterial.texture_slots.add()
-            MTex.texture = hairTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-            
-            
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            hairParticles = bpy.context.object.particle_systems.active
-            hairParticles.name = "LongRedStraightHairPar"
-            hairParticles.settings.type = "HAIR"
-            hairParticles.settings.use_advanced_hair = True
-            hairParticles.settings.count = 500
-            hairParticles.settings.normal_factor = 0.05
-            hairParticles.settings.factor_random = 0.001
-            hairParticles.settings.use_dynamic_rotation = True
-            
-            hairParticles.settings.material = NumberOfMaterials
-            
-            hairParticles.settings.use_strand_primitive = True
-            hairParticles.settings.use_hair_bspline = True
-            hairParticles.settings.render_step = 5
-            hairParticles.settings.length_random = 0.5
-            hairParticles.settings.draw_step = 5
-# children
-            hairParticles.settings.child_type = "INTERPOLATED"
-            hairParticles.settings.create_long_hair_children = True
-            hairParticles.settings.clump_factor = 0.55
-            hairParticles.settings.roughness_endpoint = 0.005
-            hairParticles.settings.roughness_end_shape = 5
-            hairParticles.settings.roughness_2 = 0.003
-            hairParticles.settings.roughness_2_size = 0.230
-        
-        
-######################################################################
-########################Long Brown Curl Hair##########################
-        if scene.hair_type == '1':
-###############Create New Material##################
-# add new material
-            hairMaterial = bpy.data.materials.new('LongBrownCurlHairMat')
-            ob.data.materials.append(hairMaterial)
-            
-#Material settings
-            hairMaterial.preview_render_type = "HAIR"
-            hairMaterial.diffuse_color = (0.662, 0.518, 0.458)
-            hairMaterial.specular_color = (0.351, 0.249, 0.230)
-            hairMaterial.specular_intensity = 0.3
-            hairMaterial.specular_hardness = 100
-            hairMaterial.use_specular_ramp = True
-            
-            ramp = hairMaterial.specular_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.0356,0.0152,0.009134,0]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.352,0.250,0.231,1]
-            rampElement1 = rampElements.new(0.255)
-            rampElement1.color = [0.214,0.08244,0.0578,0.31]
-            rampElement2 = rampElements.new(0.594)
-            rampElement2.color = [0.296,0.143,0.0861,0.72]
-            
-            hairMaterial.ambient = 0
-            hairMaterial.use_cubic = True
-            hairMaterial.use_transparency = True
-            hairMaterial.alpha = 0
-            hairMaterial.use_transparent_shadows = True
-#strand
-            hairMaterial.strand.use_blender_units = True
-            hairMaterial.strand.root_size = 0.00030
-            hairMaterial.strand.tip_size = 0.00015
-            hairMaterial.strand.size_min = 0.450
-            hairMaterial.strand.width_fade = 0.1
-            hairMaterial.strand.shape = 0.02
-            hairMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            hairTex = bpy.data.textures.new("HairTex", type='BLEND')
-            hairTex.name = "LongBrownCurlHairTex"
-            hairTex.use_preview_alpha = True
-            hairTex.use_color_ramp = True
-            ramp = hairTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.01467,0.005307,0.00316,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.0272,0.01364,0.01013,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.04445,0.02294,0.01729,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.04092,0.0185,0.01161,0.64]
-            
-# add texture to material
-            MTex = hairMaterial.texture_slots.add()
-            MTex.texture = hairTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-            
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            hairParticles = bpy.context.object.particle_systems.active
-            hairParticles.name = "LongBrownCurlHairPar"
-            hairParticles.settings.type = "HAIR"
-            hairParticles.settings.use_advanced_hair = True
-            hairParticles.settings.count = 500
-            hairParticles.settings.normal_factor = 0.05
-            hairParticles.settings.factor_random = 0.001
-            hairParticles.settings.use_dynamic_rotation = True
-            
-            hairParticles.settings.material = NumberOfMaterials
-            
-            hairParticles.settings.use_strand_primitive = True
-            hairParticles.settings.use_hair_bspline = True
-            hairParticles.settings.render_step = 7
-            hairParticles.settings.length_random = 0.5
-            hairParticles.settings.draw_step = 5
-# children
-            hairParticles.settings.child_type = "INTERPOLATED"
-            hairParticles.settings.create_long_hair_children = True
-            hairParticles.settings.clump_factor = 0.523
-            hairParticles.settings.clump_shape = 0.383
-            hairParticles.settings.roughness_endpoint = 0.002
-            hairParticles.settings.roughness_end_shape = 5
-            hairParticles.settings.roughness_2 = 0.003
-            hairParticles.settings.roughness_2_size = 2
-            
-            hairParticles.settings.kink = "CURL"
-            hairParticles.settings.kink_amplitude = 0.007597
-            hairParticles.settings.kink_frequency = 6
-            hairParticles.settings.kink_shape = 0.4
-            hairParticles.settings.kink_flat = 0.8
-        
-        
-######################################################################
-########################Short Dark Hair##########################
-        elif scene.hair_type == '2':
-###############Create New Material##################
-# add new material
-            hairMaterial = bpy.data.materials.new('ShortDarkHairMat')
-            ob.data.materials.append(hairMaterial)
-            
-#Material settings
-            hairMaterial.preview_render_type = "HAIR"
-            hairMaterial.diffuse_color = (0.560, 0.536, 0.506)
-            hairMaterial.specular_color = (0.196, 0.177, 0.162)
-            hairMaterial.specular_intensity = 0.5
-            hairMaterial.specular_hardness = 100
-            hairMaterial.ambient = 0
-            hairMaterial.use_cubic = True
-            hairMaterial.use_transparency = True
-            hairMaterial.alpha = 0
-            hairMaterial.use_transparent_shadows = True
-#strand
-            hairMaterial.strand.use_blender_units = True
-            hairMaterial.strand.root_size = 0.0002
-            hairMaterial.strand.tip_size = 0.0001
-            hairMaterial.strand.size_min = 0.3
-            hairMaterial.strand.width_fade = 0.1
-            hairMaterial.strand.shape = 0
-            hairMaterial.strand.blend_distance = 0.001
-            
-# add texture
-            hairTex = bpy.data.textures.new("ShortDarkHair", type='BLEND')
-            hairTex.use_preview_alpha = True
-            hairTex.use_color_ramp = True
-            ramp = hairTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.004025,0.002732,0.002428,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.141,0.122,0.107,0.2]
-            rampElement1 = rampElements.new(0.202)
-            rampElement1.color = [0.01885,0.0177,0.01827,0.65]
-            rampElement2 = rampElements.new(0.499)
-            rampElement2.color = [0.114,0.109,0.09822,0.87]
-            rampElement3 = rampElements.new(0.828)
-            rampElement3.color = [0.141,0.127,0.117,0.64]
-            
-# add texture to material
-            MTex = hairMaterial.texture_slots.add()
-            MTex.texture = hairTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-            
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            hairParticles = bpy.context.object.particle_systems.active
-            hairParticles.name = "ShortDarkHair"
-            hairParticles.settings.type = "HAIR"
-            hairParticles.settings.use_advanced_hair = True
-            hairParticles.settings.hair_step = 2
-            hairParticles.settings.count = 450
-            hairParticles.settings.normal_factor = 0.007
-            hairParticles.settings.factor_random = 0.001
-            hairParticles.settings.use_dynamic_rotation = True
-            
-            hairParticles.settings.material = NumberOfMaterials
-            
-            hairParticles.settings.use_strand_primitive = True
-            hairParticles.settings.use_hair_bspline = True
-            hairParticles.settings.render_step = 3
-            hairParticles.settings.length_random = 0.3
-            hairParticles.settings.draw_step = 3
-# children
-            hairParticles.settings.child_type = "INTERPOLATED"
-            hairParticles.settings.rendered_child_count = 200
-            hairParticles.settings.virtual_parents = 1
-            hairParticles.settings.clump_factor = 0.425
-            hairParticles.settings.clump_shape = 0.1
-            hairParticles.settings.roughness_endpoint = 0.003
-            hairParticles.settings.roughness_end_shape = 5
-            
-            
-        
-        return {'FINISHED'}
-####
-######## FUR LAB ########
-####
-
-class FurLabPanel(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    bl_label = "Fur Lab"
-    bl_context = "objectmode"
-    
-
-    def draw(self, context):
-        active_obj = bpy.context.active_object
-        active_scn = bpy.context.scene.name
-        layout = self.layout
-        col = layout.column(align=True)
-        
-        WhatToDo = getActionToDo(active_obj)
-      
-        
-        if WhatToDo == "GENERATE":
-            col.operator("fur.generate_fur", text="Create Fur")
-
-            col.prop(context.scene, "fur_type")
-        else:
-            col.label(text="Select mesh object")
-        
-        if active_scn == "TestFurScene":
-            col.operator("hair.switch_back", text="Switch back to scene")
-        else:
-            col.operator("fur.test_scene", text="Create Test Scene")
-
-# TO DO
-"""
-class saveSelection(bpy.types.Operator):
-    bl_idname = "save.selection"
-    bl_label = "Save Selection"
-    bl_description = "Save selected particles"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-        
-        return {"FINISHED"}
-"""
-class testScene5(bpy.types.Operator):
-    bl_idname = "fur.switch_back"
-    bl_label = "Switch back to scene"
-    bl_description = "If you want keep this scene, switch scene in info window"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-        scene = bpy.context.scene
-        bpy.data.scenes.remove(scene)
-        
-        return {"FINISHED"}
-        
-        
-class testScene6(bpy.types.Operator):
-    bl_idname = "fur.test_scene"
-    bl_label = "Create test scene"
-    bl_description = "You can switch scene in info panel"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-# add new scene
-        bpy.ops.scene.new(type="NEW")
-        scene = bpy.context.scene
-        scene.name = "TestFurScene"
-# render settings
-        render = scene.render
-        render.resolution_x = 1920
-        render.resolution_y = 1080
-        render.resolution_percentage = 50
-# add new world
-        world = bpy.data.worlds.new("FurWorld")
-        scene.world = world
-        world.use_sky_blend = True
-        world.use_sky_paper = True
-        world.horizon_color = (0.004393,0.02121,0.050)
-        world.zenith_color = (0.03335,0.227,0.359)
-        
-# add text
-        bpy.ops.object.text_add(location=(-0.292,0,-0.152), rotation =(1.571,0,0))
-        text = bpy.context.active_object
-        text.scale = (0.05,0.05,0.05)
-        text.data.body = "Fur Lab"
-        
-# add material to text
-        textMaterial = bpy.data.materials.new('textMaterial')
-        text.data.materials.append(textMaterial)
-        textMaterial.use_shadeless = True
-        
-# add camera
-        bpy.ops.object.camera_add(location = (0,-1,0),rotation = (1.571,0,0))
-        cam = bpy.context.active_object.data
-        cam.lens = 50
-        cam.draw_size = 0.1
-        
-# add spot lamp
-        bpy.ops.object.lamp_add(type="SPOT", location = (-0.7,-0.5,0.3), rotation =(1.223,0,-0.960))
-        lamp1 = bpy.context.active_object.data
-        lamp1.name = "Key Light"
-        lamp1.energy = 1.5
-        lamp1.distance = 1.5
-        lamp1.shadow_buffer_soft = 5
-        lamp1.shadow_buffer_size = 8192
-        lamp1.shadow_buffer_clip_end = 1.5
-        lamp1.spot_blend = 0.5
-        
-# add spot lamp2
-        bpy.ops.object.lamp_add(type="SPOT", location = (0.7,-0.6,0.1), rotation =(1.571,0,0.785))
-        lamp2 = bpy.context.active_object.data
-        lamp2.name = "Fill Light"
-        lamp2.color = (0.874,0.874,1)
-        lamp2.energy = 0.5
-        lamp2.distance = 1.5
-        lamp2.shadow_buffer_soft = 5
-        lamp2.shadow_buffer_size = 4096
-        lamp2.shadow_buffer_clip_end = 1.5
-        lamp2.spot_blend = 0.5
-        
-# light Rim
-        """
-        # add spot lamp3
-        bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
-        lamp3 = bpy.context.active_object.data
-        lamp3.name = "Rim Light"
-        lamp3.color = (0.194,0.477,1)
-        lamp3.energy = 3
-        lamp3.distance = 1.5
-        lamp3.shadow_buffer_soft = 5
-        lamp3.shadow_buffer_size = 4096
-        lamp3.shadow_buffer_clip_end = 1.5
-        lamp3.spot_blend = 0.5
-        """
-# add sphere
-        bpy.ops.mesh.primitive_uv_sphere_add(size=0.1)
-        bpy.ops.object.shade_smooth()       
-        return {"FINISHED"}
-
-
-class GenerateFur(bpy.types.Operator):
-    bl_idname = "fur.generate_fur"
-    bl_label = "Generate Fur"
-    bl_description = "Create a Fur"
-    bl_register = True
-    bl_undo = True
-    
-    def execute(self, context):
-# Make variable that is the current .blend file main data blocks
-        blend_data = context.blend_data
-        ob = bpy.context.active_object
-        scene = context.scene
-
-######################################################################
-########################Short Fur########################
-        if scene.fur_type == '0':              
-            
-###############Create New Material##################
-# add new material
-            furMaterial = bpy.data.materials.new('Fur 1')
-            ob.data.materials.append(furMaterial)
-            
-#Material settings
-            furMaterial.preview_render_type = "HAIR"
-            furMaterial.diffuse_color = (0.287, 0.216, 0.04667)
-            furMaterial.specular_color = (0.604, 0.465, 0.136)
-            furMaterial.specular_intensity = 0.3
-            furMaterial.ambient = 0
-            furMaterial.use_cubic = True
-            furMaterial.use_transparency = True
-            furMaterial.alpha = 0
-            furMaterial.use_transparent_shadows = True
-#strand
-            furMaterial.strand.use_blender_units = True
-            furMaterial.strand.root_size = 0.00030
-            furMaterial.strand.tip_size = 0.00010
-            furMaterial.strand.size_min = 0.7
-            furMaterial.strand.width_fade = 0.1
-            furMaterial.strand.shape = 0.061
-            furMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            furTex = bpy.data.textures.new("Fur1Tex", type='BLEND')
-            furTex.use_preview_alpha = True
-            furTex.use_color_ramp = True
-            ramp = furTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.114,0.05613,0.004025,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.267,0.155,0.02687,0]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.281,0.168,0.03157,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.288,0.135,0.006242,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.247,0.113,0.006472,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.253,0.09919,0.01242,0.64]
-    
-# add texture to material
-            MTex = furMaterial.texture_slots.add()
-            MTex.texture = furTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True  
-            
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            furParticles = bpy.context.object.particle_systems.active
-            furParticles.name = "Fur1Par"
-            furParticles.settings.type = "HAIR"
-            furParticles.settings.use_advanced_hair = True
-            furParticles.settings.count = 500
-            furParticles.settings.normal_factor = 0.05
-            furParticles.settings.factor_random = 0.001
-            furParticles.settings.use_dynamic_rotation = True
-            
-            furParticles.settings.material = NumberOfMaterials
-            
-            furParticles.settings.use_strand_primitive = True
-            furParticles.settings.use_hair_bspline = True
-            furParticles.settings.render_step = 5
-            furParticles.settings.length_random = 0.5
-            furParticles.settings.draw_step = 5
-# children
-            furParticles.settings.child_type = "INTERPOLATED"
-            furParticles.settings.child_length = 0.134
-            furParticles.settings.create_long_hair_children = True
-            furParticles.settings.clump_factor = 0.55
-            furParticles.settings.roughness_endpoint = 0.005
-            furParticles.settings.roughness_end_shape = 5
-            furParticles.settings.roughness_2 = 0.003
-            furParticles.settings.roughness_2_size = 0.230
-        
-        
-######################################################################
-########################Dalmation Fur##########################
-        if scene.fur_type == '1':
-###############Create New Material##################
-# add new material
-            furMaterial = bpy.data.materials.new('Fur2Mat')
-            ob.data.materials.append(furMaterial)
-            
-#Material settings
-            furMaterial.preview_render_type = "HAIR"
-            furMaterial.diffuse_color = (0.300, 0.280, 0.280)
-            furMaterial.specular_color = (1.0, 1.0, 1.0)
-            furMaterial.specular_intensity = 0.500
-            furMaterial.specular_hardness = 50
-            
-            furMaterial.ambient = 0
-            furMaterial.use_cubic = True
-            furMaterial.use_transparency = True
-            furMaterial.alpha = 0
-            furMaterial.use_transparent_shadows = True
-#strand
-            furMaterial.strand.use_blender_units = True
-            furMaterial.strand.root_size = 0.00030
-            furMaterial.strand.tip_size = 0.00010
-            furMaterial.strand.size_min = 0.7
-            furMaterial.strand.width_fade = 0.1
-            furMaterial.strand.shape = 0.061
-            furMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            furTex = bpy.data.textures.new("Fur2Tex", type='BLEND')
-            furTex.name = "Fur2"
-            furTex.use_preview_alpha = True
-            furTex.use_color_ramp = True
-            ramp = furTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [1.0,1.0,1.0,1.0]
-            rampElements[1].position = 1
-            rampElements[1].color = [1.0,1.0,1.0,0.0]
-            rampElement1 = rampElements.new(0.116)
-            rampElement1.color = [1.0,1.0,1.0,1.0]
-       
-            
-# add texture to material
-            MTex = furMaterial.texture_slots.add()
-            MTex.texture = furTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-			
-# add texture 2
-            furTex = bpy.data.textures.new("Fur2bTex", type='CLOUDS')
-            furTex.name = "Fur2b"
-            furTex.use_preview_alpha = False
-            furTex.cloud_type = "COLOR"
-            furTex.noise_type = "HARD_NOISE"
-            furTex.noise_scale = 0.06410
-            furTex.use_color_ramp = True
-            ramp = furTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [1.0,1.0,1.0, 1.0]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.0,0.0,0.0,1.0]
-            rampElement1 = rampElements.new(0.317)
-            rampElement1.color = [1.0,1.0,1.0,1.0]
-            rampElement2 = rampElements.new(0.347)
-            rampElement2.color = [0.0,0.0,0.0,1.0]
-            
-# add texture 2 to material
-            MTex = furMaterial.texture_slots.add()
-            MTex.texture = furTex
-            MTex.texture_coords = "GLOBAL"
-            MTex.use_map_alpha = True      
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            furParticles = bpy.context.object.particle_systems.active
-            furParticles.name = "Fur2Par"
-            furParticles.settings.type = "HAIR"
-            furParticles.settings.use_advanced_hair = True
-            furParticles.settings.count = 500
-            furParticles.settings.normal_factor = 0.05
-            furParticles.settings.factor_random = 0.001
-            furParticles.settings.use_dynamic_rotation = True
-            
-            furParticles.settings.material = NumberOfMaterials
-            
-            furParticles.settings.use_strand_primitive = True
-            furParticles.settings.use_hair_bspline = True
-            furParticles.settings.render_step = 5
-            furParticles.settings.length_random = 0.5
-            furParticles.settings.draw_step = 5
-# children
-            furParticles.settings.child_type = "INTERPOLATED"
-            furParticles.settings.child_length = 0.07227
-            furParticles.settings.create_long_hair_children = True
-            furParticles.settings.clump_factor = 0.55
-            furParticles.settings.roughness_endpoint = 0.005
-            furParticles.settings.roughness_end_shape = 5
-            furParticles.settings.roughness_2 = 0.003
-            furParticles.settings.roughness_2_size = 0.230
-        
-######################################################################
-########################Spotted_fur##########################
-        elif scene.fur_type == '2':
-
-###############Create New Material##################
-# add new material
-            furMaterial = bpy.data.materials.new('Fur3Mat')
-            ob.data.materials.append(furMaterial)
-            
-#Material settings
-            furMaterial.preview_render_type = "HAIR"
-            furMaterial.diffuse_color = (0.300, 0.280, 0.280)
-            furMaterial.specular_color = (1.0, 1.0, 1.0)
-            furMaterial.specular_intensity = 0.500
-            furMaterial.specular_hardness = 50
-            furMaterial.use_specular_ramp = True
-            
-            ramp = furMaterial.specular_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.0356,0.0152,0.009134,0]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.352,0.250,0.231,1]
-            rampElement1 = rampElements.new(0.255)
-            rampElement1.color = [0.214,0.08244,0.0578,0.31]
-            rampElement2 = rampElements.new(0.594)
-            rampElement2.color = [0.296,0.143,0.0861,0.72]
-            
-            furMaterial.ambient = 0
-            furMaterial.use_cubic = True
-            furMaterial.use_transparency = True
-            furMaterial.alpha = 0
-            furMaterial.use_transparent_shadows = True
-#strand
-            furMaterial.strand.use_blender_units = True
-            furMaterial.strand.root_size = 0.00030
-            furMaterial.strand.tip_size = 0.00015
-            furMaterial.strand.size_min = 0.450
-            furMaterial.strand.width_fade = 0.1
-            furMaterial.strand.shape = 0.02
-            furMaterial.strand.blend_distance = 0.001
-            
-            
-# add texture
-            furTex = bpy.data.textures.new("Fur3Tex", type='BLEND')
-            furTex.name = "Fur3"
-            furTex.use_preview_alpha = True
-            furTex.use_color_ramp = True
-            ramp = furTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.01467,0.005307,0.00316,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.0272,0.01364,0.01013,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.04445,0.02294,0.01729,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.04092,0.0185,0.01161,0.64]
-            
-# add texture to material
-            MTex = furMaterial.texture_slots.add()
-            MTex.texture = furTex
-            MTex.texture_coords = "STRAND"
-            MTex.use_map_alpha = True
-			
-# add texture 2
-            furTex = bpy.data.textures.new("Fur3bTex", type='CLOUDS')
-            furTex.name = "Fur3b"
-            furTex.use_preview_alpha = True
-            furTex.cloud_type = "COLOR"
-            furTex.use_color_ramp = True
-            ramp = furTex.color_ramp
-            rampElements = ramp.elements
-            rampElements[0].position = 0
-            rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
-            rampElements[1].position = 1
-            rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
-            rampElement1 = rampElements.new(0.111)
-            rampElement1.color = [0.01467,0.005307,0.00316,0.65]
-            rampElement2 = rampElements.new(0.366)
-            rampElement2.color = [0.0272,0.01364,0.01013,0.87]
-            rampElement3 = rampElements.new(0.608)
-            rampElement3.color = [0.04445,0.02294,0.01729,0.8]
-            rampElement4 = rampElements.new(0.828)
-            rampElement4.color = [0.04092,0.0185,0.01161,0.64]
-            
-# add texture 2 to material
-            MTex = furMaterial.texture_slots.add()
-            MTex.texture = furTex
-            MTex.texture_coords = "GLOBAL"
-            MTex.use_map_alpha = False      
-            
-###############Create Particles##################
-# Add new particle system
-            
-            NumberOfMaterials = 0
-            for i in ob.data.materials:
-                NumberOfMaterials +=1
-            
-            
-            bpy.ops.object.particle_system_add()
-#Particle settings setting it up!
-            furParticles = bpy.context.object.particle_systems.active
-            furParticles.name = "Fur3Par"
-            furParticles.settings.type = "HAIR"
-            furParticles.settings.use_advanced_hair = True
-            furParticles.settings.count = 500
-            furParticles.settings.normal_factor = 0.05
-            furParticles.settings.factor_random = 0.001
-            furParticles.settings.use_dynamic_rotation = True
-            
-            furParticles.settings.material = NumberOfMaterials
-            
-            furParticles.settings.use_strand_primitive = True
-            furParticles.settings.use_hair_bspline = True
-            furParticles.settings.render_step = 5
-            furParticles.settings.length_random = 0.5
-            furParticles.settings.draw_step = 5
-# children
-            furParticles.settings.child_type = "INTERPOLATED"
-            furParticles.settings.child_length = 0.134
-            furParticles.settings.create_long_hair_children = True
-            furParticles.settings.clump_factor = 0.55
-            furParticles.settings.roughness_endpoint = 0.005
-            furParticles.settings.roughness_end_shape = 5
-            furParticles.settings.roughness_2 = 0.003
-            furParticles.settings.roughness_2_size = 0.230
-        
-        return {'FINISHED'}
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.types.Scene.grass_type = EnumProperty(
-        name="Type",
-        description="Select the type of grass",
-        items=[("0","Green Grass","Generate particle grass"),
-               ("1","Grassy Field","Generate particle grass"),
-               ("2","Clumpy Grass","Generate particle grass"),
-        
-              ],
-        default='0')
-    bpy.types.Scene.hair_type = EnumProperty(
-        name="Type",
-        description="Select the type of hair",
-        items=[("0","Long Red Straight Hair","Generate particle Hair"),
-               ("1","Long Brown Curl Hair","Generate particle Hair"),
-               ("2","Short Dark Hair","Generate particle Hair"),
-        
-              ],
-        default='0')
-    bpy.types.Scene.fur_type = EnumProperty(
-        name="Type",
-        description="Select the type of fur",
-        items=[("0","Short Fur","Generate particle Fur"),
-               ("1","Dalmation","Generate particle Fur"),
-               ("2","Fur3","Generate particle Fur"),
-        
-              ],
-        default='0')
-        
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    del bpy.types.Scene.hair_type
-    
-if __name__ == "__main__":
-    register()
-    
-    
-
diff --git a/release/scripts/addons_contrib/presets/interface_theme/3ds_max.xml b/release/scripts/addons_contrib/presets/interface_theme/3ds_max.xml
deleted file mode 100644
index 370c57b..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/3ds_max.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#ffffff"
-                   editmesh_active="#fcf8ff80"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#200000"
-                   edge_seam="#e69632"
-                   edge_select="#ff3d3d"
-                   edge_sharp="#ff2020"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#a8a8a84d"
-                   extra_face_angle="#000080"
-                   extra_face_area="#002000"
-                   face_dot="#883737"
-                   facedot_size="2"
-                   normal="#22dddd"
-                   face_select="#ae606066"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#505050"
-                   lamp="#00000028"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#104010"
-                   object_grouped_active="#55bb55"
-                   object_selected="#fa3f00"
-                   outline_width="1"
-                   panel="#a5a5a5ff"
-                   speaker="#000000"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#5454f0"
-                   vertex_normal="#2361dd"
-                   vertex_select="#ae6060"
-                   vertex_size="3"
-                   wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#494949"
-                             button_text_hi="#ffffff"
-                             button_title="#494949"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#737373">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#000000"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#737373">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#dc6060"
-                    line_info="#00aa00"
-                    line_input="#ffffff"
-                    line_output="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#60c040"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#505050"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#737373">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#b4b4b4"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#828282"
-                        active_file_text="#fafafa"
-                        scroll_handle="#7f7070"
-                        scrollbar="#a0a0a0"
-                        selected_file="#d7ae6d"
-                        tiles="#b4b4b4">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#0f0f0f"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#b4b4b4"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#000000"
-                        handle_sel_auto_clamped="#000000"
-                        channel_group="#4f6549"
-                        channels_region="#707070"
-                        frame_current="#60c040"
-                        dopesheet_channel="#52606e"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#000000"
-                        handle_sel_free="#000000"
-                        grid="#505050"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ff8500"
-                        handle_vertex_size="3"
-                        lastsel_point="#ffffff"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#737373">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#b4b4b4"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff0000"
-                        facedot_size="3"
-                        face_select="#7c00003c"
-                        scope_back="#b4b4b4ff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#5454f0"
-                        vertex_select="#d00000"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#757575">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#a5a5a5">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#60c040"
-                      grid="#5e5e5e"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#757575">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#b4b4b4"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#deaf66"
-                       group_node="#3c753c"
-                       in_out_node="#faa044"
-                       node_backdrop="#9b9b9ba0"
-                       noodle_curving="5"
-                       operator_node="#9e733e"
-                       selected_text="#7f7070"
-                       wire_select="#ffffff"
-                       wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#737373">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#337f33"
-                     selected_highlight="#82878c">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#fff1e1"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#b4b4b4">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#60c040"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#404040"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#949494">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ff0000"
-                       syntax_special="#5f5f00"
-                       line_numbers_background="#404040"
-                       selected_text="#c67777"
-                       syntax_builtin="#800050"
-                       syntax_comment="#006432"
-                       syntax_numbers="#0000c8"
-                       syntax_string="#640000">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#d1d1d1">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#60c040"
-                     grid="#505050">
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#999999">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#d1d1d1ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#d8c555aa"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#b4b4b4ff"
-                             inner_sel="#2d2d2dff"
-                             item="#646464ff"
-                             outline="#424242"
-                             shadedown="30"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#8897a4ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#aeaeaeff"
-                             inner_sel="#464646ff"
-                             item="#6d8da6ff"
-                             outline="#464646"
-                             shadedown="-5"
-                             shadetop="15"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#cccccc">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#c4c4c4ff"
-                             inner_sel="#999999ff"
-                             item="#708faaff"
-                             outline="#708faa"
-                             shadedown="0"
-                             shadetop="-10"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#a2a2a2ff"
-                             inner_sel="#bbb8a3ff"
-                             item="#ffffffff"
-                             outline="#747474"
-                             shadedown="0"
-                             shadetop="10"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000019"
-                            show_header="TRUE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#bebebeff"
-                             inner_sel="#646464b4"
-                             item="#444444ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#3f3f3fff"
-                             inner_sel="#536a7e26"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#c3c3c3ff"
-                             inner_sel="#ddae64ff"
-                             item="#ffffffff"
-                             outline="#708faa"
-                             shadedown="0"
-                             shadetop="10"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#708faa26"
-                             inner_sel="#646464b4"
-                             item="#a9a9a9ff"
-                             outline="#708faa"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#b4b4b4ff"
-                             inner_sel="#999999ff"
-                             item="#c9c9c9ff"
-                             outline="#747474"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#73be4c"
-                                  inner_anim_sel="#5aa633"
-                                  blend="0.5"
-                                  inner_driven="#b400ff"
-                                  inner_driven_sel="#9900e6"
-                                  inner_key="#f0eb64"
-                                  inner_key_sel="#d7d34b">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#d1d1d1ff"
-                             inner_sel="#999999ff"
-                             item="#5a5a5aff"
-                             outline="#535353"
-                             shadedown="25"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#d0d0d0ff"
-                             inner_sel="#64717dff"
-                             item="#191919ff"
-                             outline="#708faa"
-                             shadedown="0"
-                             shadetop="10"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#c4c4c4ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#708faa"
-                             shadedown="0"
-                             shadetop="-10"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#b4b4b4"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#b4b4b4"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#b4b4b4">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/default.xml b/release/scripts/addons_contrib/presets/interface_theme/default.xml
deleted file mode 100644
index 6adb8df..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/default.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#ffaa40"
-                   editmesh_active="#ffffff80"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#200000"
-                   edge_seam="#db2512"
-                   edge_select="#ffa000"
-                   edge_sharp="#00ffff"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#00000012"
-                   extra_face_angle="#000080"
-                   extra_face_area="#002000"
-                   face_dot="#ff8500"
-                   facedot_size="4"
-                   normal="#22dddd"
-                   face_select="#ff85003c"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#404040"
-                   lamp="#00000028"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#083008"
-                   object_grouped_active="#55bb55"
-                   object_selected="#f15800"
-                   outline_width="1"
-                   panel="#a5a5a57f"
-                   speaker="#000000"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#000000"
-                   vertex_normal="#2361dd"
-                   vertex_select="#ff8500"
-                   vertex_size="3"
-                   wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#393939">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#000000"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#393939">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#dc6060"
-                    line_info="#00aa00"
-                    line_input="#ffffff"
-                    line_output="#6080ff">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#60c040"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#5e5e5e"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#828282"
-                        active_file_text="#fafafa"
-                        scroll_handle="#7f7070"
-                        scrollbar="#a0a0a0"
-                        selected_file="#ff8c19"
-                        tiles="#919191">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#fafafa"
-                             text_hi="#0f0f0f"
-                             title="#000000"
-                             back="#4c4c4c">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#4f6549"
-                        channels_region="#707070"
-                        frame_current="#60c040"
-                        dopesheet_channel="#52606e"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#000000"
-                        handle_sel_free="#000000"
-                        grid="#5e5e5e"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ff8500"
-                        handle_vertex_size="4"
-                        lastsel_point="#ffffff"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff8500"
-                        facedot_size="3"
-                        face_select="#ff85003c"
-                        scope_back="#727272ff"
-                        preview_stitch_active="#00000000"
-                        preview_stitch_edge="#ff00ff33"
-                        preview_stitch_face="#7f7f0033"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#0000ff33"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#353535">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#a5a5a5">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#646464">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#60c040"
-                      grid="#5e5e5e"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#686a75"
-                       group_node="#69756e"
-                       in_out_node="#646464"
-                       node_backdrop="#9b9b9ba0"
-                       noodle_curving="5"
-                       operator_node="#6c696f"
-                       selected_text="#7f7070"
-                       wire_select="#ffffff"
-                       wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#393939">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#337f33"
-                     selected_highlight="#82878c">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#828282">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#60c040"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#404040"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#747474">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ff0000"
-                       syntax_special="#5f5f00"
-                       line_numbers_background="#404040"
-                       selected_text="#c67777"
-                       syntax_builtin="#800050"
-                       syntax_comment="#006432"
-                       syntax_numbers="#0000c8"
-                       syntax_string="#640000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#999999">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#60c040"
-                     grid="#5b5b5b">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#808080ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#5680c2ff"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#a0a0a0"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#5680c2ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="38"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#464646ff"
-                             inner_sel="#464646ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#cccccc">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#b4b4b4ff"
-                             inner_sel="#999999ff"
-                             item="#5a5a5aff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#464646ff"
-                             inner_sel="#464646ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000019"
-                            show_header="FALSE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#bebebeff"
-                             inner_sel="#646464b4"
-                             item="#444444ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#3f3f3fff"
-                             inner_sel="#5680c2ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#464646ff"
-                             inner_sel="#5680c2ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#505050b4"
-                             inner_sel="#646464b4"
-                             item="#808080ff"
-                             outline="#323232"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#b4b4b4ff"
-                             inner_sel="#999999ff"
-                             item="#808080ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#73be4c"
-                                  inner_anim_sel="#5aa633"
-                                  blend="0.5"
-                                  inner_driven="#b400ff"
-                                  inner_driven_sel="#9900e6"
-                                  inner_key="#f0eb64"
-                                  inner_key_sel="#d7d34b">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#999999ff"
-                             item="#5a5a5aff"
-                             outline="#191919"
-                             shadedown="25"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/maya.xml b/release/scripts/addons_contrib/presets/interface_theme/maya.xml
deleted file mode 100644
index 65d6245..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/maya.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#43ffa3"
-                   editmesh_active="#ffffff80"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#200000"
-                   edge_seam="#db2512"
-                   edge_select="#ffa000"
-                   edge_sharp="#ff2020"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#00000012"
-                   extra_face_angle="#000080"
-                   extra_face_area="#002000"
-                   face_dot="#ff8500"
-                   facedot_size="4"
-                   normal="#22dddd"
-                   face_select="#ff85003c"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#7f7f7f"
-                   lamp="#00000028"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#083008"
-                   object_grouped_active="#55bb55"
-                   object_selected="#f15800"
-                   outline_width="1"
-                   panel="#a5a5a57f"
-                   speaker="#000000"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#cc1b23"
-                   vertex_normal="#2361dd"
-                   vertex_select="#ff8500"
-                   vertex_size="3"
-                   wire="#64dcff">
-        <space>
-          <ThemeSpaceGeneric header="#444444"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#444444"
-                             button_text="#ffffff"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#576471">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#000000"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#3a3a3a"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#444444"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#576471">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#dc6060"
-                    line_info="#00aa00"
-                    line_input="#ffffff"
-                    line_output="#6080ff">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#60c040"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#5e5e5e"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#828282"
-                        active_file_text="#fafafa"
-                        scroll_handle="#7f7070"
-                        scrollbar="#a0a0a0"
-                        selected_file="#ff8c19"
-                        tiles="#919191">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#fafafa"
-                             text_hi="#0f0f0f"
-                             title="#000000"
-                             back="#4c4c4c">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#4f6549"
-                        channels_region="#707070"
-                        frame_current="#60c040"
-                        dopesheet_channel="#52606e"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#000000"
-                        handle_sel_free="#000000"
-                        grid="#5e5e5e"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ff8500"
-                        handle_vertex_size="3"
-                        lastsel_point="#ffffff"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff8500"
-                        facedot_size="3"
-                        face_select="#ff85003c"
-                        scope_back="#727272ff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#353535">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#444444"
-                             header_text="#dddddd"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#a5a5a5">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#646464">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#60c040"
-                      grid="#5e5e5e"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#686a75"
-                       group_node="#69756e"
-                       in_out_node="#646464"
-                       node_backdrop="#9b9b9ba0"
-                       noodle_curving="5"
-                       operator_node="#6c696f"
-                       selected_text="#7f7070"
-                       wire_select="#ffffff"
-                       wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#393939">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#356c1a"
-                     selected_highlight="#446e1c">
-        <space>
-          <ThemeSpaceGeneric header="#444444"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#dddddd"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#444444">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#828282">
-        <space>
-          <ThemeSpaceGeneric header="#444444"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#dddddd"
-                             text_hi="#ffffff"
-                             title="#dddddd"
-                             back="#444444">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#60c040"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#404040"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#747474">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ff0000"
-                       syntax_special="#5f5f00"
-                       line_numbers_background="#404040"
-                       selected_text="#c67777"
-                       syntax_builtin="#800050"
-                       syntax_comment="#006432"
-                       syntax_numbers="#0000c8"
-                       syntax_string="#640000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#999999">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#60c040"
-                     grid="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#444444"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#737373">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#696969ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#5680c2ff"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#444444ff"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#a0a0a0"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#658aaeff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="38"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#777777ff"
-                             inner_sel="#464646ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#cccccc">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#222222ff"
-                             inner_sel="#999999ff"
-                             item="#5a5a5aff"
-                             outline="#525252"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#2b2b2bff"
-                             inner_sel="#464646ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#888284"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000019"
-                            show_header="FALSE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#bebebeff"
-                             inner_sel="#646464b4"
-                             item="#444444ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#3f3f3fff"
-                             inner_sel="#656969ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#dddddd"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#292929ff"
-                             inner_sel="#678db2ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#505050b4"
-                             inner_sel="#646464b4"
-                             item="#808080ff"
-                             outline="#323232"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#535353ff"
-                             inner_sel="#999999ff"
-                             item="#808080ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#73be4c"
-                                  inner_anim_sel="#5aa633"
-                                  blend="0.5"
-                                  inner_driven="#b400ff"
-                                  inner_driven_sel="#9900e6"
-                                  inner_key="#f0eb64"
-                                  inner_key_sel="#d7d34b">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#131313ff"
-                             inner_sel="#333230ff"
-                             item="#678db2ff"
-                             outline="#191919"
-                             shadedown="25"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#dddddd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#2c2c2cff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#8f8f8f"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#444444">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/modo.xml b/release/scripts/addons_contrib/presets/interface_theme/modo.xml
deleted file mode 100644
index 94407f5..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/modo.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#ff8c19"
-                   editmesh_active="#ffffff80"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#200000"
-                   edge_seam="#db2512"
-                   edge_select="#ffa000"
-                   edge_sharp="#ff2020"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#00000012"
-                   extra_face_angle="#002000"
-                   extra_face_area="#000080"
-                   face_dot="#ff8500"
-                   facedot_size="4"
-                   normal="#22dddd"
-                   face_select="#ff85003c"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#5b6672"
-                   lamp="#00000028"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#083008"
-                   object_grouped_active="#55bb55"
-                   object_selected="#f15800"
-                   outline_width="1"
-                   panel="#a5a5a57f"
-                   speaker="#000000"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#000000"
-                   vertex_normal="#2361dd"
-                   vertex_select="#ff8500"
-                   vertex_size="3"
-                   wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#484848"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#40464e">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#000000"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#484848"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#40464e">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#dc6060"
-                    line_info="#00aa00"
-                    line_input="#ffffff"
-                    line_output="#6080ff">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#60c040"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#5b6672"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#484848"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#828282"
-                        active_file_text="#fafafa"
-                        scroll_handle="#7f7070"
-                        scrollbar="#a0a0a0"
-                        selected_file="#ff8c19"
-                        tiles="#484848">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#726f6d"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#fafafa"
-                             text_hi="#0f0f0f"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#484848"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#4f6549"
-                        channels_region="#707070"
-                        frame_current="#60c040"
-                        dopesheet_channel="#52606e"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#000000"
-                        handle_sel_free="#000000"
-                        grid="#5b6672"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ff8500"
-                        handle_vertex_size="3"
-                        lastsel_point="#000000"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#484848"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff8500"
-                        facedot_size="3"
-                        face_select="#ff85003c"
-                        scope_back="#727272ff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#484848"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#888888"
-                             header_text_hi="#ffffff"
-                             button="#725864"
-                             button_text="#f0f0f0"
-                             button_text_hi="#ffffff"
-                             button_title="#f1c2d8"
-                             text="#888884"
-                             text_hi="#ffffff"
-                             title="#c8c6c9"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#a5a5a5">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#60c040"
-                      grid="#5b6672"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#484848"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#686a75"
-                       group_node="#69756e"
-                       in_out_node="#646464"
-                       node_backdrop="#9b9b9ba0"
-                       noodle_curving="5"
-                       operator_node="#6c696f"
-                       selected_text="#7f7070"
-                       wire_select="#ffffff"
-                       wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#484848"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#337f33"
-                     selected_highlight="#82878c">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#fdfcff"
-                             button_title="#070707"
-                             text="#000000"
-                             text_hi="#f49c1c"
-                             title="#0e0e0e"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#827d7d">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#dff5ff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#3f3a2f"
-                             text="#000000"
-                             text_hi="#000000"
-                             title="#000000"
-                             back="#484848">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#60c040"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#5b6672"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ff0000"
-                       syntax_special="#5f5f00"
-                       line_numbers_background="#404040"
-                       selected_text="#c67777"
-                       syntax_builtin="#800050"
-                       syntax_comment="#006432"
-                       syntax_numbers="#0000c8"
-                       syntax_string="#640000">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#60c040"
-                     grid="#5b6672">
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#9098a0">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#464646ff"
-                             inner_sel="#646464ff"
-                             item="#000000ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#f49c1cff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#606060e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#a0a0a0"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#f49c1cff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="38"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#606060ff"
-                             inner_sel="#f49c1cff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#9098a0ff"
-                             inner_sel="#f49c1cff"
-                             item="#5a5a5aff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#686868ff"
-                             inner_sel="#f49c1cff"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#ffffff79"
-                            show_header="FALSE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#bebebeff"
-                             inner_sel="#646464b4"
-                             item="#444444ff"
-                             outline="#000000"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#606060ff"
-                             inner_sel="#f49c1cff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#888888"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#464646ff"
-                             inner_sel="#f49c1cff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#979999ff"
-                             inner_sel="#646464ff"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#505050b4"
-                             inner_sel="#646464b4"
-                             item="#606060ff"
-                             outline="#323232"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#b4b4b4ff"
-                             inner_sel="#999999ff"
-                             item="#9098a0ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#73be4c"
-                                  inner_anim_sel="#5aa633"
-                                  blend="0.5"
-                                  inner_driven="#b400ff"
-                                  inner_driven_sel="#9900e6"
-                                  inner_key="#c9ce20"
-                                  inner_key_sel="#d7d34b">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#999999ff"
-                             item="#5a5a5aff"
-                             outline="#93a56f"
-                             shadedown="25"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#fdfdfd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#f49c1cff"
-                             item="#5a5a5aff"
-                             outline="#302e2e"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#606060ff"
-                             inner_sel="#f49c1cff"
-                             item="#000000ff"
-                             outline="#191919"
-                             shadedown="-15"
-                             shadetop="15"
-                             show_shaded="FALSE"
-                             text="#f1f1f1"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#202020"
-                             header_text="#000000"
-                             header_text_hi="#fdffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#484848">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/pinkified.xml b/release/scripts/addons_contrib/presets/interface_theme/pinkified.xml
deleted file mode 100644
index 6686ccf..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/pinkified.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#ff0034"
-                   editmesh_active="#ff5edece"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#424242"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#a0a0a0"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#200000"
-                   edge_seam="#ff0000"
-                   edge_select="#b30025"
-                   edge_sharp="#7bff00"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#ffffff0c"
-                   extra_face_angle="#008200"
-                   extra_face_area="#0000ff"
-                   face_dot="#ac0023"
-                   facedot_size="4"
-                   normal="#27ffff"
-                   face_select="#e8142f2c"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#181818"
-                   lamp="#977f491e"
-                   lastsel_point="#f0ff40"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#127112"
-                   object_grouped_active="#55bb55"
-                   object_selected="#d1687d"
-                   outline_width="1"
-                   panel="#7575757f"
-                   speaker="#a63904"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#9a001f"
-                   vertex_normal="#2361dd"
-                   vertex_select="#ff0034"
-                   vertex_size="4"
-                   wire="#505050">
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#757575"
-                             header_text_hi="#ffffff"
-                             button="#161616"
-                             button_text="#6a6a6a"
-                             button_text_hi="#ffffff"
-                             button_title="#cccccc"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#c7c7c7"
-                             back="#111111">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffe6ea"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="6"
-                       locked_marker="#7f7f7f"
-                       marker="#f68026"
-                       marker_outline="#3c3c3c"
-                       path_after="#007dff"
-                       path_before="#ff0b22"
-                       selected_marker="#ff2550">
-        <space>
-          <ThemeSpaceGeneric header="#232323"
-                             header_text="#aaaaaa"
-                             header_text_hi="#ffffff"
-                             button="#0b0b0b"
-                             button_text="#888888"
-                             button_text_hi="#ffffff"
-                             button_title="#adadad"
-                             text="#888888"
-                             text_hi="#ffffff"
-                             title="#6b6b6b"
-                             back="#232323">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#00df62"
-                    line_info="#ffd600"
-                    line_input="#a4a4a4"
-                    line_output="#ff336e">
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#343434"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#828282"
-                             text_hi="#ffffff"
-                             title="#828282"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#676767"
-                      channels_selected="#ff8099"
-                      frame_current="#99112c"
-                      dopesheet_channel="#39434d"
-                      dopesheet_subchannel="#15171a"
-                      grid="#0b0b0b"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff7500"
-                      value_sliders="#000000"
-                      view_sliders="#898989">
-        <space>
-          <ThemeSpaceGeneric header="#2a2a2a"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#2a2a2a"
-                             button_text="#636363"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#828282"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#2a2a2a">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#2a2a2a"
-                                 list_text="#b3b3b3"
-                                 list_text_hi="#ffffff"
-                                 list_title="#ffffff">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#ff004b"
-                        active_file_text="#ffffff"
-                        scroll_handle="#373737"
-                        scrollbar="#242424"
-                        selected_file="#88172d"
-                        tiles="#161616">
-        <space>
-          <ThemeSpaceGeneric header="#161616"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#161616"
-                             button_text="#dddddd"
-                             button_text_hi="#ffffff"
-                             button_title="#eaeaea"
-                             text="#fafafa"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#161616">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#181818"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#9b9b9b">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#4f6549"
-                        channels_region="#707070"
-                        frame_current="#99112c"
-                        dopesheet_channel="#4c5966"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#000000"
-                        handle_sel_free="#000000"
-                        grid="#1d1d1d"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ff004b"
-                        handle_vertex_size="3"
-                        lastsel_point="#000000"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#000000"
-                        vertex_select="#ff004b"
-                        vertex_size="3"
-                        window_sliders="#3b3b3b">
-        <space>
-          <ThemeSpaceGeneric header="#232323"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#232323"
-                             button_text="#757575"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#828282"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#232323">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#232323"
-                                 list_text="#cccccc"
-                                 list_text_hi="#ffffff"
-                                 list_title="#8d7878">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff3d1d"
-                        facedot_size="3"
-                        face_select="#ff1d4a1a"
-                        scope_back="#0707075e"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#f73c00"
-                        vertex_select="#df0041"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#272727"
-                             header_text_hi="#ffffff"
-                             button="#070707"
-                             button_text="#bebebe"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#9c9c9c"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#1a1a1a">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#222222"
-                             header_text="#999999"
-                             header_text_hi="#cbcbcb"
-                             button="#161616"
-                             button_text="#0d0d0d"
-                             button_text_hi="#ffffff"
-                             button_title="#0d0d0d"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#090909">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#111111">
-        <space>
-          <ThemeSpaceGeneric header="#272727"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#111111"
-                             button_text="#ffffff"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#9d9d9d"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#272727">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#99112c"
-                      grid="#5e5e5e"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#00465d"
-                       group_node="#26960e"
-                       in_out_node="#d9003a"
-                       node_backdrop="#454545ae"
-                       noodle_curving="5"
-                       operator_node="#d87200"
-                       selected_text="#ffdddd"
-                       wire_select="#ffe500"
-                       wire="#ff0000">
-        <space>
-          <ThemeSpaceGeneric header="#111111"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#0c0c0c"
-                             button_text="#bebebe"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#ffffff"
-                             text_hi="#565656"
-                             title="#ffffff"
-                             back="#111111">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#343434"
-                                 list_text_hi="#ffffff"
-                                 list_title="#ffffff">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#337f33"
-                     selected_highlight="#870027">
-        <space>
-          <ThemeSpaceGeneric header="#232323"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#585858"
-                             button_text="#8f8f8f"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#939393"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#232323">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#131313">
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#757575"
-                             header_text_hi="#ffffff"
-                             button="#1e1e1e"
-                             button_text="#4e4e4e"
-                             button_text_hi="#ffffff"
-                             button_title="#414141"
-                             text="#999999"
-                             text_hi="#ffffff"
-                             title="#aeaeae"
-                             back="#1a1a1a">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#99112c"
-                           draw_action="#50c8ff"
-                           effect_strip="#e270a6"
-                           grid="#414141"
-                           image_strip="#675379"
-                           keyframe="#ff9f00"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#b33d59"
-                           window_sliders="#6d6d6d">
-        <space>
-          <ThemeSpaceGeneric header="#171717"
-                             header_text="#ffffff"
-                             header_text_hi="#ffffff"
-                             button="#171717"
-                             button_text="#979797"
-                             button_text_hi="#ffffff"
-                             button_title="#ffffff"
-                             text="#757575"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#171717">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ffffff"
-                       syntax_special="#ffff00"
-                       line_numbers_background="#0a0a0a"
-                       selected_text="#561423"
-                       syntax_builtin="#ff009a"
-                       syntax_comment="#00ff7a"
-                       syntax_numbers="#0088ff"
-                       syntax_string="#f20000">
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#f2f2f2"
-                             header_text_hi="#ffffff"
-                             button="#1a1a1a"
-                             button_text="#ffffff"
-                             button_text_hi="#ffffff"
-                             button_title="#d0d0d0"
-                             text="#a9a9a9"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#050505">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#ff1d4a"
-                     grid="#343434">
-        <space>
-          <ThemeSpaceGeneric header="#232323"
-                             header_text="#828282"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#0d0d0d"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#757575"
-                             text_hi="#ffffff"
-                             title="#757575"
-                             back="#232323">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#00000066"
-                             inner_sel="#ff1d4aff"
-                             item="#ffffffff"
-                             outline="#343434"
-                             shadedown="-5"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#999999"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#c69e9e00"
-                             inner_sel="#4d262eff"
-                             item="#ffffffff"
-                             outline="#4e4e4e"
-                             shadedown="0"
-                             shadetop="-12"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#0c0c0cd0"
-                             inner_sel="#414141ff"
-                             item="#232323ff"
-                             outline="#3f3e3e"
-                             shadedown="-20"
-                             shadetop="4"
-                             show_shaded="FALSE"
-                             text="#a0a0a0"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#0c0c0c4e"
-                             inner_sel="#ff1d4aff"
-                             item="#ffffffff"
-                             outline="#222222"
-                             shadedown="0"
-                             shadetop="8"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#2a2a2aff"
-                             inner_sel="#ff1d4aff"
-                             item="#000000ff"
-                             outline="#343434"
-                             shadedown="0"
-                             shadetop="12"
-                             show_shaded="TRUE"
-                             text="#dddddd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#0c0c0cff"
-                             inner_sel="#ff1d4aff"
-                             item="#5a5a5aff"
-                             outline="#343434"
-                             shadedown="-5"
-                             shadetop="9"
-                             show_shaded="TRUE"
-                             text="#757575"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#1b1b1bff"
-                             inner_sel="#000000ff"
-                             item="#ff002eff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="-14"
-                             show_shaded="TRUE"
-                             text="#808080"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000000"
-                            show_header="FALSE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#000000ff"
-                             inner_sel="#686868ff"
-                             item="#be0037ff"
-                             outline="#5d001a"
-                             shadedown="-88"
-                             shadetop="100"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ff1d4a">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#0c0c0cff"
-                             inner_sel="#ff1d4aff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#b6b6b6"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#0c0c0cff"
-                             inner_sel="#ff1d4aff"
-                             item="#ffffffff"
-                             outline="#343434"
-                             shadedown="2"
-                             shadetop="6"
-                             show_shaded="TRUE"
-                             text="#b1b1b1"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#0c0c0cff"
-                             inner_sel="#ff1d4aff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#00000080"
-                             inner_sel="#000000ff"
-                             item="#4d4d4d33"
-                             outline="#111111"
-                             shadedown="12"
-                             shadetop="12"
-                             show_shaded="TRUE"
-                             text="#bababa"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#33141bff"
-                             inner_sel="#ff1d4aff"
-                             item="#800f26ff"
-                             outline="#343434"
-                             shadedown="0"
-                             shadetop="-16"
-                             show_shaded="TRUE"
-                             text="#f7f7f7"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#194a00"
-                                  inner_anim_sel="#287700"
-                                  blend="1"
-                                  inner_driven="#b566ff"
-                                  inner_driven_sel="#ce99ff"
-                                  inner_key="#ffdf44"
-                                  inner_key_sel="#b39400">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#0d0d0dff"
-                             inner_sel="#ff1d4aff"
-                             item="#414141ff"
-                             outline="#1a1a1a"
-                             shadedown="3"
-                             shadetop="-59"
-                             show_shaded="TRUE"
-                             text="#686868"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#3e3e3eff"
-                             inner_sel="#ff1d4aff"
-                             item="#1a1a1aff"
-                             outline="#343434"
-                             shadedown="0"
-                             shadetop="27"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#4d4d4dff"
-                             inner_sel="#ff1d4aff"
-                             item="#ffffffff"
-                             outline="#676767"
-                             shadedown="-15"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#d8d8d8"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#1a1a1a"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#414141"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#686868"
-                             text_hi="#ffffff"
-                             title="#f2f2f2"
-                             back="#1a1a1a">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/softblend.xml b/release/scripts/addons_contrib/presets/interface_theme/softblend.xml
deleted file mode 100644
index 79b9d62..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/softblend.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#ffffff"
-                   editmesh_active="#ffffff00"
-                   act_spline="#c36c8c"
-                   handle_align="#e277b1"
-                   handle_sel_align="#ffffff"
-                   handle_auto="#30b6e5"
-                   handle_sel_auto="#ffffff"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#53c03b"
-                   edge_crease="#eb3bdd"
-                   extra_edge_len="#200000"
-                   edge_seam="#f0703b"
-                   edge_select="#f3f3f3"
-                   edge_sharp="#49a1ec"
-                   edge_facesel="#272727"
-                   empty="#000000"
-                   face="#838383ff"
-                   extra_face_angle="#cccccc"
-                   extra_face_area="#cccccc"
-                   face_dot="#52f27e"
-                   facedot_size="3"
-                   normal="#9cfcc8"
-                   face_select="#949494ff"
-                   handle_free="#cccccc"
-                   handle_sel_free="#ffffff"
-                   grid="#6e6e6e"
-                   lamp="#ffe56666"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#a3a3a3"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#ffffff"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#63bd87"
-                   object_grouped_active="#ffffff"
-                   object_selected="#88fca7"
-                   outline_width="1"
-                   panel="#aaa8a6ff"
-                   speaker="#000000"
-                   transform="#ffffff"
-                   handle_vect="#afafaf"
-                   handle_sel_vect="#ffffff"
-                   vertex="#343434"
-                   vertex_normal="#68a1db"
-                   vertex_select="#ff2f7a"
-                   vertex_size="4"
-                   wire="#242424">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#ffffff"
-                             button_title="#313131"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#918f8d">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#a3ff96"
-                       disabled_marker="#b54636"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ff2f7a"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#71cd7f"
-                       marker_outline="#000000"
-                       path_after="#5a7575"
-                       path_before="#22d8d1"
-                       selected_marker="#ff2f7a">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#ffffff"
-                             button_title="#222222"
-                             text="#1a1a1a"
-                             text_hi="#ffffff"
-                             title="#1a1a1a"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#9cfcc8"
-                    line_error="#dc3a77"
-                    line_info="#00aa00"
-                    line_input="#ffffff"
-                    line_output="#6080ff">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#4d4d4d"
-                             button_text="#131313"
-                             button_text_hi="#ffffff"
-                             button_title="#131313"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#0c0c0c">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#95adc1"
-                      channel_group="#8a9dac"
-                      channels="#9baeb9"
-                      channels_selected="#91ccb3"
-                      frame_current="#a3ff96"
-                      dopesheet_channel="#9baeb9"
-                      dopesheet_subchannel="#aaa8a6"
-                      grid="#7f7f7f"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ecfc37"
-                      value_sliders="#000000"
-                      view_sliders="#333333">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#111111"
-                             button_text_hi="#a3a3a3"
-                             button_title="#111111"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#aaa8a6"
-                                 list_text="#222222"
-                                 list_text_hi="#ffffff"
-                                 list_title="#cccccc">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#f1e593"
-                        active_file_text="#ffffff"
-                        scroll_handle="#8c8a88"
-                        scrollbar="#4d4b4d"
-                        selected_file="#f1e593"
-                        tiles="#aaa8a6">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#afafaf"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#cccccc"
-                             button_text_hi="#ffffff"
-                             button_title="#222222"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#aaa8a6"
-                                 list_text="#7f7f7f"
-                                 list_text_hi="#ffffff"
-                                 list_title="#3a3a3a">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#95adc1"
-                        handle_align="#1d1d1d"
-                        handle_sel_align="#f3f3f3"
-                        handle_auto="#696969"
-                        handle_sel_auto="#d4d4d4"
-                        handle_auto_clamped="#000000"
-                        handle_sel_auto_clamped="#000000"
-                        channel_group="#8a9dac"
-                        channels_region="#4d4d4d"
-                        frame_current="#a1ff8c"
-                        dopesheet_channel="#aaa8a6"
-                        dopesheet_subchannel="#aaa8a6"
-                        handle_free="#252525"
-                        handle_sel_free="#ececec"
-                        grid="#8f8f8f"
-                        handle_vertex="#525252"
-                        handle_vertex_select="#f1f1f1"
-                        handle_vertex_size="6"
-                        lastsel_point="#000000"
-                        panel="#989898"
-                        handle_vect="#191919"
-                        handle_sel_vect="#ffffff"
-                        vertex="#575757"
-                        vertex_select="#ffffff"
-                        vertex_size="3"
-                        window_sliders="#4d4d4d">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#ffffff"
-                             button_title="#333333"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#aaa8a6"
-                                 list_text="#222222"
-                                 list_text_hi="#ffffff"
-                                 list_title="#676767">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#00000032"
-                        face_dot="#ffffff"
-                        facedot_size="2"
-                        face_select="#ffffff3c"
-                        scope_back="#aaa8a6ff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#000000"
-                        vertex_select="#ffffff"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#ffffff"
-                             button_title="#383838"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#2d2d2d">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#aaa8a6">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#ffffff"
-                             button_title="#111111"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#202020"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#85c58f"
-                      bars_selected="#60c040"
-                      frame_current="#a3ff96"
-                      grid="#a39f9c"
-                      strips="#000000"
-                      strips_selected="#60c040"
-                      view_sliders="#4d4d4d">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#a3a3a3"
-                             header_text_hi="#cccccc"
-                             button="#aaa8a6"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#333333"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#aaa8a6"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#fffa90"
-                       group_node="#ffc173"
-                       in_out_node="#b1d9ff"
-                       node_backdrop="#d4d4d4ff"
-                       noodle_curving="5"
-                       operator_node="#beffcb"
-                       selected_text="#ffffff"
-                       wire_select="#ffffff"
-                       wire="#222222">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#333333"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#c5c5c5"
-                             button_title="#222222"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#a3a3a3"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#4d4d4d"
-                                 list_text="#676767"
-                                 list_text_hi="#ffffff"
-                                 list_title="#383838">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#337f33"
-                     selected_highlight="#870027">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#0f0f0f"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#ffffff"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#aaa8a6">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#222222"
-                             header_text_hi="#000000"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#ffffff"
-                             button_title="#222222"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#222222"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#e0d2a0"
-                           movieclip_strip="#20208f"
-                           frame_current="#a3ff96"
-                           draw_action="#50c8ff"
-                           effect_strip="#be8c76"
-                           grid="#afafaf"
-                           image_strip="#c99ac0"
-                           keyframe="#ffeb89"
-                           meta_strip="#91918d"
-                           movie_strip="#87a4c3"
-                           plugin_strip="#7e7e56"
-                           preview_back="#000000"
-                           scene_strip="#91b1a0"
-                           transition_strip="#d9777a"
-                           window_sliders="#777777">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#a3a3a3"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#111111"
-                             button_text_hi="#ffffff"
-                             button_title="#111111"
-                             text="#333333"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#54da70"
-                       syntax_special="#ca0c97"
-                       line_numbers_background="#a3a3a3"
-                       selected_text="#f1e593"
-                       syntax_builtin="#3162b2"
-                       syntax_comment="#535353"
-                       syntax_numbers="#b62440"
-                       syntax_string="#c31736">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#333333"
-                             button_text_hi="#ffffff"
-                             button_title="#222222"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#a3ff96"
-                     grid="#838383">
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#a3a3a3"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#222222"
-                             button_text_hi="#a3a3a3"
-                             button_title="#aeacaa"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#cccccc"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#aaa8a6ff"
-                             inner_sel="#aaa8a6ff"
-                             item="#ccccccff"
-                             outline="#9f9d9b"
-                             shadedown="6"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#474747"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#f1e59333"
-                             inner_sel="#fff29c9a"
-                             item="#ffffffff"
-                             outline="#8c8a88"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#aaa8a6ff"
-                             inner_sel="#aaa8a6ff"
-                             item="#ccccccff"
-                             outline="#474747"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#aaa8a6ff"
-                             item="#000000ff"
-                             outline="#474747"
-                             shadedown="10"
-                             shadetop="-10"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#aaa8a6ff"
-                             inner_sel="#b0aeacff"
-                             item="#8e8c8bff"
-                             outline="#aaa8a6"
-                             shadedown="3"
-                             shadetop="-4"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#353432ff"
-                             inner_sel="#353432ff"
-                             item="#222222ff"
-                             outline="#050505"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="FALSE"
-                             text="#efefef"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#a5a3a1ff"
-                             inner_sel="#ccc9c7ff"
-                             item="#000000ff"
-                             outline="#acaaa8"
-                             shadedown="0"
-                             shadetop="-2"
-                             show_shaded="TRUE"
-                             text="#676767"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000004"
-                            show_header="TRUE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#aaa8a6ff"
-                             inner_sel="#aaa8a6ff"
-                             item="#96c78eff"
-                             outline="#474747"
-                             shadedown="-3"
-                             shadetop="3"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#aaa8a6ff"
-                             inner_sel="#aaa8a6ff"
-                             item="#ccccccff"
-                             outline="#474747"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#a8a6a4ff"
-                             inner_sel="#95adc1ff"
-                             item="#aaa8a6ff"
-                             outline="#aaa8a6"
-                             shadedown="1"
-                             shadetop="-2"
-                             show_shaded="TRUE"
-                             text="#1a1a1a"
-                             text_sel="#1a1a1a">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#7b7978ff"
-                             inner_sel="#95adc1ff"
-                             item="#979594ff"
-                             outline="#5f5e5c"
-                             shadedown="0"
-                             shadetop="-2"
-                             show_shaded="TRUE"
-                             text="#1a1a1a"
-                             text_sel="#1a1a1a">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#a4a2a0ff"
-                             inner_sel="#aaa8a6ff"
-                             item="#a2a19fff"
-                             outline="#82807f"
-                             shadedown="-5"
-                             shadetop="4"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#353432ff"
-                             inner_sel="#353432ff"
-                             item="#1f1f1fff"
-                             outline="#050505"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#adb4c7"
-                                  inner_anim_sel="#c4cee0"
-                                  blend="1"
-                                  inner_driven="#c69cb1"
-                                  inner_driven_sel="#ecaacd"
-                                  inner_key="#c0bb83"
-                                  inner_key_sel="#dad37d">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#a6a4a2ff"
-                             inner_sel="#f1e593ff"
-                             item="#c2b876ff"
-                             outline="#aaa8a6"
-                             shadedown="0"
-                             shadetop="-2"
-                             show_shaded="TRUE"
-                             text="#242424"
-                             text_sel="#242424">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#a8a6a4ff"
-                             inner_sel="#95adc1ff"
-                             item="#aaa8a6ff"
-                             outline="#aaa8a6"
-                             shadedown="0"
-                             shadetop="-3"
-                             show_shaded="TRUE"
-                             text="#1c1c1c"
-                             text_sel="#1a1a1a">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#aaa8a6ff"
-                             inner_sel="#a19f9dff"
-                             item="#a19f9dff"
-                             outline="#a6a4a2"
-                             shadedown="-6"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#aaa8a6"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaa8a6"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#222222"
-                             text_hi="#ffffff"
-                             title="#222222"
-                             back="#aaa8a6">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/softdefault.xml b/release/scripts/addons_contrib/presets/interface_theme/softdefault.xml
deleted file mode 100644
index 9a2e639..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/softdefault.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#ffffff"
-                   editmesh_active="#ffffff72"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#60c040"
-                   edge_crease="#cc57b4"
-                   extra_edge_len="#200000"
-                   edge_seam="#db5c3d"
-                   edge_select="#e3e3e3"
-                   edge_sharp="#3a9fff"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#00000058"
-                   extra_face_angle="#002000"
-                   extra_face_area="#000080"
-                   face_dot="#9bff61"
-                   facedot_size="3"
-                   normal="#22dddd"
-                   face_select="#0000003c"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#555555"
-                   lamp="#e3d45966"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#083008"
-                   object_grouped_active="#55bb55"
-                   object_selected="#ffffff"
-                   outline_width="1"
-                   panel="#a5a5a57f"
-                   speaker="#5c6db2"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#000000"
-                   vertex_normal="#2361dd"
-                   vertex_select="#ff6424"
-                   vertex_size="3"
-                   wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#404040">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#000000"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#393939">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#8bdc66"
-                    line_error="#dc6060"
-                    line_info="#e4e585"
-                    line_input="#ffffff"
-                    line_output="#6080ff">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#60c040"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#5e5e5e"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#727272"
-                        active_file_text="#fafafa"
-                        scroll_handle="#7f7979"
-                        scrollbar="#a0a0a0"
-                        selected_file="#1e1e1e"
-                        tiles="#727272">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#fafafa"
-                             text_hi="#0f0f0f"
-                             title="#000000"
-                             back="#4c4c4c">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#ffffff"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#8686b0"
-                        channels_region="#707070"
-                        frame_current="#7ec068"
-                        dopesheet_channel="#76879c"
-                        dopesheet_subchannel="#8699b0"
-                        handle_free="#ffffff"
-                        handle_sel_free="#000000"
-                        grid="#5e5e5e"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ffffff"
-                        handle_vertex_size="8"
-                        lastsel_point="#000000"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#6ee854"
-                        vertex="#000000"
-                        vertex_select="#ffffff"
-                        vertex_size="5"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff8500"
-                        facedot_size="3"
-                        face_select="#ff85003c"
-                        scope_back="#727272ff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#353535">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#a5a5a5">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#646464">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#7ec068"
-                      frame_current="#7ec068"
-                      grid="#5e5e5e"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#6b6b6b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#666666"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#b5b1ea"
-                       group_node="#d5ffa2"
-                       in_out_node="#b0cae0"
-                       node_backdrop="#858585ff"
-                       noodle_curving="5"
-                       operator_node="#ffa46c"
-                       selected_text="#ffffff"
-                       wire_select="#ffffff"
-                       wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#337f33"
-                     selected_highlight="#82878c">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#828282">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#60c040"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#404040"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#747474">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#afff80"
-                       syntax_special="#92da66"
-                       line_numbers_background="#7c7c7c"
-                       selected_text="#bdbd8d"
-                       syntax_builtin="#ff5353"
-                       syntax_comment="#ffffff"
-                       syntax_numbers="#7dc8c8"
-                       syntax_string="#f7f185">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#7ec068"
-                     grid="#565656">
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#6c6c6cff"
-                             inner_sel="#6c6c6cff"
-                             item="#4a4a4aff"
-                             outline="#646464"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#6b8cafff"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#505050"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ececec">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#727272ff"
-                             item="#ffffffff"
-                             outline="#727272"
-                             shadedown="5"
-                             shadetop="-8"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#6c6c6cff"
-                             item="#464646ff"
-                             outline="#606060"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#f5f5f5">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#595959ff"
-                             inner_sel="#444444ff"
-                             item="#3b3b3bff"
-                             outline="#606060"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#838383ff"
-                             item="#000000ff"
-                             outline="#646464"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000008"
-                            show_header="TRUE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#758b69ff"
-                             inner_sel="#93af84ff"
-                             item="#93af84ff"
-                             outline="#727272"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#3f3f3fff"
-                             inner_sel="#727272ff"
-                             item="#000000ff"
-                             outline="#606060"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#6c6c6cff"
-                             inner_sel="#6b8cafff"
-                             item="#ffffffff"
-                             outline="#646464"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#646464ff"
-                             item="#626262ff"
-                             outline="#6a6a6a"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#595959ff"
-                             inner_sel="#595959ff"
-                             item="#494949ff"
-                             outline="#606060"
-                             shadedown="0"
-                             shadetop="-20"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#98cc7e"
-                                  inner_anim_sel="#5aa633"
-                                  blend="0.5"
-                                  inner_driven="#cf5bff"
-                                  inner_driven_sel="#ac45d7"
-                                  inner_key="#f0ec75"
-                                  inner_key_sel="#d7d34b">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#dbcc6fff"
-                             item="#91874aff"
-                             outline="#646464"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#6b8cafff"
-                             item="#000000ff"
-                             outline="#646464"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#727272ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#646464"
-                             shadedown="5"
-                             shadetop="-5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#727272"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/toxic.xml b/release/scripts/addons_contrib/presets/interface_theme/toxic.xml
deleted file mode 100644
index 82d3e58..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/toxic.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#97ff22"
-                   editmesh_active="#ffffff80"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#5a5a5a"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#ffedf8"
-                   edge_seam="#db2512"
-                   edge_select="#3cbc2c"
-                   edge_sharp="#ff2020"
-                   edge_facesel="#6b6b6b"
-                   empty="#000000"
-                   face="#73828f12"
-                   extra_face_angle="#00c900"
-                   extra_face_area="#fff000"
-                   face_dot="#95fd20"
-                   facedot_size="4"
-                   normal="#22dddd"
-                   face_select="#3aba2a3c"
-                   handle_free="#7f7f7f"
-                   handle_sel_free="#3b3b3b"
-                   grid="#3f3f3f"
-                   lamp="#c1d40028"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#083008"
-                   object_grouped_active="#55bb55"
-                   object_selected="#3ebe2e"
-                   outline_width="1"
-                   panel="#a5a5a57f"
-                   speaker="#535353"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#72cfdd"
-                   vertex_normal="#2361dd"
-                   vertex_select="#3cbc2c"
-                   vertex_size="3"
-                   wire="#888888">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#0f0f0f">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#1b501b"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#e2e2e2"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#0094af"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#070707"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#0d0d0d">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#dc6060"
-                    line_info="#00aa00"
-                    line_input="#cecece"
-                    line_output="#6080ff">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#0f0f0f">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#2a5c1c"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#212121"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#080808">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#020202"
-                                 list_text="#ebebeb"
-                                 list_text_hi="#ffffff"
-                                 list_title="#2c2c2c">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#b1b1b1"
-                        active_file_text="#ffffff"
-                        scroll_handle="#7f7070"
-                        scrollbar="#a0a0a0"
-                        selected_file="#2f6629"
-                        tiles="#343434">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#181818"
-                                 list_text="#5d5d5d"
-                                 list_text_hi="#ffffff"
-                                 list_title="#9e9e9e">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#4f6549"
-                        channels_region="#6d6d6d"
-                        frame_current="#336622"
-                        dopesheet_channel="#52606e"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#808080"
-                        handle_sel_free="#808080"
-                        grid="#262626"
-                        handle_vertex="#808080"
-                        handle_vertex_select="#ff8500"
-                        handle_vertex_size="3"
-                        lastsel_point="#808080"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#ffffff"
-                        vertex_select="#ff8500"
-                        vertex_size="3"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#0d0d0d">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#1a1a1a"
-                                 list_text="#bbbbbb"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#ffffff0a"
-                        face_dot="#ff8500"
-                        facedot_size="3"
-                        face_select="#ff85003c"
-                        scope_back="#050505ff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#0f13bb"
-                        vertex_select="#ff8500"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#adadad"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#9b9b9b"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#a5a5a5">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#070707">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#2f6421"
-                      grid="#5e5e5e"
-                      strips="#aa8d8d"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c3c3c3"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#585858"
-                             back="#0d0d0d">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#0c0c0c"
-                                 list_text="#d8d8d8"
-                                 list_text_hi="#ffffff"
-                                 list_title="#383838">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#113941"
-                       group_node="#091a07"
-                       in_out_node="#273053"
-                       node_backdrop="#202030bc"
-                       noodle_curving="5"
-                       operator_node="#0e3157"
-                       selected_text="#7f7070"
-                       wire_select="#0019ff"
-                       wire="#6eafff">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#c7c7c7"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#ffffff"
-                                 list_text_hi="#b8ffff"
-                                 list_title="#ffffff">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#356c1a"
-                     selected_highlight="#446e1c">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#cccccc"
-                             text_hi="#ffffff"
-                             title="#9b9b9b"
-                             back="#070707">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#6f4c82">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#0e0e0e"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#2f5f23"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#282828"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#f3f3f3"
-                             header_text_hi="#ffffff"
-                             button="#020202"
-                             button_text="#dddddd"
-                             button_text_hi="#ffffff"
-                             button_title="#bdbdbd"
-                             text="#ffffff"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#202020">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ff0000"
-                       syntax_special="#969629"
-                       line_numbers_background="#191919"
-                       selected_text="#ffffff"
-                       syntax_builtin="#cf3d99"
-                       syntax_comment="#249d60"
-                       syntax_numbers="#3c68ff"
-                       syntax_string="#cc3535">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#b9b9b9"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#cccccc"
-                             button_text_hi="#ffffff"
-                             button_title="#d8d8d8"
-                             text="#ebebeb"
-                             text_hi="#ffffff"
-                             title="#9e9e9e"
-                             back="#050505">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#3fff00"
-                     grid="#707070">
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#161616"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#c7c7c7"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#162c0c">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#72a400ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#649600ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#fdfdfd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#6c9e00ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#6a9c00ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#fdfdfd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#70a200ff"
-                             item="#2a2a2aff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#76a800ff"
-                             item="#2a2a2aff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#929292"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#7aac00ff"
-                             item="#ffffffff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#c7c7c7"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#000000ff"
-                            show_header="FALSE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#669800ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#fdfdfd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#6ea000ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#7eb000ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#0a0a0aff"
-                             inner_sel="#84b600ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#171717ff"
-                             inner_sel="#689a00ff"
-                             item="#689a00ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#fdfdfd"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#111111ff"
-                             item="#74a600ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#56ff00"
-                                  inner_anim_sel="#56ff00"
-                                  blend="0.1"
-                                  inner_driven="#629400"
-                                  inner_driven_sel="#609200"
-                                  inner_key="#fff400"
-                                  inner_key_sel="#fff400">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#7cae00ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#e4e4e4"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#111111ff"
-                             inner_sel="#78aa00ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#79b224ff"
-                             inner_sel="#80b200ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="0"
-                             shadetop="-100"
-                             show_shaded="TRUE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#000000"
-                             header_text="#979797"
-                             header_text_hi="#ffffff"
-                             button="#000000"
-                             button_text="#c3c3c3"
-                             button_text_hi="#ffffff"
-                             button_title="#c5c5c5"
-                             text="#7d7d7d"
-                             text_hi="#ffffff"
-                             title="#5d5d5d"
-                             back="#000000">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/zbrush.xml b/release/scripts/addons_contrib/presets/interface_theme/zbrush.xml
deleted file mode 100644
index 194cde8..0000000
--- a/release/scripts/addons_contrib/presets/interface_theme/zbrush.xml
+++ /dev/null
@@ -1,828 +0,0 @@
-<bpy>
-  <Theme>
-    <view_3d>
-      <ThemeView3D object_active="#c28d45"
-                   editmesh_active="#ffffff80"
-                   act_spline="#db2512"
-                   handle_align="#803060"
-                   handle_sel_align="#f090a0"
-                   handle_auto="#909000"
-                   handle_sel_auto="#f0ff40"
-                   bone_pose="#50c8ff"
-                   bone_solid="#c8c8c8"
-                   bundle_solid="#c8c8c8"
-                   camera="#000000"
-                   camera_path="#000000"
-                   frame_current="#60c040"
-                   edge_crease="#cc0099"
-                   extra_edge_len="#200000"
-                   edge_seam="#db2512"
-                   edge_select="#c28d45"
-                   edge_sharp="#00ffff"
-                   edge_facesel="#4b4b4b"
-                   empty="#000000"
-                   face="#00000054"
-                   extra_face_angle="#000080"
-                   extra_face_area="#002000"
-                   face_dot="#c28d45"
-                   facedot_size="2"
-                   normal="#22dddd"
-                   face_select="#81602e73"
-                   handle_free="#000000"
-                   handle_sel_free="#000000"
-                   grid="#353535"
-                   lamp="#00000028"
-                   lastsel_point="#ffffff"
-                   nurb_uline="#909000"
-                   nurb_vline="#803060"
-                   nurb_sel_uline="#f0ff40"
-                   nurb_sel_vline="#f090a0"
-                   object_grouped="#083008"
-                   object_grouped_active="#55bb55"
-                   object_selected="#f1f1f1"
-                   outline_width="1"
-                   panel="#a5a5a57f"
-                   speaker="#000000"
-                   transform="#ffffff"
-                   handle_vect="#409030"
-                   handle_sel_vect="#40c030"
-                   vertex="#a8a8a8"
-                   vertex_normal="#2361dd"
-                   vertex_select="#c28d45"
-                   vertex_size="3"
-                   wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#b9b9b9"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#878787"
-                             button_text_hi="#ffffff"
-                             button_title="#949494"
-                             text="#b8b8b8"
-                             text_hi="#e9e9e9"
-                             title="#000000"
-                             back="#2c2e30">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeView3D>
-    </view_3d>
-    <clip_editor>
-      <ThemeClipEditor active_marker="#ffffff"
-                       frame_current="#60c040"
-                       disabled_marker="#7f0000"
-                       grid="#5e5e5e"
-                       handle_vertex="#000000"
-                       handle_vertex_select="#ffff00"
-                       handle_vertex_size="4"
-                       locked_marker="#7f7f7f"
-                       marker="#7f7f00"
-                       marker_outline="#000000"
-                       path_after="#0000ff"
-                       path_before="#ff0000"
-                       selected_marker="#ffff00">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#2c2e30">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeClipEditor>
-    </clip_editor>
-    <console>
-      <ThemeConsole cursor="#dc6060"
-                    line_error="#dc6060"
-                    line_info="#00aa00"
-                    line_input="#ffffff"
-                    line_output="#b8b8b8">
-        <space>
-          <ThemeSpaceGeneric header="#303030"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#202020">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeConsole>
-    </console>
-    <dopesheet_editor>
-      <ThemeDopeSheet active_channels_group="#87b17d"
-                      channel_group="#4f6549"
-                      channels="#707070"
-                      channels_selected="#60c040"
-                      frame_current="#60c040"
-                      dopesheet_channel="#52606e"
-                      dopesheet_subchannel="#7c8996"
-                      grid="#4b4b4b"
-                      long_key="#0c0a0a"
-                      long_key_selected="#ff8c00"
-                      value_sliders="#000000"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#aaaaaa"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#848484"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#3b3b3b"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeDopeSheet>
-    </dopesheet_editor>
-    <file_browser>
-      <ThemeFileBrowser active_file="#828282"
-                        active_file_text="#fafafa"
-                        scroll_handle="#7f7070"
-                        scrollbar="#a0a0a0"
-                        selected_file="#755729"
-                        tiles="#3b3b3b">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#8b8b8b"
-                             header_text_hi="#ffffff"
-                             button="#303030"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#cacaca"
-                             text_hi="#0f0f0f"
-                             title="#8b8b8b"
-                             back="#3a3a3a">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#3b3b3b"
-                                 list_text="#8b8b8b"
-                                 list_text_hi="#ffffff"
-                                 list_title="#8b8b8b">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeFileBrowser>
-    </file_browser>
-    <graph_editor>
-      <ThemeGraphEditor active_channels_group="#87b17d"
-                        handle_align="#803060"
-                        handle_sel_align="#f090a0"
-                        handle_auto="#909000"
-                        handle_sel_auto="#f0ff40"
-                        handle_auto_clamped="#994030"
-                        handle_sel_auto_clamped="#f0af90"
-                        channel_group="#4f6549"
-                        channels_region="#707070"
-                        frame_current="#60c040"
-                        dopesheet_channel="#52606e"
-                        dopesheet_subchannel="#7c8996"
-                        handle_free="#000000"
-                        handle_sel_free="#000000"
-                        grid="#4b4b4b"
-                        handle_vertex="#000000"
-                        handle_vertex_select="#ff8500"
-                        handle_vertex_size="4"
-                        lastsel_point="#ffffff"
-                        panel="#ffffff"
-                        handle_vect="#409030"
-                        handle_sel_vect="#40c030"
-                        vertex="#000000"
-                        vertex_select="#ff8500"
-                        vertex_size="3"
-                        window_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#8b8b8b"
-                             button_text_hi="#ffffff"
-                             button_title="#8b8b8b"
-                             text="#848484"
-                             text_hi="#ffffff"
-                             title="#8b8b8b"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#3b3b3b"
-                                 list_text="#8b8b8b"
-                                 list_text_hi="#ffffff"
-                                 list_title="#8b8b8b">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeGraphEditor>
-    </graph_editor>
-    <image_editor>
-      <ThemeImageEditor editmesh_active="#ffffff80"
-                        face="#7c7c7c0a"
-                        face_dot="#c28d45"
-                        facedot_size="3"
-                        face_select="#c28d453c"
-                        scope_back="#3b3b3bff"
-                        preview_stitch_active="#e1d2c323"
-                        preview_stitch_edge="#ff8500b2"
-                        preview_stitch_face="#1242b026"
-                        preview_stitch_stitchable="#00ff00ff"
-                        preview_stitch_unstitchable="#ff0000ff"
-                        preview_stitch_vert="#ff85007f"
-                        vertex="#a8a8a8"
-                        vertex_select="#c28d45"
-                        vertex_size="3">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#8b8b8b"
-                             button_text_hi="#ffffff"
-                             button_title="#8b8b8b"
-                             text="#8b8b8b"
-                             text_hi="#ffffff"
-                             title="#8b8b8b"
-                             back="#303030">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeImageEditor>
-    </image_editor>
-    <info>
-      <ThemeInfo>
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#8b8b8b"
-                             header_text_hi="#000000"
-                             button="#3b3b3b"
-                             button_text="#000000"
-                             button_text_hi="#000000"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#000000"
-                             title="#000000"
-                             back="#727272">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeInfo>
-    </info>
-    <logic_editor>
-      <ThemeLogicEditor panel="#3b3b3b">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#8b8b8b"
-                             button_text_hi="#ffffff"
-                             button_title="#8b8b8b"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeLogicEditor>
-    </logic_editor>
-    <nla_editor>
-      <ThemeNLAEditor bars="#707070"
-                      bars_selected="#60c040"
-                      frame_current="#60c040"
-                      grid="#585858"
-                      strips="#0c0a0a"
-                      strips_selected="#ff8c00"
-                      view_sliders="#969696">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#000000"
-                             text_hi="#ffffff"
-                             title="#8b8b8b"
-                             back="#4b4b4b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#3b3b3b"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNLAEditor>
-    </nla_editor>
-    <node_editor>
-      <ThemeNodeEditor converter_node="#686a75"
-                       group_node="#69756e"
-                       in_out_node="#646464"
-                       node_backdrop="#9b9b9ba0"
-                       noodle_curving="5"
-                       operator_node="#6c696f"
-                       selected_text="#7f7070"
-                       wire_select="#ffffff"
-                       wire="#000000">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#8b8b8b"
-                             button_text_hi="#ffffff"
-                             button_title="#8b8b8b"
-                             text="#8b8b8b"
-                             text_hi="#ffffff"
-                             title="#8b8b8b"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-        <space_list>
-          <ThemeSpaceListGeneric list="#a5a5a5"
-                                 list_text="#000000"
-                                 list_text_hi="#ffffff"
-                                 list_title="#000000">
-          </ThemeSpaceListGeneric>
-        </space_list>
-      </ThemeNodeEditor>
-    </node_editor>
-    <outliner>
-      <ThemeOutliner match="#245824"
-                     selected_highlight="#212844">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#cacaca"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#3a3a3a">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeOutliner>
-    </outliner>
-    <properties>
-      <ThemeProperties panel="#828282">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#b8b8b8"
-                             button_text_hi="#ffffff"
-                             button_title="#b8b8b8"
-                             text="#b8b8b8"
-                             text_hi="#ffffff"
-                             title="#6d6d6d"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeProperties>
-    </properties>
-    <sequence_editor>
-      <ThemeSequenceEditor audio_strip="#2e8f8f"
-                           movieclip_strip="#20208f"
-                           frame_current="#60c040"
-                           draw_action="#50c8ff"
-                           effect_strip="#a9547c"
-                           grid="#818181"
-                           image_strip="#6d5881"
-                           keyframe="#ff8500"
-                           meta_strip="#6d9183"
-                           movie_strip="#516987"
-                           plugin_strip="#7e7e50"
-                           preview_back="#000000"
-                           scene_strip="#4e983e"
-                           transition_strip="#a25f6f"
-                           window_sliders="#a0a0a0">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#848484"
-                             text_hi="#ffffff"
-                             title="#8b8b8b"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeSequenceEditor>
-    </sequence_editor>
-    <text_editor>
-      <ThemeTextEditor cursor="#ff0000"
-                       syntax_special="#5f5f00"
-                       line_numbers_background="#404040"
-                       selected_text="#c67777"
-                       syntax_builtin="#800050"
-                       syntax_comment="#006432"
-                       syntax_numbers="#0000c8"
-                       syntax_string="#640000">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#3b3b3b"
-                             button_text="#8b8b8b"
-                             button_text_hi="#ffffff"
-                             button_title="#8b8b8b"
-                             text="#b8b8b8"
-                             text_hi="#ffffff"
-                             title="#8b8b8b"
-                             back="#4b4b4b">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTextEditor>
-    </text_editor>
-    <timeline>
-      <ThemeTimeline frame_current="#60c040"
-                     grid="#464646">
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#848484"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#303030">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeTimeline>
-    </timeline>
-    <user_interface>
-      <ThemeUserInterface icon_alpha="1"
-                          icon_file="">
-        <wcol_box>
-          <ThemeWidgetColors inner="#3e3e3eff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#2a2a2a"
-                             shadedown="-7"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_box>
-        <wcol_list_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#75582aae"
-                             item="#000000ff"
-                             outline="#000000"
-                             shadedown="-10"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#e0e0e0"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_list_item>
-        <wcol_menu_back>
-          <ThemeWidgetColors inner="#3b3b3bff"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#b8b8b8"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_menu_back>
-        <wcol_menu_item>
-          <ThemeWidgetColors inner="#00000000"
-                             inner_sel="#c28d45ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="20"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_menu_item>
-        <wcol_menu>
-          <ThemeWidgetColors inner="#2f2f2fff"
-                             inner_sel="#464646ff"
-                             item="#777777ff"
-                             outline="#151515"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#cccccc">
-          </ThemeWidgetColors>
-        </wcol_menu>
-        <wcol_num>
-          <ThemeWidgetColors inner="#333333ff"
-                             inner_sel="#999999ff"
-                             item="#727272ff"
-                             outline="#1f1f1f"
-                             shadedown="0"
-                             shadetop="10"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_num>
-        <wcol_option>
-          <ThemeWidgetColors inner="#3b3b3bff"
-                             inner_sel="#c28d45ff"
-                             item="#ffffffff"
-                             outline="#1f1f1f"
-                             shadedown="0"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_option>
-        <panel>
-          <ThemePanelColors header="#00000019"
-                            show_header="FALSE">
-          </ThemePanelColors>
-        </panel>
-        <wcol_progress>
-          <ThemeWidgetColors inner="#bebebeff"
-                             inner_sel="#646464b4"
-                             item="#444444ff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_progress>
-        <wcol_pulldown>
-          <ThemeWidgetColors inner="#3f3f3fff"
-                             inner_sel="#c28d45ff"
-                             item="#ffffffff"
-                             outline="#000000"
-                             shadedown="0"
-                             shadetop="25"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_pulldown>
-        <wcol_radio>
-          <ThemeWidgetColors inner="#333333ff"
-                             inner_sel="#c28d45ff"
-                             item="#ffffffff"
-                             outline="#1f1f1f"
-                             shadedown="-5"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_radio>
-        <wcol_regular>
-          <ThemeWidgetColors inner="#999999ff"
-                             inner_sel="#646464ff"
-                             item="#191919ff"
-                             outline="#191919"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="FALSE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_regular>
-        <wcol_scroll>
-          <ThemeWidgetColors inner="#07070719"
-                             inner_sel="#646464b4"
-                             item="#2e2e2eff"
-                             outline="#1c1c1c"
-                             shadedown="0"
-                             shadetop="0"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_scroll>
-        <wcol_numslider>
-          <ThemeWidgetColors inner="#606068ff"
-                             inner_sel="#91919dff"
-                             item="#3a3a3aff"
-                             outline="#303030"
-                             shadedown="10"
-                             shadetop="-10"
-                             show_shaded="TRUE"
-                             text="#dfdfdf"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_numslider>
-        <wcol_state>
-          <ThemeWidgetStateColors inner_anim="#73be4c"
-                                  inner_anim_sel="#5aa633"
-                                  blend="0.5"
-                                  inner_driven="#b400ff"
-                                  inner_driven_sel="#9900e6"
-                                  inner_key="#f0eb64"
-                                  inner_key_sel="#d7d34b">
-          </ThemeWidgetStateColors>
-        </wcol_state>
-        <wcol_text>
-          <ThemeWidgetColors inner="#7a8287ff"
-                             inner_sel="#999999ff"
-                             item="#5a5a5aff"
-                             outline="#303030"
-                             shadedown="0"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#000000"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_text>
-        <wcol_toggle>
-          <ThemeWidgetColors inner="#333333ff"
-                             inner_sel="#c28d45ff"
-                             item="#191919ff"
-                             outline="#1f1f1f"
-                             shadedown="0"
-                             shadetop="5"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_toggle>
-        <wcol_tool>
-          <ThemeWidgetColors inner="#333333ff"
-                             inner_sel="#c28d45ff"
-                             item="#191919ff"
-                             outline="#1f1f1f"
-                             shadedown="0"
-                             shadetop="10"
-                             show_shaded="TRUE"
-                             text="#b8b8b8"
-                             text_sel="#000000">
-          </ThemeWidgetColors>
-        </wcol_tool>
-        <wcol_tooltip>
-          <ThemeWidgetColors inner="#191919e6"
-                             inner_sel="#2d2d2de6"
-                             item="#646464ff"
-                             outline="#000000"
-                             shadedown="-20"
-                             shadetop="25"
-                             show_shaded="FALSE"
-                             text="#ffffff"
-                             text_sel="#ffffff">
-          </ThemeWidgetColors>
-        </wcol_tooltip>
-      </ThemeUserInterface>
-    </user_interface>
-    <user_preferences>
-      <ThemeUserPreferences>
-        <space>
-          <ThemeSpaceGeneric header="#3b3b3b"
-                             header_text="#000000"
-                             header_text_hi="#ffffff"
-                             button="#727272"
-                             button_text="#000000"
-                             button_text_hi="#ffffff"
-                             button_title="#000000"
-                             text="#b8b8b8"
-                             text_hi="#ffffff"
-                             title="#000000"
-                             back="#3b3b3b">
-          </ThemeSpaceGeneric>
-        </space>
-      </ThemeUserPreferences>
-    </user_preferences>
-    <bone_color_sets>
-      <ThemeBoneColorSet active="#f70a0a"
-                         show_colored_constraints="FALSE"
-                         normal="#9a0000"
-                         select="#bd1111">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#fa9900"
-                         show_colored_constraints="FALSE"
-                         normal="#f74018"
-                         select="#f66913">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#83ef1d"
-                         show_colored_constraints="FALSE"
-                         normal="#1e9109"
-                         select="#59b70b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#5ec1ef"
-                         show_colored_constraints="FALSE"
-                         normal="#0a3694"
-                         select="#3667df">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f05d91"
-                         show_colored_constraints="FALSE"
-                         normal="#a9294e"
-                         select="#c1416a">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#8764d5"
-                         show_colored_constraints="FALSE"
-                         normal="#430c78"
-                         select="#543aa3">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#6fb6ab"
-                         show_colored_constraints="FALSE"
-                         normal="#24785a"
-                         select="#3c9579">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#9bc2cd"
-                         show_colored_constraints="FALSE"
-                         normal="#4b707c"
-                         select="#6a8691">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#f3ff00"
-                         show_colored_constraints="FALSE"
-                         normal="#f4c90c"
-                         select="#eec236">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#ffffff"
-                         show_colored_constraints="FALSE"
-                         normal="#1e2024"
-                         select="#484c56">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#d330d6"
-                         show_colored_constraints="FALSE"
-                         normal="#6f2f6a"
-                         select="#9845be">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bbef5b"
-                         show_colored_constraints="FALSE"
-                         normal="#6c8e22"
-                         select="#7fb022">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#dedede"
-                         show_colored_constraints="FALSE"
-                         normal="#8d8d8d"
-                         select="#b0b0b0">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#bd6a11"
-                         show_colored_constraints="FALSE"
-                         normal="#834326"
-                         select="#8b5811">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#34622b"
-                         show_colored_constraints="FALSE"
-                         normal="#08310e"
-                         select="#1c430b">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-      <ThemeBoneColorSet active="#000000"
-                         show_colored_constraints="FALSE"
-                         normal="#000000"
-                         select="#000000">
-      </ThemeBoneColorSet>
-    </bone_color_sets>
-  </Theme>
-</bpy>
diff --git a/release/scripts/addons_contrib/presets/keyconfig/blender_2012_experimental.py b/release/scripts/addons_contrib/presets/keyconfig/blender_2012_experimental.py
deleted file mode 100644
index 757937a..0000000
--- a/release/scripts/addons_contrib/presets/keyconfig/blender_2012_experimental.py
+++ /dev/null
@@ -1,816 +0,0 @@
-""" An experimental new keymap for Blender.
-    Work in progress!
-"""
-import bpy
-
-###############################################################
-# Some configuration variables to toggle various ideas on/off #
-###############################################################
-DEVELOPER_HOTKEYS = False  # Weird hotkeys that only developers use
-
-WINDOW_TYPE_SWITCHING = False  # Shift-f# hotkeys for switching window types
-
-SUBSURF_RELATIVE = True  # Make subsurf hotkeys work by relative
-                         # shifting instead of absolute setting
-
-MAYA_STYLE_MANIPULATORS = False  # Maya-style "QWER" hotkeys for manipulators
-
-
-
-
-###############################
-# Custom operators/menus/etc. #
-###############################
-
-class ShiftSubsurfLevel(bpy.types.Operator):
-    ''' Shifts the subsurf level of the selected objects up or
-        down by the given amount.  Has maximum limit, to avoid
-        going crazy and running out of RAM.
-    '''
-    bl_idname = "object.shift_subsurf_level"
-    bl_label = "Shift Subsurf Level"
-
-    delta = bpy.props.IntProperty(name="Delta", description="Amount to increase/decrease the subsurf level.", default=1)
-    min = bpy.props.IntProperty(name="Minimum", description="The lowest subsurf level to shift to.", default=0)
-    max = bpy.props.IntProperty(name="Maximum", description="The highest subsurf level to shift to.", default=4)
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        for obj in context.selected_objects:
-            # Find the last subsurf modifier in the stack
-            m = None
-            for mod in obj.modifiers:
-                if mod.type == "SUBSURF":
-                    m = mod
-
-            # Add a subsurf modifier if necessary
-            if not m and self.delta > 0:
-                m = obj.modifiers.new(name="Subsurf", type='SUBSURF')
-                m.levels = 0
-
-            # Adjust it's subsurf level
-            if m:
-                if self.delta > 0:
-                    if (m.levels + self.delta) <= self.max:
-                        m.levels += self.delta
-                elif self.delta < 0:
-                    if (m.levels + self.delta) >= self.min:
-                        m.levels += self.delta
-        return {'FINISHED'}
-bpy.utils.register_class(ShiftSubsurfLevel)
-
-
-class SetManipulator(bpy.types.Operator):
-    '''Set's the manipulator mode.'''
-    bl_idname = "view3d.manipulator_set"
-    bl_label = "Set Manipulator"
-    mode = bpy.props.EnumProperty(items=[("NONE", "None", ""),
-                                         ("TRANSLATE", "Translate", ""),
-                                         ("ROTATE", "Rotate", ""),
-                                         ("SCALE", "Scale", "")],
-                                         default="NONE")
-
-    def execute(self, context):
-        if self.mode == "NONE":
-            context.space_data.show_manipulator = False
-        elif self.mode == "TRANSLATE":
-            context.space_data.show_manipulator = True
-            context.space_data.use_manipulator_translate = True
-            context.space_data.use_manipulator_rotate = False
-            context.space_data.use_manipulator_scale = False
-        elif self.mode == "ROTATE":
-            context.space_data.show_manipulator = True
-            context.space_data.use_manipulator_translate = False
-            context.space_data.use_manipulator_rotate = True
-            context.space_data.use_manipulator_scale = False
-        elif self.mode == "SCALE":
-            context.space_data.show_manipulator = True
-            context.space_data.use_manipulator_translate = False
-            context.space_data.use_manipulator_rotate = False
-            context.space_data.use_manipulator_scale = True
-
-        return {'FINISHED'}
-bpy.utils.register_class(SetManipulator)
-
-
-class ModeSwitchMenu(bpy.types.Menu):
-    """ A menu for switching between object modes.
-    """
-    bl_idname = "OBJECT_MT_mode_switch_menu"
-    bl_label = "Switch Mode"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_enum("object.mode_set", "mode")
-
-bpy.utils.register_class(ModeSwitchMenu)
-# Work around
-bpy.ops.object.mode_set(mode='OBJECT', toggle=False)  # XXX, WHY IS THE KEYMAP DOING THIS? - campbell
-
-
-
-
-
-
-######################################################################
-######################################################################
-############### KEYMAP BEGINS ########################################
-######################################################################
-######################################################################
-wm = bpy.context.window_manager
-kc = wm.keyconfigs.new('Blender 2012 (experimental!)')
-
-
-##############
-# Map Window #
-##############
-km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False)
-
-#------
-# Quit
-#------
-kmi = km.keymap_items.new('wm.quit_blender', 'Q', 'PRESS', ctrl=True)
-
-#----------------------
-# Operator search menu
-#----------------------
-kmi = km.keymap_items.new('wm.search_menu', 'TAB', 'PRESS')
-
-#-----------------
-# File management
-#-----------------
-# Open
-kmi = km.keymap_items.new('wm.read_homefile', 'N', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('wm.save_homefile', 'U', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('wm.open_mainfile', 'O', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('wm.link_append', 'O', 'PRESS', ctrl=True, alt=True)
-
-# Save
-kmi = km.keymap_items.new('wm.save_mainfile', 'S', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('wm.save_as_mainfile', 'S', 'PRESS', shift=True, ctrl=True)
-
-#------------------
-# Window switching
-#------------------
-if WINDOW_TYPE_SWITCHING:
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F2', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'LOGIC_EDITOR'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F3', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'NODE_EDITOR'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F4', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'CONSOLE'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F5', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'VIEW_3D'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F6', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'GRAPH_EDITOR'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F7', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'PROPERTIES'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F8', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'SEQUENCE_EDITOR'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F9', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'OUTLINER'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F10', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'IMAGE_EDITOR'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F11', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'TEXT_EDITOR'
-    kmi = km.keymap_items.new('wm.context_set_enum', 'F12', 'PRESS', shift=True)
-    kmi.properties.data_path = 'area.type'
-    kmi.properties.value = 'DOPESHEET_EDITOR'
-
-#-------------
-# NDof Device
-#-------------
-kmi = km.keymap_items.new('wm.call_menu', 'NDOF_BUTTON_MENU', 'PRESS')
-kmi.properties.name = 'USERPREF_MT_ndof_settings'
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS')
-kmi.properties.decrease = False
-kmi.properties.fast = False
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS')
-kmi.properties.decrease = True
-kmi.properties.fast = False
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS', shift=True)
-kmi.properties.decrease = False
-kmi.properties.fast = True
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS', shift=True)
-kmi.properties.decrease = True
-kmi.properties.fast = True
-
-#------
-# Misc
-#------
-kmi = km.keymap_items.new('wm.window_fullscreen_toggle', 'F11', 'PRESS', alt=True)
-
-#-----------------------
-# Development/debugging
-#-----------------------
-if DEVELOPER_HOTKEYS:
-    kmi = km.keymap_items.new('wm.redraw_timer', 'T', 'PRESS', ctrl=True, alt=True)
-    kmi = km.keymap_items.new('wm.debug_menu', 'D', 'PRESS', ctrl=True, alt=True)
-
-#-----
-# ???
-#-----
-kmi = km.keymap_items.new('info.reports_display_update', 'TIMER', 'ANY', any=True)
-
-
-
-
-##################
-# 3D View Global #
-##################
-km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
-
-#-----------------
-# View navigation
-#-----------------
-# ???
-kmi = km.keymap_items.new('view3d.rotate', 'MOUSEROTATE', 'ANY')
-kmi = km.keymap_items.new('view3d.smoothview', 'TIMER1', 'ANY', any=True)
-
-# Perspective/ortho
-kmi = km.keymap_items.new('view3d.view_persportho', 'NUMPAD_5', 'PRESS')
-
-# Camera view
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_0', 'PRESS')
-kmi.properties.type = 'CAMERA'
-
-# Basics with mouse
-kmi = km.keymap_items.new('view3d.rotate', 'MIDDLEMOUSE', 'PRESS')
-kmi = km.keymap_items.new('view3d.move', 'MIDDLEMOUSE', 'PRESS', shift=True)
-kmi = km.keymap_items.new('view3d.zoom', 'MIDDLEMOUSE', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('view3d.dolly', 'MIDDLEMOUSE', 'PRESS', shift=True, ctrl=True)
-
-# Basics with mouse wheel
-kmi = km.keymap_items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
-kmi.properties.delta = 1
-kmi = km.keymap_items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
-kmi.properties.delta = -1
-kmi = km.keymap_items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
-kmi.properties.type = 'PANRIGHT'
-kmi = km.keymap_items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
-kmi.properties.type = 'PANLEFT'
-kmi = km.keymap_items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
-kmi.properties.type = 'PANUP'
-kmi = km.keymap_items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
-kmi.properties.type = 'PANDOWN'
-kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
-kmi.properties.type = 'ORBITLEFT'
-kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
-kmi.properties.type = 'ORBITRIGHT'
-kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
-kmi.properties.type = 'ORBITUP'
-kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
-kmi.properties.type = 'ORBITDOWN'
-
-# Basics with trackpad
-kmi = km.keymap_items.new('view3d.rotate', 'TRACKPADPAN', 'ANY', alt=True)
-kmi = km.keymap_items.new('view3d.move', 'TRACKPADPAN', 'ANY')
-kmi = km.keymap_items.new('view3d.zoom', 'TRACKPADZOOM', 'ANY')
-
-# Basics with numpad
-kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_8', 'PRESS')
-kmi.properties.type = 'ORBITUP'
-kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_2', 'PRESS')
-kmi.properties.type = 'ORBITDOWN'
-kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_4', 'PRESS')
-kmi.properties.type = 'ORBITLEFT'
-kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_6', 'PRESS')
-kmi.properties.type = 'ORBITRIGHT'
-kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_8', 'PRESS', ctrl=True)
-kmi.properties.type = 'PANUP'
-kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_2', 'PRESS', ctrl=True)
-kmi.properties.type = 'PANDOWN'
-kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_4', 'PRESS', ctrl=True)
-kmi.properties.type = 'PANLEFT'
-kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_6', 'PRESS', ctrl=True)
-kmi.properties.type = 'PANRIGHT'
-kmi = km.keymap_items.new('view3d.zoom', 'NUMPAD_PLUS', 'PRESS')
-kmi.properties.delta = 1
-kmi = km.keymap_items.new('view3d.zoom', 'NUMPAD_MINUS', 'PRESS')
-kmi.properties.delta = -1
-
-# Zoom in/out alternatives
-kmi = km.keymap_items.new('view3d.zoom', 'EQUAL', 'PRESS', ctrl=True)
-kmi.properties.delta = 1
-kmi = km.keymap_items.new('view3d.zoom', 'MINUS', 'PRESS', ctrl=True)
-kmi.properties.delta = -1
-
-# Front/Right/Top/Back/Left/Bottom
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS')
-kmi.properties.type = 'FRONT'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS')
-kmi.properties.type = 'RIGHT'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS')
-kmi.properties.type = 'TOP'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', ctrl=True)
-kmi.properties.type = 'BACK'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', ctrl=True)
-kmi.properties.type = 'LEFT'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', ctrl=True)
-kmi.properties.type = 'BOTTOM'
-
-# Selection-aligned Front/Right/Top/Back/Left/Bottom
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True)
-kmi.properties.type = 'FRONT'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True)
-kmi.properties.type = 'RIGHT'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True)
-kmi.properties.type = 'TOP'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True, ctrl=True)
-kmi.properties.type = 'BACK'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True, ctrl=True)
-kmi.properties.type = 'LEFT'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True, ctrl=True)
-kmi.properties.type = 'BOTTOM'
-kmi.properties.align_active = True
-
-# NDOF Device
-kmi = km.keymap_items.new('view3d.ndof_orbit', 'NDOF_BUTTON_MENU', 'ANY')
-kmi = km.keymap_items.new('view3d.ndof_pan', 'NDOF_BUTTON_MENU', 'ANY', shift=True)
-kmi = km.keymap_items.new('view3d.view_selected', 'NDOF_BUTTON_FIT', 'PRESS')
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_FRONT', 'PRESS')
-kmi.properties.type = 'FRONT'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_BACK', 'PRESS')
-kmi.properties.type = 'BACK'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_LEFT', 'PRESS')
-kmi.properties.type = 'LEFT'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_RIGHT', 'PRESS')
-kmi.properties.type = 'RIGHT'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_TOP', 'PRESS')
-kmi.properties.type = 'TOP'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_BOTTOM', 'PRESS')
-kmi.properties.type = 'BOTTOM'
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_FRONT', 'PRESS', shift=True)
-kmi.properties.type = 'FRONT'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_RIGHT', 'PRESS', shift=True)
-kmi.properties.type = 'RIGHT'
-kmi.properties.align_active = True
-kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_TOP', 'PRESS', shift=True)
-kmi.properties.type = 'TOP'
-kmi.properties.align_active = True
-
-# Fly mode
-kmi = km.keymap_items.new('view3d.fly', 'F', 'PRESS', shift=True)
-
-# Misc
-kmi = km.keymap_items.new('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS')
-kmi = km.keymap_items.new('view3d.view_center_cursor', 'NUMPAD_PERIOD', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('view3d.zoom_camera_1_to_1', 'NUMPAD_ENTER', 'PRESS', shift=True)
-kmi = km.keymap_items.new('view3d.view_center_camera', 'HOME', 'PRESS')
-kmi = km.keymap_items.new('view3d.view_all', 'HOME', 'PRESS')
-kmi.properties.center = False
-kmi = km.keymap_items.new('view3d.view_all', 'C', 'PRESS', shift=True)
-kmi.properties.center = True
-
-#-----------
-# Selection
-#-----------
-# Click select
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS')
-kmi.properties.extend = False
-kmi.properties.center = False
-kmi.properties.enumerate = False
-kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
-kmi.properties.extend = True
-kmi.properties.center = False
-kmi.properties.enumerate = False
-kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
-kmi.properties.extend = False
-kmi.properties.center = True
-kmi.properties.enumerate = False
-kmi.properties.object = True
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True)
-kmi.properties.extend = False
-kmi.properties.center = False
-kmi.properties.enumerate = True
-kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
-kmi.properties.extend = True
-kmi.properties.center = True
-kmi.properties.enumerate = False
-kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
-kmi.properties.extend = False
-kmi.properties.center = True
-kmi.properties.enumerate = True
-kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
-kmi.properties.extend = True
-kmi.properties.center = False
-kmi.properties.enumerate = True
-kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
-kmi.properties.extend = True
-kmi.properties.center = True
-kmi.properties.enumerate = True
-kmi.properties.object = False
-
-# Box select
-kmi = km.keymap_items.new('view3d.select_border', 'B', 'PRESS')
-
-# Lasso select
-kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
-kmi.properties.deselect = False
-kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
-kmi.properties.deselect = True
-
-# Paint select
-kmi = km.keymap_items.new('view3d.select_circle', 'C', 'PRESS')
-
-#-------------
-# Manipulator
-#-------------
-kmi = km.keymap_items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
-kmi.properties.release_confirm = True
-
-if MAYA_STYLE_MANIPULATORS:
-    kmi = km.keymap_items.new('view3d.manipulator_set', 'Q', 'PRESS')
-    kmi.properties.mode = 'NONE'
-    kmi = km.keymap_items.new('view3d.manipulator_set', 'W', 'PRESS')
-    kmi.properties.mode = 'TRANSLATE'
-    kmi = km.keymap_items.new('view3d.manipulator_set', 'E', 'PRESS')
-    kmi.properties.mode = 'ROTATE'
-    kmi = km.keymap_items.new('view3d.manipulator_set', 'R', 'PRESS')
-    kmi.properties.mode = 'SCALE'
-else:
-    kmi = km.keymap_items.new('wm.context_toggle', 'SPACE', 'PRESS', ctrl=True)
-    kmi.properties.data_path = 'space_data.show_manipulator'
-
-#-----------------------
-# Transforms via hotkey
-#-----------------------
-# Grab, rotate scale
-kmi = km.keymap_items.new('transform.translate', 'G', 'PRESS')
-kmi = km.keymap_items.new('transform.translate', 'EVT_TWEAK_S', 'ANY')
-kmi = km.keymap_items.new('transform.rotate', 'R', 'PRESS')
-kmi = km.keymap_items.new('transform.resize', 'S', 'PRESS')
-
-# Mirror, shear, warp, to-sphere
-kmi = km.keymap_items.new('transform.mirror', 'M', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('transform.shear', 'S', 'PRESS', shift=True, ctrl=True, alt=True)
-kmi = km.keymap_items.new('transform.warp', 'W', 'PRESS', shift=True)
-kmi = km.keymap_items.new('transform.tosphere', 'S', 'PRESS', shift=True, alt=True)
-
-#-------------------------
-# Transform texture space
-#-------------------------
-kmi = km.keymap_items.new('transform.translate', 'T', 'PRESS', shift=True)
-kmi.properties.texture_space = True
-kmi = km.keymap_items.new('transform.resize', 'T', 'PRESS', shift=True, alt=True)
-kmi.properties.texture_space = True
-
-#------------------
-# Transform spaces
-#------------------
-kmi = km.keymap_items.new('transform.select_orientation', 'SPACE', 'PRESS', alt=True)
-kmi = km.keymap_items.new('transform.create_orientation', 'SPACE', 'PRESS', ctrl=True, alt=True)
-kmi.properties.use = True
-
-#----------
-# Snapping
-#----------
-kmi = km.keymap_items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True)
-kmi.properties.data_path = 'tool_settings.use_snap'
-kmi = km.keymap_items.new('transform.snap_type', 'TAB', 'PRESS', shift=True, ctrl=True)
-
-#---------------
-# Snapping Menu
-#---------------
-kmi = km.keymap_items.new('wm.call_menu', 'S', 'PRESS', shift=True)
-kmi.properties.name = 'VIEW3D_MT_snap'
-
-#-----------
-# 3d cursor
-#-----------
-kmi = km.keymap_items.new('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
-
-#-------------------
-# Toggle local view
-#-------------------
-kmi = km.keymap_items.new('view3d.localview', 'NUMPAD_SLASH', 'PRESS')
-
-#--------
-# Layers
-#--------
-kmi = km.keymap_items.new('view3d.layers', 'ACCENT_GRAVE', 'PRESS')
-kmi.properties.nr = 0
-kmi = km.keymap_items.new('view3d.layers', 'ONE', 'PRESS', any=True)
-kmi.properties.nr = 1
-kmi = km.keymap_items.new('view3d.layers', 'TWO', 'PRESS', any=True)
-kmi.properties.nr = 2
-kmi = km.keymap_items.new('view3d.layers', 'THREE', 'PRESS', any=True)
-kmi.properties.nr = 3
-kmi = km.keymap_items.new('view3d.layers', 'FOUR', 'PRESS', any=True)
-kmi.properties.nr = 4
-kmi = km.keymap_items.new('view3d.layers', 'FIVE', 'PRESS', any=True)
-kmi.properties.nr = 5
-kmi = km.keymap_items.new('view3d.layers', 'SIX', 'PRESS', any=True)
-kmi.properties.nr = 6
-kmi = km.keymap_items.new('view3d.layers', 'SEVEN', 'PRESS', any=True)
-kmi.properties.nr = 7
-kmi = km.keymap_items.new('view3d.layers', 'EIGHT', 'PRESS', any=True)
-kmi.properties.nr = 8
-kmi = km.keymap_items.new('view3d.layers', 'NINE', 'PRESS', any=True)
-kmi.properties.nr = 9
-kmi = km.keymap_items.new('view3d.layers', 'ZERO', 'PRESS', any=True)
-kmi.properties.nr = 10
-
-#------------------
-# Viewport drawing
-#------------------
-kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS')
-kmi.properties.data_path = 'space_data.viewport_shade'
-kmi.properties.value_1 = 'SOLID'
-kmi.properties.value_2 = 'WIREFRAME'
-kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
-kmi.properties.data_path = 'space_data.viewport_shade'
-kmi.properties.value_1 = 'TEXTURED'
-kmi.properties.value_2 = 'SOLID'
-
-#-------------
-# Pivot point
-#-------------
-kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'PRESS')
-kmi.properties.data_path = 'space_data.pivot_point'
-kmi.properties.value = 'BOUNDING_BOX_CENTER'
-kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'PRESS', ctrl=True)
-kmi.properties.data_path = 'space_data.pivot_point'
-kmi.properties.value = 'MEDIAN_POINT'
-kmi = km.keymap_items.new('wm.context_toggle', 'COMMA', 'PRESS', alt=True)
-kmi.properties.data_path = 'space_data.use_pivot_point_align'
-kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'PRESS')
-kmi.properties.data_path = 'space_data.pivot_point'
-kmi.properties.value = 'CURSOR'
-kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'PRESS', ctrl=True)
-kmi.properties.data_path = 'space_data.pivot_point'
-kmi.properties.value = 'INDIVIDUAL_ORIGINS'
-kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'PRESS', alt=True)
-kmi.properties.data_path = 'space_data.pivot_point'
-kmi.properties.value = 'ACTIVE_ELEMENT'
-
-#------
-# Misc
-#------
-kmi = km.keymap_items.new('view3d.clip_border', 'B', 'PRESS', alt=True)
-kmi = km.keymap_items.new('view3d.zoom_border', 'B', 'PRESS', shift=True)
-kmi = km.keymap_items.new('view3d.render_border', 'B', 'PRESS', shift=True)
-kmi = km.keymap_items.new('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True)
-kmi = km.keymap_items.new('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True)
-
-
-
-#######################
-# Transform Modal Map #
-#######################
-km = kc.keymaps.new('Transform Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True)
-
-# Cancel
-kmi = km.keymap_items.new_modal('CANCEL', 'ESC', 'PRESS', any=True)
-
-# Confirm
-kmi = km.keymap_items.new_modal('CONFIRM', 'LEFTMOUSE', 'PRESS', any=True)
-kmi = km.keymap_items.new_modal('CONFIRM', 'RET', 'PRESS', any=True)
-kmi = km.keymap_items.new_modal('CONFIRM', 'NUMPAD_ENTER', 'PRESS', any=True)
-
-# Snapping
-kmi = km.keymap_items.new_modal('SNAP_TOGGLE', 'TAB', 'PRESS', shift=True)
-kmi = km.keymap_items.new_modal('SNAP_INV_ON', 'LEFT_CTRL', 'PRESS', any=True)
-kmi = km.keymap_items.new_modal('SNAP_INV_OFF', 'LEFT_CTRL', 'RELEASE', any=True)
-kmi = km.keymap_items.new_modal('SNAP_INV_ON', 'RIGHT_CTRL', 'PRESS', any=True)
-kmi = km.keymap_items.new_modal('SNAP_INV_OFF', 'RIGHT_CTRL', 'RELEASE', any=True)
-kmi = km.keymap_items.new_modal('ADD_SNAP', 'A', 'PRESS')
-kmi = km.keymap_items.new_modal('REMOVE_SNAP', 'A', 'PRESS', alt=True)
-
-# Proportional edit adjusting
-kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_UP', 'PAGE_UP', 'PRESS')
-kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_DOWN', 'PAGE_DOWN', 'PRESS')
-kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_UP', 'WHEELDOWNMOUSE', 'PRESS')
-kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_DOWN', 'WHEELUPMOUSE', 'PRESS')
-
-# Auto-ik adjusting
-kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_UP', 'PAGE_UP', 'PRESS', shift=True)
-kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_DOWN', 'PAGE_DOWN', 'PRESS', shift=True)
-kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_UP', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
-kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_DOWN', 'WHEELUPMOUSE', 'PRESS', shift=True)
-
-# Constraining to axes
-kmi = km.keymap_items.new_modal('AXIS_X', 'X', 'PRESS')
-kmi = km.keymap_items.new_modal('AXIS_Y', 'Y', 'PRESS')
-kmi = km.keymap_items.new_modal('AXIS_Z', 'Z', 'PRESS')
-kmi = km.keymap_items.new_modal('PLANE_X', 'X', 'PRESS', shift=True)
-kmi = km.keymap_items.new_modal('PLANE_Y', 'Y', 'PRESS', shift=True)
-kmi = km.keymap_items.new_modal('PLANE_Z', 'Z', 'PRESS', shift=True)
-
-# ???
-#kmi = km.keymap_items.new_modal('TRANSLATE', 'G', 'PRESS')
-#kmi = km.keymap_items.new_modal('ROTATE', 'R', 'PRESS')
-#kmi = km.keymap_items.new_modal('RESIZE', 'S', 'PRESS')
-
-
-
-####################
-# Object Non-modal #
-####################
-km = kc.keymaps.new('Object Non-modal', space_type='EMPTY', region_type='WINDOW', modal=False)
-
-
-#-----------------------
-# Object mode switching
-#-----------------------
-kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS')
-kmi.properties.name = 'OBJECT_MT_mode_switch_menu'
-
-
-
-#############
-# Mesh Edit #
-#############
-km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
-
-#---------------------------------
-# Vertex/Edge/Face mode switching
-#---------------------------------
-kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_select_mode'
-
-#-----------
-# Selection
-#-----------
-kmi = km.keymap_items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', alt=True)
-kmi.properties.extend = False
-kmi = km.keymap_items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
-kmi.properties.extend = True
-kmi = km.keymap_items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
-kmi.properties.extend = False
-kmi = km.keymap_items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
-kmi.properties.extend = True
-kmi = km.keymap_items.new('mesh.select_shortest_path', 'SELECTMOUSE', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.select_all', 'A', 'PRESS')
-kmi.properties.action = 'TOGGLE'
-kmi = km.keymap_items.new('mesh.select_all', 'I', 'PRESS', ctrl=True)
-kmi.properties.action = 'INVERT'
-kmi = km.keymap_items.new('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True)
-kmi = km.keymap_items.new('mesh.select_linked', 'L', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'PRESS')
-kmi.properties.deselect = False
-kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'PRESS', shift=True)
-kmi.properties.deselect = True
-kmi = km.keymap_items.new('mesh.faces_select_linked_flat', 'F', 'PRESS', shift=True, ctrl=True, alt=True)
-kmi = km.keymap_items.new('mesh.select_similar', 'G', 'PRESS', shift=True)
-
-#----------------------
-# Proportional editing
-#----------------------
-kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS')
-kmi.properties.data_path = 'tool_settings.proportional_edit'
-kmi.properties.value_1 = 'DISABLED'
-kmi.properties.value_2 = 'ENABLED'
-kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
-kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
-kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
-kmi.properties.data_path = 'tool_settings.proportional_edit'
-kmi.properties.value_1 = 'DISABLED'
-kmi.properties.value_2 = 'CONNECTED'
-
-#--------
-# Hiding
-#--------
-kmi = km.keymap_items.new('mesh.hide', 'H', 'PRESS')
-kmi.properties.unselected = False
-kmi = km.keymap_items.new('mesh.hide', 'H', 'PRESS', shift=True)
-kmi.properties.unselected = True
-kmi = km.keymap_items.new('mesh.reveal', 'H', 'PRESS', alt=True)
-
-#--------
-# Create
-#--------
-kmi = km.keymap_items.new('mesh.loopcut_slide', 'R', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.knifetool', 'K', 'PRESS')
-kmi = km.keymap_items.new('view3d.edit_mesh_extrude_move_normal', 'E', 'PRESS')
-kmi = km.keymap_items.new('wm.call_menu', 'E', 'PRESS', alt=True)
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_extrude'
-kmi = km.keymap_items.new('mesh.edge_face_add', 'F', 'PRESS')
-kmi = km.keymap_items.new('mesh.vert_connect', 'J', 'PRESS')
-kmi = km.keymap_items.new('mesh.spin', 'R', 'PRESS', alt=True)
-kmi = km.keymap_items.new('mesh.fill', 'F', 'PRESS', alt=True)
-kmi = km.keymap_items.new('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True)
-kmi = km.keymap_items.new('mesh.duplicate_move', 'D', 'PRESS', shift=True)
-kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
-kmi.properties.name = 'INFO_MT_mesh_add'
-kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
-kmi.properties.rotate_source = True
-kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', shift=True, ctrl=True)
-kmi.properties.rotate_source = False
-
-#--------
-# Delete
-#--------
-kmi = km.keymap_items.new('wm.call_menu', 'X', 'PRESS')
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
-kmi = km.keymap_items.new('wm.call_menu', 'DEL', 'PRESS')
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
-
-#----------
-# Separate
-#----------
-kmi = km.keymap_items.new('mesh.rip_move', 'V', 'PRESS')
-kmi = km.keymap_items.new('mesh.split', 'Y', 'PRESS')
-kmi = km.keymap_items.new('mesh.separate', 'P', 'PRESS')
-
-#-------
-# Merge
-#-------
-kmi = km.keymap_items.new('mesh.merge', 'M', 'PRESS', alt=True)
-
-#-----------
-# Transform
-#-----------
-kmi = km.keymap_items.new('transform.shrink_fatten', 'S', 'PRESS', alt=True)
-kmi = km.keymap_items.new('transform.edge_crease', 'E', 'PRESS', shift=True)
-kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', shift=True, ctrl=True)
-kmi.properties.use_beauty = False
-kmi = km.keymap_items.new('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
-
-#------------
-# Tool Menus
-#------------
-kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS')
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials'
-kmi = km.keymap_items.new('wm.call_menu', 'F', 'PRESS', ctrl=True)
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_faces'
-kmi = km.keymap_items.new('wm.call_menu', 'E', 'PRESS', ctrl=True)
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_edges'
-kmi = km.keymap_items.new('wm.call_menu', 'V', 'PRESS', ctrl=True)
-kmi.properties.name = 'VIEW3D_MT_edit_mesh_vertices'
-
-#------
-# UV's
-#------
-kmi = km.keymap_items.new('wm.call_menu', 'U', 'PRESS')
-kmi.properties.name = 'VIEW3D_MT_uv_map'
-
-#-------------------
-# Calculate normals
-#-------------------
-kmi = km.keymap_items.new('mesh.normals_make_consistent', 'N', 'PRESS', ctrl=True)
-kmi.properties.inside = False
-kmi = km.keymap_items.new('mesh.normals_make_consistent', 'N', 'PRESS', shift=True, ctrl=True)
-kmi.properties.inside = True
-
-#-------------------
-# Subsurf shortcuts
-#-------------------
-
-if SUBSURF_RELATIVE:
-    kmi = km.keymap_items.new('object.shift_subsurf_level', 'EQUAL', 'CLICK')
-    kmi.properties.delta = 1
-    kmi.properties.max = 4
-    kmi = km.keymap_items.new('object.shift_subsurf_level', 'MINUS', 'CLICK')
-    kmi.properties.delta = -1
-    kmi.properties.min = 0
-else:
-    kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
-    kmi.properties.level = 0
-    kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
-    kmi.properties.level = 1
-    kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
-    kmi.properties.level = 2
-    kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
-    kmi.properties.level = 3
-    kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
-    kmi.properties.level = 4
-    kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
-    kmi.properties.level = 5
-
-#---------
-# Rigging
-#---------
-kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('wm.call_menu', 'H', 'PRESS', ctrl=True)
-kmi.properties.name = 'VIEW3D_MT_hook'
-kmi = km.keymap_items.new('wm.call_menu', 'G', 'PRESS', ctrl=True)
-kmi.properties.name = 'VIEW3D_MT_vertex_group'
diff --git a/release/scripts/addons_contrib/render_clay.py b/release/scripts/addons_contrib/render_clay.py
deleted file mode 100644
index 541b2be..0000000
--- a/release/scripts/addons_contrib/render_clay.py
+++ /dev/null
@@ -1,226 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-    "name": "Clay Render",
-    "author": "Fabio Russo <ruesp83 at libero.it>",
-    "version": (1, 2),
-    "blender": (2, 5, 6),
-    "location": "Render > Clay Render",
-    "description": "This script, applies a temporary material to all objects"\
-        " of the scene.",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Clay_Render",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=22971",
-    "category": "Render"}
-
-import bpy
-from bpy.props import BoolProperty
-
-
-def Create_Mat():
-    id = bpy.data.materials.new("Clay_Render")
-    #diffuse
-    id.diffuse_shader = "OREN_NAYAR"
-    id.diffuse_color = 0.800, 0.741, 0.536
-    id.diffuse_intensity = 1
-    id.roughness = 0.909
-    #specular
-    id.specular_shader = "COOKTORR"
-    id.specular_color = 1, 1, 1
-    id.specular_hardness = 10
-    id.specular_intensity = 0.115
-
-
-def Alternative_Clay(self, msg):
-    Find = False
-    AM = None
-    i = 0
-    for mat in bpy.data.materials:
-        if (mat.Mat_Clay) and (not Find):
-            Find = True
-            AM = mat
-            i += 1
-
-        else:
-            if (mat.Mat_Clay):
-                i += 1
-
-    if msg == True:
-        if (i == 1):
-            self.report({'INFO'}, "The material \"" + AM.name + "\" is set "\
-                "as Clay!")
-        else:
-            if (i > 1):
-                self.report({'WARNING'}, "Two or more materials are set as "\
-                    "Clay. \"" + AM.name + "\" will be used!")
-
-    return AM
-
-
-def Get_Mat():
-    Mat = bpy.data.materials["Clay_Render"]
-    return Mat
-
-
-def Exist_Mat():
-    if bpy.data.materials.get("Clay_Render"):
-        return True
-
-    else:
-        return False
-
-
-class ClayPinned(bpy.types.Operator):
-    bl_idname = "render.clay_pinned"
-    bl_label = "Clay Pinned"
-    bl_description = "Clay Material Stores"
-
-    def execute(self, context):
-        if bpy.types.Scene.Clay_Pinned:
-            bpy.types.Scene.Clay_Pinned = False
-        else:
-            if bpy.types.Scene.Clay:
-                if bpy.data.materials[0].users == 0:
-                    bpy.data.materials.remove(Get_Mat())
-                    bpy.types.Scene.Clay_Pinned = True
-
-            else:
-                bpy.types.Scene.Clay_Pinned = True
-
-        return {'FINISHED'}
-
-
-class CheckClay(bpy.types.Operator):
-    bl_idname = "render.clay"
-    bl_label = "Clay Render"
-    bl_description = "Use Clay Render"
-
-    def execute(self, context):
-        if bpy.types.Scene.Clay:
-            #Clay Attivato
-            ac = Alternative_Clay(self, True)
-            if ac is None:
-                if not Exist_Mat():
-                    Create_Mat()
-                rl = context.scene.render.layers
-                rl.active.material_override = Get_Mat()
-
-            else:
-                context.scene.render.layers.active.material_override = ac
-
-            bpy.types.Scene.Clay = False
-
-        else:
-            context.scene.render.layers.active.material_override = None
-            if bpy.types.Scene.Clay_Pinned:
-                if bpy.data.materials[0].users == 0:
-                    bpy.data.materials.remove(Get_Mat())
-            bpy.types.Scene.Clay = True
-
-        return {'FINISHED'}
-
-
-def draw_clay_render(self, context):
-    ok_clay = not bpy.types.Scene.Clay
-    pin = not bpy.types.Scene.Clay_Pinned
-
-    rnl = context.scene.render.layers.active
-    split = self.layout.split()
-    col = split.column()
-
-    col.operator(CheckClay.bl_idname, emboss=False, icon='CHECKBOX_HLT'\
-        if ok_clay else 'CHECKBOX_DEHLT')
-    col = split.column()
-    if Alternative_Clay(self, False) is None:
-        if Exist_Mat():
-            if (bpy.data.materials[0].users == 0) or (ok_clay):
-                row = col.row(align=True)
-                im = Get_Mat()
-                row.prop(im, "diffuse_color", text="")
-                row.operator(ClayPinned.bl_idname, text="", icon='PINNED'\
-                    if pin else 'UNPINNED')
-
-                if ok_clay:
-                    row.active = True
-
-                else:
-                    row.active = False
-
-            else:
-                col.label('Clay Material applied to an object')
-
-    else:
-        col.label('Custom Material Clay')
-
-    self.layout.separator()
-
-
-def draw_clay_options(self, context):
-    cm = context.material
-    layout = self.layout
-    layout.prop(cm, "Mat_Clay", text="Clay")
-
-
-def draw_clay_warning(self, context):
-    if not bpy.types.Scene.Clay:
-        self.layout.label("Render Clay Enabled", "ERROR")
-
-
-def register():
-    bpy.types.Scene.Clay = BoolProperty(
-    name='Clay Render',
-    description='Use Clay Render',
-    default=False)
-
-    bpy.types.Scene.Clay_Pinned = BoolProperty(
-    name='Clay Pinned',
-    description='Clay Material Stores',
-    default=False)
-
-    bpy.types.Material.Mat_Clay = bpy.props.BoolProperty(
-        name='Use as Clay',
-        description='Use as Clay',
-        default=False)
-
-    bpy.utils.register_class(ClayPinned)
-    bpy.utils.register_class(CheckClay)
-    bpy.types.RENDER_PT_render.prepend(draw_clay_render)
-    bpy.types.MATERIAL_PT_options.append(draw_clay_options)
-    bpy.types.INFO_HT_header.append(draw_clay_warning)
-
-
-def unregister():
-    bpy.context.scene.render.layers.active.material_override = None
-    if (Exist_Mat()) and (bpy.data.materials[0].users == 0):
-        bpy.data.materials.remove(Get_Mat())
-    del bpy.types.Scene.Clay
-    del bpy.types.Scene.Clay_Pinned
-    del bpy.types.Material.Mat_Clay
-    bpy.utils.unregister_class(ClayPinned)
-    bpy.utils.unregister_class(CheckClay)
-    bpy.types.RENDER_PT_render.remove(draw_clay_render)
-    bpy.types.MATERIAL_PT_options.remove(draw_clay_options)
-    bpy.types.INFO_HT_header.remove(draw_clay_warning)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/render_time.py b/release/scripts/addons_contrib/render_time.py
deleted file mode 100644
index 7647196..0000000
--- a/release/scripts/addons_contrib/render_time.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-
-bl_info = {
-    "name": "Render Time Estimation",
-    "author": "Jason van Gumster (Fweeb)",
-    "version": (0, 5, 0),
-    "blender": (2, 62, 1),
-    "location": "UV/Image Editor > Properties > Image",
-    "description": "Estimates the time to complete rendering on animations",
-    "warning": "Does not work on OpenGL renders",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Render/Render_Time_Estimation",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=30452&group_id=153&atid=467",
-    "category": "Render"}
-
-
-import bpy, time
-from bpy.app.handlers import persistent
-from datetime import timedelta
-import blf
-
-
-timer = {"average": 0.0, "total": 0.0, "time_start": 0.0, "is_rendering": False, "hud": False}
-
-def set_rendering(scene):
-    timer["is_rendering"] = True
-
- at persistent
-def unset_rendering(scene):
-    timer["is_rendering"] = False
-
- at persistent
-def start_timer(scene):
-    set_rendering(scene)
-
-    if scene.frame_current == scene.frame_start:
-        timer["average"] = 0.0
-        timer["total"] = 0.0
-
-    timer["time_start"] = time.time()
-
- at persistent
-def end_timer(scene):
-    render_time = time.time() - timer["time_start"]
-    timer["total"] += render_time
-    if scene.frame_current == scene.frame_start:
-        timer["average"] = render_time
-    else:
-        timer["average"] = (timer["average"] + render_time) / 2
-
-    print("Total render time: " + str(timedelta(seconds = timer["total"])))
-    print("Estimated completion: " + str(timedelta(seconds = (timer["average"] * (scene.frame_end - scene.frame_current)))))
-
-
-# UI
-
-def image_panel_rendertime(self, context):
-    scene = context.scene
-    layout = self.layout
-
-    if context.space_data.image is not None and context.space_data.image.type == 'RENDER_RESULT':
-        layout.label(text = "Total render time: " + str(timedelta(seconds = timer["total"])))
-
-        if timer["is_rendering"] and scene.frame_current != scene.frame_start:
-            layout.label(text = "Estimated completion: " + str(timedelta(seconds = (timer["average"] * (scene.frame_end - scene.frame_current)))))
-
-def draw_callback_px(self, context):
-    scene = context.scene
-
-    font_id = 0  # XXX, need to find out how best to get this.
-
-    # draw some text
-    blf.position(font_id, 15, 30, 0)
-    blf.size(font_id, 18, 72)
-    blf.enable(font_id, blf.SHADOW)
-    blf.shadow(font_id, 5, 0.0, 0.0, 0.0, 1.0)
-
-    blf.draw(font_id, "Total render time " + str(timedelta(seconds = timer["total"])))
-    if timer["is_rendering"] and scene.frame_current != scene.frame_start:
-        blf.position(font_id, 15, 12, 0)
-        blf.draw(font_id, "Estimated completion: " + str(timedelta(seconds = (timer["average"] * (scene.frame_end - scene.frame_current)))))
-
-    # restore defaults
-    blf.disable(font_id, blf.SHADOW)
-
-class RenderTimeHUD(bpy.types.Operator):
-    bl_idname = "view2d.rendertime_hud"
-    bl_label = "Display Render Times"
-    last_activity = 'NONE'
-
-    def modal(self, context, event):
-        if context.area:
-            context.area.tag_redraw()
-
-        #if event.type in {'ESC'}:
-        if timer["hud"] == False:
-            context.region.callback_remove(self._handle)
-            return {'CANCELLED'}
-
-        return {'PASS_THROUGH'}
-
-    def invoke(self, context, event):
-        if context.area.type == 'IMAGE_EDITOR':
-            if timer["hud"] == False:
-                context.window_manager.modal_handler_add(self)
-
-                # Add the region OpenGL drawing callback
-                self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
-                timer["hud"] = True
-                return {'RUNNING_MODAL'}
-            else:
-                timer["hud"] = False
-                return {'CANCELLED'}
-        else:
-            self.report({'WARNING'}, "UV/Image Editor not found, cannot run operator")
-            return {'CANCELLED'}
-
-def display_hud(self, context):
-    scene = context.scene
-    layout = self.layout
-    layout.operator("view2d.rendertime_hud")
-
-
-# Registration
-
-def register():
-    bpy.app.handlers.render_complete.append(unset_rendering)
-    bpy.app.handlers.render_cancel.append(unset_rendering)
-    bpy.app.handlers.render_pre.append(start_timer)
-    bpy.app.handlers.render_post.append(end_timer)
-    bpy.types.IMAGE_PT_image_properties.append(image_panel_rendertime)
-    bpy.utils.register_class(RenderTimeHUD)
-    bpy.types.IMAGE_HT_header.append(display_hud)
-
-    # Keymapping      XXX TODO - This doesn't work for some reason
-    #kc = bpy.context.window_manager.keyconfigs.addon
-    #km = kc.keymaps.new(name = "View 2D", space_type = 'IMAGE_EDITOR')
-    #kmi = km.keymap_items.new("view2d.rendertime_hud", 'E', 'PRESS')
-    #kmi.active = True
-
-def unregister():
-    #kc = bpy.context.window_manager.keyconfigs.addon
-    #km = kc.keymaps["View 2D"]
-    #km.keymap_items.remove(km.keymap_items["view2d.rendertime_hud"])
-
-    bpy.types.IMAGE_HT_header.remove(display_hud)
-    bpy.utils.register_class(RenderTimeHUD)
-    bpy.app.handlers.render_pre.remove(start_timer)
-    bpy.app.handlers.render_post.remove(end_timer)
-    bpy.app.handlers.render_cancel.append(unset_rendering)
-    bpy.app.handlers.render_complete.remove(unset_rendering)
-    bpy.types.IMAGE_PT_image_properties.remove(image_panel_rendertime)
-
-if __name__ == '__main__':
-    register()
diff --git a/release/scripts/addons_contrib/render_to_print.py b/release/scripts/addons_contrib/render_to_print.py
deleted file mode 100644
index d1475f8..0000000
--- a/release/scripts/addons_contrib/render_to_print.py
+++ /dev/null
@@ -1,346 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-    'name': 'Render to Print',
-    'author': 'Marco Crippa <thekrypt77 at tiscali.it>, Dealga McArdle',
-    'version': (0, 2),
-    'blender': (2, 5, 8),
-    'location': 'Render > Render to Print',
-    'description': 'Set the size of the render for a print',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\
-        'Scripts/Render/Render to Print',
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
-        'func=detail&aid=24219',
-    'category': 'Render'}
-
-
-import math
-import bpy
-from bpy.types import Panel, Operator, Scene, PropertyGroup
-from bpy.props import (IntProperty,
-                       FloatProperty,
-                       StringProperty,
-                       EnumProperty,
-                       PointerProperty,
-                       )
-
-
-paper_presets = (
-    ("custom_1_1", "custom", ""),
-    ("A0_84.1_118.9", "A0 (84.1x118.9 cm)", ""),
-    ("A1_59.4_84.1", "A1 (59.4x84.1 cm)", ""),
-    ("A2_42.0_59.4", "A2 (42.0x59.4 cm)", ""),
-    ("A3_29.7_42.0", "A3 (29.7 42.0 cm)", ""),
-    ("A4_21.0_29.7", "A4 (21.0x29.7 cm)", ""),
-    ("A5_14.8_21.0", "A5 (14.8x21.0 cm)", ""),
-    ("A6_10.5_14.8", "A6 (10.5x14.8 cm)", ""),
-    ("A7_7.4_10.5", "A7 (7.4x10.5 cm)", ""),
-    ("A8_5.2_7.4", "A8 (5.2x7.4 cm)", ""),
-    ("A9_3.7_5.2", "A9 (3.7x5.2 cm)", ""),
-    ("A10_2.6_3.7", "A10 (2.6x3.7 cm)", ""),
-
-    ("B0_100.0_141.4", "B0 (100.0x141.4 cm)", ""),
-    ("B1_70.7_100.0", "B1 (70.7x100.0 cm)", ""),
-    ("B2_50.0_70.7", "B2 (50.0x70.7 cm)", ""),
-    ("B3_35.3_50.0", "B3 (35.3x50.0 cm)", ""),
-    ("B4_25.0_35.3", "B4 (25.0x35.3 cm)", ""),
-    ("B5_17.6_25.0", "B5 (17.6x25.0 cm)", ""),
-    ("B6_12.5_17.6", "B6 (12.5x17.6 cm)", ""),
-    ("B7_8.8_12.5", "B7 (8.8x12.5 cm)", ""),
-    ("B8_6.2_8.8", "B8 (6.2x8.8 cm)", ""),
-    ("B9_4.4_6.2", "B9 (4.4x6.2 cm)", ""),
-    ("B10_3.1_4.4", "B10 (3.1x4.4 cm)", ""),
-
-    ("C0_91.7_129.7", "C0 (91.7x129.7 cm)", ""),
-    ("C1_64.8_91.7", "C1 (64.8x91.7 cm)", ""),
-    ("C2_45.8_64.8", "C2 (45.8x64.8 cm)", ""),
-    ("C3_32.4_45.8", "C3 (32.4x45.8 cm)", ""),
-    ("C4_22.9_32.4", "C4 (22.9x32.4 cm)", ""),
-    ("C5_16.2_22.9", "C5 (16.2x22.9 cm)", ""),
-    ("C6_11.4_16.2", "C6 (11.4x16.2 cm)", ""),
-    ("C7_8.1_11.4", "C7 (8.1x11.4 cm)", ""),
-    ("C8_5.7_8.1", "C8 (5.7x8.1 cm)", ""),
-    ("C9_4.0_5.7", "C9 (4.0x5.7 cm)", ""),
-    ("C10_2.8_4.0", "C10 (2.8x4.0 cm)", ""),
-
-    ("Letter_21.6_27.9", "Letter (21.6x27.9 cm)", ""),
-    ("Legal_21.6_35.6", "Legal (21.6x35.6 cm)", ""),
-    ("Legal junior_20.3_12.7", "Legal junior (20.3x12.7 cm)", ""),
-    ("Ledger_43.2_27.9", "Ledger (43.2x27.9 cm)", ""),
-    ("Tabloid_27.9_43.2", "Tabloid (27.9x43.2 cm)", ""),
-
-    ("ANSI C_43.2_55.9", "ANSI C (43.2x55.9 cm)", ""),
-    ("ANSI D_55.9_86.4", "ANSI D (55.9x86.4 cm)", ""),
-    ("ANSI E_86.4_111.8", "ANSI E (86.4x111.8 cm)", ""),
-
-    ("Arch A_22.9_30.5", "Arch A (22.9x30.5 cm)", ""),
-    ("Arch B_30.5_45.7", "Arch B (30.5x45.7 cm)", ""),
-    ("Arch C_45.7_61.0", "Arch C (45.7x61.0 cm)", ""),
-    ("Arch D_61.0_91.4", "Arch D (61.0x91.4 cm)", ""),
-    ("Arch E_91.4_121.9", "Arch E (91.4x121.9 cm)", ""),
-    ("Arch E1_76.2_106.7", "Arch E1 (76.2x106.7 cm)", ""),
-    ("Arch E2_66.0_96.5", "Arch E2 (66.0x96.5 cm)", ""),
-    ("Arch E3_68.6_99.1", "Arch E3 (68.6x99.1 cm)", ""),
-    )
-
-
-def paper_enum_parse(idname):
-    tipo, dim_w, dim_h = idname.split("_")
-    return tipo, float(dim_w), float(dim_h)
-
-
-paper_presets_data = {idname: paper_enum_parse(idname)
-                      for idname, name, descr in paper_presets}
-
-
-def update_settings_cb(self, context):
-    # annoying workaround for recursive call
-    if update_settings_cb.level == False:
-        update_settings_cb.level = True
-        pixels_from_print(self)
-        update_settings_cb.level = False
-
-update_settings_cb.level = False
-
-
-class RenderPrintSertings(PropertyGroup):
-    unit_from = EnumProperty(
-            name="Set from",
-            description="Set from",
-            items=(
-                ("CM_TO_PIXELS", "CM -> Pixel", "Centermeters to Pixels"),
-                ("PIXELS_TO_CM", "Pixel -> CM", "Pixels to Centermeters")
-                ),
-            default="CM_TO_PIXELS",
-            )
-    orientation = EnumProperty(
-            name="Page Orientation",
-            description="Set orientation",
-            items=(
-                ("Portrait", "Portrait", "Portrait"),
-                ("Landscape", "Landscape", "Landscape")
-            ),
-            default="Portrait",
-            update=update_settings_cb,
-            )
-    preset = EnumProperty(
-            name="Select Preset",
-            description="Select from preset",
-            items=paper_presets,
-            default="custom_1_1",
-            update=update_settings_cb,
-            )
-    dpi = IntProperty(
-            name="DPI",
-            description="Dots per Inch",
-            default=300,
-            min=72, max=1800,
-            update=update_settings_cb,
-            )
-    width_cm = FloatProperty(
-            name="Width",
-            description="Width in CM",
-            default=5.0,
-            min=1.0, max=100000.0,
-            update=update_settings_cb,
-            )
-    height_cm = FloatProperty(
-            name="Height",
-            description="Height in CM",
-            default=3.0,
-            min=1.0, max=100000.0,
-            update=update_settings_cb,
-            )
-    width_px = IntProperty(
-            name="Pixel Width",
-            description="Pixel Width",
-            default=900,
-            min=4, max=10000,
-            update=update_settings_cb,
-            )
-    height_px = IntProperty(
-            name="Pixel Height",
-            description="Pixel Height",
-            default=600,
-            min=4, max=10000,
-            update=update_settings_cb,
-            )
-
-
-def pixels_from_print(ps):
-    tipo, dim_w, dim_h = paper_presets_data[ps.preset]
-
-    if ps.unit_from == "CM_TO_PIXELS":
-        if tipo == "custom":
-            dim_w = ps.width_cm
-            dim_h = ps.height_cm
-            ps.width_cm = dim_w
-            ps.height_cm = dim_h
-        elif tipo != "custom" and ps.orientation == "Landscape":
-            ps.width_cm = dim_h
-            ps.height_cm = dim_w
-        elif tipo != "custom" and ps.orientation == "Portrait":
-            ps.width_cm = dim_w
-            ps.height_cm = dim_h
-
-        ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54)
-        ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54)
-    else:
-        if tipo != "custom" and ps.orientation == "Landscape":
-            ps.width_cm = dim_h
-            ps.height_cm = dim_w
-            ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54)
-            ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54)
-        elif tipo != "custom" and ps.orientation == "Portrait":
-            ps.width_cm = dim_w
-            ps.height_cm = dim_h
-            ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54)
-            ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54)
-
-        ps.width_cm = (ps.width_px / ps.dpi) * 2.54
-        ps.height_cm = (ps.height_px / ps.dpi) * 2.54
-
-
-class RENDER_PT_print(Panel):
-    bl_label = "Render to Print"
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'render'
-
-    def draw(self, context):
-
-        layout = self.layout
-        scene = context.scene
-        ps = scene.print_settings
-
-        row = layout.row(align=True)
-        row1 = layout.row(align=True)
-        row2 = layout.row(align=True)
-        row3 = layout.row(align=True)
-        row4 = layout.row(align=True)
-        row5 = layout.row(align=True)
-        row6 = layout.row(align=True)
-        row7 = layout.row(align=True)
-        col = layout.column(align=True)
-
-        row.prop(ps, "unit_from")
-        row1.prop(ps, "orientation")
-        row2.prop(ps, "preset")
-
-        col.separator()
-        row3.prop(ps, "width_cm")
-        row3.separator()
-        row3.prop(ps, "height_cm")
-        col.separator()
-        row4.prop(ps, "dpi")
-        col.separator()
-        row5.prop(ps, "width_px")
-        row5.separator()
-        row5.prop(ps, "height_px")
-
-        col.separator()
-        row6.label("Inch Width: %.2f" % (ps.width_cm / 2.54))
-        row6.label("Inch Height: %.2f" % (ps.height_cm / 2.54))
-        col.separator()
-
-        row7.operator("render.apply_size", icon="RENDER_STILL")
-
-        #  this if else deals with hiding UI elements when logic demands it.
-        tipo = paper_presets_data[ps.preset][0]
-
-        if tipo != "custom":
-            row.active = False
-            row.enabled = False
-
-        if ps.unit_from == "CM_TO_PIXELS":
-            row5.active = False
-            row5.enabled = False
-
-            if tipo == "custom":
-                row3.active = True
-                row3.enabled = True
-                row1.active = False
-                row1.enabled = False
-            elif tipo != "custom" and ps.orientation == "Landscape":
-                row3.active = False
-                row3.enabled = False
-                row1.active = True
-                row1.enabled = True
-            elif tipo != "custom" and ps.orientation == "Portrait":
-                row3.active = False
-                row3.enabled = False
-                row1.active = True
-                row1.enabled = True
-        else:
-            row3.active = False
-            row3.enabled = False
-
-            if tipo == "custom":
-                row1.active = False
-                row1.enabled = False
-            elif tipo != "custom" and ps.orientation == "Landscape":
-                row1.active = True
-                row1.enabled = True
-                row5.active = False
-                row5.enabled = False
-            elif tipo != "custom" and ps.orientation == "Portrait":
-                row1.active = True
-                row1.enabled = True
-                row5.active = False
-                row5.enabled = False
-
-
-class RENDER_OT_apply_size(Operator):
-    bl_idname = "render.apply_size"
-    bl_label = "Apply Print to Render"
-    bl_description = "Set the render dimension"
-
-    def execute(self, context):
-
-        scene = context.scene
-        ps = scene.print_settings
-
-        pixels_from_print(ps)
-
-        render = scene.render
-        render.resolution_x = ps.width_px
-        render.resolution_y = ps.height_px
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(RENDER_OT_apply_size)
-    bpy.utils.register_class(RENDER_PT_print)
-    bpy.utils.register_class(RenderPrintSertings)
-
-    Scene.print_settings = PointerProperty(type=RenderPrintSertings)
-
-
-def unregister():
-    bpy.utils.unregister_class(RENDER_OT_apply_size)
-    bpy.utils.unregister_class(RENDER_PT_print)
-    bpy.utils.unregister_class(RenderPrintSertings)
-    del Scene.print_settings
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py b/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py
deleted file mode 100644
index 8b3288c..0000000
--- a/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py
+++ /dev/null
@@ -1,245 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    'name': "Surround Projection Tools",
-    'author': "Cole Ingraham",
-    'location': "View3D > Tool Shelf > Surround Projection panel",
-    'description': "Setup cameras and create rendering scenes for n-screen surround projection.",
-    'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Surround_Projection_Tools",
-    'version': (0,1,2),
-    'blender': (2, 6, 0),
-    'category': '3D View'
-}
-
-import bpy
-from bpy.props import IntProperty
-from bpy.props import BoolProperty
-from math import pi
-import re
-
-CAMERA_ORIGIN_NAME = "CameraOrigin"
-
-# property for how many screens to add
-bpy.types.WindowManager.num_surround_screens = IntProperty(
-    name="Number of screens",
-    description="How many screens to add",
-    default=4,
-    min=3)
-
-# safeguard for removing previous cameras/scenes
-bpy.types.WindowManager.previous_num_surround_screens = IntProperty(
-    name="Previous number of screens",
-    description="used for removing cameras/scenes",
-    default=-1)
-
-# used to enable/disable make/remove scenes and cameras
-bpy.types.WindowManager.surround_screens_init = BoolProperty(
-    name="SurroundScenesInit",
-    default=False)
-
-# GUI panel
-class AddSurroundCamerasPanel(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_label = "Surround Projection"
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-
-        row = col.row()
-        row.prop(context.window_manager, "num_surround_screens")
-        row = col.row()
-        
-        if context.window_manager.previous_num_surround_screens is not -1:
-             row.operator('objects.remove_surround_cameras', icon='X')
-        else:
-             row.operator('objects.add_surround_cameras', icon='CAMERA_DATA')
-        
-        row = col.row()
-        
-        if context.window_manager.surround_screens_init is True:
-             row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
-        else:
-             row.operator('scene.add_linked_scenes_for_surround_cameras', icon='SCENE_DATA')
-
-        #col = layout.column(align=True)
-        #row = col.row()
-        #row.operator('objects.remove_surround_cameras', icon='X')
-        #row = col.row()
-        #row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
-
-
-# operator for adding cameras
-class AddSurroundCamerasOperator(bpy.types.Operator):
-    bl_idname = 'objects.add_surround_cameras'
-    bl_label = "Add Cameras"
-    bl_description = "Add n cameras"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        return context.window_manager.previous_num_surround_screens is -1
-
-    def execute(self, context):
-
-        scene = context.scene
-        numScreens = context.window_manager.num_surround_screens
-
-        # add an empty for the camera origin if not already present
-        obj_origin = scene.objects.get(CAMERA_ORIGIN_NAME)
-        if not obj_origin:
-            bpy.ops.object.add()
-            obj_origin = context.active_object
-            obj_origin.name = CAMERA_ORIGIN_NAME
-            obj_origin.location = scene.cursor_location
-
-        for i in range(0,numScreens):
-
-            # add a new camer
-            bpy.ops.object.camera_add()
-
-            # get the current camera
-            cam = context.active_object
-
-            # name the camera
-            cameraName = "Camera" + str(i)
-            cam.name = cameraName
-            cam.data.name = cameraName
-
-            # position camera
-            cam.location = 0,0,0
-            cam.rotation_euler = (pi/2), 0, ((-2*pi)/numScreens) * i
-
-            # set the field of view angle
-            cam.data.angle = (2*pi)/numScreens
-
-            # make the parent of the camera the origin
-            cam.parent = obj_origin
-
-        # sel/activate origin
-        bpy.ops.object.select_all(action='DESELECT')
-        obj_origin.select = True
-        scene.objects.active = obj_origin
-
-        context.window_manager.previous_num_surround_screens = numScreens
-        return {'FINISHED'}
-
-
-# operator for creating new linked scenes for each camera
-class AddSurroundScenesOperator(bpy.types.Operator):
-    bl_idname = 'scene.add_linked_scenes_for_surround_cameras'
-    bl_label = "Make Scenes"
-    bl_description = "Creates new scenes with linked object data for each camera"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
-            return True
-        return False
-
-    def execute(self, context):
-        scene_base = context.scene
-        numScreens = context.window_manager.previous_num_surround_screens
-        sceneName = scene_base.name
-        renderpath = scene_base.render.filepath
-
-        for i in range(0, numScreens):
-
-            thisScene = sceneName + "-Camera" + str(i)
-
-            bpy.ops.scene.new(type='EMPTY')
-            scene_new = context.scene
-            scene_new.name = thisScene
-
-            camera_object = bpy.data.objects["Camera" + str(i)]
-            scene_new.camera = camera_object
-            scene_new.background_set = scene_base
-            
-            # not essential but nice to have the camera in the scene
-            scene_new.objects.link(camera_object)
-
-            scene_new.render.filepath = renderpath + thisScene
-
-        context.screen.scene = scene_base
-        context.window_manager.surround_screens_init = True
-        return {'FINISHED'}
-
-
-# operator for removing the surround scenes
-class RemoveSurroundScenesOperator(bpy.types.Operator):
-    bl_idname = 'objects.remove_linked_scenes_for_surround_cameras'
-    bl_label = "Remove Scenes"
-    bl_description = "Removes all surround scenes"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        return context.window_manager.surround_screens_init is True
-
-    def execute(self, context):
-        numScreens = context.window_manager.previous_num_surround_screens
-
-        for scene in list(bpy.data.scenes):
-            if re.search("-Camera",scene.name):
-                bpy.data.scenes.remove(scene)
-
-        context.window_manager.surround_screens_init = False
-        return {'FINISHED'}
-
-
-# operator for removing the surround cameras/scenes
-class RemoveSurroundCamerasOperator(bpy.types.Operator):
-    bl_idname = 'objects.remove_surround_cameras'
-    bl_label = "Remove Cameras"
-    bl_description = "Removes all surround cameras"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
-            return True
-        return False
-
-    def execute(self, context):
-
-        scene = context.scene
-
-        # XXX. shouldnt there be some less general way to do this?
-        # like check if they are the child of origin? - campbell
-        for obj in scene.objects[:]:
-            if obj.type == 'CAMERA':
-                scene.objects.unlink(obj)
-
-        context.window_manager.previous_num_surround_screens = -1
-        return {'FINISHED'}
-
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py b/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py
deleted file mode 100644
index e79df1f..0000000
--- a/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py
+++ /dev/null
@@ -1,5291 +0,0 @@
-#  ***** BEGIN GPL LICENSE BLOCK *****
-#
-#  This program is free software: you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
-#
-#  ***** END GPL LICENSE BLOCK *****
-
-# <pep8-80 compliant>
-
-bl_info = {
-    "name": "Enhanced 3D Cursor",
-    "description": "Cursor history and bookmarks; drag/snap cursor.",
-    "author": "dairin0d",
-    "version": (2, 8, 5),
-    "blender": (2, 6, 3),
-    "location": "View3D > Action mouse; F10; Properties panel",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/3D_interaction/Enhanced_3D_Cursor",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=28451",
-    "category": "3D View"}
-#============================================================================#
-
-"""
-ATTENTION:
-somewhere around 45447 revision object.ray_cast() starts conflicting with
-mesh.update(calc_tessface=True) -- at least when invoked within one
-operator cycle, object.ray_cast() crashes if object's tessfaces were
-update()d earlier in the code. However, not update()ing the meshes
-seems to work fine -- ray_cast() does its job, and it's possible to
-access tessfaces afterwards.
-mesh.calc_tessface() -- ? crashes too
-
-Seems like now axes are stored in columns instead of rows.
-Perhaps it's better to write utility functions to create/decompose
-matrices from/to 3D-vector axes and a translation component
-
-Breakdown:
-    Addon registration
-    Keymap utils
-    Various utils (e.g. find_region)
-    OpenGL; drawing utils
-    Non-undoable data storage
-    Cursor utils
-    Stick-object
-    Cursor monitor
-    Addon's GUI
-    Addon's properties
-    Addon's operators
-    ID Block emulator
-    Mesh cache
-    Snap utils
-    View3D utils
-    Transform orientation / coordinate system utils
-    Generic transform utils
-    Main operator
-    ...
-.
-
-First step is to re-make the cursor addon (make something usable first).
-CAD tools should be done without the hassle.
-
-TODO:
-    strip trailing space? (one of campbellbarton's commits did that)
-    
-    IDEAS:
-        - implement 'GIMBAL' orientation (euler axes)
-        - mini-Z-buffer in the vicinity of mouse coords (using raycasts)
-        - an orientation that points towards cursor
-          (from current selection to cursor)
-        - user coordinate systems (using e.g. empties to store different
-          systems; when user switches to such UCS, origin will be set to
-          "cursor", cursor will be sticked to the empty, and a custom
-          transform orientation will be aligned with the empty)
-          - "Stick" transform orientation that is always aligned with the
-            object cursor is "sticked" to?
-        - make 'NORMAL' system also work for bones?
-        - user preferences? (stored in a file)
-        - create spline/edge_mesh from history?
-        - API to access history/bookmarks/operators from other scripts?
-        - Snap selection to bookmark?
-        - Optimize
-        - Clean up code, move to several files?
-    LATER:
-    ISSUES:
-        Limitations:
-            - I need to emulate in Python some things that Blender doesn't
-              currently expose through API:
-              - obtaining matrix of predefined transform orientation
-              - obtaining position of pivot
-              For some kinds of information (e.g. active vertex/edge,
-              selected meta-elements), there is simply no workaround.
-            - Snapping to vertices/edges works differently than in Blender.
-              First of all, iteration over all vertices/edges of all
-              objects along the ray is likely to be very slow.
-              Second, it's more human-friendly to snap to visible
-              elements (or at least with approximately known position).
-            - In editmode I have to exit-and-enter it to get relevant
-              information about current selection. Thus any operator
-              would automatically get applied when you click on 3D View.
-        Mites:
-    QUESTIONS:
-==============================================================================
-Borrowed code/logic:
-- space_view3d_panel_measure.py (Buerbaum Martin "Pontiac"):
-  - OpenGL state storing/restoring; working with projection matrices.
-"""
-
-import bpy
-import bgl
-import blf
-import bmesh
-
-from mathutils import Vector, Matrix, Quaternion, Euler
-
-from mathutils.geometry import (intersect_line_sphere,
-                                intersect_ray_tri,
-                                barycentric_transform,
-                                tessellate_polygon,
-                                intersect_line_line,
-                                intersect_line_plane,
-                                )
-
-from bpy_extras.view3d_utils import (region_2d_to_vector_3d,
-                                     region_2d_to_location_3d,
-                                     location_3d_to_region_2d,
-                                     )
-
-import math
-import time
-
-# ====== MODULE GLOBALS / CONSTANTS ====== #
-tmp_name = chr(0x10ffff) # maximal Unicode value
-epsilon = 0.000001
-
-# ====== SET CURSOR OPERATOR ====== #
-class EnhancedSetCursor(bpy.types.Operator):
-    """Cursor history and bookmarks; drag/snap cursor."""
-    bl_idname = "view3d.cursor3d_enhanced"
-    bl_label = "Enhanced Set Cursor"
-    
-    key_char_map = {
-        'PERIOD':".", 'NUMPAD_PERIOD':".",
-        'MINUS':"-", 'NUMPAD_MINUS':"-",
-        'EQUAL':"+", 'NUMPAD_PLUS':"+",
-        #'E':"e", # such big/small numbers aren't useful
-        'ONE':"1", 'NUMPAD_1':"1",
-        'TWO':"2", 'NUMPAD_2':"2",
-        'THREE':"3", 'NUMPAD_3':"3",
-        'FOUR':"4", 'NUMPAD_4':"4",
-        'FIVE':"5", 'NUMPAD_5':"5",
-        'SIX':"6", 'NUMPAD_6':"6",
-        'SEVEN':"7", 'NUMPAD_7':"7",
-        'EIGHT':"8", 'NUMPAD_8':"8",
-        'NINE':"9", 'NUMPAD_9':"9",
-        'ZERO':"0", 'NUMPAD_0':"0",
-        'SPACE':" ",
-        'SLASH':"/", 'NUMPAD_SLASH':"/",
-        'NUMPAD_ASTERIX':"*",
-    }
-    
-    key_coordsys_map = {
-        'LEFT_BRACKET':-1,
-        'RIGHT_BRACKET':1,
-        'J':'VIEW',
-        'K':"Surface",
-        'L':'LOCAL',
-        'B':'GLOBAL',
-        'N':'NORMAL',
-        'M':"Scaled",
-    }
-    
-    key_pivot_map = {
-        'H':'ACTIVE',
-        'U':'CURSOR',
-        'I':'INDIVIDUAL',
-        'O':'CENTER',
-        'P':'MEDIAN',
-    }
-    
-    key_snap_map = {
-        'C':'INCREMENT',
-        'V':'VERTEX',
-        'E':'EDGE',
-        'F':'FACE',
-    }
-    
-    key_tfm_mode_map = {
-        'G':'MOVE',
-        'R':'ROTATE',
-        'S':'SCALE',
-    }
-    
-    key_map = {
-        "confirm":{'ACTIONMOUSE'}, # also 'RET' ?
-        "cancel":{'SELECTMOUSE', 'ESC'},
-        "free_mouse":{'F10'},
-        "make_normal_snapshot":{'W'},
-        "make_tangential_snapshot":{'Q'},
-        "use_absolute_coords":{'A'},
-        "snap_to_raw_mesh":{'D'},
-        "use_object_centers":{'T'},
-        "precision_up":{'PAGE_UP'},
-        "precision_down":{'PAGE_DOWN'},
-        "move_caret_prev":{'LEFT_ARROW'},
-        "move_caret_next":{'RIGHT_ARROW'},
-        "move_caret_home":{'HOME'},
-        "move_caret_end":{'END'},
-        "change_current_axis":{'TAB', 'RET', 'NUMPAD_ENTER'},
-        "prev_axis":{'UP_ARROW'},
-        "next_axis":{'DOWN_ARROW'},
-        "remove_next_character":{'DEL'},
-        "remove_last_character":{'BACK_SPACE'},
-        "copy_axes":{'C'},
-        "paste_axes":{'V'},
-        "cut_axes":{'X'},
-    }
-    
-    gizmo_factor = 0.15
-    click_period = 0.25
-    
-    angle_grid_steps = {True:1.0, False:5.0}
-    scale_grid_steps = {True:0.01, False:0.1}
-    
-    # ====== OPERATOR METHOD OVERLOADS ====== #
-    @classmethod
-    def poll(cls, context):
-        area_types = {'VIEW_3D',} # also: IMAGE_EDITOR ?
-        return (context.area.type in area_types) and \
-               (context.region.type == "WINDOW")
-    
-    def modal(self, context, event):
-        context.area.tag_redraw()
-        return self.try_process_input(context, event)
-    
-    def invoke(self, context, event):
-        # Attempt to launch the monitor
-        if bpy.ops.view3d.cursor3d_monitor.poll():
-            bpy.ops.view3d.cursor3d_monitor()
-        
-        # Don't interfere with these modes when only mouse is pressed
-        if ('SCULPT' in context.mode) or ('PAINT' in context.mode):
-            if "MOUSE" in event.type:
-                return {'CANCELLED'}
-        
-        CursorDynamicSettings.active_transform_operator = self
-        
-        tool_settings = context.tool_settings
-        
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        settings_scene = context.scene.cursor_3d_tools_settings
-        
-        self.setup_keymaps(context)
-        
-        # Coordinate System Utility
-        self.particles, self.csu = gather_particles(context=context)
-        self.particles = [View3D_Cursor(context)]
-        
-        self.csu.source_pos = self.particles[0].get_location()
-        self.csu.source_rot = self.particles[0].get_rotation()
-        self.csu.source_scale = self.particles[0].get_scale()
-        
-        # View3D Utility
-        self.vu = ViewUtility(context.region, context.space_data,
-            context.region_data)
-        
-        # Snap Utility
-        self.su = SnapUtility(context)
-        
-        # turn off view locking for the duration of the operator
-        self.view_pos = self.vu.get_position(True)
-        self.vu.set_position(self.vu.get_position(), True)
-        self.view_locks = self.vu.get_locks()
-        self.vu.set_locks({})
-        
-        # Initialize runtime states
-        self.initiated_by_mouse = ("MOUSE" in event.type)
-        self.free_mouse = not self.initiated_by_mouse
-        self.use_object_centers = False
-        self.axes_values = ["", "", ""]
-        self.axes_coords = [None, None, None]
-        self.axes_eval_success = [True, True, True]
-        self.allowed_axes = [True, True, True]
-        self.current_axis = 0
-        self.caret_pos = 0
-        self.coord_format = "{:." + str(settings.free_coord_precision) + "f}"
-        self.transform_mode = 'MOVE'
-        self.init_xy_angle_distance(context, event)
-        
-        self.click_start = time.time()
-        if not self.initiated_by_mouse:
-            self.click_start -= self.click_period
-        
-        self.stick_obj_name = settings_scene.stick_obj_name
-        self.stick_obj_pos = settings_scene.stick_obj_pos
-        
-        # Initial run
-        self.try_process_input(context, event, True)
-        
-        context.window_manager.modal_handler_add(self)
-        return {'RUNNING_MODAL'}
-    
-    def cancel(self, context):
-        for particle in self.particles:
-            particle.revert()
-        
-        set_stick_obj(context.scene, self.stick_obj_name, self.stick_obj_pos)
-        
-        self.finalize(context)
-        return {'CANCELLED'}
-    
-    # ====== CLEANUP/FINALIZE ====== #
-    def finalize(self, context):
-        # restore view locking
-        self.vu.set_locks(self.view_locks)
-        self.vu.set_position(self.view_pos, True)
-        
-        self.cleanup(context)
-        
-        # This is to avoid "blinking" of
-        # between-history-positions line
-        settings = find_settings()
-        history = settings.history
-        # make sure the most recent history entry is displayed
-        history.curr_id = 0
-        history.last_id = 0
-        
-        # Ensure there are no leftovers from draw_callback
-        context.area.tag_redraw()
-        
-        return {'FINISHED'}
-    
-    def cleanup(self, context):
-        self.particles = None
-        self.csu = None
-        self.vu = None
-        if self.su is not None:
-            self.su.dispose()
-        self.su = None
-        
-        CursorDynamicSettings.active_transform_operator = None
-    
-    # ====== USER INPUT PROCESSING ====== #
-    def setup_keymaps(self, context):
-        self.key_map = self.key_map.copy()
-        
-        # There is no such event as 'ACTIONMOUSE',
-        # it's always 'LEFTMOUSE' or 'RIGHTMOUSE'
-        select_mouse = context.user_preferences.inputs.select_mouse
-        if select_mouse == 'RIGHT':
-            self.key_map["confirm"] = {'LEFTMOUSE'}
-            self.key_map["cancel"] = {'RIGHTMOUSE', 'ESC'}
-        else:
-            self.key_map["confirm"] = {'RIGHTMOUSE'}
-            self.key_map["cancel"] = {'LEFTMOUSE', 'ESC'}
-        
-        # Use user-defined "free mouse" key, if it exists
-        wm = context.window_manager
-        if '3D View' in wm.keyconfigs.user.keymaps:
-            km = wm.keyconfigs.user.keymaps['3D View']
-            for kmi in km.keymap_items:
-                if kmi.idname == 'view3d.cursor3d_enhanced':
-                    if kmi.map_type == 'KEYBOARD':
-                        self.key_map["free_mouse"] = {kmi.type,}
-                        break
-    
-    def try_process_input(self, context, event, initial_run=False):
-        try:
-            return self.process_input(context, event, initial_run)
-        except:
-            # If anything fails, at least dispose the resources
-            self.cleanup(context)
-            raise
-    
-    def process_input(self, context, event, initial_run=False):
-        wm = context.window_manager
-        v3d = context.space_data
-        
-        if event.type in self.key_map["confirm"]:
-            if self.free_mouse:
-                finished = (event.value == 'PRESS')
-            else:
-                finished = (event.value == 'RELEASE')
-            
-            if finished:
-                return self.finalize(context)
-        
-        if event.type in self.key_map["cancel"]:
-            return self.cancel(context)
-        
-        tool_settings = context.tool_settings
-        
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        make_snapshot = False
-        tangential_snapshot = False
-        
-        if event.value == 'PRESS':
-            if event.type in self.key_map["free_mouse"]:
-                if self.free_mouse and (not initial_run):
-                    # confirm if pressed second time
-                    return self.finalize(context)
-                else:
-                    self.free_mouse = True
-            
-            if event.type in self.key_tfm_mode_map:
-                new_mode = self.key_tfm_mode_map[event.type]
-                
-                if self.transform_mode != new_mode:
-                    # snap cursor to its initial state
-                    if new_mode != 'MOVE':
-                        for particle in self.particles:
-                            initial_matrix = particle.get_initial_matrix()
-                            particle.set_matrix(initial_matrix)
-                    # reset intial mouse position
-                    self.init_xy_angle_distance(context, event)
-                
-                self.transform_mode = new_mode
-            
-            if event.type in self.key_map["make_normal_snapshot"]:
-                make_snapshot = True
-                tangential_snapshot = False
-            
-            if event.type in self.key_map["make_tangential_snapshot"]:
-                make_snapshot = True
-                tangential_snapshot = True
-            
-            if event.type in self.key_map["snap_to_raw_mesh"]:
-                tool_settings.use_snap_self = \
-                    not tool_settings.use_snap_self
-            
-            if (not event.alt) and (event.type in {'X', 'Y', 'Z'}):
-                axis_lock = [(event.type == 'X') != event.shift,
-                             (event.type == 'Y') != event.shift,
-                             (event.type == 'Z') != event.shift]
-                
-                if self.allowed_axes != axis_lock:
-                    self.allowed_axes = axis_lock
-                else:
-                    self.allowed_axes = [True, True, True]
-            
-            if event.type in self.key_map["use_absolute_coords"]:
-                tfm_opts.use_relative_coords = \
-                    not tfm_opts.use_relative_coords
-                
-                self.update_origin_projection(context)
-            
-            incr = 0
-            if event.type in self.key_map["change_current_axis"]:
-                incr = (-1 if event.shift else 1)
-            elif event.type in self.key_map["next_axis"]:
-                incr = 1
-            elif event.type in self.key_map["prev_axis"]:
-                incr = -1
-            
-            if incr != 0:
-                self.current_axis = (self.current_axis + incr) % 3
-                self.caret_pos = len(self.axes_values[self.current_axis])
-            
-            incr = 0
-            if event.type in self.key_map["precision_up"]:
-                incr = 1
-            elif event.type in self.key_map["precision_down"]:
-                incr = -1
-            
-            if incr != 0:
-                settings.free_coord_precision += incr
-                self.coord_format = "{:." + \
-                    str(settings.free_coord_precision) + "f}"
-            
-            if (event.type == 'ZERO') and event.ctrl:
-                self.snap_to_system_origin()
-            else:
-                self.process_axis_input(event)
-            
-            if event.alt:
-                jc = (", " if tfm_opts.use_comma_separator else "\t")
-                if event.type in self.key_map["copy_axes"]:
-                    wm.clipboard = jc.join(self.get_axes_text(True))
-                elif event.type in self.key_map["cut_axes"]:
-                    wm.clipboard = jc.join(self.get_axes_text(True))
-                    self.set_axes_text("\t\t\t")
-                elif event.type in self.key_map["paste_axes"]:
-                    if jc == "\t":
-                        self.set_axes_text(wm.clipboard, True)
-                    else:
-                        jc = jc.strip()
-                        ttext = ""
-                        brackets = 0
-                        for c in wm.clipboard:
-                            if c in "[{(":
-                                brackets += 1
-                            elif c in "]})":
-                                brackets -= 1
-                            if (brackets == 0) and (c == jc):
-                                c = "\t"
-                            ttext += c
-                        self.set_axes_text(ttext, True)
-            
-            if event.type in self.key_coordsys_map:
-                new_orientation = self.key_coordsys_map[event.type]
-                self.csu.set_orientation(new_orientation)
-                
-                self.update_origin_projection(context)
-                
-                if event.ctrl:
-                    self.snap_to_system_origin()
-            
-            if event.type in self.key_map["use_object_centers"]:
-                v3d.use_pivot_point_align = not v3d.use_pivot_point_align
-            
-            if event.type in self.key_pivot_map:
-                self.csu.set_pivot(self.key_pivot_map[event.type])
-                
-                self.update_origin_projection(context)
-                
-                if event.ctrl:
-                    self.snap_to_system_origin(force_pivot=True)
-            
-            if (not event.alt) and (event.type in self.key_snap_map):
-                snap_element = self.key_snap_map[event.type]
-                if tool_settings.snap_element == snap_element:
-                    if snap_element == 'VERTEX':
-                        snap_element = 'VOLUME'
-                    elif snap_element == 'VOLUME':
-                        snap_element = 'VERTEX'
-                tool_settings.snap_element = snap_element
-        # end if
-        
-        if initial_run or (('MOVE' not in event.type) and \
-                ('TIMER' not in event.type)):
-            use_snap = (tool_settings.use_snap != event.ctrl)
-            if use_snap:
-                snap_type = tool_settings.snap_element
-            else:
-                snap_type = None
-            
-            axes_coords = [None, None, None]
-            if self.transform_mode == 'MOVE':
-                for i in range(3):
-                    if self.axes_coords[i] is not None:
-                        axes_coords[i] = self.axes_coords[i]
-                    elif not self.allowed_axes[i]:
-                        axes_coords[i] = 0.0
-            
-            self.su.set_modes(
-                interpolation=tfm_opts.snap_interpolate_normals_mode,
-                use_relative_coords=tfm_opts.use_relative_coords,
-                editmode=tool_settings.use_snap_self,
-                snap_type=snap_type,
-                snap_align=tool_settings.use_snap_align_rotation,
-                axes_coords=axes_coords,
-                )
-        
-        self.do_raycast = ("MOUSE" in event.type)
-        self.grid_substep = event.shift
-        self.modify_surface_orientation = (len(self.particles) == 1)
-        self.xy = Vector((event.mouse_region_x, event.mouse_region_y))
-        
-        self.use_object_centers = v3d.use_pivot_point_align
-        
-        if event.type == 'MOUSEMOVE':
-            self.update_transform_mousemove()
-        
-        if self.transform_mode == 'MOVE':
-            transform_func = self.transform_move
-        elif self.transform_mode == 'ROTATE':
-            transform_func = self.transform_rotate
-        elif self.transform_mode == 'SCALE':
-            transform_func = self.transform_scale
-        
-        for particle in self.particles:
-            transform_func(particle)
-        
-        if make_snapshot:
-            self.make_normal_snapshot(context.scene, tangential_snapshot)
-        
-        return {'RUNNING_MODAL'}
-    
-    def update_origin_projection(self, context):
-        r = context.region
-        rv3d = context.region_data
-        
-        origin = self.csu.get_origin()
-        # prehaps not projection, but intersection with plane?
-        self.origin_xy = location_3d_to_region_2d(r, rv3d, origin)
-        if self.origin_xy is None:
-            self.origin_xy = Vector((r.width / 2, r.height / 2))
-        
-        self.delta_xy = (self.start_xy - self.origin_xy).to_3d()
-        self.prev_delta_xy = self.delta_xy
-    
-    def init_xy_angle_distance(self, context, event):
-        self.start_xy = Vector((event.mouse_region_x, event.mouse_region_y))
-        
-        self.update_origin_projection(context)
-        
-        # Distinction between angles has to be made because
-        # angles can go beyond 360 degrees (we cannot snap
-        # to increment the original ones).
-        self.raw_angles = [0.0, 0.0, 0.0]
-        self.angles = [0.0, 0.0, 0.0]
-        self.scales = [1.0, 1.0, 1.0]
-    
-    def update_transform_mousemove(self):
-        delta_xy = (self.xy - self.origin_xy).to_3d()
-        
-        n_axes = sum(int(v) for v in self.allowed_axes)
-        if n_axes == 1:
-            # rotate using angle as value
-            rd = self.prev_delta_xy.rotation_difference(delta_xy)
-            offset = -rd.angle * round(rd.axis[2])
-            
-            sys_matrix = self.csu.get_matrix()
-            
-            i_allowed = 0
-            for i in range(3):
-                if self.allowed_axes[i]:
-                    i_allowed = i
-            
-            view_dir = self.vu.get_direction()
-            if view_dir.dot(sys_matrix[i_allowed][:3]) < 0:
-                offset = -offset
-            
-            for i in range(3):
-                if self.allowed_axes[i]:
-                    self.raw_angles[i] += offset
-        elif n_axes == 2:
-            # rotate using XY coords as two values
-            offset = (delta_xy - self.prev_delta_xy) * (math.pi / 180.0)
-            
-            if self.grid_substep:
-                offset *= 0.1
-            else:
-                offset *= 0.5
-            
-            j = 0
-            for i in range(3):
-                if self.allowed_axes[i]:
-                    self.raw_angles[i] += offset[1 - j]
-                    j += 1
-        elif n_axes == 3:
-            # rotate around view direction
-            rd = self.prev_delta_xy.rotation_difference(delta_xy)
-            offset = -rd.angle * round(rd.axis[2])
-            
-            view_dir = self.vu.get_direction()
-            
-            sys_matrix = self.csu.get_matrix()
-            
-            try:
-                view_dir = sys_matrix.inverted().to_3x3() * view_dir
-            except:
-                # this is some degenerate system
-                pass
-            view_dir.normalize()
-            
-            rot = Matrix.Rotation(offset, 3, view_dir)
-            
-            matrix = Euler(self.raw_angles, 'XYZ').to_matrix()
-            matrix.rotate(rot)
-            
-            euler = matrix.to_euler('XYZ')
-            self.raw_angles[0] += clamp_angle(euler.x - self.raw_angles[0])
-            self.raw_angles[1] += clamp_angle(euler.y - self.raw_angles[1])
-            self.raw_angles[2] += clamp_angle(euler.z - self.raw_angles[2])
-        
-        scale = delta_xy.length / self.delta_xy.length
-        if self.delta_xy.dot(delta_xy) < 0:
-            scale *= -1
-        for i in range(3):
-            if self.allowed_axes[i]:
-                self.scales[i] = scale
-        
-        self.prev_delta_xy = delta_xy
-    
-    def transform_move(self, particle):
-        src_matrix = particle.get_matrix()
-        initial_matrix = particle.get_initial_matrix()
-        
-        matrix = self.su.snap(
-            self.xy, src_matrix, initial_matrix,
-            self.do_raycast, self.grid_substep,
-            self.vu, self.csu,
-            self.modify_surface_orientation,
-            self.use_object_centers)
-        
-        particle.set_matrix(matrix)
-    
-    def rotate_matrix(self, matrix):
-        sys_matrix = self.csu.get_matrix()
-        
-        try:
-            matrix = sys_matrix.inverted() * matrix
-        except:
-            # this is some degenerate system
-            pass
-        
-        # Blender's order of rotation [in local axes]
-        rotation_order = [2, 1, 0]
-        
-        # Seems that 4x4 matrix cannot be rotated using rotate() ?
-        sys_matrix3 = sys_matrix.to_3x3()
-        
-        for i in range(3):
-            j = rotation_order[i]
-            axis = sys_matrix3[j]
-            angle = self.angles[j]
-            
-            rot = angle_axis_to_quat(angle, axis)
-            # this seems to be buggy too
-            #rot = Matrix.Rotation(angle, 3, axis)
-            
-            sys_matrix3 = rot.to_matrix() * sys_matrix3
-            # sys_matrix3.rotate has a bug? or I don't understand how it works?
-            #sys_matrix3.rotate(rot)
-        
-        for i in range(3):
-            sys_matrix[i][:3] = sys_matrix3[i]
-        
-        matrix = sys_matrix * matrix
-        
-        return matrix
-    
-    def transform_rotate(self, particle):
-        grid_step = self.angle_grid_steps[self.grid_substep]
-        grid_step *= (math.pi / 180.0)
-        
-        for i in range(3):
-            if self.axes_values[i] and self.axes_eval_success[i]:
-                self.raw_angles[i] = self.axes_coords[i] * (math.pi / 180.0)
-            
-            self.angles[i] = self.raw_angles[i]
-        
-        if self.su.implementation.snap_type == 'INCREMENT':
-            for i in range(3):
-                self.angles[i] = round_step(self.angles[i], grid_step)
-        
-        initial_matrix = particle.get_initial_matrix()
-        matrix = self.rotate_matrix(initial_matrix)
-        
-        particle.set_matrix(matrix)
-    
-    def scale_matrix(self, matrix):
-        sys_matrix = self.csu.get_matrix()
-        
-        try:
-            matrix = sys_matrix.inverted() * matrix
-        except:
-            # this is some degenerate system
-            pass
-        
-        for i in range(3):
-            sys_matrix[i] *= self.scales[i]
-        
-        matrix = sys_matrix * matrix
-        
-        return matrix
-    
-    def transform_scale(self, particle):
-        grid_step = self.scale_grid_steps[self.grid_substep]
-        
-        for i in range(3):
-            if self.axes_values[i] and self.axes_eval_success[i]:
-                self.scales[i] = self.axes_coords[i]
-        
-        if self.su.implementation.snap_type == 'INCREMENT':
-            for i in range(3):
-                self.scales[i] = round_step(self.scales[i], grid_step)
-        
-        initial_matrix = particle.get_initial_matrix()
-        matrix = self.scale_matrix(initial_matrix)
-        
-        particle.set_matrix(matrix)
-    
-    def set_axis_input(self, axis_id, axis_val):
-        if axis_val == self.axes_values[axis_id]:
-            return
-        
-        self.axes_values[axis_id] = axis_val
-        
-        if len(axis_val) == 0:
-            self.axes_coords[axis_id] = None
-            self.axes_eval_success[axis_id] = True
-        else:
-            try:
-                #self.axes_coords[axis_id] = float(eval(axis_val, {}, {}))
-                self.axes_coords[axis_id] = \
-                    float(eval(axis_val, math.__dict__))
-                self.axes_eval_success[axis_id] = True
-            except:
-                self.axes_eval_success[axis_id] = False
-    
-    def snap_to_system_origin(self, force_pivot=False):
-        if self.transform_mode == 'MOVE':
-            pivot = self.csu.get_pivot_name(raw=force_pivot)
-            p = self.csu.get_origin(relative=False, pivot=pivot)
-            m = self.csu.get_matrix()
-            try:
-                p = m.inverted() * p
-            except:
-                # this is some degenerate system
-                pass
-            for i in range(3):
-                self.set_axis_input(i, str(p[i]))
-        elif self.transform_mode == 'ROTATE':
-            for i in range(3):
-                self.set_axis_input(i, "0")
-        elif self.transform_mode == 'SCALE':
-            for i in range(3):
-                self.set_axis_input(i, "1")
-    
-    def get_axes_values(self, as_string=False):
-        if self.transform_mode == 'MOVE':
-            localmat = CursorDynamicSettings.local_matrix
-            raw_axes = localmat.translation
-        elif self.transform_mode == 'ROTATE':
-            raw_axes = Vector(self.angles) * (180.0 / math.pi)
-        elif self.transform_mode == 'SCALE':
-            raw_axes = Vector(self.scales)
-        
-        axes_values = []
-        for i in range(3):
-            if as_string and self.axes_values[i]:
-                value = self.axes_values[i]
-            elif self.axes_eval_success[i] and \
-                    (self.axes_coords[i] is not None):
-                value = self.axes_coords[i]
-            else:
-                value = raw_axes[i]
-                if as_string:
-                    value = self.coord_format.format(value)
-            axes_values.append(value)
-        
-        return axes_values
-    
-    def get_axes_text(self, offset=False):
-        axes_values = self.get_axes_values(as_string=True)
-        
-        axes_text = []
-        for i in range(3):
-            j = i
-            if offset:
-                j = (i + self.current_axis) % 3
-            
-            axes_text.append(axes_values[j])
-        
-        return axes_text
-    
-    def set_axes_text(self, text, offset=False):
-        if "\n" in text:
-            text = text.replace("\r", "")
-        else:
-            text = text.replace("\r", "\n")
-        text = text.replace("\n", "\t")
-        #text = text.replace(",", ".") # ???
-        
-        axes_text = text.split("\t")
-        for i in range(min(len(axes_text), 3)):
-            j = i
-            if offset:
-                j = (i + self.current_axis) % 3
-            self.set_axis_input(j, axes_text[i])
-    
-    def process_axis_input(self, event):
-        axis_id = self.current_axis
-        axis_val = self.axes_values[axis_id]
-        
-        if event.type in self.key_map["remove_next_character"]:
-            if event.ctrl:
-                # clear all
-                for i in range(3):
-                    self.set_axis_input(i, "")
-                self.caret_pos = 0
-                return
-            else:
-                axis_val = axis_val[0:self.caret_pos] + \
-                           axis_val[self.caret_pos + 1:len(axis_val)]
-        elif event.type in self.key_map["remove_last_character"]:
-            if event.ctrl:
-                # clear current
-                axis_val = ""
-            else:
-                axis_val = axis_val[0:self.caret_pos - 1] + \
-                           axis_val[self.caret_pos:len(axis_val)]
-                self.caret_pos -= 1
-        elif event.type in self.key_map["move_caret_next"]:
-            self.caret_pos += 1
-            if event.ctrl:
-                snap_chars = ".-+*/%()"
-                i = self.caret_pos
-                while axis_val[i:i + 1] not in snap_chars:
-                    i += 1
-                self.caret_pos = i
-        elif event.type in self.key_map["move_caret_prev"]:
-            self.caret_pos -= 1
-            if event.ctrl:
-                snap_chars = ".-+*/%()"
-                i = self.caret_pos
-                while axis_val[i - 1:i] not in snap_chars:
-                    i -= 1
-                self.caret_pos = i
-        elif event.type in self.key_map["move_caret_home"]:
-            self.caret_pos = 0
-        elif event.type in self.key_map["move_caret_end"]:
-            self.caret_pos = len(axis_val)
-        elif event.type in self.key_char_map:
-            # Currently accessing event.ascii seems to crash Blender
-            c = self.key_char_map[event.type]
-            if event.shift:
-                if c == "8":
-                    c = "*"
-                elif c == "5":
-                    c = "%"
-                elif c == "9":
-                    c = "("
-                elif c == "0":
-                    c = ")"
-            axis_val = axis_val[0:self.caret_pos] + c + \
-                       axis_val[self.caret_pos:len(axis_val)]
-            self.caret_pos += 1
-        
-        self.caret_pos = min(max(self.caret_pos, 0), len(axis_val))
-        
-        self.set_axis_input(axis_id, axis_val)
-    
-    # ====== DRAWING ====== #
-    def gizmo_distance(self, pos):
-        rv3d = self.vu.region_data
-        if rv3d.view_perspective == 'ORTHO':
-            dist = rv3d.view_distance
-        else:
-            view_pos = self.vu.get_viewpoint()
-            view_dir = self.vu.get_direction()
-            dist = (pos - view_pos).dot(view_dir)
-        return dist
-    
-    def gizmo_scale(self, pos):
-        return self.gizmo_distance(pos) * self.gizmo_factor
-    
-    def check_v3d_local(self, context):
-        csu_v3d = self.csu.space_data
-        v3d = context.space_data
-        if csu_v3d.local_view:
-            return csu_v3d != v3d
-        return v3d.local_view
-    
-    def draw_3d(self, context):
-        if self.check_v3d_local(context):
-            return
-        
-        if time.time() < (self.click_start + self.click_period):
-            return
-        
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        initial_matrix = self.particles[0].get_initial_matrix()
-        
-        sys_matrix = self.csu.get_matrix()
-        if tfm_opts.use_relative_coords:
-            sys_matrix.translation = initial_matrix.translation.copy()
-        sys_origin = sys_matrix.to_translation()
-        dest_point = self.particles[0].get_location()
-        
-        if self.is_normal_visible():
-            p0, x, y, z, _x, _z = \
-                self.get_normal_params(tfm_opts, dest_point)
-            
-            # use theme colors?
-            #ThemeView3D.normal
-            #ThemeView3D.vertex_normal
-            
-            bgl.glDisable(bgl.GL_LINE_STIPPLE)
-            
-            if settings.draw_N:
-                bgl.glColor4f(0, 1, 1, 1)
-                draw_arrow(p0, _x, y, z) # Z (normal)
-            if settings.draw_T1:
-                bgl.glColor4f(1, 0, 1, 1)
-                draw_arrow(p0, y, _z, x) # X (1st tangential)
-            if settings.draw_T2:
-                bgl.glColor4f(1, 1, 0, 1)
-                draw_arrow(p0, _z, x, y) # Y (2nd tangential)
-            
-            bgl.glEnable(bgl.GL_BLEND)
-            bgl.glDisable(bgl.GL_DEPTH_TEST)
-            
-            if settings.draw_N:
-                bgl.glColor4f(0, 1, 1, 0.25)
-                draw_arrow(p0, _x, y, z) # Z (normal)
-            if settings.draw_T1:
-                bgl.glColor4f(1, 0, 1, 0.25)
-                draw_arrow(p0, y, _z, x) # X (1st tangential)
-            if settings.draw_T2:
-                bgl.glColor4f(1, 1, 0, 0.25)
-                draw_arrow(p0, _z, x, y) # Y (2nd tangential)
-        
-        if settings.draw_guides:
-            p0 = dest_point
-            try:
-                p00 = sys_matrix.inverted() * p0
-            except:
-                # this is some degenerate system
-                p00 = p0.copy()
-            
-            axes_line_params = [
-                (Vector((0, p00.y, p00.z)), (1, 0, 0)),
-                (Vector((p00.x, 0, p00.z)), (0, 1, 0)),
-                (Vector((p00.x, p00.y, 0)), (0, 0, 1)),
-            ]
-            
-            for i in range(3):
-                p1, color = axes_line_params[i]
-                p1 = sys_matrix * p1
-                constrained = (self.axes_coords[i] is not None) or \
-                    (not self.allowed_axes[i])
-                alpha = (0.25 if constrained else 1.0)
-                draw_line_hidden_depth(p0, p1, color, \
-                    alpha, alpha, False, True)
-            
-            # line from origin to cursor
-            p0 = sys_origin
-            p1 = dest_point
-            
-            bgl.glEnable(bgl.GL_LINE_STIPPLE)
-            bgl.glColor4f(1, 1, 0, 1)
-            
-            draw_line_hidden_depth(p0, p1, (1, 1, 0), 1.0, 0.5, True, True)
-        
-        if settings.draw_snap_elements:
-            sui = self.su.implementation
-            if sui.potential_snap_elements and (sui.snap_type == 'EDGE'):
-                bgl.glDisable(bgl.GL_LINE_STIPPLE)
-                
-                bgl.glEnable(bgl.GL_BLEND)
-                bgl.glDisable(bgl.GL_DEPTH_TEST)
-                
-                bgl.glLineWidth(2)
-                bgl.glColor4f(0, 0, 1, 0.5)
-                
-                bgl.glBegin(bgl.GL_LINE_LOOP)
-                for p in sui.potential_snap_elements:
-                    bgl.glVertex3f(p[0], p[1], p[2])
-                bgl.glEnd()
-            elif sui.potential_snap_elements and (sui.snap_type == 'FACE'):
-                bgl.glEnable(bgl.GL_BLEND)
-                bgl.glDisable(bgl.GL_DEPTH_TEST)
-                
-                bgl.glColor4f(0, 1, 0, 0.5)
-                
-                co = sui.potential_snap_elements
-                tris = tessellate_polygon([co])
-                bgl.glBegin(bgl.GL_TRIANGLES)
-                for tri in tris:
-                    for vi in tri:
-                        p = co[vi]
-                        bgl.glVertex3f(p[0], p[1], p[2])
-                bgl.glEnd()
-    
-    def draw_2d(self, context):
-        if self.check_v3d_local(context):
-            return
-        
-        r = context.region
-        rv3d = context.region_data
-        
-        settings = find_settings()
-        
-        if settings.draw_snap_elements:
-            sui = self.su.implementation
-            
-            snap_points = []
-            if sui.potential_snap_elements and \
-                    (sui.snap_type in {'VERTEX', 'VOLUME'}):
-                snap_points.extend(sui.potential_snap_elements)
-            if sui.extra_snap_points:
-                snap_points.extend(sui.extra_snap_points)
-            
-            if snap_points:
-                bgl.glEnable(bgl.GL_BLEND)
-                
-                bgl.glPointSize(5)
-                bgl.glColor4f(1, 0, 0, 0.5)
-                
-                bgl.glBegin(bgl.GL_POINTS)
-                for p in snap_points:
-                    p = location_3d_to_region_2d(r, rv3d, p)
-                    if p is not None:
-                        bgl.glVertex2f(p[0], p[1])
-                bgl.glEnd()
-                
-                bgl.glPointSize(1)
-        
-        if self.transform_mode == 'MOVE':
-            return
-        
-        bgl.glEnable(bgl.GL_LINE_STIPPLE)
-        
-        bgl.glLineWidth(1)
-        
-        bgl.glColor4f(0, 0, 0, 1)
-        draw_line_2d(self.origin_xy, self.xy)
-        
-        bgl.glDisable(bgl.GL_LINE_STIPPLE)
-        
-        line_width = 3
-        bgl.glLineWidth(line_width)
-        
-        L = 12.0
-        arrow_len = 6.0
-        arrow_width = 8.0
-        arrow_space = 5.0
-        
-        Lmax = arrow_space * 2 + L * 2 + line_width
-        
-        pos = self.xy.to_2d()
-        normal = self.prev_delta_xy.to_2d().normalized()
-        dist = self.prev_delta_xy.length
-        tangential = Vector((-normal[1], normal[0]))
-        
-        if self.transform_mode == 'ROTATE':
-            n_axes = sum(int(v) for v in self.allowed_axes)
-            if n_axes == 2:
-                bgl.glColor4f(0.4, 0.15, 0.15, 1)
-                for sgn in (-1, 1):
-                    n = sgn * Vector((0, 1))
-                    p0 = pos + arrow_space * n
-                    draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
-                
-                bgl.glColor4f(0.11, 0.51, 0.11, 1)
-                for sgn in (-1, 1):
-                    n = sgn * Vector((1, 0))
-                    p0 = pos + arrow_space * n
-                    draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
-            else:
-                bgl.glColor4f(0, 0, 0, 1)
-                for sgn in (-1, 1):
-                    n = sgn * tangential
-                    if dist < Lmax:
-                        n *= dist / Lmax
-                    p0 = pos + arrow_space * n
-                    draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
-        elif self.transform_mode == 'SCALE':
-            bgl.glColor4f(0, 0, 0, 1)
-            for sgn in (-1, 1):
-                n = sgn * normal
-                p0 = pos + arrow_space * n
-                draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
-        
-        bgl.glLineWidth(1)
-    
-    def draw_axes_coords(self, context, header_size):
-        if self.check_v3d_local(context):
-            return
-        
-        if time.time() < (self.click_start + self.click_period):
-            return
-        
-        v3d = context.space_data
-        
-        userprefs_view = context.user_preferences.view
-        
-        tool_settings = context.tool_settings
-        
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        localmat = CursorDynamicSettings.local_matrix
-        
-        font_id = 0 # default font
-        
-        font_size = 11
-        blf.size(font_id, font_size, 72) # font, point size, dpi
-        
-        tet = context.user_preferences.themes[0].text_editor
-        
-        # Prepare the table...
-        if self.transform_mode == 'MOVE':
-            axis_prefix = ("D" if tfm_opts.use_relative_coords else "")
-        elif self.transform_mode == 'SCALE':
-            axis_prefix = "S"
-        else:
-            axis_prefix = "R"
-        axis_names = ["X", "Y", "Z"]
-        
-        axis_cells = []
-        coord_cells = []
-        #caret_cell = TextCell("_", tet.cursor)
-        caret_cell = TextCell("|", tet.cursor)
-        
-        try:
-            axes_text = self.get_axes_text()
-            
-            for i in range(3):
-                color = tet.space.text
-                alpha = (1.0 if self.allowed_axes[i] else 0.5)
-                text = axis_prefix + axis_names[i] + " : "
-                axis_cells.append(TextCell(text, color, alpha))
-                
-                if self.axes_values[i]:
-                    if self.axes_eval_success[i]:
-                        color = tet.syntax_numbers
-                    else:
-                        color = tet.syntax_string
-                else:
-                    color = tet.space.text
-                text = axes_text[i]
-                coord_cells.append(TextCell(text, color))
-        except Exception as e:
-            print(e)
-        
-        mode_cells = []
-        
-        try:
-            snap_type = self.su.implementation.snap_type
-            if snap_type is None:
-                color = tet.space.text
-            elif (not self.use_object_centers) or \
-                    (snap_type == 'INCREMENT'):
-                color = tet.syntax_numbers
-            else:
-                color = tet.syntax_special
-            text = tool_settings.snap_element
-            if text == 'VOLUME':
-                text = "BBOX"
-            mode_cells.append(TextCell(text, color))
-            
-            if self.csu.tou.is_custom:
-                color = tet.space.text
-            else:
-                color = tet.syntax_builtin
-            text = self.csu.tou.get_title()
-            mode_cells.append(TextCell(text, color))
-            
-            color = tet.space.text
-            text = self.csu.get_pivot_name(raw=True)
-            if self.use_object_centers:
-                color = tet.syntax_special
-            mode_cells.append(TextCell(text, color))
-        except Exception as e:
-            print(e)
-        
-        hdr_w, hdr_h = header_size
-        
-        try:
-            xyz_x_start_min = 12
-            xyz_x_start = xyz_x_start_min
-            mode_x_start = 6
-            
-            mode_margin = 4
-            xyz_margin = 16
-            blend_margin = 32
-            
-            color = tet.space.back
-            bgl.glColor4f(color[0], color[1], color[2], 1.0)
-            draw_rect(0, 0, hdr_w, hdr_h)
-            
-            if tool_settings.use_snap_self:
-                x = hdr_w - mode_x_start
-                y = hdr_h / 2
-                cell = mode_cells[0]
-                x -= cell.w
-                y -= cell.h * 0.5
-                bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-                draw_rect(x, y, cell.w, cell.h, 1, True)
-            
-            x = hdr_w - mode_x_start
-            y = hdr_h / 2
-            for cell in mode_cells:
-                cell.draw(x, y, (1, 0.5))
-                x -= (cell.w + mode_margin)
-            
-            curr_axis_x_start = 0
-            curr_axis_x_end = 0
-            caret_x = 0
-            
-            xyz_width = 0
-            for i in range(3):
-                if i == self.current_axis:
-                    curr_axis_x_start = xyz_width
-                
-                xyz_width += axis_cells[i].w
-                
-                if i == self.current_axis:
-                    char_offset = 0
-                    if self.axes_values[i]:
-                        char_offset = blf.dimensions(font_id,
-                            coord_cells[i].text[:self.caret_pos])[0]
-                    caret_x = xyz_width + char_offset
-                
-                xyz_width += coord_cells[i].w
-                
-                if i == self.current_axis:
-                    curr_axis_x_end = xyz_width
-                
-                xyz_width += xyz_margin
-            
-            xyz_width = int(xyz_width)
-            xyz_width_ext = xyz_width + blend_margin
-            
-            offset = (xyz_x_start + curr_axis_x_end) - hdr_w
-            if offset > 0:
-                xyz_x_start -= offset
-            
-            offset = xyz_x_start_min - (xyz_x_start + curr_axis_x_start)
-            if offset > 0:
-                xyz_x_start += offset
-            
-            offset = (xyz_x_start + caret_x) - hdr_w
-            if offset > 0:
-                xyz_x_start -= offset
-            
-            # somewhy GL_BLEND should be set right here
-            # to actually draw the box with blending %)
-            # (perhaps due to text draw happened before)
-            bgl.glEnable(bgl.GL_BLEND)
-            bgl.glShadeModel(bgl.GL_SMOOTH)
-            gl_enable(bgl.GL_SMOOTH, True)
-            color = tet.space.back
-            bgl.glBegin(bgl.GL_TRIANGLE_STRIP)
-            bgl.glColor4f(color[0], color[1], color[2], 1.0)
-            bgl.glVertex2i(0, 0)
-            bgl.glVertex2i(0, hdr_h)
-            bgl.glVertex2i(xyz_width, 0)
-            bgl.glVertex2i(xyz_width, hdr_h)
-            bgl.glColor4f(color[0], color[1], color[2], 0.0)
-            bgl.glVertex2i(xyz_width_ext, 0)
-            bgl.glVertex2i(xyz_width_ext, hdr_h)
-            bgl.glEnd()
-            
-            x = xyz_x_start
-            y = hdr_h / 2
-            for i in range(3):
-                cell = axis_cells[i]
-                cell.draw(x, y, (0, 0.5))
-                x += cell.w
-                
-                cell = coord_cells[i]
-                cell.draw(x, y, (0, 0.5))
-                x += (cell.w + xyz_margin)
-            
-            caret_x -= blf.dimensions(font_id, caret_cell.text)[0] * 0.5
-            caret_cell.draw(xyz_x_start + caret_x, y, (0, 0.5))
-            
-            bgl.glEnable(bgl.GL_BLEND)
-            bgl.glShadeModel(bgl.GL_SMOOTH)
-            gl_enable(bgl.GL_SMOOTH, True)
-            color = tet.space.back
-            bgl.glBegin(bgl.GL_TRIANGLE_STRIP)
-            bgl.glColor4f(color[0], color[1], color[2], 1.0)
-            bgl.glVertex2i(0, 0)
-            bgl.glVertex2i(0, hdr_h)
-            bgl.glVertex2i(xyz_x_start_min, 0)
-            bgl.glColor4f(color[0], color[1], color[2], 0.0)
-            bgl.glVertex2i(xyz_x_start_min, hdr_h)
-            bgl.glEnd()
-            
-        except Exception as e:
-            print(e)
-        
-        return
-    
-    # ====== NORMAL SNAPSHOT ====== #
-    def is_normal_visible(self):
-        if self.csu.tou.get() == "Surface":
-            return True
-        
-        if self.use_object_centers:
-            return False
-        
-        return self.su.implementation.snap_type \
-            not in {None, 'INCREMENT', 'VOLUME'}
-    
-    def get_normal_params(self, tfm_opts, dest_point):
-        surf_matrix = self.csu.get_matrix("Surface")
-        if tfm_opts.use_relative_coords:
-            surf_origin = dest_point
-        else:
-            surf_origin = surf_matrix.to_translation()
-        
-        m3 = surf_matrix.to_3x3()
-        p0 = surf_origin
-        scl = self.gizmo_scale(p0)
-        
-        # Normal and tangential are not always orthogonal
-        # (e.g. when normal is interpolated)
-        x = (m3 * Vector((1, 0, 0))).normalized()
-        y = (m3 * Vector((0, 1, 0))).normalized()
-        z = (m3 * Vector((0, 0, 1))).normalized()
-        
-        _x = z.cross(y)
-        _z = y.cross(x)
-        
-        return p0, x * scl, y * scl, z * scl, _x * scl, _z * scl
-    
-    def make_normal_snapshot(self, scene, tangential=False):
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        dest_point = self.particles[0].get_location()
-        
-        if self.is_normal_visible():
-            p0, x, y, z, _x, _z = \
-                self.get_normal_params(tfm_opts, dest_point)
-            
-            snapshot = bpy.data.objects.new("normal_snapshot", None)
-            
-            if tangential:
-                m = MatrixCompose(_z, y, x, p0)
-            else:
-                m = MatrixCompose(_x, y, z, p0)
-            snapshot.matrix_world = m
-            
-            snapshot.empty_draw_type = 'SINGLE_ARROW'
-            #snapshot.empty_draw_type = 'ARROWS'
-            #snapshot.layers = [True] * 20 # ?
-            scene.objects.link(snapshot)
-#============================================================================#
-
-
-class Particle:
-    pass
-
-class View3D_Cursor(Particle):
-    def __init__(self, context):
-        assert context.space_data.type == 'VIEW_3D'
-        self.v3d = context.space_data
-        self.initial_pos = self.get_location()
-        self.initial_matrix = Matrix.Translation(self.initial_pos)
-    
-    def revert(self):
-        self.set_location(self.initial_pos)
-    
-    def get_location(self):
-        return get_cursor_location(v3d=self.v3d)
-    
-    def set_location(self, value):
-        set_cursor_location(Vector(value), v3d=self.v3d)
-    
-    def get_rotation(self):
-        return Quaternion()
-    
-    def set_rotation(self, value):
-        pass
-    
-    def get_scale(self):
-        return Vector((1.0, 1.0, 1.0))
-    
-    def set_scale(self, value):
-        pass
-    
-    def get_matrix(self):
-        return Matrix.Translation(self.get_location())
-    
-    def set_matrix(self, value):
-        self.set_location(value.to_translation())
-    
-    def get_initial_matrix(self):
-        return self.initial_matrix
-
-class View3D_Object(Particle):
-    def __init__(self, obj):
-        self.obj = obj
-    
-    def get_location(self):
-        # obj.location seems to be in parent's system...
-        # or even maybe not bounded by constraints %)
-        return self.obj.matrix_world.to_translation()
-
-class View3D_EditMesh_Vertex(Particle):
-    pass
-
-class View3D_EditMesh_Edge(Particle):
-    pass
-
-class View3D_EditMesh_Face(Particle):
-    pass
-
-class View3D_EditSpline_Point(Particle):
-    pass
-
-class View3D_EditSpline_BezierPoint(Particle):
-    pass
-
-class View3D_EditSpline_BezierHandle(Particle):
-    pass
-
-class View3D_EditMeta_Element(Particle):
-    pass
-
-class View3D_EditBone_Bone(Particle):
-    pass
-
-class View3D_EditBone_HeadTail(Particle):
-    pass
-
-class View3D_PoseBone(Particle):
-    pass
-
-class UV_Cursor(Particle):
-    pass
-
-class UV_Vertex(Particle):
-    pass
-
-class UV_Edge(Particle):
-    pass
-
-class UV_Face(Particle):
-    pass
-
-# Other types:
-# NLA / Dopesheet / Graph editor ...
-
-# Particles are used in the following situations:
-# - as subjects of transformation
-# - as reference point(s) for cursor transformation
-# Note: particles 'dragged' by Proportional Editing
-# are a separate issue (they can come and go).
-def gather_particles(**kwargs):
-    context = kwargs.get("context", bpy.context)
-    
-    area_type = kwargs.get("area_type", context.area.type)
-    
-    scene = kwargs.get("scene", context.scene)
-    
-    space_data = kwargs.get("space_data", context.space_data)
-    region_data = kwargs.get("region_data", context.region_data)
-    
-    particles = []
-    pivots = {}
-    normal_system = None
-    
-    active_element = None
-    cursor_pos = None
-    median = None
-    
-    if area_type == 'VIEW_3D':
-        context_mode = kwargs.get("context_mode", context.mode)
-        
-        selected_objects = kwargs.get("selected_objects",
-            context.selected_objects)
-        
-        active_object = kwargs.get("active_object",
-            context.active_object)
-        
-        if context_mode == 'OBJECT':
-            for obj in selected_objects:
-                particle = View3D_Object(obj)
-                particles.append(particle)
-            
-            if active_object:
-                active_element = active_object.\
-                    matrix_world.to_translation()
-        
-        # On Undo/Redo scene hash value is changed ->
-        # -> the monitor tries to update the CSU ->
-        # -> object.mode_set seem to somehow conflict
-        # with Undo/Redo mechanisms.
-        elif False and active_object and active_object.data and \
-        (context_mode in {
-        'EDIT_MESH', 'EDIT_METABALL',
-        'EDIT_CURVE', 'EDIT_SURFACE',
-        'EDIT_ARMATURE', 'POSE'}):
-            
-            prev_mode = active_object.mode
-            
-            if context_mode not in {'EDIT_ARMATURE', 'POSE'}:
-                bpy.ops.object.mode_set(mode='OBJECT')
-            
-            m = active_object.matrix_world
-            
-            positions = []
-            normal = Vector((0, 0, 0))
-            
-            if context_mode == 'EDIT_MESH':
-                # We currently don't need to create particles
-                # for these; vertices are enough now.
-                #for face in active_object.data.polygons:
-                #    pass
-                #for edge in active_object.data.edges:
-                #    pass
-                for vertex in active_object.data.vertices:
-                    if vertex.select:
-                        positions.append(vertex.co)
-                        normal += vertex.normal
-            elif context_mode == 'EDIT_METABALL':
-                active_elem = active_object.data.elements.active
-                if active_elem:
-                    active_element = active_elem.co.copy()
-                    active_element = active_object.\
-                        matrix_world * active_element
-                
-                # Currently there is no API for element.select
-                #for element in active_object.data.elements:
-                #    if element.select:
-                #        positions.append(element.co)
-            elif context_mode == 'EDIT_ARMATURE':
-                # active bone seems to have the same pivot
-                # as median of the selection
-                '''
-                active_bone = active_object.data.edit_bones.active
-                if active_bone:
-                    active_element = active_bone.head + \
-                                     active_bone.tail
-                    active_element = active_object.\
-                        matrix_world * active_element
-                '''
-                
-                for bone in active_object.data.edit_bones:
-                    if bone.select_head:
-                        positions.append(bone.head)
-                    if bone.select_tail:
-                        positions.append(bone.tail)
-            elif context_mode == 'POSE':
-                active_bone = active_object.data.bones.active
-                if active_bone:
-                    active_element = active_bone.\
-                        matrix_local.translation.to_3d()
-                    active_element = active_object.\
-                        matrix_world * active_element
-                
-                # consider only topmost parents
-                bones = set()
-                for bone in active_object.data.bones:
-                    if bone.select:
-                        bones.add(bone)
-                
-                parents = set()
-                for bone in bones:
-                    if not set(bone.parent_recursive).intersection(bones):
-                        parents.add(bone)
-                
-                for bone in parents:
-                    positions.append(bone.matrix_local.translation.to_3d())
-            else:
-                for spline in active_object.data.splines:
-                    for point in spline.bezier_points:
-                        if point.select_control_point:
-                            positions.append(point.co)
-                        else:
-                            if point.select_left_handle:
-                                positions.append(point.handle_left)
-                            if point.select_right_handle:
-                                positions.append(point.handle_right)
-                        
-                        n = None
-                        nL = point.co - point.handle_left
-                        nR = point.co - point.handle_right
-                        #nL = point.handle_left.copy()
-                        #nR = point.handle_right.copy()
-                        if point.select_control_point:
-                            n = nL + nR
-                        elif point.select_left_handle or \
-                             point.select_right_handle:
-                            n = nL + nR
-                        else:
-                            if point.select_left_handle:
-                                n = -nL
-                            if point.select_right_handle:
-                                n = nR
-                        
-                        if n is not None:
-                            if n.length_squared < epsilon:
-                                n = -nL
-                            normal += n.normalized()
-                    
-                    for point in spline.points:
-                        if point.select:
-                            positions.append(point.co)
-            
-            if len(positions) != 0:
-                if normal.length_squared < epsilon:
-                    normal = Vector((0, 0, 1))
-                normal.rotate(m)
-                normal.normalize()
-                
-                if (1.0 - abs(normal.z)) < epsilon:
-                    t1 = Vector((1, 0, 0))
-                else:
-                    t1 = Vector((0, 0, 1)).cross(normal)
-                t2 = t1.cross(normal)
-                normal_system = MatrixCompose(t1, t2, normal)
-                
-                median, bbox_center = calc_median_bbox_pivots(positions)
-                median = m * median
-                bbox_center = m * bbox_center
-                
-                # Currently I don't know how to get active mesh element
-                if active_element is None:
-                    if context_mode == 'EDIT_ARMATURE':
-                        # Somewhy EDIT_ARMATURE has such behavior
-                        active_element = bbox_center
-                    else:
-                        active_element = median
-            else:
-                if active_element is None:
-                    active_element = active_object.\
-                        matrix_world.to_translation()
-                
-                median = active_element
-                bbox_center = active_element
-                
-                normal_system = active_object.matrix_world.to_3x3()
-                normal_system.col[0].normalize()
-                normal_system.col[1].normalize()
-                normal_system.col[2].normalize()
-            
-            if context_mode not in {'EDIT_ARMATURE', 'POSE'}:
-                bpy.ops.object.mode_set(mode=prev_mode)
-        else:
-            # paint/sculpt, etc.?
-            particle = View3D_Object(active_object)
-            particles.append(particle)
-            
-            if active_object:
-                active_element = active_object.\
-                    matrix_world.to_translation()
-        
-        cursor_pos = get_cursor_location(v3d=space_data)
-    
-    #elif area_type == 'IMAGE_EDITOR':
-        # currently there is no way to get UV editor's
-        # offset (and maybe some other parameters
-        # required to implement these operators)
-        #cursor_pos = space_data.uv_editor.cursor_location
-    
-    #elif area_type == 'EMPTY':
-    #elif area_type == 'GRAPH_EDITOR':
-    #elif area_type == 'OUTLINER':
-    #elif area_type == 'PROPERTIES':
-    #elif area_type == 'FILE_BROWSER':
-    #elif area_type == 'INFO':
-    #elif area_type == 'SEQUENCE_EDITOR':
-    #elif area_type == 'TEXT_EDITOR':
-    #elif area_type == 'AUDIO_WINDOW':
-    #elif area_type == 'DOPESHEET_EDITOR':
-    #elif area_type == 'NLA_EDITOR':
-    #elif area_type == 'SCRIPTS_WINDOW':
-    #elif area_type == 'TIMELINE':
-    #elif area_type == 'NODE_EDITOR':
-    #elif area_type == 'LOGIC_EDITOR':
-    #elif area_type == 'CONSOLE':
-    #elif area_type == 'USER_PREFERENCES':
-    
-    else:
-        print("gather_particles() not implemented for '{}'".\
-              format(area_type))
-        return None, None
-    
-    # 'INDIVIDUAL_ORIGINS' is not handled here
-    
-    if cursor_pos:
-        pivots['CURSOR'] = cursor_pos.copy()
-    
-    if active_element:
-        # in v3d: ACTIVE_ELEMENT
-        pivots['ACTIVE'] = active_element.copy()
-    
-    if (len(particles) != 0) and (median is None):
-        positions = (p.get_location() for p in particles)
-        median, bbox_center = calc_median_bbox_pivots(positions)
-    
-    if median:
-        # in v3d: MEDIAN_POINT, in UV editor: MEDIAN
-        pivots['MEDIAN'] = median.copy()
-        # in v3d: BOUNDING_BOX_CENTER, in UV editor: CENTER
-        pivots['CENTER'] = bbox_center.copy()
-    
-    csu = CoordinateSystemUtility(scene, space_data, region_data, \
-        pivots, normal_system)
-    
-    return particles, csu
-
-def calc_median_bbox_pivots(positions):
-    median = None # pos can be 3D or 2D
-    bbox = [None, None]
-    
-    n = 0
-    for pos in positions:
-        extend_bbox(bbox, pos)
-        try:
-            median += pos
-        except:
-            median = pos.copy()
-        n += 1
-    
-    median = median / n
-    bbox_center = (Vector(bbox[0]) + Vector(bbox[1])) * 0.5
-    
-    return median, bbox_center
-
-def extend_bbox(bbox, pos):
-    try:
-        bbox[0] = tuple(min(e0, e1) for e0, e1 in zip(bbox[0], pos))
-        bbox[1] = tuple(max(e0, e1) for e0, e1 in zip(bbox[1], pos))
-    except:
-        bbox[0] = tuple(pos)
-        bbox[1] = tuple(pos)
-
-
-# ====== COORDINATE SYSTEM UTILITY ====== #
-class CoordinateSystemUtility:
-    pivot_name_map = {
-        'CENTER':'CENTER',
-        'BOUNDING_BOX_CENTER':'CENTER',
-        'MEDIAN':'MEDIAN',
-        'MEDIAN_POINT':'MEDIAN',
-        'CURSOR':'CURSOR', 
-        'INDIVIDUAL_ORIGINS':'INDIVIDUAL',
-        'ACTIVE_ELEMENT':'ACTIVE',
-        'WORLD':'WORLD',
-        'SURFACE':'SURFACE', # ?
-        'BOOKMARK':'BOOKMARK',
-    }
-    pivot_v3d_map = {
-        'CENTER':'BOUNDING_BOX_CENTER',
-        'MEDIAN':'MEDIAN_POINT',
-        'CURSOR':'CURSOR', 
-        'INDIVIDUAL':'INDIVIDUAL_ORIGINS',
-        'ACTIVE':'ACTIVE_ELEMENT',
-    }
-    
-    def __init__(self, scene, space_data, region_data, \
-                 pivots, normal_system):
-        self.space_data = space_data
-        self.region_data = region_data
-        
-        if space_data.type == 'VIEW_3D':
-            self.pivot_map_inv = self.pivot_v3d_map
-        
-        self.tou = TransformOrientationUtility(
-            scene, space_data, region_data)
-        self.tou.normal_system = normal_system
-        
-        self.pivots = pivots
-        
-        # Assigned by caller (for cursor or selection)
-        self.source_pos = None
-        self.source_rot = None
-        self.source_scale = None
-    
-    def set_orientation(self, name):
-        self.tou.set(name)
-    
-    def set_pivot(self, pivot):
-        self.space_data.pivot_point = self.pivot_map_inv[pivot]
-    
-    def get_pivot_name(self, name=None, relative=None, raw=False):
-        pivot = self.pivot_name_map[self.space_data.pivot_point]
-        if raw:
-            return pivot
-        
-        if not name:
-            name = self.tou.get()
-        
-        if relative is None:
-            settings = find_settings()
-            tfm_opts = settings.transform_options
-            relative = tfm_opts.use_relative_coords
-        
-        if relative:
-            pivot = "RELATIVE"
-        elif (name == 'GLOBAL') or (pivot == 'WORLD'):
-            pivot = 'WORLD'
-        elif (name == "Surface") or (pivot == 'SURFACE'):
-            pivot = "SURFACE"
-        
-        return pivot
-    
-    def get_origin(self, name=None, relative=None, pivot=None):
-        if not pivot:
-            pivot = self.get_pivot_name(name, relative)
-        
-        if relative or (pivot == "RELATIVE"):
-            # "relative" parameter overrides "pivot"
-            return self.source_pos
-        elif pivot == 'WORLD':
-            return Vector()
-        elif pivot == "SURFACE":
-            runtime_settings = find_runtime_settings()
-            return Vector(runtime_settings.surface_pos)
-        else:
-            if pivot == 'INDIVIDUAL':
-                pivot = 'MEDIAN'
-            
-            #if pivot == 'ACTIVE':
-            #    print(self.pivots)
-            
-            try:
-                return self.pivots[pivot]
-            except:
-                return Vector()
-    
-    def get_matrix(self, name=None, relative=None, pivot=None):
-        if not name:
-            name = self.tou.get()
-        
-        matrix = self.tou.get_matrix(name)
-        
-        if isinstance(pivot, Vector):
-            pos = pivot
-        else:
-            pos = self.get_origin(name, relative, pivot)
-        
-        return to_matrix4x4(matrix, pos)
-
-# ====== TRANSFORM ORIENTATION UTILITIES ====== #
-class TransformOrientationUtility:
-    special_systems = {"Surface", "Scaled"}
-    predefined_systems = {
-        'GLOBAL', 'LOCAL', 'VIEW', 'NORMAL', 'GIMBAL',
-        "Scaled", "Surface",
-    }
-    
-    def __init__(self, scene, v3d, rv3d):
-        self.scene = scene
-        self.v3d = v3d
-        self.rv3d = rv3d
-        
-        self.custom_systems = [item for item in scene.orientations \
-            if item.name not in self.special_systems]
-        
-        self.is_custom = False
-        self.custom_id = -1
-        
-        # This is calculated elsewhere
-        self.normal_system = None
-        
-        self.set(v3d.transform_orientation)
-    
-    def get(self):
-        return self.transform_orientation
-    
-    def get_title(self):
-        if self.is_custom:
-            return self.transform_orientation
-        
-        name = self.transform_orientation
-        return name[:1].upper() + name[1:].lower()
-    
-    def set(self, name):
-        if isinstance(name, int):
-            n = len(self.custom_systems)
-            if n == 0:
-                # No custom systems, do nothing
-                return
-            
-            increment = name
-            
-            if self.is_custom:
-                # If already custom, switch to next custom system
-                self.custom_id = (self.custom_id + increment) % n
-            
-            self.is_custom = True
-            
-            name = self.custom_systems[self.custom_id].name
-        else:
-            self.is_custom = name not in self.predefined_systems
-            
-            if self.is_custom:
-                self.custom_id = next((i for i, v in \
-                    enumerate(self.custom_systems) if v.name == name), -1)
-            
-            if name in self.special_systems:
-                # Ensure such system exists
-                self.get_custom(name)
-        
-        self.transform_orientation = name
-        
-        self.v3d.transform_orientation = name
-    
-    def get_matrix(self, name=None):
-        active_obj = self.scene.objects.active
-        
-        if not name:
-            name = self.transform_orientation
-        
-        if self.is_custom:
-            matrix = self.custom_systems[self.custom_id].matrix.copy()
-        else:
-            if (name == 'VIEW') and self.rv3d:
-                matrix = self.rv3d.view_rotation.to_matrix()
-            elif name == "Surface":
-                matrix = self.get_custom(name).matrix.copy()
-            elif (name == 'GLOBAL') or (not active_obj):
-                matrix = Matrix().to_3x3()
-            elif (name == 'NORMAL') and self.normal_system:
-                matrix = self.normal_system.copy()
-            else:
-                matrix = active_obj.matrix_world.to_3x3()
-                if name == "Scaled":
-                    self.get_custom(name).matrix = matrix
-                else: # 'LOCAL', 'GIMBAL', ['NORMAL'] for now
-                    matrix[0].normalize()
-                    matrix[1].normalize()
-                    matrix[2].normalize()
-        
-        return matrix
-    
-    def get_custom(self, name):
-        try:
-            return self.scene.orientations[name]
-        except:
-            return create_transform_orientation(
-                self.scene, name, Matrix())
-
-# Is there a less cumbersome way to create transform orientation?
-def create_transform_orientation(scene, name=None, matrix=None):
-    active_obj = scene.objects.active
-    prev_mode = None
-    
-    if active_obj:
-        prev_mode = active_obj.mode
-        bpy.ops.object.mode_set(mode='OBJECT')
-    else:
-        bpy.ops.object.add()
-    
-    # ATTENTION! This uses context's scene
-    bpy.ops.transform.create_orientation()
-    
-    tfm_orient = scene.orientations[-1]
-    
-    if name is not None:
-        tfm_orient.name = name
-    
-    if matrix:
-        tfm_orient.matrix = matrix.to_3x3()
-    
-    if active_obj:
-        bpy.ops.object.mode_set(mode=prev_mode)
-    else:
-        bpy.ops.object.delete()
-    
-    return tfm_orient
-
-# ====== VIEW UTILITY CLASS ====== #
-class ViewUtility:
-    methods = dict(
-        get_locks = lambda: {},
-        set_locks = lambda locks: None,
-        get_position = lambda: Vector(),
-        set_position = lambda: None,
-        get_rotation = lambda: Quaternion(),
-        get_direction = lambda: Vector((0, 0, 1)),
-        get_viewpoint = lambda: Vector(),
-        get_matrix = lambda: Matrix(),
-        get_point = lambda xy, pos: \
-            Vector((xy[0], xy[1], 0)),
-        get_ray = lambda xy: tuple(
-            Vector((xy[0], xy[1], 0)),
-            Vector((xy[0], xy[1], 1)),
-            False),
-    )
-    
-    def __init__(self, region, space_data, region_data):
-        self.region = region
-        self.space_data = space_data
-        self.region_data = region_data
-        
-        if space_data.type == 'VIEW_3D':
-            self.implementation = View3DUtility(
-                region, space_data, region_data)
-        else:
-            self.implementation = None
-        
-        if self.implementation:
-            for name in self.methods:
-                setattr(self, name,
-                    getattr(self.implementation, name))
-        else:
-            for name, value in self.methods.items():
-                setattr(self, name, value)
-
-class View3DUtility:
-    lock_types = {"lock_cursor":False, "lock_object":None, "lock_bone":""}
-    
-    # ====== INITIALIZATION / CLEANUP ====== #
-    def __init__(self, region, space_data, region_data):
-        self.region = region
-        self.space_data = space_data
-        self.region_data = region_data
-    
-    # ====== GET VIEW MATRIX AND ITS COMPONENTS ====== #
-    def get_locks(self):
-        v3d = self.space_data
-        return {k:getattr(v3d, k) for k in self.lock_types}
-    
-    def set_locks(self, locks):
-        v3d = self.space_data
-        for k in self.lock_types:
-            setattr(v3d, k, locks.get(k, self.lock_types[k]))
-    
-    def _get_lock_obj_bone(self):
-        v3d = self.space_data
-        
-        obj = v3d.lock_object
-        if not obj:
-            return None, None
-        
-        if v3d.lock_bone:
-            try:
-                # this is not tested!
-                if obj.mode == 'EDIT':
-                    bone = obj.data.edit_bones[v3d.lock_bone]
-                else:
-                    bone = obj.data.bones[v3d.lock_bone]
-            except:
-                bone = None
-        
-        return obj, bone
-    
-    # TODO: learn how to get these values from
-    # rv3d.perspective_matrix and rv3d.view_matrix ?
-    def get_position(self, no_locks=False):
-        v3d = self.space_data
-        rv3d = self.region_data
-        
-        if no_locks:
-            return rv3d.view_location.copy()
-        
-        # rv3d.perspective_matrix and rv3d.view_matrix
-        # seem to have some weird translation components %)
-        
-        if rv3d.view_perspective == 'CAMERA':
-            p = v3d.camera.matrix_world.to_translation()
-            d = self.get_direction()
-            return p + d * rv3d.view_distance
-        else:
-            if v3d.lock_object:
-                obj, bone = self._get_lock_obj_bone()
-                if bone:
-                    return (obj.matrix_world * bone.matrix).to_translation()
-                else:
-                    return obj.matrix_world.to_translation()
-            elif v3d.lock_cursor:
-                return get_cursor_location(v3d=v3d)
-            else:
-                return rv3d.view_location.copy()
-    
-    def set_position(self, pos, no_locks=False):
-        v3d = self.space_data
-        rv3d = self.region_data
-        
-        pos = pos.copy()
-        
-        if no_locks:
-            rv3d.view_location = pos
-            return
-        
-        if rv3d.view_perspective == 'CAMERA':
-            d = self.get_direction()
-            v3d.camera.matrix_world.translation = pos - d * rv3d.view_distance
-        else:
-            if v3d.lock_object:
-                obj, bone = self._get_lock_obj_bone()
-                if bone:
-                    try:
-                        bone.matrix.translation = \
-                            obj.matrix_world.inverted() * pos
-                    except:
-                        # this is some degenerate object
-                        bone.matrix.translation = pos
-                else:
-                    obj.matrix_world.translation = pos
-            elif v3d.lock_cursor:
-                set_cursor_location(pos, v3d=v3d)
-            else:
-                rv3d.view_location = pos
-    
-    def get_rotation(self):
-        v3d = self.space_data
-        rv3d = self.region_data
-        
-        if rv3d.view_perspective == 'CAMERA':
-            return v3d.camera.matrix_world.to_quaternion()
-        else:
-            return rv3d.view_rotation
-    
-    def get_direction(self):
-        # Camera (as well as viewport) looks in the direction of -Z;
-        # Y is up, X is left
-        d = self.get_rotation() * Vector((0, 0, -1))
-        d.normalize()
-        return d
-    
-    def get_viewpoint(self):
-        v3d = self.space_data
-        rv3d = self.region_data
-        
-        if rv3d.view_perspective == 'CAMERA':
-            return v3d.camera.matrix_world.to_translation()
-        else:
-            p = self.get_position()
-            d = self.get_direction()
-            return p - d * rv3d.view_distance
-    
-    def get_matrix(self):
-        m = self.get_rotation().to_matrix()
-        m.resize_4x4()
-        m.translation = self.get_viewpoint()
-        return m
-    
-    def get_point(self, xy, pos):
-        region = self.region
-        rv3d = self.region_data
-        return region_2d_to_location_3d(region, rv3d, xy, pos)
-    
-    def get_ray(self, xy):
-        region = self.region
-        v3d = self.space_data
-        rv3d = self.region_data
-        
-        viewPos = self.get_viewpoint()
-        viewDir = self.get_direction()
-        
-        near = viewPos + viewDir * v3d.clip_start
-        far = viewPos + viewDir * v3d.clip_end
-        
-        a = region_2d_to_location_3d(region, rv3d, xy, near)
-        b = region_2d_to_location_3d(region, rv3d, xy, far)
-        
-        # When viewed from in-scene camera, near and far
-        # planes clip geometry even in orthographic mode.
-        clip = rv3d.is_perspective or (rv3d.view_perspective == 'CAMERA')
-        
-        return a, b, clip
-
-# ====== SNAP UTILITY CLASS ====== #
-class SnapUtility:
-    def __init__(self, context):
-        if context.area.type == 'VIEW_3D':
-            v3d = context.space_data
-            shade = v3d.viewport_shade
-            self.implementation = Snap3DUtility(context.scene, shade)
-            self.implementation.update_targets(
-                context.visible_objects, [])
-    
-    def dispose(self):
-        self.implementation.dispose()
-    
-    def update_targets(self, to_include, to_exclude):
-        self.implementation.update_targets(to_include, to_exclude)
-    
-    def set_modes(self, **kwargs):
-        return self.implementation.set_modes(**kwargs)
-    
-    def snap(self, *args, **kwargs):
-        return self.implementation.snap(*args, **kwargs)
-    
-class SnapUtilityBase:
-    def __init__(self):
-        self.targets = set()
-        # TODO: set to current blend settings?
-        self.interpolation = 'NEVER'
-        self.editmode = False
-        self.snap_type = None
-        self.projection = [None, None, None]
-        self.potential_snap_elements = None
-        self.extra_snap_points = None
-    
-    def update_targets(self, to_include, to_exclude):
-        self.targets.update(to_include)
-        self.targets.difference_update(to_exclude)
-    
-    def set_modes(self, **kwargs):
-        if "use_relative_coords" in kwargs:
-            self.use_relative_coords = kwargs["use_relative_coords"]
-        if "interpolation" in kwargs:
-            # NEVER, ALWAYS, SMOOTH
-            self.interpolation = kwargs["interpolation"]
-        if "editmode" in kwargs:
-            self.editmode = kwargs["editmode"]
-        if "snap_align" in kwargs:
-            self.snap_align = kwargs["snap_align"]
-        if "snap_type" in kwargs:
-            # 'INCREMENT', 'VERTEX', 'EDGE', 'FACE', 'VOLUME'
-            self.snap_type = kwargs["snap_type"]
-        if "axes_coords" in kwargs:
-            # none, point, line, plane
-            self.axes_coords = kwargs["axes_coords"]
-    
-    # ====== CURSOR REPOSITIONING ====== #
-    def snap(self, xy, src_matrix, initial_matrix, do_raycast, \
-        alt_snap, vu, csu, modify_Surface, use_object_centers):
-        
-        grid_step = self.grid_steps[alt_snap]
-        
-        su = self
-        use_relative_coords = su.use_relative_coords
-        snap_align = su.snap_align
-        axes_coords = su.axes_coords
-        snap_type = su.snap_type
-        
-        runtime_settings = find_runtime_settings()
-        
-        matrix = src_matrix.to_3x3()
-        pos = src_matrix.to_translation().copy()
-        
-        sys_matrix = csu.get_matrix()
-        if use_relative_coords:
-            sys_matrix.translation = initial_matrix.translation.copy()
-        
-        # Axes of freedom and line/plane parameters
-        start = Vector(((0 if v is None else v) for v in axes_coords))
-        direction = Vector(((v is not None) for v in axes_coords))
-        axes_of_freedom = 3 - int(sum(direction))
-        
-        # do_raycast is False when mouse is not moving
-        if do_raycast:
-            su.hide_bbox(True)
-            
-            self.potential_snap_elements = None
-            self.extra_snap_points = None
-            
-            set_stick_obj(csu.tou.scene, None)
-            
-            raycast = None
-            snap_to_obj = (snap_type != 'INCREMENT') #or use_object_centers
-            snap_to_obj = snap_to_obj and (snap_type is not None)
-            if snap_to_obj:
-                a, b, clip = vu.get_ray(xy)
-                view_dir = vu.get_direction()
-                raycast = su.snap_raycast(a, b, clip, view_dir, csu, alt_snap)
-            
-            if raycast:
-                surf_matrix, face_id, obj, orig_obj = raycast
-                
-                if not use_object_centers:
-                    self.potential_snap_elements = [
-                        (obj.matrix_world * obj.data.vertices[vi].co)
-                        for vi in obj.data.tessfaces[face_id].vertices
-                    ]
-                
-                if use_object_centers:
-                    self.extra_snap_points = \
-                        [obj.matrix_world.to_translation()]
-                elif alt_snap:
-                    pse = self.potential_snap_elements
-                    n = len(pse)
-                    if self.snap_type == 'EDGE':
-                        self.extra_snap_points = []
-                        for i in range(n):
-                            v0 = pse[i]
-                            v1 = pse[(i + 1) % n]
-                            self.extra_snap_points.append((v0 + v1) / 2)
-                    elif self.snap_type == 'FACE':
-                        self.extra_snap_points = []
-                        v0 = Vector()
-                        for v1 in pse:
-                            v0 += v1
-                        self.extra_snap_points.append(v0 / n)
-                
-                if snap_align:
-                    matrix = surf_matrix.to_3x3()
-                
-                if not use_object_centers:
-                    pos = surf_matrix.to_translation()
-                else:
-                    pos = orig_obj.matrix_world.to_translation()
-                
-                try:
-                    local_pos = orig_obj.matrix_world.inverted() * pos
-                except:
-                    # this is some degenerate object
-                    local_pos = pos
-                
-                set_stick_obj(csu.tou.scene, orig_obj.name, local_pos)
-                
-                modify_Surface = modify_Surface and \
-                    (snap_type != 'VOLUME') and (not use_object_centers)
-                
-                # === Update "Surface" orientation === #
-                if modify_Surface:
-                    # Use raycast[0], not matrix! If snap_align == False,
-                    # matrix will be src_matrix!
-                    coordsys = csu.tou.get_custom("Surface")
-                    coordsys.matrix = surf_matrix.to_3x3()
-                    runtime_settings.surface_pos = pos
-                    if csu.tou.get() == "Surface":
-                        sys_matrix = to_matrix4x4(matrix, pos)
-            else:
-                if axes_of_freedom == 0:
-                    # Constrained in all axes, can't move.
-                    pass
-                elif axes_of_freedom == 3:
-                    # Not constrained, move in view plane.
-                    pos = vu.get_point(xy, pos)
-                else:
-                    a, b, clip = vu.get_ray(xy)
-                    view_dir = vu.get_direction()
-                    
-                    start = sys_matrix * start
-                    
-                    if axes_of_freedom == 1:
-                        direction = Vector((1, 1, 1)) - direction
-                    direction.rotate(sys_matrix)
-                    
-                    if axes_of_freedom == 2:
-                        # Constrained in one axis.
-                        # Find intersection with plane.
-                        i_p = intersect_line_plane(a, b, start, direction)
-                        if i_p is not None:
-                            pos = i_p
-                    elif axes_of_freedom == 1:
-                        # Constrained in two axes.
-                        # Find nearest point to line.
-                        i_p = intersect_line_line(a, b, start,
-                                                  start + direction)
-                        if i_p is not None:
-                            pos = i_p[1]
-        #end if do_raycast
-        
-        try:
-            sys_matrix_inv = sys_matrix.inverted()
-        except:
-            # this is some degenerate system
-            sys_matrix_inv = Matrix()
-        
-        _pos = sys_matrix_inv * pos
-        
-        # don't snap when mouse hasn't moved
-        if (snap_type == 'INCREMENT') and do_raycast:
-            for i in range(3):
-                _pos[i] = round_step(_pos[i], grid_step)
-        
-        for i in range(3):
-            if axes_coords[i] is not None:
-                _pos[i] = axes_coords[i]
-        
-        if (snap_type == 'INCREMENT') or (axes_of_freedom != 3):
-            pos = sys_matrix * _pos
-        
-        res_matrix = to_matrix4x4(matrix, pos)
-        
-        CursorDynamicSettings.local_matrix = \
-            sys_matrix_inv * res_matrix
-        
-        return res_matrix
-
-class Snap3DUtility(SnapUtilityBase):
-    grid_steps = {False:1.0, True:0.1}
-    
-    cube_verts = [Vector((i, j, k))
-        for i in (-1, 1)
-        for j in (-1, 1)
-        for k in (-1, 1)]
-    
-    def __init__(self, scene, shade):
-        SnapUtilityBase.__init__(self)
-        
-        self.cache = MeshCache(scene)
-        
-        # ? seems that dict is enough
-        self.bbox_cache = {}#collections.OrderedDict()
-        self.sys_matrix_key = [0.0] * 9
-        
-        bm = prepare_gridbox_mesh(subdiv=2)
-        mesh = bpy.data.meshes.new(tmp_name)
-        bm.to_mesh(mesh)
-        mesh.update(calc_tessface=True)
-        #mesh.calc_tessface()
-        
-        self.bbox_obj = self.cache.create_temporary_mesh_obj(mesh, Matrix())
-        self.bbox_obj.hide = True
-        self.bbox_obj.draw_type = 'WIRE'
-        self.bbox_obj.name = "BoundBoxSnap"
-        # make it displayable
-        #self.cache.scene.objects.link(self.bbox_obj)
-        #self.cache.scene.update()
-        
-        self.shade_bbox = (shade == 'BOUNDBOX')
-    
-    def update_targets(self, to_include, to_exclude):
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        only_solid = tfm_opts.snap_only_to_solid
-        
-        # Ensure this is a set and not some other
-        # type of collection
-        to_exclude = set(to_exclude)
-        
-        for target in to_include:
-            if only_solid and ((target.draw_type == 'BOUNDS') \
-                    or (target.draw_type == 'WIRE')):
-                to_exclude.add(target)
-        
-        SnapUtilityBase.update_targets(self, to_include, to_exclude)
-    
-    def dispose(self):
-        self.hide_bbox(True)
-        
-        mesh = self.bbox_obj.data
-        bpy.data.objects.remove(self.bbox_obj)
-        bpy.data.meshes.remove(mesh)
-        
-        self.cache.dispose()
-    
-    def hide_bbox(self, hide):
-        if self.bbox_obj.hide == hide:
-            return
-        
-        self.bbox_obj.hide = hide
-        
-        # We need to unlink bbox until required to show it,
-        # because otherwise outliner will blink each
-        # time cursor is clicked
-        if hide:
-            self.cache.scene.objects.unlink(self.bbox_obj)
-        else:
-            self.cache.scene.objects.link(self.bbox_obj)
-    
-    def get_bbox_obj(self, obj, sys_matrix, sys_matrix_inv, is_local):
-        if is_local:
-            bbox = None
-        else:
-            bbox = self.bbox_cache.get(obj, None)
-        
-        if bbox is None:
-            m = obj.matrix_world
-            if is_local:
-                sys_matrix = m.copy()
-                try:
-                    sys_matrix_inv = sys_matrix.inverted()
-                except Exception:
-                    # this is some degenerate system
-                    sys_matrix_inv = Matrix()
-            m_combined = sys_matrix_inv * m
-            bbox = [None, None]
-            
-            mesh_obj = self.cache[obj, True, self.editmode]
-            if (mesh_obj is None) or self.shade_bbox or \
-                    (obj.draw_type == 'BOUNDS'):
-                if is_local:
-                    bbox = [(-1, -1, -1), (1, 1, 1)]
-                else:
-                    for p in self.cube_verts:
-                        extend_bbox(bbox, m_combined * p.copy())
-            elif is_local:
-                bbox = [mesh_obj.bound_box[0], mesh_obj.bound_box[6]]
-            else:
-                for v in mesh_obj.data.vertices:
-                    extend_bbox(bbox, m_combined * v.co.copy())
-            
-            bbox = (Vector(bbox[0]), Vector(bbox[1]))
-            
-            if not is_local:
-                self.bbox_cache[obj] = bbox
-        
-        half = (bbox[1] - bbox[0]) * 0.5
-        
-        m = MatrixCompose(half[0], half[1], half[2])
-        m = sys_matrix.to_3x3() * m
-        m.resize_4x4()
-        m.translation = sys_matrix * (bbox[0] + half)
-        self.bbox_obj.matrix_world = m
-        
-        return self.bbox_obj
-    
-    # TODO: ?
-    # - Sort snap targets according to raycasted distance?
-    # - Ignore targets if their bounding sphere is further
-    #   than already picked position?
-    # Perhaps these "optimizations" aren't worth the overhead.
-    
-    def raycast(self, a, b, clip, view_dir, is_bbox, \
-                sys_matrix, sys_matrix_inv, is_local, x_ray):
-        # If we need to interpolate normals or snap to
-        # vertices/edges, we must convert mesh.
-        #force = (self.interpolation != 'NEVER') or \
-        #    (self.snap_type in {'VERTEX', 'EDGE'})
-        # Actually, we have to always convert, since
-        # we need to get face at least to find tangential.
-        force = True
-        edit = self.editmode
-        
-        res = None
-        L = None
-        
-        for obj in self.targets:
-            orig_obj = obj
-            
-            if obj.name == self.bbox_obj.name:
-                # is there a better check?
-                # ("a is b" doesn't work here)
-                continue
-            if obj.show_x_ray != x_ray:
-                continue
-            
-            if is_bbox:
-                obj = self.get_bbox_obj(obj, \
-                    sys_matrix, sys_matrix_inv, is_local)
-            elif obj.draw_type == 'BOUNDS':
-                # Outside of BBox, there is no meaningful visual snapping
-                # for such display mode
-                continue
-            
-            m = obj.matrix_world.copy()
-            try:
-                mi = m.inverted()
-            except:
-                # this is some degenerate object
-                continue
-            la = mi * a
-            lb = mi * b
-            
-            # Bounding sphere check (to avoid unnecesary conversions
-            # and to make ray 'infinite')
-            bb_min = Vector(obj.bound_box[0])
-            bb_max = Vector(obj.bound_box[6])
-            c = (bb_min + bb_max) * 0.5
-            r = (bb_max - bb_min).length * 0.5
-            sec = intersect_line_sphere(la, lb, c, r, False)
-            if sec[0] is None:
-                continue # no intersection with the bounding sphere
-            
-            if not is_bbox:
-                # Ensure we work with raycastable object.
-                obj = self.cache[obj, force, edit]
-                if obj is None:
-                    continue # the object has no geometry
-            
-            # If ray must be infinite, ensure that
-            # endpoints are outside of bounding volume
-            if not clip:
-                # Seems that intersect_line_sphere()
-                # returns points in flipped order
-                lb, la = sec
-            
-            # Does ray actually intersect something?
-            lp, ln, face_id = obj.ray_cast(la, lb)
-            if face_id == -1:
-                continue
-            
-            # transform position to global space
-            p = m * lp
-            
-            # This works both for prespective and ortho
-            l = p.dot(view_dir)
-            if (L is None) or (l < L):
-                res = (lp, ln, face_id, obj, p, m, la, lb, orig_obj)
-                L = l
-        #end for
-        
-        return res
-    
-    # Returns:
-    # Matrix(X -- tangential,
-    #        Y -- 2nd tangential,
-    #        Z -- normal,
-    #        T -- raycasted/snapped position)
-    # Face ID (-1 if not applicable)
-    # Object (None if not applicable)
-    def snap_raycast(self, a, b, clip, view_dir, csu, alt_snap):
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        if self.shade_bbox and tfm_opts.snap_only_to_solid:
-            return None
-        
-        # Since introduction of "use object centers",
-        # this check is useless (use_object_centers overrides
-        # even INCREMENT snapping)
-        #if self.snap_type not in {'VERTEX', 'EDGE', 'FACE', 'VOLUME'}:
-        #    return None
-        
-        # key shouldn't depend on system origin;
-        # for bbox calculation origin is always zero
-        #if csu.tou.get() != "Surface":
-        #    sys_matrix = csu.get_matrix().to_3x3()
-        #else:
-        #    sys_matrix = csu.get_matrix('LOCAL').to_3x3()
-        sys_matrix = csu.get_matrix().to_3x3()
-        sys_matrix_key = list(c for v in sys_matrix for c in v)
-        sys_matrix_key.append(self.editmode)
-        sys_matrix = sys_matrix.to_4x4()
-        try:
-            sys_matrix_inv = sys_matrix.inverted()
-        except:
-            # this is some degenerate system
-            return None
-        
-        if self.sys_matrix_key != sys_matrix_key:
-            self.bbox_cache.clear()
-            self.sys_matrix_key = sys_matrix_key
-        
-        # In this context, Volume represents BBox :P
-        is_bbox = (self.snap_type == 'VOLUME')
-        is_local = (csu.tou.get() in \
-            {'LOCAL', "Scaled"})
-        
-        res = self.raycast(a, b, clip, view_dir, \
-            is_bbox, sys_matrix, sys_matrix_inv, is_local, True)
-        
-        if res is None:
-            res = self.raycast(a, b, clip, view_dir, \
-                is_bbox, sys_matrix, sys_matrix_inv, is_local, False)
-        
-        # Occlusion-based edge/vertex snapping will be
-        # too inefficient in Python (well, even without
-        # the occlusion, iterating over all edges/vertices
-        # of each object is inefficient too)
-        
-        if not res:
-            return None
-        
-        lp, ln, face_id, obj, p, m, la, lb, orig_obj = res
-        
-        if is_bbox:
-            self.bbox_obj.matrix_world = m.copy()
-            self.bbox_obj.show_x_ray = orig_obj.show_x_ray
-            self.hide_bbox(False)
-        
-        _ln = ln.copy()
-        
-        face = obj.data.tessfaces[face_id]
-        L = None
-        t1 = None
-        
-        if self.snap_type == 'VERTEX' or self.snap_type == 'VOLUME':
-            for v0 in face.vertices:
-                v = obj.data.vertices[v0]
-                p0 = v.co
-                l = (lp - p0).length_squared
-                if (L is None) or (l < L):
-                    p = p0
-                    ln = v.normal.copy()
-                    #t1 = ln.cross(_ln)
-                    L = l
-            
-            _ln = ln.copy()
-            '''
-            if t1.length < epsilon:
-                if (1.0 - abs(ln.z)) < epsilon:
-                    t1 = Vector((1, 0, 0))
-                else:
-                    t1 = Vector((0, 0, 1)).cross(_ln)
-            '''
-            p = m * p
-        elif self.snap_type == 'EDGE':
-            use_smooth = face.use_smooth
-            if self.interpolation == 'NEVER':
-                use_smooth = False
-            elif self.interpolation == 'ALWAYS':
-                use_smooth = True
-            
-            for v0, v1 in face.edge_keys:
-                p0 = obj.data.vertices[v0].co
-                p1 = obj.data.vertices[v1].co
-                dp = p1 - p0
-                q = dp.dot(lp - p0) / dp.length_squared
-                if (q >= 0.0) and (q <= 1.0):
-                    ep = p0 + dp * q
-                    l = (lp - ep).length_squared
-                    if (L is None) or (l < L):
-                        if alt_snap:
-                            p = (p0 + p1) * 0.5
-                            q = 0.5
-                        else:
-                            p = ep
-                        if not use_smooth:
-                            q = 0.5
-                        ln = obj.data.vertices[v1].normal * q + \
-                             obj.data.vertices[v0].normal * (1.0 - q)
-                        t1 = dp
-                        L = l
-            
-            p = m * p
-        else:
-            if alt_snap:
-                lp = face.center
-                p = m * lp
-            
-            if self.interpolation != 'NEVER':
-                ln = self.interpolate_normal(
-                    obj, face_id, lp, la, lb - la)
-            
-            # Comment this to make 1st tangential 
-            # always lie in the face's plane
-            _ln = ln.copy()
-            
-            '''
-            for v0, v1 in face.edge_keys:
-                p0 = obj.data.vertices[v0].co
-                p1 = obj.data.vertices[v1].co
-                dp = p1 - p0
-                q = dp.dot(lp - p0) / dp.length_squared
-                if (q >= 0.0) and (q <= 1.0):
-                    ep = p0 + dp * q
-                    l = (lp - ep).length_squared
-                    if (L is None) or (l < L):
-                        t1 = dp
-                        L = l
-            '''
-        
-        n = ln.copy()
-        n.rotate(m)
-        n.normalize()
-        
-        if t1 is None:
-            _ln.rotate(m)
-            _ln.normalize()
-            if (1.0 - abs(_ln.z)) < epsilon:
-                t1 = Vector((1, 0, 0))
-            else:
-                t1 = Vector((0, 0, 1)).cross(_ln)
-            t1.normalize()
-        else:
-            t1.rotate(m)
-            t1.normalize()
-        
-        t2 = t1.cross(n)
-        t2.normalize()
-        
-        matrix = MatrixCompose(t1, t2, n, p)
-        
-        return (matrix, face_id, obj, orig_obj)
-    
-    def interpolate_normal(self, obj, face_id, p, orig, ray):
-        face = obj.data.tessfaces[face_id]
-        
-        use_smooth = face.use_smooth
-        if self.interpolation == 'NEVER':
-            use_smooth = False
-        elif self.interpolation == 'ALWAYS':
-            use_smooth = True
-        
-        if not use_smooth:
-            return face.normal.copy()
-        
-        # edge.use_edge_sharp affects smoothness only if
-        # mesh has EdgeSplit modifier
-        
-        # ATTENTION! Coords/Normals MUST be copied
-        # (a bug in barycentric_transform implementation ?)
-        # Somewhat strangely, the problem also disappears
-        # if values passed to barycentric_transform
-        # are print()ed beforehand.
-        
-        co = [obj.data.vertices[vi].co.copy()
-            for vi in face.vertices]
-        
-        normals = [obj.data.vertices[vi].normal.copy()
-            for vi in face.vertices]
-        
-        if len(face.vertices) != 3:
-            tris = tessellate_polygon([co])
-            for tri in tris:
-                i0, i1, i2 = tri
-                if intersect_ray_tri(co[i0], co[i1], co[i2], ray, orig):
-                    break
-        else:
-            i0, i1, i2 = 0, 1, 2
-        
-        n = barycentric_transform(p, co[i0], co[i1], co[i2],
-            normals[i0], normals[i1], normals[i2])
-        n.normalize()
-        
-        return n
-
-# ====== CONVERTED-TO-MESH OBJECTS CACHE ====== #
-class MeshCache:
-    # ====== INITIALIZATION / CLEANUP ====== #
-    def __init__(self, scene):
-        self.scene = scene
-        
-        self.mesh_cache = {}
-        self.object_cache = {}
-        self.edit_object = None
-    
-    def dispose(self):
-        if self.edit_object:
-            mesh = self.edit_object.data
-            bpy.data.objects.remove(self.edit_object)
-            bpy.data.meshes.remove(mesh)
-        del self.edit_object
-        
-        for rco in self.object_cache.values():
-            if rco:
-                bpy.data.objects.remove(rco)
-        del self.object_cache
-    
-        for mesh in self.mesh_cache.values():
-            bpy.data.meshes.remove(mesh)
-        del self.mesh_cache
-    
-    # ====== GET RELEVANT MESH/OBJECT ====== #
-    def __convert(self, obj, force=False, apply_modifiers=True, \
-                  add_to_cache=True):
-        # In Edit (and Sculpt?) mode mesh will not reflect
-        # changes until mode is changed to Object.
-        unstable_shape = ('EDIT' in obj.mode) or ('SCULPT' in obj.mode)
-        
-        force = force or (len(obj.modifiers) != 0)
-        
-        if (obj.data.bl_rna.name == 'Mesh'):
-            if not (force or unstable_shape):
-                # Existing mesh actually satisfies us
-                return obj
-        
-        #if (not force) and (obj.data in self.mesh_cache):
-        if obj.data in self.mesh_cache:
-            mesh = self.mesh_cache[obj.data]
-        else:
-            if unstable_shape:
-                prev_mode = obj.mode
-                bpy.ops.object.mode_set(mode='OBJECT')
-            
-            mesh = obj.to_mesh(self.scene, apply_modifiers, 'PREVIEW')
-            mesh.name = tmp_name
-            
-            if unstable_shape:
-                bpy.ops.object.mode_set(mode=prev_mode)
-            
-            if add_to_cache:
-                self.mesh_cache[obj.data] = mesh
-        
-        rco = self.create_temporary_mesh_obj(mesh, obj.matrix_world)
-        rco.show_x_ray = obj.show_x_ray # necessary for corrent bbox display
-        
-        return rco
-    
-    def __getitem__(self, args):
-        # If more than one argument is passed to getitem,
-        # Python wraps them into tuple.
-        if not isinstance(args, tuple):
-            args = (args,)
-        
-        obj = args[0]
-        force = (args[1] if len(args) > 1 else True)
-        edit = (args[2] if len(args) > 2 else False)
-        
-        # Currently edited object's raw mesh is a separate issue...
-        if edit and obj.data and ('EDIT' in obj.mode):
-            if (obj.data.bl_rna.name == 'Mesh'):
-                if self.edit_object is None:
-                    self.edit_object = self.__convert(
-                                obj, True, False, False)
-                    #self.edit_object.data.update(calc_tessface=True)
-                    #self.edit_object.data.calc_tessface()
-                    self.edit_object.data.calc_normals()
-                return self.edit_object
-        
-        # A usual object. Cached data will suffice.
-        if obj in self.object_cache:
-            return self.object_cache[obj]
-        
-        # Actually, convert and cache.
-        try:
-            rco = self.__convert(obj, force)
-            
-            if rco is obj:
-                # Source objects are not added to cache
-                return obj
-        except Exception as e:
-            # Object has no solid geometry, just ignore it
-            rco = None
-        
-        self.object_cache[obj] = rco
-        if rco:
-            #rco.data.update(calc_tessface=True)
-            #rco.data.calc_tessface()
-            rco.data.calc_normals()
-            pass
-        
-        return rco
-    
-    def create_temporary_mesh_obj(self, mesh, matrix=None):
-        rco = bpy.data.objects.new(tmp_name, mesh)
-        if matrix:
-            rco.matrix_world = matrix
-        
-        # Make Blender recognize object as having geometry
-        # (is there a simpler way to do this?)
-        self.scene.objects.link(rco)
-        self.scene.update()
-        # We don't need this object in scene
-        self.scene.objects.unlink(rco)
-        
-        return rco
-
-#============================================================================#
-
-# A base class for emulating ID-datablock behavior
-class PseudoIDBlockBase(bpy.types.PropertyGroup):
-    # TODO: use normal metaprogramming?
-
-    @staticmethod
-    def create_props(type, name, options={'ANIMATABLE'}):
-        def active_update(self, context):
-            # necessary to avoid recursive calls
-            if self._self_update[0]:
-                return
-            
-            if self._dont_rename[0]:
-                return
-            
-            if len(self.collection) == 0:
-                return
-            
-            # prepare data for renaming...
-            old_key = (self.enum if self.enum else self.collection[0].name)
-            new_key = (self.active if self.active else "Untitled")
-            
-            if old_key == new_key:
-                return
-            
-            old_item = None
-            new_item = None
-            existing_names = []
-            
-            for item in self.collection:
-                if (item.name == old_key) and (not new_item):
-                    new_item = item
-                elif (item.name == new_key) and (not old_item):
-                    old_item = item
-                else:
-                    existing_names.append(item.name)
-            existing_names.append(new_key)
-            
-            # rename current item
-            new_item.name = new_key
-            
-            if old_item:
-                # rename other item if it has that name
-                name = new_key
-                i = 1
-                while name in existing_names:
-                    name = "{}.{:0>3}".format(new_key, i)
-                    i += 1
-                old_item.name = name
-            
-            # update the enum
-            self._self_update[0] += 1
-            self.update_enum()
-            self._self_update[0] -= 1
-        # end def
-        
-        def enum_update(self, context):
-            # necessary to avoid recursive calls
-            if self._self_update[0]:
-                return
-            
-            self._dont_rename[0] = True
-            self.active = self.enum
-            self._dont_rename[0] = False
-            
-            self.on_item_select()
-        # end def
-        
-        collection = bpy.props.CollectionProperty(
-            type=type)
-        active = bpy.props.StringProperty(
-            name="Name",
-            description="Name of the active {}".format(name),
-            options=options,
-            update=active_update)
-        enum = bpy.props.EnumProperty(
-            items=[],
-            name="Choose",
-            description="Choose {}".format(name),
-            default=set(),
-            options={'ENUM_FLAG'},
-            update=enum_update)
-        
-        return collection, active, enum
-    # end def
-    
-    def add(self, name="", **kwargs):
-        if not name:
-            name = 'Untitled'
-        _name = name
-        
-        existing_names = [item.name for item in self.collection]
-        i = 1
-        while name in existing_names:
-            name = "{}.{:0>3}".format(_name, i)
-            i += 1
-        
-        instance = self.collection.add()
-        instance.name = name
-        
-        for key, value in kwargs.items():
-            setattr(instance, key, value)
-        
-        self._self_update[0] += 1
-        self.active = name
-        self.update_enum()
-        self._self_update[0] -= 1
-        
-        return instance
-    
-    def remove(self, key):
-        if isinstance(key, int):
-            i = key
-        else:
-            i = self.indexof(key)
-        
-        # Currently remove() ignores non-existing indices...
-        # In the case this behavior changes, we have the try block.
-        try:
-            self.collection.remove(i)
-        except:
-            pass
-        
-        self._self_update[0] += 1
-        if len(self.collection) != 0:
-            i = min(i, len(self.collection) - 1)
-            self.active = self.collection[i].name
-        else:
-            self.active = ""
-        self.update_enum()
-        self._self_update[0] -= 1
-    
-    def get_item(self, key=None):
-        if key is None:
-            i = self.indexof(self.active)
-        elif isinstance(key, int):
-            i = key
-        else:
-            i = self.indexof(key)
-        
-        try:
-            return self.collection[i]
-        except:
-            return None
-    
-    def indexof(self, key):
-        return next((i for i, v in enumerate(self.collection) \
-            if v.name == key), -1)
-        
-        # Which is more Pythonic?
-        
-        #for i, item in enumerate(self.collection):
-        #    if item.name == key:
-        #        return i
-        #return -1 # non-existing index
-    
-    def update_enum(self):
-        names = []
-        items = []
-        for item in self.collection:
-            names.append(item.name)
-            items.append((item.name, item.name, ""))
-        
-        prop_class, prop_params = type(self).enum
-        prop_params["items"] = items
-        if len(items) == 0:
-            prop_params["default"] = set()
-            prop_params["options"] = {'ENUM_FLAG'}
-        else:
-            # Somewhy active may be left from previous times,
-            # I don't want to dig now why that happens.
-            if self.active not in names:
-                self.active = items[0][0]
-            prop_params["default"] = self.active
-            prop_params["options"] = set()
-        
-        # Can this cause problems? In the near future, shouldn't...
-        type(self).enum = (prop_class, prop_params)
-        #type(self).enum = bpy.props.EnumProperty(**prop_params)
-        
-        if len(items) != 0:
-            self.enum = self.active
-    
-    def on_item_select(self):
-        pass
-    
-    data_name = ""
-    op_new = ""
-    op_delete = ""
-    icon = 'DOT'
-    
-    def draw(self, context, layout):
-        if len(self.collection) == 0:
-            if self.op_new:
-                layout.operator(self.op_new, icon=self.icon)
-            else:
-                layout.label(
-                    text="({})".format(self.data_name),
-                    icon=self.icon)
-            return
-        
-        row = layout.row(align=True)
-        row.prop_menu_enum(self, "enum", text="", icon=self.icon)
-        row.prop(self, "active", text="")
-        if self.op_new:
-            row.operator(self.op_new, text="", icon='ZOOMIN')
-        if self.op_delete:
-            row.operator(self.op_delete, text="", icon='X')
-# end class
-#============================================================================#
-# ===== PROPERTY DEFINITIONS ===== #
-
-# ===== TRANSFORM EXTRA OPTIONS ===== #
-class TransformExtraOptionsProp(bpy.types.PropertyGroup):
-    use_relative_coords = bpy.props.BoolProperty(
-        name="Relative coordinates", 
-        description="Consider existing transformation as the strating point", 
-        default=True)
-    snap_interpolate_normals_mode = bpy.props.EnumProperty(
-        items=[('NEVER', "Never", "Don't interpolate normals"),
-               ('ALWAYS', "Always", "Always interpolate normals"),
-               ('SMOOTH', "Smoothness-based", "Interpolate normals only "\
-               "for faces with smooth shading"),],
-        name="Normal interpolation", 
-        description="Normal interpolation mode for snapping", 
-        default='SMOOTH')
-    snap_only_to_solid = bpy.props.BoolProperty(
-        name="Snap only to soild", 
-        description="Ignore wireframe/non-solid objects during snapping", 
-        default=False)
-    snap_element_screen_size = bpy.props.IntProperty(
-        name="Snap distance", 
-        description="Radius in pixels for snapping to edges/vertices", 
-        default=8,
-        min=2,
-        max=64)
-    use_comma_separator = bpy.props.BoolProperty(
-        name="Use comma separator",
-        description="Use comma separator when copying/pasting"\
-                    "coordinate values (instead of Tab character)",
-        default=True,
-        options={'HIDDEN'})
-
-# ===== 3D VECTOR LOCATION ===== #
-class LocationProp(bpy.types.PropertyGroup):
-    pos = bpy.props.FloatVectorProperty(
-        name="xyz", description="xyz coords",
-        options={'HIDDEN'}, subtype='XYZ')
-
-# ===== HISTORY ===== #
-def update_history_max_size(self, context):
-    settings = find_settings()
-    
-    history = settings.history
-    
-    prop_class, prop_params = type(history).current_id
-    old_max = prop_params["max"]
-    
-    size = history.max_size
-    try:
-        int_size = int(size)
-        int_size = max(int_size, 0)
-        int_size = min(int_size, history.max_size_limit)
-    except:
-        int_size = old_max
-    
-    if old_max != int_size:
-        prop_params["max"] = int_size
-        type(history).current_id = (prop_class, prop_params)
-    
-    # also: clear immediately?
-    for i in range(len(history.entries) - 1, int_size, -1):
-        history.entries.remove(i)
-    
-    if str(int_size) != size:
-        # update history.max_size if it's not inside the limits
-        history.max_size = str(int_size)
-
-def update_history_id(self, context):
-    scene = bpy.context.scene
-    
-    settings = find_settings()
-    history = settings.history
-    
-    pos = history.get_pos()
-    if pos is not None:
-        # History doesn't depend on view (?)
-        cursor_pos = get_cursor_location(scene=scene)
-        
-        if CursorHistoryProp.update_cursor_on_id_change:
-            # Set cursor position anyway (we're changing v3d's
-            # cursor, which may be separate from scene's)
-            # This, however, should be done cautiously
-            # from scripts, since, e.g., CursorMonitor
-            # can supply wrong context -> cursor will be set
-            # in a different view than required
-            set_cursor_location(pos, v3d=context.space_data)
-        
-        if pos != cursor_pos:
-            if (history.current_id == 0) and (history.last_id <= 1):
-                history.last_id = 1
-            else:
-                history.last_id = history.curr_id
-            history.curr_id = history.current_id
-
-class CursorHistoryProp(bpy.types.PropertyGroup):
-    max_size_limit = 500
-    
-    update_cursor_on_id_change = True
-    
-    show_trace = bpy.props.BoolProperty(
-        name="Trace",
-        description="Show history trace",
-        default=False)
-    max_size = bpy.props.StringProperty(
-        name="Size",
-        description="History max size",
-        default=str(50),
-        update=update_history_max_size)
-    current_id = bpy.props.IntProperty(
-        name="Index",
-        description="Current position in cursor location history",
-        default=50,
-        min=0,
-        max=50,
-        update=update_history_id)
-    entries = bpy.props.CollectionProperty(
-        type=LocationProp)
-    
-    curr_id = bpy.props.IntProperty(options={'HIDDEN'})
-    last_id = bpy.props.IntProperty(options={'HIDDEN'})
-    
-    def get_pos(self, id = None):
-        if id is None:
-            id = self.current_id
-        
-        id = min(max(id, 0), len(self.entries) - 1)
-        
-        if id < 0:
-            # history is empty
-            return None
-        
-        return self.entries[id].pos
-    
-    # for updating the upper bound on file load
-    def update_max_size(self):
-        prop_class, prop_params = type(self).current_id
-        # self.max_size expected to be always a correct integer
-        prop_params["max"] = int(self.max_size)
-        type(self).current_id = (prop_class, prop_params)
-    
-    def draw_trace(self, context):
-        bgl.glColor4f(0.75, 1.0, 0.75, 1.0)
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        for entry in self.entries:
-            p = entry.pos
-            bgl.glVertex3f(p[0], p[1], p[2])
-        bgl.glEnd()
-    
-    def draw_offset(self, context):
-        bgl.glShadeModel(bgl.GL_SMOOTH)
-        
-        tfm_operator = CursorDynamicSettings.active_transform_operator
-        
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        
-        if tfm_operator:
-            p = tfm_operator.particles[0]. \
-                get_initial_matrix().to_translation()
-        else:
-            p = self.get_pos(self.last_id)
-        bgl.glColor4f(1.0, 0.75, 0.5, 1.0)
-        bgl.glVertex3f(p[0], p[1], p[2])
-        
-        p = get_cursor_location(v3d=context.space_data)
-        bgl.glColor4f(1.0, 1.0, 0.25, 1.0)
-        bgl.glVertex3f(p[0], p[1], p[2])
-        
-        bgl.glEnd()
-
-# ===== BOOKMARK ===== #
-class BookmarkProp(bpy.types.PropertyGroup):
-    name = bpy.props.StringProperty(
-        name="name", description="bookmark name",
-        options={'HIDDEN'})
-    pos = bpy.props.FloatVectorProperty(
-        name="xyz", description="xyz coords",
-        options={'HIDDEN'}, subtype='XYZ')
-
-class BookmarkIDBlock(PseudoIDBlockBase):
-    # Somewhy instance members aren't seen in update()
-    # callbacks... but class members are.
-    _self_update = [0]
-    _dont_rename = [False]
-    
-    data_name = "Bookmark"
-    op_new = "scene.cursor_3d_new_bookmark"
-    op_delete = "scene.cursor_3d_delete_bookmark"
-    icon = 'CURSOR'
-    
-    collection, active, enum = PseudoIDBlockBase.create_props(
-        BookmarkProp, "Bookmark")
-
-class NewCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_new_bookmark"
-    bl_label = "New Bookmark"
-    bl_description = "Add a new bookmark"
-    
-    name = bpy.props.StringProperty(
-        name="Name",
-        description="Name of the new bookmark",
-        default="Mark")
-    
-    @classmethod
-    def poll(cls, context):
-        return context.area.type == 'VIEW_3D'
-    
-    def execute(self, context):
-        settings = find_settings()
-        library = settings.libraries.get_item()
-        if not library:
-            return {'CANCELLED'}
-        
-        bookmark = library.bookmarks.add(name=self.name)
-        
-        cusor_pos = get_cursor_location(v3d=context.space_data)
-        
-        try:
-            bookmark.pos = library.convert_from_abs(context.space_data,
-                                                    cusor_pos, True)
-        except Exception as exc:
-            self.report('ERROR_INVALID_CONTEXT', exc.args[0])
-            return {'CANCELLED'}
-        
-        return {'FINISHED'}
-
-class DeleteCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_delete_bookmark"
-    bl_label = "Delete Bookmark"
-    bl_description = "Delete active bookmark"
-    
-    def execute(self, context):
-        settings = find_settings()
-        library = settings.libraries.get_item()
-        if not library:
-            return {'CANCELLED'}
-        
-        name = library.bookmarks.active
-        
-        library.bookmarks.remove(key=name)
-        
-        return {'FINISHED'}
-
-class OverwriteCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_overwrite_bookmark"
-    bl_label = "Overwrite"
-    bl_description = "Overwrite active bookmark "\
-        "with the current cursor location"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.area.type == 'VIEW_3D'
-    
-    def execute(self, context):
-        settings = find_settings()
-        library = settings.libraries.get_item()
-        if not library:
-            return {'CANCELLED'}
-        
-        bookmark = library.bookmarks.get_item()
-        if not bookmark:
-            return {'CANCELLED'}
-        
-        cusor_pos = get_cursor_location(v3d=context.space_data)
-        
-        try:
-            bookmark.pos = library.convert_from_abs(context.space_data,
-                                                    cusor_pos, True)
-        except Exception as exc:
-            self.report('ERROR_INVALID_CONTEXT', exc.args[0])
-            return {'CANCELLED'}
-        
-        CursorDynamicSettings.recalc_csu(context, 'PRESS')
-        
-        return {'FINISHED'}
-
-class RecallCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_recall_bookmark"
-    bl_label = "Recall"
-    bl_description = "Move cursor to the active bookmark"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.area.type == 'VIEW_3D'
-    
-    def execute(self, context):
-        settings = find_settings()
-        library = settings.libraries.get_item()
-        if not library:
-            return {'CANCELLED'}
-        
-        bookmark = library.bookmarks.get_item()
-        if not bookmark:
-            return {'CANCELLED'}
-        
-        try:
-            bookmark_pos = library.convert_to_abs(context.space_data,
-                                                  bookmark.pos, True)
-            set_cursor_location(bookmark_pos, v3d=context.space_data)
-        except Exception as exc:
-            self.report('ERROR_INVALID_CONTEXT', exc.args[0])
-            return {'CANCELLED'}
-        
-        CursorDynamicSettings.recalc_csu(context)
-        
-        return {'FINISHED'}
-
-class SwapCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_swap_bookmark"
-    bl_label = "Swap"
-    bl_description = "Swap cursor position with the active bookmark"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.area.type == 'VIEW_3D'
-    
-    def execute(self, context):
-        settings = find_settings()
-        library = settings.libraries.get_item()
-        if not library:
-            return {'CANCELLED'}
-        
-        bookmark = library.bookmarks.get_item()
-        if not bookmark:
-            return {'CANCELLED'}
-        
-        cusor_pos = get_cursor_location(v3d=context.space_data)
-        
-        try:
-            bookmark_pos = library.convert_to_abs(context.space_data,
-                                                  bookmark.pos, True)
-            
-            set_cursor_location(bookmark_pos, v3d=context.space_data)
-            
-            bookmark.pos = library.convert_from_abs(context.space_data,
-                                                    cusor_pos, True,
-                use_history=False)
-        except Exception as exc:
-            self.report('ERROR_INVALID_CONTEXT', exc.args[0])
-            return {'CANCELLED'}
-        
-        CursorDynamicSettings.recalc_csu(context)
-        
-        return {'FINISHED'}
-
-# Will this be used?
-class SnapSelectionToCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_snap_selection_to_bookmark"
-    bl_label = "Snap Selection"
-    bl_description = "Snap selection to the active bookmark"
-
-# Will this be used?
-class AddEmptyAtCursor3DBookmark(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_add_empty_at_bookmark"
-    bl_label = "Add Empty"
-    bl_description = "Add new Empty at the active bookmark"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.area.type == 'VIEW_3D'
-    
-    def execute(self, context):
-        settings = find_settings()
-        library = settings.libraries.get_item()
-        if not library:
-            return {'CANCELLED'}
-        
-        bookmark = library.bookmarks.get_item()
-        if not bookmark:
-            return {'CANCELLED'}
-        
-        try:
-            matrix = library.get_matrix(use_history=False,
-                                        v3d=context.space_data, warn=True)
-            bookmark_pos = matrix * bookmark.pos
-        except Exception as exc:
-            self.report('ERROR_INVALID_CONTEXT', exc.args[0])
-            return {'CANCELLED'}
-        
-        name = "{}.{}".format(library.name, bookmark.name)
-        obj = bpy.data.objects.new(name, None)
-        obj.matrix_world = to_matrix4x4(matrix, bookmark_pos)
-        context.scene.objects.link(obj)
-        
-        """
-        for sel_obj in list(context.selected_objects):
-            sel_obj.select = False
-        obj.select = True
-        context.scene.objects.active = obj
-        
-        # We need this to update bookmark position if
-        # library's system is local/scaled/normal/etc.
-        CursorDynamicSettings.recalc_csu(context, "PRESS")
-        """
-        
-        # TODO: exit from editmode? It has separate history!
-        # If we just link object to scene, it will not trigger
-        # addition of new entry to Undo history
-        bpy.ops.ed.undo_push(message="Add Object")
-        
-        return {'FINISHED'}
-
-# ===== BOOKMARK LIBRARY ===== #
-class BookmarkLibraryProp(bpy.types.PropertyGroup):
-    name = bpy.props.StringProperty(
-        name="Name", description="Name of the bookmark library",
-        options={'HIDDEN'})
-    bookmarks = bpy.props.PointerProperty(
-        type=BookmarkIDBlock,
-        options={'HIDDEN'})
-    system = bpy.props.EnumProperty(
-        items=[
-            ('GLOBAL', "Global", "Global (absolute) coordinates"),
-            ('LOCAL', "Local", "Local coordinate system, "\
-                "relative to the active object"),
-            ('SCALED', "Scaled", "Scaled local coordinate system, "\
-                "relative to the active object"),
-            ('NORMAL', "Normal", "Normal coordinate system, "\
-                "relative to the selected elements"),
-            ('CONTEXT', "Context", "Current transform orientation; "\
-                "origin depends on selection"),
-        ],
-        default="GLOBAL",
-        name="System",
-        description="Coordinate system in which to store/recall "\
-                    "cursor locations",
-        options={'HIDDEN'})
-    offset = bpy.props.BoolProperty(
-        name="Offset",
-        description="Store/recall relative to the last cursor position",
-        default=False,
-        options={'HIDDEN'})
-    
-    # Returned None means "operation is not aplicable"
-    def get_matrix(self, use_history, v3d, warn=True, **kwargs):
-        #particles, csu = gather_particles(**kwargs)
-        
-        # Ensure we have relevant CSU (Blender will crash
-        # if we use the old one after Undo/Redo)
-        CursorDynamicSettings.recalc_csu(bpy.context)
-        
-        csu = CursorDynamicSettings.csu
-        
-        if self.offset:
-            # history? or keep separate for each scene?
-            if not use_history:
-                csu.source_pos = get_cursor_location(v3d=v3d)
-            else:
-                settings = find_settings()
-                history = settings.history
-                csu.source_pos = history.get_pos(history.last_id)
-        else:
-            csu.source_pos = Vector()
-        
-        active_obj = csu.tou.scene.objects.active
-        
-        if self.system == 'GLOBAL':
-            sys_name = 'GLOBAL'
-            pivot = 'WORLD'
-        elif self.system == 'LOCAL':
-            if not active_obj:
-                if warn:
-                    raise Exception("There is no active object")
-                return None
-            sys_name = 'LOCAL'
-            pivot = 'ACTIVE'
-        elif self.system == 'SCALED':
-            if not active_obj:
-                if warn:
-                    raise Exception("There is no active object")
-                return None
-            sys_name = 'Scaled'
-            pivot = 'ACTIVE'
-        elif self.system == 'NORMAL':
-            if (not active_obj) or ('EDIT' not in active_obj.mode):
-                if warn:
-                    raise Exception("Active object must be in Edit mode")
-                return None
-            sys_name = 'NORMAL'
-            pivot = 'MEDIAN' # ?
-        elif self.system == 'CONTEXT':
-            sys_name = None # use current orientation
-            pivot = None
-            
-            if active_obj and (active_obj.mode != 'OBJECT'):
-                if len(particles) == 0:
-                    pivot = active_obj.matrix_world.to_translation()
-        
-        return csu.get_matrix(sys_name, self.offset, pivot)
-    
-    def convert_to_abs(self, v3d, pos, warn=False, **kwargs):
-        kwargs.pop("use_history", None)
-        matrix = self.get_matrix(False, v3d, warn, **kwargs)
-        if not matrix:
-            return None
-        return matrix * pos
-    
-    def convert_from_abs(self, v3d, pos, warn=False, **kwargs):
-        use_history = kwargs.pop("use_history", True)
-        matrix = self.get_matrix(use_history, v3d, warn, **kwargs)
-        if not matrix:
-            return None
-        
-        try:
-            return matrix.inverted() * pos
-        except:
-            # this is some degenerate object
-            return Vector()
-    
-    def draw_bookmark(self, context):
-        r = context.region
-        rv3d = context.region_data
-        
-        bookmark = self.bookmarks.get_item()
-        if not bookmark:
-            return
-        
-        pos = self.convert_to_abs(context.space_data, bookmark.pos)
-        if pos is None:
-            return
-        
-        projected = location_3d_to_region_2d(r, rv3d, pos)
-        
-        if projected:
-            # Store previous OpenGL settings
-            smooth_prev = gl_get(bgl.GL_SMOOTH)
-            
-            bgl.glShadeModel(bgl.GL_SMOOTH)
-            bgl.glLineWidth(2)
-            bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
-            bgl.glBegin(bgl.GL_LINE_STRIP)
-            radius = 6
-            n = 8
-            da = 2 * math.pi / n
-            x, y = projected
-            x, y = int(x), int(y)
-            for i in range(n + 1):
-                a = i * da
-                dx = math.sin(a) * radius
-                dy = math.cos(a) * radius
-                if (i % 2) == 0:
-                    bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
-                else:
-                    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-                bgl.glVertex2i(x + int(dx), y + int(dy))
-            bgl.glEnd()
-            
-            # Restore previous OpenGL settings
-            gl_enable(bgl.GL_SMOOTH, smooth_prev)
-
-class BookmarkLibraryIDBlock(PseudoIDBlockBase):
-    # Somewhy instance members aren't seen in update()
-    # callbacks... but class members are.
-    _self_update = [0]
-    _dont_rename = [False]
-    
-    data_name = "Bookmark Library"
-    op_new = "scene.cursor_3d_new_bookmark_library"
-    op_delete = "scene.cursor_3d_delete_bookmark_library"
-    icon = 'BOOKMARKS'
-    
-    collection, active, enum = PseudoIDBlockBase.create_props(
-        BookmarkLibraryProp, "Bookmark Library")
-    
-    def on_item_select(self):
-        library = self.get_item()
-        library.bookmarks.update_enum()
-
-class NewCursor3DBookmarkLibrary(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_new_bookmark_library"
-    bl_label = "New Library"
-    bl_description = "Add a new bookmark library"
-    
-    name = bpy.props.StringProperty(
-        name="Name",
-        description="Name of the new library",
-        default="Lib")
-    
-    def execute(self, context):
-        settings = find_settings()
-        
-        settings.libraries.add(name=self.name)
-        
-        return {'FINISHED'}
-
-class DeleteCursor3DBookmarkLibrary(bpy.types.Operator):
-    bl_idname = "scene.cursor_3d_delete_bookmark_library"
-    bl_label = "Delete Library"
-    bl_description = "Delete active bookmark library"
-    
-    def execute(self, context):
-        settings = find_settings()
-        
-        name = settings.libraries.active
-        
-        settings.libraries.remove(key=name)
-        
-        return {'FINISHED'}
-
-# ===== MAIN PROPERTIES ===== #
-# TODO: ~a bug? Somewhy tooltip shows "Cursor3DToolsSettings.foo"
-# instead of "bpy.types.Screen.cursor_3d_tools_settings.foo"
-class Cursor3DToolsSettings(bpy.types.PropertyGroup):
-    transform_options = bpy.props.PointerProperty(
-        type=TransformExtraOptionsProp,
-        options={'HIDDEN'})
-    
-    draw_guides = bpy.props.BoolProperty(
-        name="Guides",
-        description="Display guides",
-        default=True)
-    
-    draw_snap_elements = bpy.props.BoolProperty(
-        name="Snap elements",
-        description="Display snap elements",
-        default=True)
-    
-    draw_N = bpy.props.BoolProperty(
-        name="Surface normal",
-        description="Display surface normal",
-        default=True)
-    
-    draw_T1 = bpy.props.BoolProperty(
-        name="Surface 1st tangential",
-        description="Display 1st surface tangential",
-        default=True)
-    
-    draw_T2 = bpy.props.BoolProperty(
-        name="Surface 2nd tangential",
-        description="Display 2nd surface tangential",
-        default=True)
-    
-    stick_to_obj = bpy.props.BoolProperty(
-        name="Stick to objects",
-        description="Move cursor along with object it was snapped to",
-        default=True)
-    
-    # HISTORY-RELATED
-    history = bpy.props.PointerProperty(
-        type=CursorHistoryProp,
-        options={'HIDDEN'})
-    
-    # BOOKMARK-RELATED
-    libraries = bpy.props.PointerProperty(
-        type=BookmarkLibraryIDBlock,
-        options={'HIDDEN'})
-    
-    show_bookmarks = bpy.props.BoolProperty(
-        name="Show bookmarks",
-        description="Show active bookmark in 3D view",
-        default=True,
-        options={'HIDDEN'})
-    
-    free_coord_precision = bpy.props.IntProperty(
-        name="Coord precision",
-        description="Numer of digits afer comma "\
-                    "for displayed coordinate values",
-        default=4,
-        min=0,
-        max=10,
-        options={'HIDDEN'})
-
-class Cursor3DToolsSceneSettings(bpy.types.PropertyGroup):
-    stick_obj_name = bpy.props.StringProperty(
-        name="Stick-to-object name",
-        description="Name of the object to stick cursor to",
-        options={'HIDDEN'})
-    stick_obj_pos = bpy.props.FloatVectorProperty(
-        default=(0.0, 0.0, 0.0),
-        options={'HIDDEN'},
-        subtype='XYZ')
-
-# ===== CURSOR RUNTIME PROPERTIES ===== #
-class CursorRuntimeSettings(bpy.types.PropertyGroup):
-    current_monitor_id = bpy.props.IntProperty(
-        default=0,
-        options={'HIDDEN'})
-    
-    surface_pos = bpy.props.FloatVectorProperty(
-        default=(0.0, 0.0, 0.0),
-        options={'HIDDEN'},
-        subtype='XYZ')
-
-class CursorDynamicSettings:
-    local_matrix = Matrix()
-    
-    active_transform_operator = None
-    
-    csu = None
-    
-    active_scene_hash = 0
-    
-    @classmethod
-    def recalc_csu(cls, context, event_value=None):
-        scene_hash_changed = (cls.active_scene_hash != hash(context.scene))
-        cls.active_scene_hash = hash(context.scene)
-        
-        # Don't recalc if mouse is over some UI panel!
-        # (otherwise, this may lead to applying operator
-        # (e.g. Subdivide) in Edit Mode, even if user
-        # just wants to change some operator setting)
-        clicked = (event_value in {'PRESS', 'RELEASE'}) and \
-            (context.region.type == 'WINDOW')
-        
-        if clicked or scene_hash_changed:
-            particles, cls.csu = gather_particles()
-
-#============================================================================#
-# ===== PANELS AND DIALOGS ===== #
-class TransformExtraOptions(bpy.types.Panel):
-    bl_label = "Transform Extra Options"
-    bl_idname = "OBJECT_PT_transform_extra_options"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "UI"
-    #bl_context = "object"
-    #bl_options = {'DEFAULT_CLOSED'}
-    
-    def draw(self, context):
-        layout = self.layout
-        
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        layout.prop(tfm_opts, "use_relative_coords")
-        layout.prop(tfm_opts, "snap_only_to_solid")
-        layout.prop(tfm_opts, "snap_interpolate_normals_mode", text="")
-        layout.prop(tfm_opts, "use_comma_separator")
-        #layout.prop(tfm_opts, "snap_element_screen_size")
-
-class Cursor3DTools(bpy.types.Panel):
-    bl_label = "3D Cursor Tools"
-    bl_idname = "OBJECT_PT_cursor_3d_tools"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "UI"
-    #bl_context = "object"
-    
-    def draw(self, context):
-        layout = self.layout
-        
-        # Attempt to launch the monitor
-        if bpy.ops.view3d.cursor3d_monitor.poll():
-            bpy.ops.view3d.cursor3d_monitor()
-        
-        # If addon is enabled by default, the new scene
-        # created on Blender startup will have disabled
-        # standard Cursor3D behavior. However, if user
-        # creates new scene, somehow Cursor3D is active
-        # as if nothing happened xD
-        update_keymap(True)
-        #=============================================#
-        
-        settings = find_settings()
-        
-        row = layout.split(0.5)
-        #row = layout.row()
-        row.operator("view3d.set_cursor3d_dialog",
-            "Set", 'CURSOR')
-        row = row.split(1 / 3, align=True)
-        #row = row.row(align=True)
-        row.prop(settings, "draw_guides",
-            text="", icon='MANIPUL', toggle=True)
-        row.prop(settings, "draw_snap_elements",
-            text="", icon='EDITMODE_HLT', toggle=True)
-        row.prop(settings, "stick_to_obj",
-            text="", icon='SNAP_ON', toggle=True)
-        
-        row = layout.row()
-        row.label(text="Draw")
-        row = row.split(1 / 3, align=True)
-        row.prop(settings, "draw_N",
-            text="N", toggle=True, index=0)
-        row.prop(settings, "draw_T1",
-            text="T1", toggle=True, index=1)
-        row.prop(settings, "draw_T2",
-            text="T2", toggle=True, index=2)
-        
-        # === HISTORY === #
-        history = settings.history
-        row = layout.row(align=True)
-        row.prop(history, "show_trace", text="", icon='SORTTIME')
-        row = row.split(0.35, True)
-        row.prop(history, "max_size", text="")
-        row.prop(history, "current_id", text="")
-        
-        # === BOOKMARK LIBRARIES === #
-        settings.libraries.draw(context, layout)
-        
-        library = settings.libraries.get_item()
-        
-        if library is None:
-            return
-        
-        row = layout.row()
-        row.prop(settings, "show_bookmarks",
-            text="", icon='RESTRICT_VIEW_OFF')
-        row = row.row(align=True)
-        row.prop(library, "system", text="")
-        row.prop(library, "offset", text="",
-            icon='ARROW_LEFTRIGHT')
-        
-        # === BOOKMARKS === #
-        library.bookmarks.draw(context, layout)
-        
-        if len(library.bookmarks.collection) == 0:
-            return
-        
-        row = layout.row()
-        row = row.split(align=True)
-        # PASTEDOWN
-        # COPYDOWN
-        row.operator("scene.cursor_3d_overwrite_bookmark",
-            text="", icon='REC')
-        row.operator("scene.cursor_3d_swap_bookmark",
-            text="", icon='FILE_REFRESH')
-        row.operator("scene.cursor_3d_recall_bookmark",
-            text="", icon='FILE_TICK')
-        row.operator("scene.cursor_3d_add_empty_at_bookmark",
-            text="", icon='EMPTY_DATA')
-        # Not implemented (and maybe shouldn't)
-        #row.operator("scene.cursor_3d_snap_selection_to_bookmark",
-        #    text="", icon='SNAP_ON')
-
-class SetCursorDialog(bpy.types.Operator):
-    bl_idname = "view3d.set_cursor3d_dialog"
-    bl_label = "Set 3D Cursor"
-    bl_description = "Set 3D Cursor XYZ values"
-    
-    pos = bpy.props.FloatVectorProperty(
-        name="Location",
-        description="3D Cursor location in current coordinate system",
-        subtype='XYZ',
-        )
-    
-    @classmethod
-    def poll(cls, context):
-        return context.area.type == 'VIEW_3D'
-    
-    def execute(self, context):
-        scene = context.scene
-        
-        # "current system" / "relative" could have changed
-        self.matrix = self.csu.get_matrix()
-        
-        pos = self.matrix * self.pos
-        set_cursor_location(pos, v3d=context.space_data)
-        
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        scene = context.scene
-        
-        cursor_pos = get_cursor_location(v3d=context.space_data)
-        
-        particles, self.csu = gather_particles(context=context)
-        self.csu.source_pos = cursor_pos
-        
-        self.matrix = self.csu.get_matrix()
-        
-        try:
-            self.pos = self.matrix.inverted() * cursor_pos
-        except:
-            # this is some degenerate system
-            self.pos = Vector()
-        
-        wm = context.window_manager
-        return wm.invoke_props_dialog(self, width=160)
-    
-    def draw(self, context):
-        layout = self.layout
-        
-        settings = find_settings()
-        tfm_opts = settings.transform_options
-        
-        v3d = context.space_data
-        
-        col = layout.column()
-        col.prop(self, "pos", text="")
-        
-        row = layout.row()
-        row.prop(tfm_opts, "use_relative_coords", text="Relative")
-        row.prop(v3d, "transform_orientation", text="")
-
-class AlignOrientation(bpy.types.Operator):
-    bl_idname = "view3d.align_orientation"
-    bl_label = "Align Orientation"
-    bl_description = "Rotates active object to match axis of current "\
-        "orientation to axis of another orientation"
-    
-    axes_items = [
-        ('X', 'X', 'X axis'),
-        ('Y', 'Y', 'Y axis'),
-        ('Z', 'Z', 'Z axis'),
-        ('-X', '-X', '-X axis'),
-        ('-Y', '-Y', '-Y axis'),
-        ('-Z', '-Z', '-Z axis'),
-    ]
-    
-    axes_items_ = [
-        ('X', 'X', 'X axis'),
-        ('Y', 'Y', 'Y axis'),
-        ('Z', 'Z', 'Z axis'),
-        (' ', ' ', 'Same as source axis'),
-    ]
-    
-    axes_ids = {'X':0, 'Y':1, 'Z':2}
-    
-    def get_orients(self, context):
-        orients = []
-        orients.append(('GLOBAL', "Global", ""))
-        orients.append(('LOCAL', "Local", ""))
-        orients.append(('GIMBAL', "Gimbal", ""))
-        orients.append(('NORMAL', "Normal", ""))
-        orients.append(('VIEW', "View", ""))
-        
-        for orientation in context.scene.orientations:
-            name = orientation.name
-            orients.append((name, name, ""))
-        
-        return orients
-    
-    src_axis = bpy.props.EnumProperty(default='Z', items=axes_items,
-                                      name="Initial axis")
-    #src_orient = bpy.props.EnumProperty(default='GLOBAL', items=get_orients)
-    
-    dest_axis = bpy.props.EnumProperty(default=' ', items=axes_items_,
-                                       name="Final axis")
-    dest_orient = bpy.props.EnumProperty(items=get_orients,
-                                         name="Final orientation")
-    
-    @classmethod
-    def poll(cls, context):
-        return (context.area.type == 'VIEW_3D') and context.object
-    
-    def execute(self, context):
-        obj = context.object
-        scene = context.scene
-        v3d = context.space_data
-        rv3d = context.region_data
-        
-        tou = TransformOrientationUtility(scene, v3d, rv3d)
-        
-        src_matrix = tou.get_matrix(v3d.transform_orientation)
-        src_axes = MatrixDecompose(src_matrix)
-        src_axis_name = self.src_axis
-        if src_axis_name.startswith("-"):
-            src_axis_name = src_axis_name[1:]
-            src_axis = -src_axes[self.axes_ids[src_axis_name]]
-        else:
-            src_axis = src_axes[self.axes_ids[src_axis_name]]
-        
-        dest_matrix = tou.get_matrix(self.dest_orient)
-        dest_axes = MatrixDecompose(dest_matrix)
-        if self.dest_axis != ' ':
-            dest_axis_name = self.dest_axis
-        else:
-            dest_axis_name = src_axis_name
-        dest_axis = dest_axes[self.axes_ids[dest_axis_name]]
-        
-        q = src_axis.rotation_difference(dest_axis)
-        
-        m = obj.matrix_world.to_3x3()
-        m.rotate(q)
-        m.resize_4x4()
-        m.translation = obj.matrix_world.translation.copy()
-        
-        obj.matrix_world = m
-        
-        bpy.ops.ed.undo_push(message="Align Orientation")
-        
-        return {'FINISHED'}
-    
-    # ATTENTION!
-    # This _must_ be a dialog, because with 'UNDO' option
-    # the last selected orientation may revert to the previous state
-    def invoke(self, context, event):
-        wm = context.window_manager
-        return wm.invoke_props_dialog(self)
-
-class CopyOrientation(bpy.types.Operator):
-    bl_idname = "view3d.copy_orientation"
-    bl_label = "Copy Orientation"
-    bl_description = "Makes a copy of current orientation"
-    
-    def execute(self, context):
-        scene = context.scene
-        v3d = context.space_data
-        rv3d = context.region_data
-        
-        tou = TransformOrientationUtility(scene, v3d, rv3d)
-        
-        orient = create_transform_orientation(scene,
-            name=tou.get()+".copy", matrix=tou.get_matrix())
-        
-        tou.set(orient.name)
-        
-        return {'FINISHED'}
-
-def transform_orientations_panel_extension(self, context):
-    row = self.layout.row()
-    row.operator("view3d.align_orientation", text="Align")
-    row.operator("view3d.copy_orientation", text="Copy")
-
-# ===== CURSOR MONITOR ===== #
-class CursorMonitor(bpy.types.Operator):
-    '''Monitor changes in cursor location and write to history'''
-    bl_idname = "view3d.cursor3d_monitor"
-    bl_label = "Cursor Monitor"
-    
-    # A class-level variable (it must be accessed from poll())
-    is_running = False
-    
-    storage = {}
-    
-    @classmethod
-    def poll(cls, context):
-        try:
-            runtime_settings = find_runtime_settings()
-            if not runtime_settings:
-                return False
-            
-            # When addon is enabled by default and
-            # user started another new scene, is_running
-            # would still be True
-            return (not CursorMonitor.is_running) or \
-                (runtime_settings.current_monitor_id == 0)
-        except Exception as e:
-            print("Cursor monitor exeption in poll:\n" + str(e))
-            return False
-    
-    def modal(self, context, event):
-        try:
-            return self._modal(context, event)
-        except Exception as e:
-            print("Cursor monitor exeption in modal:\n" + str(e))
-            # Remove callbacks at any cost
-            self.cancel(context)
-            #raise
-            return {'CANCELLED'}
-    
-    def _modal(self, context, event):
-        runtime_settings = find_runtime_settings()
-        
-        # ATTENTION: will this work correctly when another
-        # blend is loaded? (it should, since all scripts
-        # seem to be reloaded in such case)
-        if (runtime_settings is None) or \
-                (self.id != runtime_settings.current_monitor_id):
-            # Another (newer) monitor was launched;
-            # this one should stop.
-            # (OR addon was disabled)
-            return self.cancel(context)
-        
-        # Somewhy after addon re-registration
-        # this permanently becomes False
-        CursorMonitor.is_running = True
-        
-        if self.update_storage(runtime_settings):
-            # hmm... can this cause flickering of menus?
-            context.area.tag_redraw()
-        
-        settings = find_settings()
-        
-        # ================== #
-        # Update bookmark enums when addon is initialized.
-        # Since CursorMonitor operator can be called from draw(),
-        # we have to postpone all re-registration-related tasks
-        # (such as redefining the enums).
-        if self.just_initialized:
-            # update the relevant enums, bounds and other options
-            # (is_running becomes False once another scene is loaded,
-            # so this operator gets restarted)
-            settings.history.update_max_size()
-            settings.libraries.update_enum()
-            library = settings.libraries.get_item()
-            if library:
-                library.bookmarks.update_enum()
-            
-            self.just_initialized = False
-        # ================== #
-        
-        # Seems like recalc_csu() in this place causes trouble
-        # if space type is switched from 3D to e.g. UV
-        '''
-        tfm_operator = CursorDynamicSettings.active_transform_operator
-        if tfm_operator:
-            CursorDynamicSettings.csu = tfm_operator.csu
-        else:
-            CursorDynamicSettings.recalc_csu(context, event.value)
-        '''
-        
-        return {'PASS_THROUGH'}
-    
-    def update_storage(self, runtime_settings):
-        if CursorDynamicSettings.active_transform_operator:
-            # Don't add to history while operator is running
-            return False
-        
-        new_pos = None
-        
-        last_locations = {}
-        
-        for scene in bpy.data.scenes:
-            # History doesn't depend on view (?)
-            curr_pos = get_cursor_location(scene=scene)
-            
-            last_locations[scene.name] = curr_pos
-            
-            # Ignore newly-created or some renamed scenes
-            if scene.name in self.last_locations:
-                if curr_pos != self.last_locations[scene.name]:
-                    new_pos = curr_pos
-            elif runtime_settings.current_monitor_id == 0:
-                # startup location should be added
-                new_pos = curr_pos
-        
-        # Seems like scene.cursor_location is fast enough here
-        # -> no need to resort to v3d.cursor_location.
-        """
-        screen = bpy.context.screen
-        scene = screen.scene
-        v3d = None
-        for area in screen.areas:
-            for space in area.spaces:
-                if space.type == 'VIEW_3D':
-                    v3d = space
-                    break
-        
-        if v3d is not None:
-            curr_pos = get_cursor_location(v3d=v3d)
-            
-            last_locations[scene.name] = curr_pos
-            
-            # Ignore newly-created or some renamed scenes
-            if scene.name in self.last_locations:
-                if curr_pos != self.last_locations[scene.name]:
-                    new_pos = curr_pos
-        """
-        
-        self.last_locations = last_locations
-        
-        if new_pos is not None:
-            settings = find_settings()
-            history = settings.history
-            
-            pos = history.get_pos()
-            if (pos is not None):# and (history.current_id != 0): # ?
-                if pos == new_pos:
-                    return False # self.just_initialized ?
-            
-            entry = history.entries.add()
-            entry.pos = new_pos
-            
-            last_id = len(history.entries) - 1
-            history.entries.move(last_id, 0)
-            
-            if last_id > int(history.max_size):
-                history.entries.remove(last_id)
-            
-            # make sure the most recent history entry is displayed
-            
-            CursorHistoryProp.update_cursor_on_id_change = False
-            history.current_id = 0
-            CursorHistoryProp.update_cursor_on_id_change = True
-            
-            history.curr_id = history.current_id
-            history.last_id = 1
-            
-            return True
-        
-        return False # self.just_initialized ?
-    
-    def execute(self, context):
-        print("Cursor monitor: launched")
-        
-        runtime_settings = find_runtime_settings()
-        
-        self.just_initialized = True
-        
-        self.id = 0
-        
-        self.last_locations = {}
-        
-        # Important! Call update_storage() before assigning
-        # current_monitor_id (used to add startup cursor location)
-        self.update_storage(runtime_settings)
-        
-        # Indicate that this is the most recent monitor.
-        # All others should shut down.
-        self.id = runtime_settings.current_monitor_id + 1
-        runtime_settings.current_monitor_id = self.id
-        
-        CursorMonitor.is_running = True
-        
-        CursorDynamicSettings.recalc_csu(context, 'PRESS')
-        
-        # Currently there seems to be only one window manager
-        context.window_manager.modal_handler_add(self)
-        
-        # I suppose that cursor position would change
-        # only with user interaction.
-        #self._timer = context.window_manager. \
-        #    event_timer_add(0.1, context.window)
-        
-        #'''
-        #self._draw_callback_view = context.region.callback_add( \
-        #    draw_callback_view, (self, context), 'POST_VIEW')
-        self._draw_callback_view = find_region(context.area).\
-            callback_add(draw_callback_view, \
-            (self, context), 'POST_VIEW')
-        self._draw_callback_px = find_region(context.area).\
-            callback_add(draw_callback_px, \
-            (self, context), 'POST_PIXEL')
-        
-        self._draw_header_px = find_region(context.area, 'HEADER').\
-            callback_add(draw_callback_header_px, \
-            (self, context), 'POST_PIXEL')
-        #'''
-        
-        # Here we cannot return 'PASS_THROUGH',
-        # or Blender will crash!
-        return {'RUNNING_MODAL'}
-    
-    def cancel(self, context):
-        CursorMonitor.is_running = False
-        #type(self).is_running = False
-        
-        # Unregister callbacks...
-        #'''
-        #context.region.callback_remove(self._draw_callback_view)
-        find_region(context.area).callback_remove(self._draw_callback_view)
-        find_region(context.area).callback_remove(self._draw_callback_px)
-        
-        find_region(context.area, 'HEADER').\
-            callback_remove(self._draw_header_px)
-        #'''
-        
-        return {'CANCELLED'}
-
-
-# ===== MATH / GEOMETRY UTILITIES ===== #
-def to_matrix4x4(orient, pos):
-    if not isinstance(orient, Matrix):
-        orient = orient.to_matrix()
-    m = orient.to_4x4()
-    m.translation = pos.to_3d()
-    return m
-
-def MatrixCompose(*args):
-    size = len(args)
-    m = Matrix.Identity(size)
-    axes = m.col # m.row
-    
-    if size == 2:
-        for i in (0, 1):
-            c = args[i]
-            if isinstance(c, Vector):
-                axes[i] = c.to_2d()
-            elif hasattr(c, "__iter__"):
-                axes[i] = Vector(c).to_2d()
-            else:
-                axes[i][i] = c
-    else:
-        for i in (0, 1, 2):
-            c = args[i]
-            if isinstance(c, Vector):
-                axes[i][:3] = c.to_3d()
-            elif hasattr(c, "__iter__"):
-                axes[i][:3] = Vector(c).to_3d()
-            else:
-                axes[i][i] = c
-        
-        if size == 4:
-            c = args[3]
-            if isinstance(c, Vector):
-                m.translation = c.to_3d()
-            elif hasattr(c, "__iter__"):
-                m.translation = Vector(c).to_3d()
-    
-    return m
-
-def MatrixDecompose(m, res_size=None):
-    size = len(m)
-    axes = m.col # m.row
-    if res_size is None:
-        res_size = size
-    
-    if res_size == 2:
-        return (axes[0].to_2d(), axes[1].to_2d())
-    else:
-        x = axes[0].to_3d()
-        y = axes[1].to_3d()
-        z = (axes[2].to_3d() if size > 2 else Vector())
-        if res_size == 3:
-            return (x, y, z)
-        
-        t = (m.translation.to_3d() if size == 4 else Vector())
-        if res_size == 4:
-            return (x, y, z, t)
-
-def angle_axis_to_quat(angle, axis):
-    w = math.cos(angle / 2.0)
-    xyz = axis.normalized() * math.sin(angle / 2.0)
-    return Quaternion((w, xyz.x, xyz.y, xyz.z))
-
-def round_step(x, s=1.0):
-    #return math.floor(x * s + 0.5) / s
-    return math.floor(x / s + 0.5) * s
-
-twoPi = 2.0 * math.pi
-def clamp_angle(ang):
-    # Attention! In Python the behaviour is:
-    # -359.0 % 180.0 == 1.0
-    # -359.0 % -180.0 == -179.0
-    ang = (ang % twoPi)
-    return ((ang - twoPi) if (ang > math.pi) else ang)
-
-def prepare_grid_mesh(bm, nx=1, ny=1, sx=1.0, sy=1.0,
-                      z=0.0, xyz_indices=(0,1,2)):
-    vertices = []
-    for i in range(nx + 1):
-        x = 2 * (i / nx) - 1
-        x *= sx
-        for j in range(ny + 1):
-            y = 2 * (j / ny) - 1
-            y *= sy
-            pos = (x, y, z)
-            vert = bm.verts.new((pos[xyz_indices[0]],
-                                 pos[xyz_indices[1]],
-                                 pos[xyz_indices[2]]))
-            vertices.append(vert)
-    
-    nxmax = nx + 1
-    for i in range(nx):
-        i1 = i + 1
-        for j in range(ny):
-            j1 = j + 1
-            verts = [vertices[j + i * nxmax],
-                     vertices[j1 + i * nxmax],
-                     vertices[j1 + i1 * nxmax],
-                     vertices[j + i1 * nxmax]]
-            bm.faces.new(verts)
-    #return
-
-def prepare_gridbox_mesh(subdiv=1):
-    bm = bmesh.new()
-    
-    sides = [
-        (-1, (0,1,2)), # -Z
-        (1, (1,0,2)), # +Z
-        (-1, (1,2,0)), # -Y
-        (1, (0,2,1)), # +Y
-        (-1, (2,0,1)), # -X
-        (1, (2,1,0)), # +X
-        ]
-    
-    for side in sides:
-        prepare_grid_mesh(bm, nx=subdiv, ny=subdiv,
-            z=side[0], xyz_indices=side[1])
-    
-    return bm
-
-# ===== DRAWING UTILITIES ===== #
-class GfxCell:
-    def __init__(self, w, h, color=None, alpha=None, draw=None):
-        self.w = w
-        self.h = h
-        
-        self.color = (0, 0, 0, 1)
-        self.set_color(color, alpha)
-        
-        if draw:
-            self.draw = draw
-    
-    def set_color(self, color=None, alpha=None):
-        if color is None:
-            color = self.color
-        if alpha is None:
-            alpha = (color[3] if len(color) > 3 else self.color[3])
-        self.color = Vector((color[0], color[1], color[2], alpha))
-    
-    def prepare_draw(self, x, y, align=(0, 0)):
-        if self.color[3] <= 0.0:
-            return None
-        
-        if (align[0] != 0) or (align[1] != 0):
-            x -= self.w * align[0]
-            y -= self.h * align[1]
-        
-        x = int(math.floor(x + 0.5))
-        y = int(math.floor(y + 0.5))
-        
-        bgl.glColor4f(*self.color)
-        
-        return x, y
-    
-    def draw(self, x, y, align=(0, 0)):
-        xy = self.prepare_draw(x, y, align)
-        if not xy:
-            return
-        
-        draw_rect(xy[0], xy[1], w, h)
-
-class TextCell(GfxCell):
-    font_id = 0
-    
-    def __init__(self, text="", color=None, alpha=None, font_id=None):
-        if font_id is None:
-            font_id = TextCell.font_id
-        self.font_id = font_id
-        
-        self.set_text(text)
-        
-        self.color = (0, 0, 0, 1)
-        self.set_color(color, alpha)
-    
-    def set_text(self, text):
-        self.text = str(text)
-        dims = blf.dimensions(self.font_id, self.text)
-        self.w = dims[0]
-        dims = blf.dimensions(self.font_id, "dp") # fontheight
-        self.h = dims[1]
-    
-    def draw(self, x, y, align=(0, 0)):
-        xy = self.prepare_draw(x, y, align)
-        if not xy:
-            return
-        
-        blf.position(self.font_id, xy[0], xy[1], 0)
-        blf.draw(self.font_id, self.text)
-
-def find_region(area, region_type='WINDOW'):
-    # 'WINDOW', 'HEADER', 'CHANNELS', 'TEMPORARY',
-    # 'UI', 'TOOLS', 'TOOL_PROPS', 'PREVIEW'
-    for region in area.regions:
-        if region.type == region_type:
-            return region
-
-def draw_text(x, y, value, font_id=0, align=(0, 0), font_height=None):
-    value = str(value)
-    
-    if (align[0] != 0) or (align[1] != 0):
-        dims = blf.dimensions(font_id, value)
-        if font_height is not None:
-            dims = (dims[0], font_height)
-        x -= dims[0] * align[0]
-        y -= dims[1] * align[1]
-    
-    x = int(math.floor(x + 0.5))
-    y = int(math.floor(y + 0.5))
-    
-    blf.position(font_id, x, y, 0)
-    blf.draw(font_id, value)
-
-def draw_rect(x, y, w, h, margin=0, outline=False):
-    if w < 0:
-        x += w
-        w = abs(w)
-    
-    if h < 0:
-        y += h
-        h = abs(h)
-    
-    x = int(x)
-    y = int(y)
-    w = int(w)
-    h = int(h)
-    margin = int(margin)
-    
-    if outline:
-        bgl.glBegin(bgl.GL_LINE_LOOP)
-    else:
-        bgl.glBegin(bgl.GL_TRIANGLE_FAN)
-    bgl.glVertex2i(x - margin, y - margin)
-    bgl.glVertex2i(x + w + margin, y - margin)
-    bgl.glVertex2i(x + w + margin, y + h + margin)
-    bgl.glVertex2i(x - margin, y + h + margin)
-    bgl.glEnd()
-
-def append_round_rect(verts, x, y, w, h, rw, rh=None):
-    if rh is None:
-        rh = rw
-    
-    if w < 0:
-        x += w
-        w = abs(w)
-    
-    if h < 0:
-        y += h
-        h = abs(h)
-    
-    if rw < 0:
-        rw = min(abs(rw), w * 0.5)
-        x += rw
-        w -= rw * 2
-    
-    if rh < 0:
-        rh = min(abs(rh), h * 0.5)
-        y += rh
-        h -= rh * 2
-    
-    n = int(max(rw, rh) * math.pi / 2.0)
-    
-    a0 = 0.0
-    a1 = math.pi / 2.0
-    append_oval_segment(verts, x + w, y + h, rw, rh, a0, a1, n)
-    
-    a0 = math.pi / 2.0
-    a1 = math.pi
-    append_oval_segment(verts, x + w, y, rw, rh, a0, a1, n)
-    
-    a0 = math.pi
-    a1 = 3.0 * math.pi / 2.0
-    append_oval_segment(verts, x, y, rw, rh, a0, a1, n)
-    
-    a0 = 3.0 * math.pi / 2.0
-    a1 = math.pi * 2.0
-    append_oval_segment(verts, x, y + h, rw, rh, a0, a1, n)
-
-def append_oval_segment(verts, x, y, rw, rh, a0, a1, n, skip_last=False):
-    nmax = n - 1
-    da = a1 - a0
-    for i in range(n - int(skip_last)):
-        a = a0 + da * (i / nmax)
-        dx = math.sin(a) * rw
-        dy = math.cos(a) * rh
-        verts.append((x + int(dx), y + int(dy)))
-
-def draw_line(p0, p1, c=None):
-    if c is not None:
-        bgl.glColor4f(c[0], c[1], c[2], \
-            (c[3] if len(c) > 3 else 1.0))
-    bgl.glBegin(bgl.GL_LINE_STRIP)
-    bgl.glVertex3f(p0[0], p0[1], p0[2])
-    bgl.glVertex3f(p1[0], p1[1], p1[2])
-    bgl.glEnd()
-
-def draw_line_2d(p0, p1, c=None):
-    if c is not None:
-        bgl.glColor4f(c[0], c[1], c[2], \
-            (c[3] if len(c) > 3 else 1.0))
-    bgl.glBegin(bgl.GL_LINE_STRIP)
-    bgl.glVertex2f(p0[0], p0[1])
-    bgl.glVertex2f(p1[0], p1[1])
-    bgl.glEnd()
-
-def draw_line_hidden_depth(p0, p1, c, a0=1.0, a1=0.5, s0=None, s1=None):
-    bgl.glEnable(bgl.GL_DEPTH_TEST)
-    bgl.glColor4f(c[0], c[1], c[2], a0)
-    if s0 is not None:
-        gl_enable(bgl.GL_LINE_STIPPLE, int(bool(s0)))
-    draw_line(p0, p1)
-    bgl.glDisable(bgl.GL_DEPTH_TEST)
-    if (a1 == a0) and (s1 == s0):
-        return
-    bgl.glColor4f(c[0], c[1], c[2], a1)
-    if s1 is not None:
-        gl_enable(bgl.GL_LINE_STIPPLE, int(bool(s1)))
-    draw_line(p0, p1)
-
-def draw_arrow(p0, x, y, z, n_scl=0.2, ort_scl=0.035):
-    p1 = p0 + z
-    
-    bgl.glBegin(bgl.GL_LINE_STRIP)
-    bgl.glVertex3f(p0[0], p0[1], p0[2])
-    bgl.glVertex3f(p1[0], p1[1], p1[2])
-    bgl.glEnd()
-    
-    p2 = p1 - z * n_scl
-    bgl.glBegin(bgl.GL_TRIANGLE_FAN)
-    bgl.glVertex3f(p1[0], p1[1], p1[2])
-    p3 = p2 + (x + y) * ort_scl
-    bgl.glVertex3f(p3[0], p3[1], p3[2])
-    p3 = p2 + (-x + y) * ort_scl
-    bgl.glVertex3f(p3[0], p3[1], p3[2])
-    p3 = p2 + (-x - y) * ort_scl
-    bgl.glVertex3f(p3[0], p3[1], p3[2])
-    p3 = p2 + (x - y) * ort_scl
-    bgl.glVertex3f(p3[0], p3[1], p3[2])
-    p3 = p2 + (x + y) * ort_scl
-    bgl.glVertex3f(p3[0], p3[1], p3[2])
-    bgl.glEnd()
-
-def draw_arrow_2d(p0, n, L, arrow_len, arrow_width):
-    p1 = p0 + n * L
-    t = Vector((-n[1], n[0]))
-    pA = p1 - n * arrow_len + t * arrow_width
-    pB = p1 - n * arrow_len - t * arrow_width
-    
-    bgl.glBegin(bgl.GL_LINES)
-    
-    bgl.glVertex2f(p0[0], p0[1])
-    bgl.glVertex2f(p1[0], p1[1])
-    
-    bgl.glVertex2f(p1[0], p1[1])
-    bgl.glVertex2f(pA[0], pA[1])
-    
-    bgl.glVertex2f(p1[0], p1[1])
-    bgl.glVertex2f(pB[0], pB[1])
-    
-    bgl.glEnd()
-
-# Store/restore OpenGL settings and working with
-# projection matrices -- inspired by space_view3d_panel_measure
-# of Buerbaum Martin (Pontiac).
-
-# OpenGl helper functions/data
-gl_state_info = {
-    bgl.GL_MATRIX_MODE:(bgl.GL_INT, 1),
-    bgl.GL_PROJECTION_MATRIX:(bgl.GL_DOUBLE, 16),
-    bgl.GL_LINE_WIDTH:(bgl.GL_FLOAT, 1),
-    bgl.GL_BLEND:(bgl.GL_BYTE, 1),
-    bgl.GL_LINE_STIPPLE:(bgl.GL_BYTE, 1),
-    bgl.GL_COLOR:(bgl.GL_FLOAT, 4),
-    bgl.GL_SMOOTH:(bgl.GL_BYTE, 1),
-    bgl.GL_DEPTH_TEST:(bgl.GL_BYTE, 1),
-    bgl.GL_DEPTH_WRITEMASK:(bgl.GL_BYTE, 1),
-}
-gl_type_getters = {
-    bgl.GL_INT:bgl.glGetIntegerv,
-    bgl.GL_DOUBLE:bgl.glGetFloatv, # ?
-    bgl.GL_FLOAT:bgl.glGetFloatv,
-    #bgl.GL_BYTE:bgl.glGetFloatv, # Why GetFloat for getting byte???
-    bgl.GL_BYTE:bgl.glGetBooleanv, # maybe like that?
-}
-
-def gl_get(state_id):
-    type, size = gl_state_info[state_id]
-    buf = bgl.Buffer(type, [size])
-    gl_type_getters[type](state_id, buf)
-    return (buf if (len(buf) != 1) else buf[0])
-
-def gl_enable(state_id, enable):
-    if enable:
-        bgl.glEnable(state_id)
-    else:
-        bgl.glDisable(state_id)
-
-def gl_matrix_to_buffer(m):
-    tempMat = [m[i][j] for i in range(4) for j in range(4)]
-    return bgl.Buffer(bgl.GL_FLOAT, 16, tempMat)
-
-
-# ===== DRAWING CALLBACKS ===== #
-def draw_callback_view(self, context):
-    settings = find_settings()
-    if settings is None:
-        return
-    
-    update_stick_to_obj(context)
-    
-    if "EDIT" not in context.mode:
-        # It's nice to have bookmark position update interactively
-        # However, this still can be slow if there are many
-        # selected objects
-        
-        # ATTENTION!!!
-        # This eats a lot of processor time!
-        #CursorDynamicSettings.recalc_csu(context, 'PRESS')
-        pass
-    
-    history = settings.history
-    
-    tfm_operator = CursorDynamicSettings.active_transform_operator
-    
-    is_drawing = history.show_trace or tfm_operator
-    
-    if is_drawing:
-        # Store previous OpenGL settings
-        MatrixMode_prev = gl_get(bgl.GL_MATRIX_MODE)
-        ProjMatrix_prev = gl_get(bgl.GL_PROJECTION_MATRIX)
-        lineWidth_prev = gl_get(bgl.GL_LINE_WIDTH)
-        blend_prev = gl_get(bgl.GL_BLEND)
-        line_stipple_prev = gl_get(bgl.GL_LINE_STIPPLE)
-        color_prev = gl_get(bgl.GL_COLOR)
-        smooth_prev = gl_get(bgl.GL_SMOOTH)
-        depth_test_prev = gl_get(bgl.GL_DEPTH_TEST)
-        depth_mask_prev = gl_get(bgl.GL_DEPTH_WRITEMASK)
-    
-    if history.show_trace:
-        bgl.glDepthRange(0.0, 0.9999)
-        
-        history.draw_trace(context)
-        
-        library = settings.libraries.get_item()
-        if library and library.offset:
-            history.draw_offset(context)
-        
-        bgl.glDepthRange(0.0, 1.0)
-    
-    if tfm_operator:
-        tfm_operator.draw_3d(context)
-    
-    if is_drawing:
-        # Restore previous OpenGL settings
-        bgl.glLineWidth(lineWidth_prev)
-        gl_enable(bgl.GL_BLEND, blend_prev)
-        gl_enable(bgl.GL_LINE_STIPPLE, line_stipple_prev)
-        gl_enable(bgl.GL_SMOOTH, smooth_prev)
-        gl_enable(bgl.GL_DEPTH_TEST, depth_test_prev)
-        bgl.glDepthMask(depth_mask_prev)
-        bgl.glColor4f(color_prev[0],
-            color_prev[1],
-            color_prev[2],
-            color_prev[3])
-
-def draw_callback_header_px(self, context):
-    r = context.region
-    
-    tfm_operator = CursorDynamicSettings.active_transform_operator
-    if not tfm_operator:
-        return
-    
-    smooth_prev = gl_get(bgl.GL_SMOOTH)
-    
-    tfm_operator.draw_axes_coords(context, (r.width, r.height))
-    
-    gl_enable(bgl.GL_SMOOTH, smooth_prev)
-    
-    bgl.glDisable(bgl.GL_BLEND)
-    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-
-def draw_callback_px(self, context):
-    settings = find_settings()
-    if settings is None:
-        return
-    library = settings.libraries.get_item()
-    
-    tfm_operator = CursorDynamicSettings.active_transform_operator
-    
-    if settings.show_bookmarks and library:
-        library.draw_bookmark(context)
-    
-    if tfm_operator:
-        tfm_operator.draw_2d(context)
-    
-    # restore opengl defaults
-    bgl.glLineWidth(1)
-    bgl.glDisable(bgl.GL_BLEND)
-    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-
-
-# ===== UTILITY FUNCTIONS ===== #
-
-def update_stick_to_obj(context):
-    settings = find_settings()
-    
-    if not settings.stick_to_obj:
-        return
-    
-    scene = context.scene
-    
-    settings_scene = scene.cursor_3d_tools_settings
-    
-    name = settings_scene.stick_obj_name
-    
-    try:
-        obj = scene.objects[name]
-        pos = settings_scene.stick_obj_pos
-        pos = obj.matrix_world * pos
-        context.space_data.cursor_location = pos
-    except Exception as e:
-        pass
-
-def get_cursor_location(v3d=None, scene=None):
-    if v3d:
-        pos = v3d.cursor_location
-    elif scene:
-        pos = scene.cursor_location
-    
-    return pos.copy()
-
-def set_cursor_location(pos, v3d=None, scene=None):
-    pos = pos.to_3d().copy()
-    
-    if v3d:
-        scene = bpy.context.scene
-        # Accessing scene.cursor_location is SLOW
-        # (well, at least assigning to it).
-        # Accessing v3d.cursor_location is fast.
-        v3d.cursor_location = pos
-    elif scene:
-        scene.cursor_location = pos
-    
-    set_stick_obj(scene, None)
-
-def set_stick_obj(scene, name=None, pos=None):
-    settings_scene = scene.cursor_3d_tools_settings
-    
-    if name:
-        settings_scene.stick_obj_name = name
-    else:
-        settings_scene.stick_obj_name = ""
-    
-    if pos is not None:
-        settings_scene.stick_obj_pos = Vector(pos).to_3d()
-
-# WHERE TO STORE SETTINGS:
-# Currently there are two types of ID blocks
-# which properties don't change on Undo/Redo.
-# - WindowManager seems to be unique (at least
-#   for majority of situations). However, the
-#   properties stored in it are not saved
-#   with the blend.
-# - Screen. Properties are saved with blend,
-#   but there is some probability that any of
-#   the pre-chosen screen names may not exist
-#   in the user's blend.
-
-def find_settings():
-    #wm = bpy.data.window_managers[0]
-    #settings = wm.cursor_3d_tools_settings
-    
-    screen = bpy.data.screens.get("Default", bpy.data.screens[0])
-    try:
-        settings = screen.cursor_3d_tools_settings
-    except:
-        # addon was unregistered
-        settings = None
-    
-    return settings
-
-def find_runtime_settings():
-    wm = bpy.data.window_managers[0]
-    try:
-        runtime_settings = wm.cursor_3d_runtime_settings
-    except:
-        # addon was unregistered
-        runtime_settings = None
-    
-    return runtime_settings
-
-# ===== REGISTRATION ===== #
-def find_keymap_items(km, idname):
-    items = []
-    for kmi in km.keymap_items:
-        if kmi.idname == idname:
-            items.append(kmi)
-    return items
-
-def update_keymap(activate):
-    #if activate:
-    #    if bpy.ops.view3d.cursor3d_monitor.poll():
-    #        bpy.ops.view3d.cursor3d_monitor()
-    
-    wm = bpy.context.window_manager
-    
-    try:
-        km = wm.keyconfigs.user.keymaps['3D View']
-    except:
-        # wm.keyconfigs.user is empty on Blender startup!
-        if activate:
-            # activate temporary operator
-            km = wm.keyconfigs.active.keymaps['Window']
-            kmi = km.keymap_items.new( \
-                'wm.enhanced_3d_cursor_registration', \
-                'MOUSEMOVE', 'ANY')
-        return
-    
-    # We need for the enhanced operator to take precedence over
-    # the default cursor3d, but not over the manipulator.
-    # If we add the operator to "addon" keymaps, it will
-    # take precedence over both. If we add it to "user"
-    # keymaps, the default will take precedence.
-    # However, we may just simply turn it off or remove
-    # (depending on what saves with blend).
-    
-    items = find_keymap_items(km, 'view3d.cursor3d_enhanced')
-    if activate and (len(items) == 0):
-        kmi = km.keymap_items.new('view3d.cursor3d_enhanced', \
-            'ACTIONMOUSE', 'PRESS')
-        for key in EnhancedSetCursor.key_map["free_mouse"]:
-            kmi = km.keymap_items.new('view3d.cursor3d_enhanced', \
-                key, 'PRESS')
-    else:
-        if activate:
-            for kmi in items:
-                kmi.active = activate
-        else:
-            for kmi in items:
-                km.keymap_items.remove(kmi)
-    
-    items = find_keymap_items(km, 'view3d.cursor3d')
-    for kmi in items:
-        kmi.active = not activate
-    
-    km = wm.keyconfigs.active.keymaps['3D View']
-    items = find_keymap_items(km, 'view3d.cursor3d')
-    for kmi in items:
-        kmi.active = not activate
-    
-    km = wm.keyconfigs.default.keymaps['3D View']
-    items = find_keymap_items(km, 'view3d.cursor3d')
-    for kmi in items:
-        kmi.active = not activate
-
-def register():
-    bpy.utils.register_class(AlignOrientation)
-    bpy.utils.register_class(CopyOrientation)
-    bpy.types.VIEW3D_PT_transform_orientations.append(
-        transform_orientations_panel_extension)
-    
-    bpy.utils.register_class(SetCursorDialog)
-    
-    bpy.utils.register_class(NewCursor3DBookmarkLibrary)
-    bpy.utils.register_class(DeleteCursor3DBookmarkLibrary)
-    
-    bpy.utils.register_class(NewCursor3DBookmark)
-    bpy.utils.register_class(DeleteCursor3DBookmark)
-    bpy.utils.register_class(OverwriteCursor3DBookmark)
-    bpy.utils.register_class(RecallCursor3DBookmark)
-    bpy.utils.register_class(SwapCursor3DBookmark)
-    bpy.utils.register_class(SnapSelectionToCursor3DBookmark)
-    bpy.utils.register_class(AddEmptyAtCursor3DBookmark)
-    
-    bpy.utils.register_class(TransformExtraOptionsProp)
-    bpy.utils.register_class(TransformExtraOptions)
-    
-    # View properties panel is already long. Appending something
-    # to it would make it too inconvenient
-    #bpy.types.VIEW3D_PT_view3d_properties.append(draw_cursor_tools)
-    bpy.utils.register_class(Cursor3DTools)
-    
-    bpy.utils.register_class(LocationProp)
-    bpy.utils.register_class(CursorHistoryProp)
-    
-    bpy.utils.register_class(BookmarkProp)
-    bpy.utils.register_class(BookmarkIDBlock)
-    
-    bpy.utils.register_class(BookmarkLibraryProp)
-    bpy.utils.register_class(BookmarkLibraryIDBlock)
-    
-    bpy.utils.register_class(Cursor3DToolsSettings)
-    
-    bpy.utils.register_class(CursorRuntimeSettings)
-    bpy.utils.register_class(CursorMonitor)
-    
-    bpy.utils.register_class(Cursor3DToolsSceneSettings)
-    
-    bpy.types.Screen.cursor_3d_tools_settings = \
-        bpy.props.PointerProperty(type=Cursor3DToolsSettings)
-    
-    bpy.types.WindowManager.cursor_3d_runtime_settings = \
-        bpy.props.PointerProperty(type=CursorRuntimeSettings)
-    
-    bpy.types.Scene.cursor_3d_tools_settings = \
-        bpy.props.PointerProperty(type=Cursor3DToolsSceneSettings)
-    
-    bpy.utils.register_class(EnhancedSetCursor)
-    
-    bpy.utils.register_class(DelayRegistrationOperator)
-    
-    update_keymap(True)
-
-def unregister():
-    # Manually set this to False on unregister
-    CursorMonitor.is_running = False
-    
-    update_keymap(False)
-    
-    bpy.utils.unregister_class(DelayRegistrationOperator)
-    
-    bpy.utils.unregister_class(EnhancedSetCursor)
-    
-    if hasattr(bpy.types.Scene, "cursor_3d_tools_settings"):
-        del bpy.types.Scene.cursor_3d_tools_settings
-    
-    if hasattr(bpy.types.WindowManager, "cursor_3d_runtime_settings"):
-        del bpy.types.WindowManager.cursor_3d_runtime_settings
-    
-    if hasattr(bpy.types.Screen, "cursor_3d_tools_settings"):
-        del bpy.types.Screen.cursor_3d_tools_settings
-    
-    bpy.utils.unregister_class(Cursor3DToolsSceneSettings)
-    
-    bpy.utils.unregister_class(CursorMonitor)
-    bpy.utils.unregister_class(CursorRuntimeSettings)
-    
-    bpy.utils.unregister_class(Cursor3DToolsSettings)
-    
-    bpy.utils.unregister_class(BookmarkLibraryIDBlock)
-    bpy.utils.unregister_class(BookmarkLibraryProp)
-    
-    bpy.utils.unregister_class(BookmarkIDBlock)
-    bpy.utils.unregister_class(BookmarkProp)
-    
-    bpy.utils.unregister_class(CursorHistoryProp)
-    bpy.utils.unregister_class(LocationProp)
-    
-    bpy.utils.unregister_class(Cursor3DTools)
-    #bpy.types.VIEW3D_PT_view3d_properties.remove(draw_cursor_tools)
-    
-    bpy.utils.unregister_class(TransformExtraOptions)
-    bpy.utils.unregister_class(TransformExtraOptionsProp)
-    
-    bpy.utils.unregister_class(NewCursor3DBookmarkLibrary)
-    bpy.utils.unregister_class(DeleteCursor3DBookmarkLibrary)
-    
-    bpy.utils.unregister_class(NewCursor3DBookmark)
-    bpy.utils.unregister_class(DeleteCursor3DBookmark)
-    bpy.utils.unregister_class(OverwriteCursor3DBookmark)
-    bpy.utils.unregister_class(RecallCursor3DBookmark)
-    bpy.utils.unregister_class(SwapCursor3DBookmark)
-    bpy.utils.unregister_class(SnapSelectionToCursor3DBookmark)
-    bpy.utils.unregister_class(AddEmptyAtCursor3DBookmark)
-    
-    bpy.utils.unregister_class(SetCursorDialog)
-    
-    bpy.types.VIEW3D_PT_transform_orientations.remove(
-        transform_orientations_panel_extension)
-    bpy.utils.unregister_class(CopyOrientation)
-    bpy.utils.unregister_class(AlignOrientation)
-
-class DelayRegistrationOperator(bpy.types.Operator):
-    bl_idname = "wm.enhanced_3d_cursor_registration"
-    bl_label = "[Enhanced 3D Cursor] registration delayer"
-    
-    _timer = None
-    
-    def modal(self, context, event):
-        if (not self.keymap_updated) and \
-            ((event.type == 'TIMER') or ("MOVE" in event.type)):
-            # clean up (we don't need this operator to run anymore)
-            wm = bpy.context.window_manager
-            
-            for kcfg in wm.keyconfigs.values():
-                for km in kcfg.keymaps.values():
-                    items = find_keymap_items(km,
-                        'wm.enhanced_3d_cursor_registration')
-                    for kmi in items:
-                        km.keymap_items.remove(kmi)
-            
-            """
-            try:
-                # A bug when using Maya keymap presets
-                # (reported by chafouin in BlenderArtists thread)
-                # KeyError: key "Window" not found'
-                # Circumvent for now.
-                km = wm.keyconfigs.active.keymaps['Window']
-            except KeyError:
-                km = None
-            
-            if km:
-                items = find_keymap_items(km,
-                    'wm.enhanced_3d_cursor_registration')
-                for kmi in items:
-                    km.keymap_items.remove(kmi)
-            """
-            
-            update_keymap(True)
-            
-            self.keymap_updated = True
-            
-            # No, better don't (at least in current version),
-            # since the monitor has dependencies on View3D context.
-            # Attempt to launch the monitor
-            #if bpy.ops.view3d.cursor3d_monitor.poll():
-            #    bpy.ops.view3d.cursor3d_monitor()
-            
-            return self.cancel(context)
-        
-        return {'PASS_THROUGH'}
-    
-    def execute(self, context):
-        self.keymap_updated = False
-        
-        context.window_manager.modal_handler_add(self)
-        
-        self._timer = context.window_manager.\
-            event_timer_add(0.1, context.window)
-        
-        return {'RUNNING_MODAL'}
-    
-    def cancel(self, context):
-        context.window_manager.event_timer_remove(self._timer)
-        
-        return {'CANCELLED'}
-
-if __name__ == "__main__":
-    # launched from the Blender text editor
-    try:
-        register()
-    except Exception as e:
-        print(e)
-        raise
diff --git a/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py b/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py
deleted file mode 100644
index 0e55875..0000000
--- a/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-
-bl_info = {
-    'name': 'Game Property Visualiser',
-    'author': 'Bartius Crouch/Vilem Novak',
-    'version': (2,5),
-    'blender': (2, 5, 3),
-    'location': 'View3D > Properties panel > Display tab',
-    'description': 'Display the game properties next to selected objects '\
-        'in the 3d-view',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Game_Property_Visualiser',
-    'tracker_url': 'http://projects.blender.org/tracker/?func=detail&aid=22607&group_id=153&atid=468',
-    'category': '3D View'}
-
-"""
-Displays game properties next to selected objects(under name)
-
-How to use:
-    just toggle the button 'Visualise game props' in the right side panel
-"""
-
-import bgl
-import blf
-import bpy
-import mathutils
-
-
-# calculate locations and store them as ID property in the mesh
-def calc_callback(self, context):
-    # polling
-    if context.mode == 'EDIT_MESH':
-        return
-    
-    # get screen information
-    mid_x = context.region.width/2.0
-    mid_y = context.region.height/2.0
-    width = context.region.width
-    height = context.region.height
-    
-    # get matrices
-    view_mat = context.space_data.region_3d.perspective_matrix
-
-    ob_mat = context.active_object.matrix_world
-    total_mat = view_mat*ob_mat
-    
-    # calculate location info
-    texts = []
-    
-    # uncomment 2 lines below, to enable live updating of the selection
-    #ob=context.active_object
-    for ob in context.selected_objects:
-        locs = []
-        ob_mat = ob.matrix_world
-        total_mat = view_mat*ob_mat
- 
-        for p in ob.game.properties:
-            d=0.0#{'data':p.name+':'+str(p.value)}
-            # print (d)
-            locs.append([ mathutils.Vector([0,0,0]).resize_4d()])
-    
-    
-        for loc in locs:
-    
-            vec = loc[0]*total_mat # order is important
-            # dehomogenise
-            vec = mathutils.Vector((vec[0]/vec[3],vec[1]/vec[3],vec[2]/vec[3]))
-            x = int(mid_x + vec[0]*width/2.0)
-            y = int(mid_y + vec[1]*height/2.0)
-            texts+=[x, y]
-        
-
-    # store as ID property in mesh
-    #print (texts)
-    context.scene['GamePropsVisualiser'] = texts
-
-
-# draw in 3d-view
-def draw_callback(self, context):
-    # polling
-    if context.mode == 'EDIT_MESH':
-        return
-    # retrieving ID property data
-    try:
-        #print(context.scene['GamePropsVisualiser'])
-        texts = context.scene['GamePropsVisualiser']
-        
-    except:
-        return
-    if not texts:
-        return
-    
-    # draw
-    i=0
-
-    blf.size(0, 12, 72)
-   
-        
-    bgl.glColor3f(1.0,1.0,1.0)
-    for ob in bpy.context.selected_objects:
-        for pi,p in enumerate(ob.game.properties):
-            blf.position(0, texts[i], texts[i+1]-(pi+1)*14, 0)
-            if p.type=='FLOAT':
-                t=p.name+':  '+ str('%g'% p.value)
-            else:    
-                t=p.name+':  '+ str(p.value)
-            blf.draw(0, t)
-            i+=2
-
-
-# operator
-class GamePropertyVisualiser(bpy.types.Operator):
-    bl_idname = "view3d.game_props_visualiser"
-    bl_label = "Game Properties Visualiser"
-    bl_description = "Toggle the visualisation of game properties"
-    
-    @classmethod
-    def poll(cls, context):
-        return context.mode!='EDIT_MESH'
-    
-    def modal(self, context, event):
-        context.area.tag_redraw()
-
-        # removal of callbacks when operator is called again
-        #print(context.scene.display_game_properties)
-        if context.scene.display_game_properties == -1:
-           # print('deinit2')
-
-            context.scene.display_game_properties = 0
-            context.region.callback_remove(self.handle1)
-            context.region.callback_remove(self.handle2)
-            context.scene.display_game_properties = 0
-            
-            return {'FINISHED'}
-        
-        return {'PASS_THROUGH'}
-    
-    def invoke(self, context, event):
-        if context.area.type == 'VIEW_3D':
-            print(context.scene.display_game_properties)
-            if context.scene.display_game_properties == 0 or context.scene.display_game_properties == -1:
-                print('init')
-                # operator is called for the first time, start everything
-                context.scene.display_game_properties = 1
-                context.window_manager.modal_handler_add(self)
-                self.handle1 = context.region.callback_add(calc_callback,
-                    (self, context), 'POST_VIEW')
-                self.handle2 = context.region.callback_add(draw_callback,
-                    (self, context), 'POST_PIXEL')
-                return {'RUNNING_MODAL'}
-            else:
-                # operator is called again, stop displaying
-                context.scene.display_game_properties = -1
-                #print(dir(self))
-                #
-                return {'RUNNING_MODAL'}
-        else:
-            self.report({'WARNING'}, "View3D not found, can't run operator")
-            return {'CANCELLED'}
-
-
-# defining the panel
-def menu_func(self, context):
-    col = self.layout.column(align=True)
-    col.operator(GamePropertyVisualiser.bl_idname, text="Visualise game props")
-    self.layout.separator()
-
-
-def register():
-    bpy.types.Scene.display_game_properties = bpy.props.IntProperty(name='Visualise Game Poperties')
-    bpy.types.VIEW3D_PT_view3d_display.prepend(menu_func)
-
-def unregister():
-    del bpy.types.Scene.display_game_properties
-    bpy.types.VIEW3D_PT_view3d_display.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py b/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py
deleted file mode 100644
index 6a588c5..0000000
--- a/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#re creating the functionality of the manipulator menu from 2.49
-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-bl_info = {
-    'name': '3d View: Manipulator Menu',
-    'author': 'MichaelW',
-    'version': (1, 2 ,1),
-    'blender': (2, 6, 1),
-    'location': 'View3D > Ctrl Space ',
-    'description': 'Menu to change the manipulator type and/or disable it',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\
-        'Scripts/3D_interaction/Manipulator_Menu',
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
-        'func=detail&aid=22092',
-    'category': '3D View'}
-
-
-
-
-
-
-import bpy
-
-def main(context):
-    bpy.context.space_data.manipulator = False
-
-#class VIEW3D_OT_disable_manipulator(bpy.types.Operator):
-#    ''''''
-#    bl_idname = "VIEW3D_OT_disable_manipulator"
-#    bl_label = "disable manipulator"
-#
-#    def poll(self, context):
-#        return context.active_object != None
-#
-#    def execute(self, context):
-#        main(context)
-#        return {'FINISHED'}
-#
-
-
-class VIEW3D_MT_ManipulatorMenu(bpy.types.Menu):
-    bl_label = "ManipulatorType"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        props = layout.operator("view3d.enable_manipulator",text ='Translate', icon='MAN_TRANS')
-        props.translate = True
-
-        props = layout.operator("view3d.enable_manipulator",text ='Rotate', icon='MAN_ROT')
-        props.rotate = True
-
-        props = layout.operator("view3d.enable_manipulator",text ='Scale', icon='MAN_SCALE')
-        props.scale = True
-        layout.separator()
-
-        props = layout.operator("view3d.enable_manipulator",text ='Combo', icon='MAN_SCALE')
-        props.scale = True
-        props.rotate = True
-        props.translate = True
-
-        layout.separator()
-
-        props = layout.operator("view3d.enable_manipulator",text ='Hide', icon='MAN_SCALE')
-        props.scale = False
-        props.rotate = False
-        props.translate = False
-        
-        layout.separator()
-
-
-            
-def register():
-    bpy.utils.register_module(__name__)
-
-    wm = bpy.context.window_manager
-    km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
-    kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS', ctrl=True)
-    kmi.properties.name = "VIEW3D_MT_ManipulatorMenu"
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    wm = bpy.context.window_manager
-    km = wm.keyconfigs.addon.keymaps['3D View Generic']
-    for kmi in km.keymap_items:
-        if kmi.idname == 'wm.call_menu':
-            if kmi.properties.name == "VIEW3D_MT_ManipulatorMenu":
-                km.keymap_items.remove(kmi)
-                break
-
-if __name__ == "__main__":
-    register
diff --git a/release/scripts/addons_contrib/space_view3d_multiselect_menu.py b/release/scripts/addons_contrib/space_view3d_multiselect_menu.py
deleted file mode 100644
index b7b1ccd..0000000
--- a/release/scripts/addons_contrib/space_view3d_multiselect_menu.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#view3d_multiselect_menu.py (c) 2011 Sean Olson (liquidApe)
-#Original Script by: Mariano Hidalgo (uselessdreamer)
-#contributed to by: Crouch, sim88, sam, meta-androcto, and Michael W
-#
-#Tested with r37702
-#
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    'name': '3D View: Multiselect Menu',
-    'author': 'Sean Olson (liquidApe)',
-    'version': (1, 2),
-    'blender': (2, 6, 1),
-    'location': 'View3D > Mouse > Menu ',
-    'warning':'',
-    'description': 'Added options for multiselect to the ctrl-tab menu',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
-        'Scripts/3D_interaction/multiselect_Menu',
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'
-                   'func=detail&aid=22132',
-    'category': '3D View'}
-
-import bpy
-
-# multiselect menu
-class VIEW3D_MT_Multiselect_Menu(bpy.types.Menu):
-    bl_label = "MultiSelect Menu"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.separator()
-        prop = layout.operator("wm.context_set_value", text="Vertex Select",
-            icon='VERTEXSEL')
-        prop.value = "(True, False, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value", text="Edge Select",
-            icon='EDGESEL')
-        prop.value = "(False, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value", text="Face Select",
-            icon='FACESEL')
-        prop.value = "(False, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-        layout.separator()
-
-        prop = layout.operator("wm.context_set_value",
-            text="Vertex & Edge Select", icon='EDITMODE_HLT')
-        prop.value = "(True, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-            text="Vertex & Face Select", icon='ORTHO')
-        prop.value = "(True, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-            text="Edge & Face Select", icon='SNAP_FACE')
-        prop.value = "(False, True, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-        layout.separator()
-
-        prop = layout.operator("wm.context_set_value",
-            text="Vertex & Edge & Face Select", icon='SNAP_VOLUME')
-        prop.value = "(True, True, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-        layout.separator()
-
-def register():
-    bpy.utils.register_module(__name__)
-    
-    #add multiselect keybinding
-    km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
-    kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
-    kmi.properties.name = "VIEW3D_MT_Multiselect_Menu"
-
-    #remove default keybinding
-    km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
-    for kmi in km.keymap_items:
-        if kmi.idname == 'wm.call_menu':
-            if kmi.properties.name == "VIEW3D_MT_edit_mesh_select_mode":
-                km.keymap_items.remove(kmi)
-                break
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    #remove multiselect keybinding
-    km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
-    for kmi in km.keymap_items:
-        if kmi.idname == 'wm.call_menu':
-            if kmi.properties.name == "VIEW3D_MT_Multiselect_Menu":
-                km.keymap_items.remove(kmi)
-                break
-
-    #replace default keymap
-    km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
-    kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
-    kmi.properties.name = "VIEW3D_MT_edit_mesh_select_mode"
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/space_view3d_objects_panel.py b/release/scripts/addons_contrib/space_view3d_objects_panel.py
deleted file mode 100644
index 4815bfe..0000000
--- a/release/scripts/addons_contrib/space_view3d_objects_panel.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Add Objects Panel",
-    "author": "Murat Egretli (Demohero)",
-    "version": (1,2),
-    "blender": (2, 6, 1),
-    "location": "View3D > Toolbar",
-    "description": "add objects(mesh, curve etc.) from Toolbar",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=22154",
-    "category": "3D View"}
-
-
-import bpy
-
-
-class View3DPanel():
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    
-
-class VIEW3D_PT_add_menu(View3DPanel,bpy.types.Panel):
-    bl_context = "objectmode"
-    bl_label = "Add Objects"
-    
-    def draw(self, context):
-        layout = self.layout
-
-        layout.menu("INFO_MT_mesh_add", text="Mesh", icon='OUTLINER_OB_MESH')
-        layout.menu("INFO_MT_curve_add", text="Curve", icon='OUTLINER_OB_CURVE')
-        layout.menu("INFO_MT_surface_add", text="Surface", icon='OUTLINER_OB_SURFACE')
-        layout.operator_menu_enum("object.metaball_add", "type", text="Metaball", icon='OUTLINER_OB_META')
-        layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
-        layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP')
-        layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY')
-        layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
-        layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY'
-        layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
-        layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
-        layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
-      
-# register the class
-def register():
-    bpy.utils.register_module(__name__)
- 
-    pass 
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
- 
-    pass 
-
-if __name__ == "__main__": 
-    register()
diff --git a/release/scripts/addons_contrib/space_view3d_paint_bprojection.py b/release/scripts/addons_contrib/space_view3d_paint_bprojection.py
deleted file mode 100644
index 461f90e..0000000
--- a/release/scripts/addons_contrib/space_view3d_paint_bprojection.py
+++ /dev/null
@@ -1,1126 +0,0 @@
-bl_info = {
-    "name": "BProjection",
-    "description": "Help Clone tool",
-    "author": "kgeogeo",
-    "version": (1, 0),
-    "blender": (2, 6, 3),
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/bprojection",
-    "tracker_url":"http://projects.blender.org/tracker/index.php?func=detail&aid=30521&group_id=153&atid=468",
-    "category": "Paint"}
-
-import bpy
-from bpy.types import Panel, Operator
-from bpy.props import IntProperty, FloatProperty, BoolProperty, IntVectorProperty, StringProperty, FloatVectorProperty, CollectionProperty
-from bpy_extras import view3d_utils
-import math
-from math import *
-import mathutils
-from mathutils import *
-
-# Main function for align the plan to view
-def align_to_view(context):
-    ob = context.object        
-    rotation = ob.custom_rotation
-    scale = ob.custom_scale
-    z = ob.custom_location.z
-    pos = [ob.custom_location.x, ob.custom_location.y]
-    
-    reg = context.area.regions[4]        
-    width = reg.width
-    height = reg.height 
-    
-    sd = context.space_data    
-    r3d = sd.region_3d     
-    r3d.update()
-    vr = r3d.view_rotation
-    quat = mathutils.Quaternion((0.0, 0.0, 1.0), math.radians(float(rotation)))
-    v = Vector((pos[0],pos[1],z))
-    v.rotate(vr)
-
-    em = bpy.data.objects['Empty for BProjection']
-    img = bpy.data.textures['Texture for BProjection'].image
-    if img and img.size[1] != 0:
-        prop = img.size[0]/img.size[1]
-    else: prop = 1    
-    
-    if ob.custom_linkscale:    
-        em.scale = Vector((prop*scale[0], scale[0], 1))
-    else:
-        em.scale = Vector((prop*scale[0], scale[1], 1))
-    pos_cur = em.location - sd.cursor_location
-    rot_cur1 = em.rotation_euler.to_quaternion()
-    em.location = v + ob.location            
-    em.rotation_euler = Quaternion.to_euler(vr*quat)
-        
-    if ob.custom_c3d:
-        if ob.custom_old_scale != ob.custom_scale:
-            pos_cur = em.location - sd.cursor_location        
-        rot_cur2 = em.rotation_euler.to_quaternion()
-        rot_cur1.invert()
-        pos_cur.rotate(rot_cur1)
-        pos_cur.rotate(rot_cur2)
-        v = em.location - pos_cur
-        sd.cursor_location =  v
-
-# Function to update the properties
-def update_Location(self, context):          
-    align_to_view(context)
-
-# Function to update the scaleUV
-def update_UVScale(self, context):
-    v = Vector((context.object.custom_offsetuv[0]/10 + 0.5, context.object.custom_offsetuv[1]/10 + 0.5))
-    l = Vector((0.0,0.0))
-    ob = context.object
-    s = ob.custom_scaleuv
-    os = ob.custom_old_scaleuv 
-    scale = s - os
-    uvdata = ob.data.uv_layers.active.data
-    for i in range(trunc(pow(ob.custom_sub+1, 2)*4)):
-        vres =  v - uvdata[len(uvdata)-1-i].uv  
-        uvdata[len(uvdata)-1-i].uv.x = v.x - vres.x/os[0]*s[0]
-        uvdata[len(uvdata)-1-i].uv.y = v.y - vres.y/os[1]*s[1]
-
-    ob.custom_old_scaleuv = s  
-    align_to_view(context)
-
-def update_PropUVScale(self, context):
-    ob = context.object
-    if ob.custom_linkscaleuv:
-        ob.custom_scaleuv = [ob.custom_propscaleuv,ob.custom_propscaleuv]
-
-def update_LinkUVScale(self, context):
-    ob = context.object
-    if ob.custom_linkscaleuv:
-        ob.custom_propscaleuv = ob.custom_scaleuv.x
-        update_PropUVScale(self, context)
-    else:
-        update_UVScale(self, context) 
-        
-# Function to update the offsetUV
-def update_UVOffset(self, context):
-    ob = context.object
-    o = ob.custom_offsetuv
-    oo = ob.custom_old_offsetuv 
-    uvdata = ob.data.uv_layers.active.data
-    for i in range(trunc(pow(ob.custom_sub+1, 2)*4)):
-        uvdata[len(uvdata)-1-i].uv = [uvdata[len(uvdata)-1-i].uv[0] - oo[0]/10 + o[0]/10, uvdata[len(uvdata)-1-i].uv[1] - oo[1]/10 + o[1]/10]   
-    ob.custom_old_offsetuv = o
-    
-    align_to_view(context)
-
-# Function to update the flip horizontal
-def update_FlipUVX(self, context):          
-    uvdata = context.object.data.uv_layers.active.data
-    for i in range(trunc(pow(context.object.custom_sub+1, 2)*4)):
-        x = uvdata[len(uvdata)-1-i].uv[0]
-        uvdata[len(uvdata)-1-i].uv[0] = 1 - x
-    
-    align_to_view(context)
-
-# Function to update the flip vertical
-def update_FlipUVY(self, context):          
-    uvdata = context.object.data.uv_layers.active.data
-    for i in range(trunc(pow(context.object.custom_sub+1, 2)*4)):
-        y = uvdata[len(uvdata)-1-i].uv[1]
-        uvdata[len(uvdata)-1-i].uv[1] = 1 - y
-    
-    align_to_view(context)
-
-# Function to update
-def update_Rotation(self, context):              
-    if context.object.custom_rotc3d:
-        ob = context.object
-        angle = ob.custom_rotation - ob.custom_old_rotation
-        sd = context.space_data
-        vr = sd.region_3d.view_rotation.copy()        
-        c = sd.cursor_location.copy() - ob.location
-        e = bpy.data.objects['Empty for BProjection'].location - ob.location
-        vo = Vector((0.0, 0.0, 1.0))
-        vo.rotate(vr)
-        quat = mathutils.Quaternion(vo, math.radians(angle))
-        v = e-c
-        v.rotate(quat)
-        vr.invert()
-        v.rotate(vr)
-        c.rotate(vr)
-        context.object.custom_location = c + v
-    else:        
-        align_to_view(context)
-   
-    context.object.custom_old_rotation = context.object.custom_rotation
-
-# Function to update scale
-def update_Scale(self, context):              
-    ob = context.object
-    
-    if context.object.custom_scac3d:
-        #ob.custom_c3d = False
-        sd = context.space_data
-        r3d =  sd.region_3d
-        vr = r3d.view_rotation.copy()
-        vr.invert()
-        e = bpy.data.objects['Empty for BProjection'].location - ob.location
-        c = sd.cursor_location.copy() - ob.location
-        ce = e - c
-        
-        s = ob.custom_scale
-        os = ob.custom_old_scale
-        delta =  ob.custom_scale - ob.custom_old_scale
-        c.rotate(vr)
-        ce.rotate(vr)
-        
-        img = bpy.data.textures['Texture for BProjection'].image
-        if img and img.size[1] != 0:
-            prop = img.size[0]/img.size[1]
-        else: prop = 1
-        
-        v = Vector((s.x*ce.x/os.x, s.y*ce.y/os.y,0.0))
-        ob.custom_location = c + v
-        #ob.custom_c3d = True
-        
-
-    else:          
-        align_to_view(context)
-            
-    
-    ob.custom_old_scale = ob.custom_scale
-
-def update_PropScale(self, context):
-    ob = context.object
-    if ob.custom_linkscale:
-        ob.custom_scale = [ob.custom_propscale,ob.custom_propscale]
-    
-def update_LinkScale(self, context):
-    ob = context.object
-    if ob.custom_linkscale:
-        ob.custom_propscale = ob.custom_scale.x
-        update_PropScale(self, context)
-    else:
-        update_Scale(self, context) 
-
-def update_activeviewname(self, context):
-    if self.custom_active:
-        context.object.custom_active_view = self.custom_active_view
-
-class custom_props(bpy.types.PropertyGroup):
-    custom_location = FloatVectorProperty(name="Location", description="Location of the plan",
-                                           default=(0,0,-1.0),
-                                           subtype = 'XYZ', size=3)
-                                           
-    custom_rotation = FloatProperty(name="Rotation", description="Rotate the plane",
-                                     min=-180, max=180, default=0)
-                                         
-    custom_scale = FloatVectorProperty(name="Scales", description="Scale the planes",
-                                       subtype = 'XYZ', default=(1.0, 1.0),min = 0.1, size=2)
-    custom_propscale = FloatProperty(name="PropScale", description="Scale the Plan",
-                                           default=1.0,min = 0.1)
-                                                                                    
-    custom_linkscale = BoolProperty(name="linkscale", default=True)
-   
-    # UV properties
-    custom_scaleuv = FloatVectorProperty(name="ScaleUV", description="Scale the texture's UV",
-                                            default=(1.0,1.0),min = 0.01, subtype = 'XYZ', size=2)
-    custom_propscaleuv = FloatProperty(name="PropScaleUV", description="Scale the texture's UV",
-                                           default=1.0,min = 0.01) 
-    custom_offsetuv = FloatVectorProperty(name="OffsetUV", description="Decal the texture's UV",
-                                            default=(0.0,0.0), subtype = 'XYZ', size=2)       
-    custom_linkscaleuv = BoolProperty(name="linkscaleUV", default=True)
-    custom_flipuvx = BoolProperty(name="flipuvx", default=False)
-    custom_flipuvy = BoolProperty(name="flipuvy", default=False)
-    
-    # other properties
-    custom_active= BoolProperty(name="custom_active", default=True)   
-    custom_expand = BoolProperty(name="expand", default=False)
-    
-    custom_active_view = StringProperty(name = "custom_active_view",default = "View",update = update_activeviewname)
-    
-    custom_image = StringProperty(name = "custom_image",default = "")
-    
-    custom_index = IntProperty()
-
-# Function to create custom properties
-def createcustomprops(context):
-    Ob = bpy.types.Object    
-    
-    # plane properties 
-    Ob.custom_location = FloatVectorProperty(name="Location", description="Location of the plan",
-                                           default=(5.0,0.0,-1.0),
-                                           subtype = 'XYZ', size=3, update = update_Location)
-                                           
-    Ob.custom_rotation = FloatProperty(name="Rotation", description="Rotate the plane",
-                                     min=-180, max=180, default=0,update = update_Rotation)
-                                     
-    Ob.custom_old_rotation = FloatProperty(name="old_Rotation", description="Old Rotate the plane",
-                                         min=-180, max=180, default=0)
-                                         
-    Ob.custom_scale = FloatVectorProperty(name="Scales", description="Scale the planes",
-                                          subtype = 'XYZ', default=(1.0, 1.0),min = 0.1, size=2,update = update_Scale)
-    Ob.custom_propscale = FloatProperty(name="PropScale", description="Scale the Plan",
-                                           default=1.0,min = 0.1,update = update_PropScale)
-    Ob.custom_old_scale = FloatVectorProperty(name="old_Scales", description="Old Scale the planes",
-                                          subtype = 'XYZ', default=(1.0, 1.0),min = 0.1, size=2)
-                                          
-    Ob.custom_linkscale = BoolProperty(name="linkscale", default=True, update = update_LinkScale)
-    
-                                
-    Ob.custom_sub = IntProperty(name="Subdivide", description="Number of subdivision of the plan",
-                                     min=1, max=20, default=10)                                
-    
-    # UV properties
-    Ob.custom_scaleuv = FloatVectorProperty(name="ScaleUV", description="Scale the texture's UV",
-                                            default=(1.0,1.0),min = 0.01, subtype = 'XYZ', size=2,update = update_UVScale)
-    Ob.custom_propscaleuv = FloatProperty(name="PropScaleUV", description="Scale the texture's UV",
-                                           default=1.0,min = 0.01,update = update_PropUVScale)    
-    Ob.custom_old_scaleuv = FloatVectorProperty(name="old_ScaleUV", description="Scale the texture's UV",
-                                                default=(1.0,1.0),min = 0.01, subtype = 'XYZ', size=2)
-    Ob.custom_offsetuv = FloatVectorProperty(name="OffsetUV", description="Decal the texture's UV",
-                                            default=(0.0,0.0), subtype = 'XYZ', size=2,update = update_UVOffset)    
-    Ob.custom_old_offsetuv = FloatVectorProperty(name="old_OffsetUV", description="Decal the texture's UV",
-                                                 default=(0.0,0.0), subtype = 'XYZ', size=2)    
-    Ob.custom_linkscaleuv = BoolProperty(name="linkscaleUV", default=True, update = update_LinkUVScale)
-    Ob.custom_flipuvx = BoolProperty(name="flipuvx", default=False, update = update_FlipUVX)
-    Ob.custom_flipuvy = BoolProperty(name="flipuvy", default=False, update = update_FlipUVY)
-    
-    # other properties    
-    Ob.custom_c3d = BoolProperty(name="c3d", default=True)
-    Ob.custom_rot = BoolProperty(name="rot", default=True)
-    Ob.custom_rotc3d = BoolProperty(name="rotc3d", default=False)
-    Ob.custom_scac3d = BoolProperty(name="scac3d", default=False)
-    Ob.custom_expand = BoolProperty(name="expand", default=True)
-    Ob.custom_active_view = StringProperty(name = "custom_active_view",default = "View")
-    
-    Ob.custom_props = CollectionProperty(type = custom_props)
-
-# Function to remove custom properties
-def removecustomprops():    
-    list_prop = ['custom_location', 'custom_rotation', 'custom_old_rotation', 'custom_scale', 'custom_old_scale', 'custom_c3d',
-                 'custom_rot', 'custom_rotc3d', 'custom_scaleuv', 'custom_flipuvx', 'custom_flipuvy', 'custom_linkscale',
-                 'custom_linkscaleuv', 'custom_old_scaleuv', 'custom_offsetuv', 'custom_old_offsetuv', 'custom_scac3d', 'custom_sub',
-                 'custom_expand', 'custom_active_view', 'custom_propscaleuv', 'custom_props', 'custom_propscale']
-    for prop in list_prop:
-        try:
-            del bpy.context.object[prop]
-        except:
-            do = 'nothing'
-
-# Oprerator Class to create view            
-class CreateView(Operator):
-    bl_idname = "object.create_view"
-    bl_label = "Create a new view"
-
-    def execute(self, context):              
-        ob = context.object
-        new_props = ob.custom_props.add()
-        
-        ob.custom_active_view = new_props.custom_active_view               
-        new_props.custom_index = len(bpy.context.object.custom_props)-1
-        bpy.ops.object.active_view(index = new_props.custom_index)
-        ob.data.shape_keys.key_blocks[ob.active_shape_key_index].mute = True
-        bpy.ops.object.shape_key_add(from_mix = False)
-        ob.data.shape_keys.key_blocks[ob.active_shape_key_index].value = 1.0
-        return {'FINISHED'}
-
-# Oprerator Class to copy view 
-class SaveView(Operator):
-    bl_idname = "object.save_view"
-    bl_label = "copy the view"
-    
-    index = IntProperty(default = 0)
-    
-    def execute(self, context):              
-        ob = context.object
-        prop = ob.custom_props[self.index]        
-        prop.custom_location =  ob.custom_location                    
-        prop.custom_rotation =  ob.custom_rotation                    
-        prop.custom_scale =  ob.custom_scale                  
-        prop.custom_linkscale =  ob.custom_linkscale                                      
-        prop.custom_scaleuv = ob.custom_scaleuv
-        prop.custom_propscale = ob.custom_propscale
-        prop.custom_offsetuv =  ob.custom_offsetuv  
-        prop.custom_linkscaleuv = ob.custom_linkscaleuv
-        prop.custom_propscaleuv = ob.custom_propscaleuv
-        prop.custom_flipuvx = ob.custom_flipuvx
-        prop.custom_flipuvy = ob.custom_flipuvy
-        try:
-            prop.custom_image = bpy.data.textures['Texture for BProjection'].image.name
-        except:
-            do = 'nothing'
-        
-        return {'FINISHED'}
-
-# Oprerator Class to copy view 
-class PasteView(Operator):
-    bl_idname = "object.paste_view"
-    bl_label = "paste the view"
-    
-    index = IntProperty(default = 0)
-    
-    def execute(self, context):              
-        ob = context.object
-        prop = ob.custom_props[self.index]
-        ob.custom_linkscale =  prop.custom_linkscale
-        ob.custom_offsetuv =  prop.custom_offsetuv 
-        ob.custom_linkscaleuv = prop.custom_linkscaleuv
-        ob.custom_scaleuv = prop.custom_scaleuv
-        ob.custom_propscaleuv = prop.custom_propscaleuv       
-        ob.custom_rotation =  prop.custom_rotation                    
-        ob.custom_scale =  prop.custom_scale
-        ob.custom_propscale = prop.custom_propscale 
-        ob.custom_location =  prop.custom_location                    
-        if prop.custom_image != '':
-            if bpy.data.textures['Texture for BProjection'].image.name != prop.custom_image:
-                bpy.data.textures['Texture for BProjection'].image = bpy.data.images[prop.custom_image]
-                bpy.ops.object.applyimage()
-        if ob.custom_flipuvx != prop.custom_flipuvx:
-            ob.custom_flipuvx = prop.custom_flipuvx
-        if ob.custom_flipuvy != prop.custom_flipuvy:
-            ob.custom_flipuvy = prop.custom_flipuvy
-        
-        return {'FINISHED'}
-
-# Oprerator Class to remove view 
-class RemoveView(Operator):
-    bl_idname = "object.remove_view"
-    bl_label = "Rmeove the view"
-    
-    index = IntProperty(default = 0)
-    
-    def execute(self, context):              
-        ob = context.object
-        
-        ob.active_shape_key_index =  self.index + 1
-        bpy.ops.object.shape_key_remove()
-        
-        if  context.object.custom_props[self.index].custom_active: 
-            if len(ob.custom_props) > 0:
-                bpy.ops.object.active_view(index = self.index-1)
-            if self.index == 0 and len(ob.custom_props) > 1:
-                bpy.ops.object.active_view(index = 1)            
-                
-        ob.custom_props.remove(self.index)
-        
-        print(len(context.object.custom_props))
-                
-        if len(context.object.custom_props) == 0:
-            ob.custom_scale = [1,1]
-            ob.custom_rotation = 0
-            ob.custom_scaleuv =[1.0,1.0]
-            ob.custom_offsetuv =[0.0,0.0]
-            ob.custom_propscaleuv = 1.0
-            ob.custom_propscale = 1.0
-            if ob.custom_flipuvx == True:
-                ob.custom_flipuvx = False
-            if ob.custom_flipuvy == True:
-                ob.custom_flipuvy = False
-            
-            bpy.ops.object.create_view()            
-                 
-        i=0
-        for item in context.object.custom_props:
-            item.custom_index = i           
-            i+=1 
-
-        for item in [item for item in context.object.custom_props if item.custom_active]:
-                ob.active_shape_key_index = item.custom_index+1
-           
-        return {'FINISHED'}
-
-# Oprerator Class to copy view 
-class ActiveView(Operator):
-    bl_idname = "object.active_view"
-    bl_label = "Active the view"
-    
-    index = IntProperty(default = 0)
-    
-    def execute(self, context):
-        ob = context.object
-        for item in [ item for item in ob.custom_props if item.custom_active == True]:
-                bpy.ops.object.save_view(index = item.custom_index)
-                item.custom_active = False
-        ob.custom_props[self.index].custom_active  = True
-        ob.custom_active_view = ob.custom_props[self.index].custom_active_view 
-        ob.active_shape_key_index =  self.index + 1
-        
-        for i in ob.data.shape_keys.key_blocks:
-            i.mute = True
-        
-        ob.data.shape_keys.key_blocks[ob.active_shape_key_index].mute = False
-        
-        bpy.ops.object.paste_view(index = self.index)         
-        
-        return {'FINISHED'}
-
-# Draw Class to show the panel
-class BProjection(Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "BProjection"
-
-    @classmethod
-    def poll(cls, context):
-        return (context.image_paint_object or context.sculpt_object)
-
-    def draw(self, context):        
-        layout = self.layout
-                
-        try: 
-            bpy.data.objects['Empty for BProjection']
-            
-            tex = bpy.data.textures['Texture for BProjection']
-            ob = context.object
-                        
-            col = layout.column(align =True)
-            col.operator("object.removebprojectionplane", text="Remove BProjection plane")           
-                
-            box = layout.box()
-
-            row = box.row()
-            if not ob.custom_expand:
-                row.prop(ob, "custom_expand", text  = "", icon="TRIA_RIGHT", emboss=False)
-                row.label(text=ob.custom_active_view)
-            else:
-                row.prop(ob, "custom_expand", text = "" , icon="TRIA_DOWN", emboss=False)                
-                row.label(text=ob.custom_active_view)
-                
-                col = box.column(align =True)
-                col.template_ID(tex, "image", open="image.open")
-                row  = box.row(align=True)
-                row.operator('object.applyimage', text="Apply image", icon = 'FILE_TICK')
-                row.prop(ob, "custom_c3d",text="", icon='CURSOR')
-                row.prop(ob, "custom_rot",text="", icon='ROTATE')
-                row  = box.row(align =True)
-                row.label(text="Location:")
-                row  = box.row(align =True)
-                row.prop(ob,'custom_location', text='')
-                row  = box.row(align =True)            
-                row.prop(ob,'custom_rotation')
-                row.prop(ob,'custom_rotc3d',text="",icon='MANIPUL')            
-                row  = box.row(align =True)
-                row.label(text="Scale:")
-                row  = box.row(align =True) 
-                if ob.custom_linkscale :
-                    row.prop(ob, "custom_propscale",text="")
-                    row.prop(ob, "custom_linkscale",text="",icon='LINKED')
-                else: 
-                    row.prop(ob,'custom_scale',text='')
-                    row.prop(ob, "custom_linkscale",text="",icon='UNLINKED')
-                row.prop(ob,'custom_scac3d',text="",icon='MANIPUL')                            
-                row  = box.row(align =True)
-                row.label(text="UV's Offset:")
-                row  = box.row(align =True)
-                row.prop(ob,'custom_offsetuv',text='')
-                row.prop(ob, "custom_flipuvx",text="",icon='ARROW_LEFTRIGHT')   
-                row.prop(ob, "custom_flipuvy",text="",icon='FULLSCREEN_ENTER') 
-                row  = box.row(align =True)
-                row.label(text="UV's Scale:")
-                row  = box.row(align =True)                            
-                if ob.custom_linkscaleuv:
-                    row.prop(ob,'custom_propscaleuv',text='')
-                    row.prop(ob, "custom_linkscaleuv",text="",icon='LINKED')
-                else: 
-                    row.prop(ob,'custom_scaleuv',text='')
-                    row.prop(ob, "custom_linkscaleuv",text="",icon='UNLINKED')            
-                row = box.column(align =True)
-                row.prop(ob.material_slots['Material for BProjection'].material,'alpha', slider = True)
-                row = box.column(align =True)
-
-                
-            for item in ob.custom_props:
-                box = layout.box()
-                row = box.row()
-                if item.custom_active:
-                    row.operator("object.active_view",text = "", icon='RADIOBUT_ON', emboss = False).index = item.custom_index 
-                else:
-                    row.operator("object.active_view",text = "", icon='RADIOBUT_OFF', emboss = False).index = item.custom_index 
-                row.prop(item, "custom_active_view", text="")        
-                row.operator('object.remove_view', text="", icon = 'PANEL_CLOSE', emboss = False).index = item.custom_index
-            row = layout.row()
-            row.operator('object.create_view', text="Create View", icon = 'RENDER_STILL')        
-
-        except:
-            col = layout.column(align = True)
-            col.operator("object.addbprojectionplane", text="Add BProjection plan")
-                   
-
-# Oprerator Class to apply the image to the plane             
-class ApplyImage(Operator):
-    bl_idname = "object.applyimage"
-    bl_label = "Apply image"
-
-    def execute(self, context):        
-        img = bpy.data.textures['Texture for BProjection'].image
-        em = bpy.data.objects['Empty for BProjection']
-        ob = context.object
-        cm = context.object.mode
-               
-        bpy.ops.object.editmode_toggle()
-        f = ob.data.polygons
-        nbface = len(ob.data.polygons)
-        uvdata = ob.data.uv_textures.active.data 
-        wasnul = False
-        if len(uvdata) == 0:
-            bpy.ops.object.editmode_toggle()
-            uvdata = ob.data.uv_textures.active.data
-            wasnul = True                        
-        
-        
-        vglen = trunc(pow(ob.custom_sub+1, 2))
-        
-        for i in range(vglen):  
-            uvdata[f[nbface-i-1].index].image = img
-        
-        if wasnul == False:
-            bpy.ops.object.editmode_toggle()
-        else:
-            bpy.ops.object.mode_set(mode = cm, toggle=False)
-                
-        align_to_view(context)
-        
-        return {'FINISHED'}
-
-# Oprerator Class to make the 4 or 6 point and scale the plan
-class IntuitiveScale(Operator):
-    bl_idname = "object.intuitivescale"
-    bl_label = "Draw lines"
-
-    def invoke(self, context, event):
-        ob = context.object 
-        x = event.mouse_region_x
-        y = event.mouse_region_y                
-        if len(ob.grease_pencil.layers.active.frames) == 0: 
-            bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
-                                                       "is_start":True, "location":(0, 0, 0),
-                                                       "mouse":(x,y), "pressure":1, "time":0}])
-        else:
-            if ob.custom_linkscale:
-                nb_point = 4
-            else:
-                nb_point = 6
-                   
-            if len(ob.grease_pencil.layers.active.frames[0].strokes) < nb_point:
-                bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
-                                                           "is_start":True, "location":(0, 0, 0),
-                                                           "mouse":(x,y), "pressure":1, "time":0}])
-                                                           
-            if len(ob.grease_pencil.layers.active.frames[0].strokes) == nb_point:
-                s = ob.grease_pencil.layers.active.frames[0]
-                v1 = s.strokes[1].points[0].co - s.strokes[0].points[0].co
-                if not ob.custom_linkscale:
-                    v2 = s.strokes[4].points[0].co - s.strokes[3].points[0].co
-                else:
-                    v2 = s.strokes[3].points[0].co - s.strokes[2].points[0].co
-                propx = v1.x/v2.x                
-                ob.custom_scale[0] *= abs(propx)
-                
-                if not ob.custom_linkscale:
-                    v1 = s.strokes[2].points[0].co - s.strokes[0].points[0].co
-                    v2 = s.strokes[5].points[0].co - s.strokes[3].points[0].co
-                    propy = v1.y/v2.y
-                    ob.custom_scale[1] *= abs(propy)
-                bpy.ops.gpencil.active_frame_delete()
-        
-        return {'FINISHED'}
-
-# Oprerator Class to configure all wath is needed
-class AddBProjectionPlane(Operator):
-    bl_idname = "object.addbprojectionplane"
-    bl_label = "Configure"
-    
-    def creatematerial(self, context):        
-        try:
-            matBProjection = bpy.data.materials['Material for BProjection']
-        except:            
-            bpy.data.textures.new(name='Texture for BProjection',type='IMAGE')
-    
-            bpy.data.materials.new(name='Material for BProjection')
-            
-            matBProjection = bpy.data.materials['Material for BProjection']
-            matBProjection.texture_slots.add()
-            matBProjection.use_shadeless = True
-            matBProjection.use_transparency = True
-            matBProjection.active_texture = bpy.data.textures['Texture for BProjection']
-        
-            index = matBProjection.active_texture_index
-            matBProjection.texture_slots[index].texture_coords = 'UV'
-        
-        ob = context.object 
-        old_index = ob.active_material_index
-        bpy.ops.object.material_slot_add()
-        index = ob.active_material_index
-        ob.material_slots[index].material = bpy.data.materials['Material for BProjection']
-        bpy.ops.object.material_slot_assign()
-        ob.active_material_index = old_index
-        ob.data.update()
-            
-    def execute(self, context):    
-        try:
-            bpy.data.objects['Empty for BProjection']
-
-        except:            
-            createcustomprops(context)
-            cm = bpy.context.object.mode
-            bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
-            
-            context.space_data.show_relationship_lines = False
-            
-            ob = context.object
-        
-            bpy.ops.object.add()
-            em = context.object
-            em.name = "Empty for BProjection"
-                        
-            bpy.data.scenes['Scene'].objects.active = ob
-            ob.select = True
-    
-            bpy.ops.object.editmode_toggle()
-    
-            bpy.ops.mesh.primitive_plane_add()
-            bpy.ops.object.vertex_group_assign(new = True)
-            ob.vertex_groups.active.name = 'texture plane'   
-            bpy.ops.uv.unwrap()
-            
-            bpy.ops.object.editmode_toggle()
-            for i in range(4):
-                ob.data.edges[len(ob.data.edges)-1-i].crease = 1
-            bpy.ops.object.editmode_toggle()
-
-            bpy.ops.mesh.subdivide(number_cuts = ob.custom_sub)
-    
-            em.select = True
-            bpy.ops.object.hook_add_selob()
-            em.select = False
-            em.hide = True   
-                     
-            self.creatematerial(context)
-  
-          
-            bpy.ops.gpencil.data_add()
-            ob.grease_pencil.draw_mode = 'VIEW'
-            bpy.ops.gpencil.layer_add()
-            ob.grease_pencil.layers.active.color = [1.0,0,0]
-            
-            bpy.ops.object.editmode_toggle()
-            
-            bpy.ops.object.shape_key_add(from_mix = False)
-            
-            bpy.ops.object.create_view()
-            # ----------------------------------------------
-            # XXX, this isnt future proof, DON'T USE INDEX's - campbell                    
-            km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
-            km.keymap_items[3-1].idname = 'view3d.rotate_view3d'
-            km.keymap_items[19-1].idname = 'view3d.zoom_view3d'
-            km.keymap_items[19-1].properties.delta = 1.0
-            km.keymap_items[20-1].idname = 'view3d.zoom_view3d'
-            km.keymap_items[20-1].properties.delta = -1.0
-            km.keymap_items[4-1].idname = 'view3d.pan_view3d'
-            km.keymap_items[26-1].idname = 'view3d.preset_view3d'
-            km.keymap_items[26-1].properties.view = 'FRONT'
-            km.keymap_items[28-1].idname = 'view3d.preset_view3d'
-            km.keymap_items[28-1].properties.view = 'RIGHT'            
-            km.keymap_items[32-1].idname = 'view3d.preset_view3d'
-            km.keymap_items[32-1].properties.view = 'TOP'
-            km.keymap_items[34-1].idname = 'view3d.preset_view3d'
-            km.keymap_items[34-1].properties.view = 'BACK'
-            km.keymap_items[35-1].idname = 'view3d.preset_view3d'
-            km.keymap_items[35-1].properties.view = 'LEFT'            
-            km.keymap_items[36-1].idname = 'view3d.preset_view3d'
-            km.keymap_items[36-1].properties.view = 'BOTTOM'                                   
-            km = context.window_manager.keyconfigs.default.keymaps['Image Paint']
-            kmi = km.keymap_items.new("object.intuitivescale", 'LEFTMOUSE', 'PRESS', shift=True)
-                        
-            align_to_view(context)
-            
-            context.space_data.cursor_location = em.location
-            
-            bpy.ops.object.mode_set(mode = cm, toggle=False)
-            
-        return {'FINISHED'}
-
-# Oprerator Class to remove what is no more needed    
-class RemoveBProjectionPlane(Operator):
-    bl_idname = "object.removebprojectionplane"
-    bl_label = "Configure"
-
-    def removematerial(self, context):
-        ob = context.object 
-        i = 0
-
-        for ms in ob.material_slots:
-            if ms.name == 'Material for BProjection':
-                index = i
-            i+=1
-                
-        ob.active_material_index = index
-        bpy.ops.object.material_slot_remove()
-    
-    def execute(self, context):
-        try:               
-            cm = bpy.context.object.mode
-            bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
-            
-            context.space_data.show_relationship_lines = True
-            
-            bpy.ops.object.modifier_remove(modifier="Hook-Empty for BProjection")
-            
-            self.removematerial(context)
-
-            ob = context.object
-    
-            bpy.ops.object.editmode_toggle()
-    
-            bpy.ops.mesh.reveal()
-                                   
-            bpy.ops.mesh.select_all()
-            bpy.ops.object.editmode_toggle() 
-            if ob.data.vertices[0].select:
-                bpy.ops.object.editmode_toggle()
-                bpy.ops.mesh.select_all()
-                bpy.ops.object.editmode_toggle()
-            bpy.ops.object.editmode_toggle()                    
-            
-            ob.vertex_groups.active.name = 'texture plane'
-            bpy.ops.object.vertex_group_select()
-            bpy.ops.mesh.delete()
-            bpy.ops.object.vertex_group_remove()
-    
-            bpy.ops.object.editmode_toggle()
-   
-            ob.select = False
-                
-            em = bpy.data.objects['Empty for BProjection']
-            bpy.data.scenes['Scene'].objects.active = em
-            em.hide = False
-            em.select = True
-            bpy.ops.object.delete()
-    
-            bpy.data.scenes['Scene'].objects.active = ob
-            ob.select = True
-            
-            km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
-            # ----------------------------------------------
-            # XXX, this isnt future proof, DON'T USE INDEX's - campbell
-            km.keymap_items[3-1].idname = 'view3d.rotate'
-            km.keymap_items[19-1].idname = 'view3d.zoom'
-            km.keymap_items[19-1].properties.delta = 1.0
-            km.keymap_items[20-1].idname = 'view3d.zoom'
-            km.keymap_items[20-1].properties.delta = -1.0
-            km.keymap_items[4-1].idname = 'view3d.move'
-            km.keymap_items[26-1].idname = 'view3d.viewnumpad'
-            km.keymap_items[26-1].properties.type = 'FRONT'
-            km.keymap_items[28-1].idname = 'view3d.viewnumpad'
-            km.keymap_items[28-1].properties.type = 'RIGHT'            
-            km.keymap_items[32-1].idname = 'view3d.viewnumpad'
-            km.keymap_items[32-1].properties.type = 'TOP'
-            km.keymap_items[34-1].idname = 'view3d.viewnumpad'
-            km.keymap_items[34-1].properties.type = 'BACK'
-            km.keymap_items[35-1].idname = 'view3d.viewnumpad'
-            km.keymap_items[35-1].properties.type = 'LEFT'            
-            km.keymap_items[36-1].idname = 'view3d.viewnumpad'
-            km.keymap_items[36-1].properties.type = 'BOTTOM'            
-            
-            km = context.window_manager.keyconfigs.default.keymaps['Image Paint']
-            #to do
-            for kmi in [kmi for kmi in km.keymap_items if kmi.idname in {"object.intuitivescale", }]:
-                    km.keymap_items.remove(kmi)
-            
-            bpy.ops.object.mode_set(mode = cm, toggle=False)
-            
-            for i in ob.data.shape_keys.key_blocks:
-                bpy.ops.object.shape_key_remove()
-            bpy.ops.object.shape_key_remove()    
-            
-            removecustomprops()
-                    
-        except:
-            nothing = 0
-        
-        return {'FINISHED'}
-
-# Oprerator Class to rotate the view3D
-class RotateView3D(Operator):
-    bl_idname = "view3d.rotate_view3d"
-    bl_label = "Rotate the View3D"
-    
-    first_mouse = Vector((0,0))
-
-    pan = Vector((0,0))
-
-    key = ['']
- 
-    first_time = True
-    
-    def vect_sphere(self, context, mx, my):
-        width = context.area.regions[4].width
-        height = context.area.regions[4].height
-           
-        if width >= height:
-            ratio = height/width
-        
-            x = 2*mx/width
-            y = 2*ratio*my/height
-            
-            x = x - 1
-            y = y - ratio
-        else:
-            ratio = width/height
-        
-            x = 2*ratio*mx/width
-            y = 2*my/height
- 
-            x = x - ratio
-            y = y - 1
-        
-        z2 = 1 - x * x - y * y
-        if z2 > 0:
-            z= sqrt(z2)
-        else : z=0
-            
-        p = Vector((x, y, z))
-        p.normalize()
-        return p
-    
-    def tracball(self, context, mx, my, origine):
-        sd = context.space_data
-        ob = context.object         
-        if ob.custom_rot:
-            vr_b = sd.region_3d.view_rotation.copy()
-            vr_b.invert()
-            pos_init = sd.region_3d.view_location - origine
-            sd.region_3d.view_location = origine
-        
-        v1 = self.vect_sphere(context, self.first_mouse.x, self.first_mouse.y)
-        v2 = self.vect_sphere(context, mx, my)
-                        
-        axis = Vector.cross(v1,v2);
-        angle = Vector.angle(v1,v2);
-            
-        q =  Quaternion(axis,-2*angle)
-                        
-        sd.region_3d.view_rotation *=q
-        sd.region_3d.update()
-        
-        if ob.custom_rot:
-            vr_a = sd.region_3d.view_rotation.copy()                           
-            pos_init.rotate(vr_a*vr_b)            
-            sd.region_3d.view_location =  pos_init + origine
-        
-        self.first_mouse = Vector((mx, my))
-                
-    def modal(self, context, event):                                
-        ob = context.object 
-        reg = context.area.regions[4]        
-        if event.value == 'PRESS':
-            self.pan = Vector((event.mouse_region_x, event.mouse_region_y))
-                    
-            self.key = [event.type]
-
-        if event.value == 'RELEASE':
-            self.key = [''] 
-
-        if event.type == 'MOUSEMOVE':                        
-            
-            if '' in self.key:
-                self.tracball(context, event.mouse_region_x, event.mouse_region_y,ob.location)
-                align_to_view(context)
-                if self.first_time:
-                    rot_ang = context.user_preferences.view.rotation_angle            
-                    context.user_preferences.view.rotation_angle = 0
-                    bpy.ops.view3d.view_orbit(type='ORBITLEFT')
-                    context.user_preferences.view.rotation_angle = rot_ang   
-                    bpy.ops.view3d.view_persportho()         
-                    bpy.ops.view3d.view_persportho()
-                    self.first_time = False
-          
-            deltax = event.mouse_region_x - round(self.pan.x)
-            deltay = event.mouse_region_y - round(self.pan.y)          
-
-            if 'G' in self.key:       
-                sd = context.space_data              
-                l =  sd.region_3d
-                vr = l.view_rotation.copy()
-                vr.invert()
-                
-                v_init = Vector((0.0,0.0,1.0))
-                
-                pos = [-deltax,-deltay]
-                v = view3d_utils.region_2d_to_location_3d(context.region, l, pos, v_init)
-                pos = [0,0]
-                vbl = view3d_utils.region_2d_to_location_3d(context.region, l, pos, v_init)        
-                loc = vbl - v            
-                loc.rotate(vr)
-                ob.custom_location += loc              
-                                   
-            if 'S' in self.key:                
-                s = ob.custom_scale
-                if ob.custom_linkscale:
-                    ob.custom_propscale += deltax/20
-                else:
-                    ob.custom_scale = [s[0] + deltax/20, s[1] + deltay/20]
-                                          
-            if 'Z' in self.key:                
-                ob.custom_location.z+=deltax/10
-                      
-            if 'R' in self.key:
-                ob.custom_rotation+=deltax
-                    
-            if 'U' in self.key:
-                suv = ob.custom_scaleuv
-                if ob.custom_linkscaleuv:    
-                    ob.custom_propscaleuv += deltax/50
-                else:
-                    ob.custom_scaleuv= [suv[0] + deltax/50 , suv[1] + deltay/50]               
-
-            if 'Y' in self.key:       
-                ouv = ob.custom_offsetuv
-                ob.custom_offsetuv = [ouv[0] - deltax/50,ouv[1] - deltay/50] 
-
-            self.pan = Vector((event.mouse_region_x, event.mouse_region_y))
-            self.first_mouse = Vector((event.mouse_region_x, self.first_mouse.y))
-                        
-        elif event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':       
-            
-            return {'FINISHED'}
-        
-        if 'C' in self.key:
-            ob.custom_scale = [1,1]
-            ob.custom_rotation = 0
-            ob.custom_scaleuv =[1.0,1.0]
-            ob.custom_offsetuv =[0.0,0.0]
-            ob.custom_propscaleuv = 1.0
-            ob.custom_propscale = 1.0
-            if ob.custom_flipuvx == True:
-                ob.custom_flipuvx = False
-            if ob.custom_flipuvy == True:
-                ob.custom_flipuvy = False
-                    
-        return {'RUNNING_MODAL'}
-    
-    def execute(self, context):        
-        align_to_view(context)  
-        
-        return{'FINISHED'}
-
-    def invoke(self, context, event):
-        context.window_manager.modal_handler_add(self)
-        self.first_mouse = Vector((event.mouse_region_x,event.mouse_region_y))
-        self.first_time = True
-        
-        return {'RUNNING_MODAL'}
-
-# Oprerator Class to pan the view3D
-class PanView3D(bpy.types.Operator):
-    bl_idname = "view3d.pan_view3d"
-    bl_label = "Pan View3D"
-    
-    first_mouse = Vector((0,0))
-
-    def modal(self, context, event):
-        ob = context.object
-        width = context.area.regions[4].width
-        height = context.area.regions[4].height
-
-        deltax = event.mouse_region_x - self.first_mouse.x
-        deltay = event.mouse_region_y - self.first_mouse.y                
-        
-        sd = context.space_data              
-        r3d =  sd.region_3d
-        vr = r3d.view_rotation.copy()
-        vr.invert()
-        
-        v_init = Vector((0.0,0.0,1.0))
-        
-        pos = [deltax,deltay]
-        v = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
-        pos = [0,0]
-        vbl = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)        
-        loc = vbl - v       
-        sd.region_3d.view_location += loc         
-        loc.rotate(vr)
-        ob.custom_location += loc
-
-        self.first_mouse.x = event.mouse_region_x
-        self.first_mouse.y = event.mouse_region_y
-
-        if event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':
-            return {'FINISHED'}
-        
-        return {'RUNNING_MODAL'}
-                
-    def invoke(self, context, event):
-        context.window_manager.modal_handler_add(self)
-        self.first_mouse.x = event.mouse_region_x
-        self.first_mouse.y = event.mouse_region_y   
-        
-        return {'RUNNING_MODAL'}
-
-    def execute(self, context):        
-        align_to_view(context)  
-        
-        return{'FINISHED'}
-
-# Oprerator Class to zoom the view3D
-class ZoomView3D(Operator):
-    bl_idname = "view3d.zoom_view3d"
-    bl_label = "Zoom View3D"
-
-    delta = FloatProperty(
-        name="delta",
-        description="Delta",
-        min=-1.0, max=1,
-        default=1.0)
-
-    def invoke(self, context, event):                   
-        ob = context.object 
-        sd = context.space_data
-        
-        bpy.ops.view3d.zoom(delta = self.delta)
-        
-        align_to_view(context)
-        
-        return {'FINISHED'}
-
-    def execute(self, context):        
-        align_to_view(context)
-        
-        return{'FINISHED'}
-
-# Oprerator Class to use numpad shortcut
-class PresetView3D(Operator):
-    bl_idname = "view3d.preset_view3d"
-    bl_label = "Preset View3D"
-
-    view = StringProperty(name="View", description="Select the view", default='TOP')
-
-    def invoke(self, context, event):                   
-        ob = context.object 
-        origine = ob.location
-        sd = context.space_data
-
-        if ob.custom_rot:
-            vr_b = sd.region_3d.view_rotation.copy()
-            vr_b.invert()
-            pos_init = sd.region_3d.view_location - origine
-            sd.region_3d.view_location = origine
-
-        tmp = context.user_preferences.view.smooth_view
-        context.user_preferences.view.smooth_view = 0
-        bpy.ops.view3d.viewnumpad(type=self.view)
-        align_to_view(context)        
-        context.user_preferences.view.smooth_view = tmp
-     
-        if ob.custom_rot:
-            vr_a = sd.region_3d.view_rotation.copy()                           
-            pos_init.rotate(vr_a*vr_b)            
-            sd.region_3d.view_location =  pos_init + origine
-               
-                    
-        return {'FINISHED'}
-
-def register():
-    bpy.utils.register_module(__name__)
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-if __name__ == "__main__":
-    register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/space_view3d_simple_align.py b/release/scripts/addons_contrib/space_view3d_simple_align.py
deleted file mode 100644
index 28366ad..0000000
--- a/release/scripts/addons_contrib/space_view3d_simple_align.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# AlingTools.py (c) 2009, 2010 Gabriel Beaudin (gabhead)
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    "name": "Simple Align",
-    "author": "Gabriel Beaudin (gabhead)",
-    "version": (0,1),
-    "blender": (2, 6, 1),
-    "location": "View3D > Tool Shelf > Simple Align Panel",
-    "description": "Align Selected Objects to Active Object",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/3D interaction/Align_Tools",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid==22389",
-    "category": "3D View"}
-
-"""Align Selected Objects"""
-
-import bpy
-
-
-class AlignUi(bpy.types.Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-
-    bl_label = "Simple Align"
-    bl_context = "objectmode"
-
-    def draw(self, context):
-        layout = self.layout
-        obj = context.object
-
-        if obj != None:
-            row = layout.row()
-            row.label(text="Active object is: ", icon='OBJECT_DATA')
-            row = layout.row()
-            row.label(obj.name, icon='EDITMODE_HLT')
-        
-        layout.separator()
-        
-        col = layout.column()
-        col.label(text="Align Loc + Rot:", icon='MANIPUL')
-
-        
-        col = layout.column(align=False)
-        col.operator("object.align",text="XYZ")
-        
-        col = layout.column()
-        col.label(text="Align Location:", icon='MAN_TRANS')
-
-        col = layout.column_flow(columns=5,align=True)
-        col.operator("object.align_location_x",text="X")
-        col.operator("object.align_location_y",text="Y")
-        col.operator("object.align_location_z",text="Z")
-        col.operator("object.align_location_all",text="All")
-
-        col = layout.column()
-        col.label(text="Align Rotation:", icon='MAN_ROT')
-
-        col = layout.column_flow(columns=5,align=True)
-        col.operator("object.align_rotation_x",text="X")
-        col.operator("object.align_rotation_y",text="Y")
-        col.operator("object.align_rotation_z",text="Z")
-        col.operator("object.align_rotation_all",text="All")
-        
-        col = layout.column()
-        col.label(text="Align Scale:", icon='MAN_SCALE')
-
-        col = layout.column_flow(columns=5,align=True)
-        col.operator("object.align_objects_scale_x",text="X")
-        col.operator("object.align_objects_scale_y",text="Y")
-        col.operator("object.align_objects_scale_z",text="Z")
-        col.operator("object.align_objects_scale_all",text="All")
-
-
-##Align all
-def main(context):
-    for i in bpy.context.selected_objects:
-        i.location = bpy.context.active_object.location
-        i.rotation_euler = bpy.context.active_object.rotation_euler
-
-## Align Location
-
-def LocAll(context):
-    for i in bpy.context.selected_objects:
-        i.location = bpy.context.active_object.location
-
-def LocX(context):
-    for i in bpy.context.selected_objects:
-        i.location.x = bpy.context.active_object.location.x
-
-def LocY(context):
-    for i in bpy.context.selected_objects:
-        i.location.y = bpy.context.active_object.location.y
-
-def LocZ(context):
-    for i in bpy.context.selected_objects:
-        i.location.z = bpy.context.active_object.location.z
-
-## Aling Rotation
-def RotAll(context):
-    for i in bpy.context.selected_objects:
-        i.rotation_euler = bpy.context.active_object.rotation_euler
-
-def RotX(context):
-    for i in bpy.context.selected_objects:
-        i.rotation_euler.x = bpy.context.active_object.rotation_euler.x
-
-def RotY(context):
-    for i in bpy.context.selected_objects:
-        i.rotation_euler.y = bpy.context.active_object.rotation_euler.y
-
-def RotZ(context):
-    for i in bpy.context.selected_objects:
-        i.rotation_euler.z = bpy.context.active_object.rotation_euler.z
-## Aling Scale
-def ScaleAll(context):
-    for i in bpy.context.selected_objects:
-        i.scale = bpy.context.active_object.scale
-
-def ScaleX(context):
-    for i in bpy.context.selected_objects:
-        i.scale.x = bpy.context.active_object.scale.x
-
-def ScaleY(context):
-    for i in bpy.context.selected_objects:
-        i.scale.y = bpy.context.active_object.scale.y
-
-def ScaleZ(context):
-    for i in bpy.context.selected_objects:
-        i.scale.z = bpy.context.active_object.scale.z
-
-## Classes
-
-## Align All Rotation And Location
-class AlignOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align"
-    bl_label = "Align Selected To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        main(context)
-        return {'FINISHED'}
-
-#######################Align Location########################
-## Align LocationAll
-class AlignLocationOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_location_all"
-    bl_label = "Align Selected Location To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        LocAll(context)
-        return {'FINISHED'}
-## Align LocationX
-class AlignLocationXOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_location_x"
-    bl_label = "Align Selected Location X To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        LocX(context)
-        return {'FINISHED'}
-## Align LocationY
-class AlignLocationYOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_location_y"
-    bl_label = "Align Selected Location Y To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        LocY(context)
-        return {'FINISHED'}
-## Align LocationZ
-class AlignLocationZOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_location_z"
-    bl_label = "Align Selected Location Z To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        LocZ(context)
-        return {'FINISHED'}
-
-#######################Align Rotation########################
-## Align RotationAll
-class AlignRotationOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_rotation_all"
-    bl_label = "Align Selected Rotation To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        RotAll(context)
-        return {'FINISHED'}
-## Align RotationX
-class AlignRotationXOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_rotation_x"
-    bl_label = "Align Selected Rotation X To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        RotX(context)
-        return {'FINISHED'}
-## Align RotationY
-class AlignRotationYOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_rotation_y"
-    bl_label = "Align Selected Rotation Y To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        RotY(context)
-        return {'FINISHED'}
-## Align RotationZ
-class AlignRotationZOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_rotation_z"
-    bl_label = "Align Selected Rotation Z To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        RotZ(context)
-        return {'FINISHED'}
-#######################Align Scale########################
-## Scale All
-class AlignScaleOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_objects_scale_all"
-    bl_label = "Align Selected Scale To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        ScaleAll(context)
-        return {'FINISHED'}
-## Align ScaleX
-class AlignScaleXOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_objects_scale_x"
-    bl_label = "Align Selected Scale X To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        ScaleX(context)
-        return {'FINISHED'}
-## Align ScaleY
-class AlignScaleYOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_objects_scale_y"
-    bl_label = "Align Selected Scale Y To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        ScaleY(context)
-        return {'FINISHED'}
-## Align ScaleZ
-class AlignScaleZOperator(bpy.types.Operator):
-    ''''''
-    bl_idname = "object.align_objects_scale_z"
-    bl_label = "Align Selected Scale Z To Active"
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
-
-    def execute(self, context):
-        ScaleZ(context)
-        return {'FINISHED'}
-
-## registring
-def register():
-    bpy.utils.register_module(__name__)
-
-    pass
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-    pass
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/system_keyboard_svg.py b/release/scripts/addons_contrib/system_keyboard_svg.py
deleted file mode 100644
index f61744b..0000000
--- a/release/scripts/addons_contrib/system_keyboard_svg.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# this script creates Keyboard layout images of the current keyboard configuration.
-# the result will be writen to the blender default directory.
-
-# first implementation done by jbakker
-# <pep8 compliant>
-
-bl_info = {
-    "name": "Keyboard Layout (svg)",
-    "author": "Jbakker",
-    "version": (0, 1),
-    "blender": (2, 6, 0),
-    "location": "",
-    "description": "Save the hotkeys as a .svg file (search: Keyboard)",
-    "warning": "may not work in recent svn",
-    "wiki_url": 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
-        'Scripts/System/keymaps_to_svg',
-    "tracker_url": "https://projects.blender.org/tracker/index.php?" \
-        "func==detail&aid=21490",
-    "category": "System"}
-
-import bpy
-
-keyboard = [
-['`', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 'ZERO', 'MINUS', 'EQUAL', 'BACKSPACE'],
-['TAB', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\\'],
-['CAPSLOCK', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'", 'ENTER'],
-['SHIFT', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 'SHIFT'],
-['CONTROL', 'OSKEY', 'ALT', 'SPACE', 'ALT', 'OSKEY', 'MENUKEY', 'CONTROL']
-]
-
-# default dimension of a single key [width, heidgh]
-DEFAULT_KEY_DIMENSION = [100, 100]
-# alternative dimensions of specufic keys [keyname,[width, height]]
-ALTERNATIVE_KEY_DIMENSIONS = {
-'BACKSPACE': [250, 100],
-'TAB': [175, 100],
-'\\': [175, 100],
-'CAPSLOCK': [225, 100],
-'ENTER': [240, 100],
-'SHIFT': [290, 100],
-'CONTROL': [225, 100],
-'ALT': [100, 100],
-'OSKEY': [100, 100],
-'MENUKEY': [100, 100],
-'SPACE': [690, 100],
-}
-
-
-def createKeyboard(viewtype):
-    """
-    Creates a keyboard layout (.svg) file of the current configuration for a specific viewtype.
-    example of a viewtype is "VIEW_3D".
-    """
-    for keyconfig in bpy.data.window_managers[0].keyconfigs:
-        map = {}
-        for keymap in keyconfig.keymaps:
-            if keymap.space_type in [viewtype]:
-                for key in keymap.keymap_items:
-                    if key.map_type == 'KEYBOARD':
-                        test = 0
-                        pre = []
-                        cont = ""
-                        if key.ctrl:
-                            test = test + 1
-                            cont = "C"
-                        if key.alt:
-                            test = test + 2
-                            cont = cont + "A"
-                        if key.shift:
-                            test = test + 4
-                            cont = cont + "S"
-                        if key.oskey:
-                            test = test + 8
-                            cont = cont + "O"
-                        if len(cont) > 0:
-                            cont = "[" + cont + "] "
-                        ktype = key.type
-                        if ktype not in map.keys():
-                            map[ktype] = []
-                        map[ktype].append((test, cont + key.name))
-
-        filename = "keyboard_" + viewtype + ".svg"
-        print(filename)
-        svgfile = open(filename, "w")
-        svgfile.write("""<?xml version="1.0" standalone="no"?>
-    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-    """)
-        svgfile.write("""<svg width="2000" height="800" version="1.1" xmlns="http://www.w3.org/2000/svg">
-    """)
-        svgfile.write("""<style>
-    rect {
-        fill:rgb(192,192,192);
-        stroke-width:1;
-        stroke:rgb(0,0,0);
-    }
-    text.header {
-        font-size:xx-large;
-    }
-    text.key {
-        stroke-width:1;
-        stroke:rgb(0,0,0);
-    }
-    text.action {
-        font-size:smaller;
-    }
-    text.add0 {
-        font-size:smaller;
-        fill:rgb(0,0,0)
-    }
-    text.add1 {
-        font-size:smaller;
-        fill:rgb(255,0,0)
-    }
-    text.add2 {
-        font-size:smaller;
-        fill:rgb(0,255,0)
-    }
-    text.add3 {
-       font-size:smaller;
-       fill:rgb(128,128,0)
-    }
-    text.add4 {
-        font-size:smaller;
-        fill:rgb(0,0,255)
-    }
-    text.add5 {
-        font-size:smaller;
-        fill:rgb(128,0,128)
-    }
-    text.add6 {
-        font-size:smaller;
-        fill:rgb(0, 128, 128)
-    }
-    text.add7 {
-        font-size:smaller;
-        fill:rgb(128,128,128)
-    }
-    text.add8 {
-        font-size:smaller;
-        fill:rgb(128,128,128)
-    }
-    text.add9 {
-        font-size:smaller;
-        fill:rgb(255,128,128)
-    }
-    text.add10 {
-        font-size:smaller;
-        fill:rgb(128,255,128)
-    }
-    text.add11 {
-        font-size:smaller;
-        fill:rgb(255,255,128)
-    }
-    text.add12 {
-        font-size:smaller;
-        fill:rgb(128,128,255)
-    }
-    text.add13 {
-        font-size:smaller;
-        fill:rgb(255,128,255)
-    }
-    text.add14 {
-        font-size:smaller;
-        fill:rgb(128,255,255)
-    }
-    text.add15 {
-        font-size:smaller;
-        fill:rgb(255,255,128)
-    }
-    </style>
-    """)
-        svgfile.write("""<text class="header" x="100" y="24">keyboard layout - """ + viewtype + """</text>
-""")
-
-        x = 0
-        xgap = 15
-        ygap = 15
-        y = 32
-        for row in keyboard:
-            x = 0
-            for key in row:
-                width = DEFAULT_KEY_DIMENSION[0]
-                height = DEFAULT_KEY_DIMENSION[1]
-                if key in ALTERNATIVE_KEY_DIMENSIONS.keys():
-                    width = ALTERNATIVE_KEY_DIMENSIONS[key][0]
-                    height = ALTERNATIVE_KEY_DIMENSIONS[key][1]
-                tx = 16
-                ty = 16
-                svgfile.write("""<rect x=\"""" + str(x) + """\" y=\"""" + str(y) + """\" width=\"""" + str(width) + """\" height=\"""" + str(height) + """\" rx="20" ry="20" />
-    """)
-                svgfile.write("""<text class="key" x=\"""" + str(x + tx) + """\" y=\"""" + str(y + ty) + """\" width=\"""" + str(width) + """\" height=\"""" + str(height) + """\">
-    """)
-                svgfile.write(key)
-                svgfile.write("</text>")
-                ty = ty + 16
-                tx = 4
-                if key in map.keys():
-                    for a in map[key]:
-                        svgfile.write("""<text class="add""" + str(a[0]) + """" x=\"""" + str(x + tx) + """\" y=\"""" + str(y + ty) + """\" width=\"""" + str(width) + """\" height=\"""" + str(height) + """\">
-    """)
-                        svgfile.write(a[1])
-                        svgfile.write("</text>")
-                        ty = ty + 16
-                x = x + width + xgap
-            y = y + 100 + ygap
-        svgfile.write("""</svg>""")
-        svgfile.flush()
-        svgfile.close()
-
-
-class WM_OT_Keyboardlayout(bpy.types.Operator):
-    """
-        Windows manager operator for keyboard leyout export
-    """
-    bl_idname = "wm.keyboardlayout"
-    bl_label = "Keyboard layout (SGV)"
-
-    def execute(self, context):
-        """
-        Iterate over all viewtypes to export the keyboard layout.
-        """
-        for vt in ['VIEW_3D', 'LOGIC_EDITOR', 'NODE_EDITOR', 'CONSOLE', 'GRAPH_EDITOR', 'PROPERTIES', 'SEQUENCE_EDITOR', 'OUTLINER', 'IMAGE_EDITOR', 'TEXT_EDITOR', 'DOPESHEET_EDITOR', 'Window']:
-            createKeyboard(vt)
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/system_project_folder.py b/release/scripts/addons_contrib/system_project_folder.py
deleted file mode 100644
index e1250e1..0000000
--- a/release/scripts/addons_contrib/system_project_folder.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# system_project_folder.py (c) 2010 Dany Lebel (Axon_D)
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-    "name": "Project Folder",
-    "author": "Dany Lebel (Axon_D), Spirou4D",
-    "version": (0,3, 1),
-    "blender": (2, 6, 1),
-    "api": 43260,
-    "location": "Info -> File Menu -> Project Folder",
-    "description": "Open the project folder in a file browser",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/System/Project_Folder",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25910",
-    "category": "System"}
-
-
-import bpy
-import os
-from platform import system as currentOS
-
-
-class ProjectFolder(bpy.types.Operator):
-    """Open the Project Folder in a file Browser"""
-    bl_idname = "file.project_folder"
-    bl_label = "Project Folder"
-    
-    
-    def execute(self, context):
-        try :
-            path = self.path()
-        except ValueError:
-            self.report({'INFO'}, "No project folder yet")
-            return {'FINISHED'}
-        
-        bpy.ops.wm.path_open(filepath=path)
-
-        
-        return {'FINISHED'}
-
-    def path(self):
-        filepath = bpy.data.filepath
-        relpath = bpy.path.relpath(filepath)
-        path = filepath[0: -1 * (relpath.__len__() - 2)]
-        return path
-
-
-# Registration
-
-def menu_func(self, context):
-    self.layout.operator(
-        ProjectFolder.bl_idname,
-        text="Project Folder", 
-        icon="FILESEL")
-
-def register():
-    bpy.utils.register_class(ProjectFolder)
-    bpy.types.INFO_MT_file.prepend(menu_func)
-
-def unregister():
-    bpy.utils.unregister_class(ProjectFolder)
-    bpy.types.INFO_MT_file.remove(menu_func)
-
-if __name__ == "__main__":
-    register()
diff --git a/release/scripts/addons_contrib/text_editor_pasteall.py b/release/scripts/addons_contrib/text_editor_pasteall.py
deleted file mode 100644
index ec9fa66..0000000
--- a/release/scripts/addons_contrib/text_editor_pasteall.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "PasteAll",
-    "author": "Dalai Felinto (dfelinto)",
-    "version": (0,7),
-    "blender": (2, 6, 0),
-    "location": "Text editor > Properties panel",
-    "description": "Send your selection or text to www.pasteall.org",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Text_Editor/PasteAll",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=23493",
-    "category": "Text Editor"}
-
-# ########################################################
-# PasteAll.org Text Sender Script
-#
-# Dalai Felinto (dfelinto)
-# blenderecia.orgfree.com
-#
-# Rio de Janeiro - Brasil
-# Vancouver - Canada
-#
-# Original code: 23rd August 2010 (Blender 2.5.3 rev. 31525)
-#
-# Important Note:
-# This script is not official. I did it for fun and for my own usage.
-# And please do not abuse of their generosity - use it wisely (a.k.a no flood).
-#
-# ########################################################
-
-
-import bpy
-import urllib
-import urllib.request
-import webbrowser
-
-class TEXT_PT_pasteall(bpy.types.Panel):
-    bl_space_type = 'TEXT_EDITOR'
-    bl_region_type = 'UI'
-    bl_label = "PasteAll.org"
-
-    def draw(self, context):
-        layout = self.layout        
-        layout.operator("text.pasteall", icon='URL')
-        layout.prop(context.scene, "use_webbrowser")
-
-class TEXT_OT_pasteall(bpy.types.Operator):
-    ''''''
-    bl_idname = "text.pasteall"
-    bl_label = "PasteAll.org"
-    bl_description = "Send the current text or selection to www.pasteall.org"
-
-    @classmethod
-    def poll(cls, context):
-        if context.area.type != 'TEXT_EDITOR':
-            return False
-        else:
-            return context.space_data.text != None
-
-    def invoke(self, context, event):
-        import webbrowser
-        st = context.space_data
-
-        # get the selected text
-        text = self.get_selected_text(st.text)
-        # if no text is selected send the whole file
-        if text is None: text = st.text.as_string()
-
-        # get the file type based on the extension
-        format = self.get_file_format(st.text)
-
-        # send the text and receive the returned page
-        html = self.send_text(text, format)
-
-        if html is None:
-            self.report({'ERROR'}, "Error in sending the text to the server.")
-            return {'CANCELLED'}
-
-        # get the link of the posted page
-        page = self.get_page(str(html))
-        
-        if page is None or page == "":
-            self.report({'ERROR'}, "Error in retrieving the page.")
-            return {'CANCELLED'}
-        else:
-            self.report({'INFO'}, page)
-
-        # store the link in the clipboard
-        bpy.context.window_manager.clipboard = page
-
-        if context.scene.use_webbrowser:
-            try:
-                webbrowser.open_new_tab(page)
-            except:
-                self.report('WARNING', "Error in opening the page %s." % (page))
-
-        return {'FINISHED'}
-            
-    def send_text(self, text, format):
-        ''''''
-        import urllib
-        url = "http://www.pasteall.org/index.php"
-        values = {  'action' : 'savepaste',
-                    'parent_id' : '0',
-                    'language_id': format,
-                    'code' : text }
-
-        try:
-            data = urllib.parse.urlencode(values).encode()
-            req = urllib.request.Request(url, data)
-            response = urllib.request.urlopen(req)
-            page_source = response.read()
-        except:
-            return None
-        else:
-            return page_source
-
-    def get_page(self, html):
-        ''''''
-        id = html.find('directlink')
-        id_begin = id + 12 # hardcoded: directlink">
-        id_end = html[id_begin:].find("</a>")
-
-        if id != -1 and id_end != -1:
-            return html[id_begin:id_begin + id_end]
-        else:
-            return None
-
-    def get_selected_text(self, text):
-        ''''''
-        current_line = text.current_line
-        select_end_line = text.select_end_line
-        
-        current_character = text.current_character
-        select_end_character = text.select_end_character
-        
-        # if there is no selected text return None
-        if current_line == select_end_line:
-            if current_character == select_end_character:
-                return None
-            else:
-                return current_line.body[min(current_character,select_end_character):max(current_character,select_end_character)]
-
-        text_return = None
-        writing = False
-        normal_order = True # selection from top to bottom
-
-        for line in text.lines:
-            if not writing:
-                if line == current_line:
-                    text_return = current_line.body[current_character:] + "\n"
-                    writing = True
-                    continue
-                elif line == select_end_line:
-                    text_return =  select_end_line.body[select_end_character:] + "\n"
-                    writing = True
-                    normal_order = False
-                    continue
-            else:
-                if normal_order:
-                    if line == select_end_line:
-                        text_return += select_end_line.body[:select_end_character]
-                        break
-                    else:
-                        text_return += line.body + "\n"
-                        continue
-                else:
-                    if line == current_line:
-                        text_return += current_line.body[:current_character]
-                        break
-                    else:
-                        text_return += line.body + "\n"
-                        continue
-
-        return text_return
-    
-    def get_file_format(self, text):
-        '''Try to guess what is the format based on the file extension'''
-        extensions =   {'diff':'24',
-                        'patch':'24',
-                        'py':'62',
-                        'c':'12',
-                        'cpp':'18'}
-
-        type = text.name.split(".")[-1]
-        return extensions.get(type, '0')
-
-def register():
-    bpy.types.Scene.use_webbrowser = bpy.props.BoolProperty(
-        name='Launch Browser',
-        description='Opens the page with the submitted text.',
-        default=True)
-
-    bpy.utils.register_module(__name__)
-
-def unregister():
-    del bpy.types.Scene.use_webbrowser
-    bpy.utils.unregister_module(__name__)
-
-if __name__ == "__main__":
-    register()
-
-
diff --git a/release/scripts/addons_contrib/text_intellisense.py b/release/scripts/addons_contrib/text_intellisense.py
deleted file mode 100644
index 1e1c0cb..0000000
--- a/release/scripts/addons_contrib/text_intellisense.py
+++ /dev/null
@@ -1,436 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-
-bl_info = {
-	"name": "Intellisense for Text Editor",
-	"author": "Mackraken",
-	"version": (0, 2),
-	"blender": (2, 6, 0),
-	"api": 41851,
-	"location": "Ctrl + Space at Text Editor",
-	"description": "Adds intellense to the Text Editor",
-	"warning": "Only works with 2.57 intellisense",
-	"wiki_url": "",
-	"tracker_url": "",
-	"category": "Development"}
-
-import bpy
-
-def complete(context):
-	from console import intellisense
-	from console_python import get_console
-	
-	sc = context.space_data
-	text = sc.text
-	
-	region = context.region
-	for area in context.screen.areas:
-		if area.type=="CONSOLE":
-			region = area.regions[1]
-			break
-	
-	console = get_console(hash(region))[0]
-
-	line = text.current_line.body
-	cursor = text.current_character
-	
-	result  = intellisense.expand(line, cursor, console.locals, bpy.app.debug)
-	
-	return result
-
-	
-class Intellimenu(bpy.types.Menu):
-	bl_label = ""
-	bl_idname = "IntelliMenu"
-	
-	text = ""
-	
-	def draw(self, context):
-		layout = self.layout
-		#Very ugly see how can i fix this
-		options = complete(context)
-		
-		options = options[2].split("  ")
-		for op in options:
-			layout.operator("text.intellioptions", text=op).text=op
-		
-#This operator executes when hits Ctrl+Space at the text editor
-
-class Intellisense(bpy.types.Operator):
-	#'''Tooltip'''
-	bl_idname = "text.intellisense"
-	bl_label = "Text Editor Intellisense"
-	
-	text = ""
-	
-#	@classmethod
-#	def poll(cls, context):
-#		return context.active_object is not None
-
-	def execute(self, context):
-		sc = context.space_data
-		text = sc.text
-		
-		if text.current_character>0:
-			result = complete(context)
-	
-			#print(result)
-			
-			if result[2]=="":
-				text.current_line.body = result[0]
-				bpy.ops.text.move(type='LINE_END')
-			else:
-				bpy.ops.wm.call_menu(name=Intellimenu.bl_idname)
-
-		return {'FINISHED'}
-	
-#this operator completes the line with the options you choose from the menu
-class Intellioptions(bpy.types.Operator):
-	#'''Tooltip'''
-	bl_idname = "text.intellioptions"
-	bl_label = "Intellisense options"
-
-	text = bpy.props.StringProperty()
-	
-	@classmethod
-	def poll(cls, context):
-		return context.active_object is not None
-
-	def execute(self, context):
-		sc = context.space_data
-		text = sc.text
-		
-		comp = self.text
-		line = text.current_line.body
-		
-		lline = len(line)
-		lcomp = len(comp)
-		
-		#intersect text 
-		intersect = [-1,-1]
-		
-		for i in range(lcomp):
-			val1 = comp[0:i+1]
-			
-			for j in range(lline):
-				val2 = line[lline-j-1::]
-				#print("	",j, val2)
-			
-				if val1==val2:
-					intersect = [i, j]
-					break
-				
-		if intersect[0]>-1:
-			newline = line[0:lline-intersect[1]-1]+comp
-		else:
-			newline = line + comp
-			
-		#print(newline)		
-		text.current_line.body = newline
-			
-		bpy.ops.text.move(type='LINE_END')
-		   
-
-		return {'FINISHED'}
-
-def send_console(context, all=0):
-	
-	sc = context.space_data
-	text = sc.text
-	
-	console = None
-	
-	for area in bpy.context.screen.areas:
-		if area.type=="CONSOLE":
-			from console_python import get_console
-				
-			console = get_console(hash(area.regions[1]))[0]
-
-	if console==None:
-		return {'FINISHED'}
-	
-	if all:
-		
-		for l in text.lines:
-			console.push(l.body)
-			
-	else:
-		#print(console.prompt)
-		console.push(text.current_line.body)
-	
-	
-	
-	
-class TestLine(bpy.types.Operator):
-	#'''Tooltip'''
-	bl_idname = "text.test_line"
-	bl_label = "Test line"
-
-	all = bpy.props.BoolProperty(default=False)
-	
-	
-#   @classmethod
-#   def poll(cls, context):
-#	   return context.active_object is not None
-
-	def execute(self, context):
-		#print("test line")
-		
-		#send_console(context, self.all)
-		sc = context.space_data
-		text = sc.text
-		
-		line = text.current_line.body
-		console = None
-		
-		for area in bpy.context.screen.areas:
-			if area.type=="CONSOLE":
-				from console_python import get_console
-					
-				console = get_console(hash(area.regions[1]))[0]
-		
-		if console==None:
-			return {'FINISHED'}
-				
-		command = ""
-			
-		forindex = line.find("for ")
-		if forindex >-1:
-			
-			var = line[forindex+4:-1]
-			var = var[0:var.find(" ")]
-			state = line[line.rindex(" ")+1:-1]
-			 
-			command = var + " = " +state+"[0]"
-			
-				
-		else:
-			command = line
-			
-		#print(command)
-		try:
-			console.push(command)
-		except:
-			pass
-		
-		bpy.ops.text.line_break()
-		
-
-		return {'FINISHED'}
-class SetBreakPoint(bpy.types.Operator):
-	bl_idname = "text.set_breakpoint"
-	bl_label = "Set Breakpoint"
-	
-	def execute(self, context):
-		
-		sc = bpy.context.space_data
-		text = sc.text
-		
-		line = text.current_line
-		br = " #breakpoint"
-		#print(line.body.find(br))
-		if line.body.find(br)>-1:
-			
-			line.body = line.body.replace(br, "")
-		else:
-			
-			line.body += br
-		
-		return {'FINISHED'}
-
-class Debug(bpy.types.Operator):
-	bl_idname = "text.debug"
-	bl_label = "Debug"
-	
-	def execute(self, context):
-		
-		binpath = bpy.app.binary_path
-			
-		addonspath = binpath[0:binpath.rindex("\\")+1]+str(bpy.app.version[0])+"."+str(bpy.app.version[1])+"\\scripts\\addons\\"
-		
-		print(addonspath)
-			
-		sc = context.space_data
-		text = sc.text
-		
-		br = " #breakpoint"
-	
-		filepath = addonspath+"debug.py"
-		file = open(filepath, "w")
-		file.write("import pdb\n")
-		
-		for line in text.lines:
-			l = line.body
-			
-			if line.body.find(br)>-1:
-				indent = ""
-				for letter in line.body:
-					
-					if not letter.isalpha():
-						indent+=letter
-					else:
-						break
-				file.write(l[0:-len(br)]+"\n")
-				
-				file.write(indent+"pdb.set_trace()\n")
-				
-			else:
-				file.write(line.body+"\n")
-						
-				
-		
-		file.close()
-		
-		import pdb
-		import debug
-		
-		pdb.runcall("debug")	
-		
-		
-		return {'FINISHED'}
-
-
-class DebugPanel(bpy.types.Panel):
-	bl_label = "Debug"
-	bl_idname = "text.test_line"
-	bl_space_type = "TEXT_EDITOR"
-	bl_region_type = "UI"
-	#bl_context = "object"
-
-	text = bpy.props.StringProperty()
-	
-	def draw(self, context):
-		layout = self.layout
-		row = layout.row()
-		
-		text = self.text
-		row = layout.row()
-		row.operator("text.debug", text ="Debug")
-		row = layout.row()
-		row.operator("text.set_breakpoint")
-		row = layout.row()
-		row.operator("text.test_line").all=False
-		row = layout.row()
-		row.operator("text.test_line", text ="Test All").all=True
-		
-		row = layout.row()
-		row.label(text="Coming Soon ...")
-
-
-### ASSIGN A KEY
- 
-#section = Input section. "Window, Text, ..."
-#name = operator name or wm.call_menu 
-#type = key 
-#event = keyboard event (Press, release, ...)
-#mods = array containing key modifiers (["ctrl", "alt", "shift"]
-#propvalue = menu name, if name is set to "wm.call_menu"
-#overwrite doesnt work at the moment
-
-def assignKey(section, name, type, event, mods=[],propvalue = "",  overwrite=0):
-	
-	kconf = bpy.context.window_manager.keyconfigs.active
-	
-	
-	#check section
-	validsections = [item.name for item in kconf.keymaps]
-	if not section in validsections:
-		print(section  + " is not a valid section.")
-		#print(validsections)	
-		return False
-	
-	#check type
-	type = type.upper()
-	validkeys = [item.identifier for item in bpy.types.KeyMapItem.bl_rna.properties['type'].enum_items]
-	if not type in validkeys:
-		print(type + " is not a valid key.")
-		#print(validkeys)
-		return False
-
-
-	#check event
-	event = event.upper()   
-	validevents = [item.identifier for item in bpy.types.KeyMapItem.bl_rna.properties['value'].enum_items]
-	if not event in validevents:
-		print(event + " is not a valid event.")
-		#print(validevents)
-		
-	kmap = kconf.keymaps[section] 
-
-	
-#   get mods
-	for i, mod in enumerate(mods):
-		mods[i]= mod.lower()
-		
-	#any, shift, ctrl, alt, oskey
-	kmod = [False, False, False, False, False]
-	
-	if "any" in mods: kmod[0] = True
-	if "shift" in mods: kmod[1] = True
-	if "ctrl" in mods: kmod[2] = True
-	if "alt" in mods: kmod[3] = True
-	if "oskey" in mods: kmod[4] = True
-	
-#   #check if key exist
-	kexists = False
-  
-	for key in kmap.keymap_items:
-		keymods = [key.any, key.shift, key.ctrl, key.alt, key.oskey]
-		if key.type == type and keymods == kmod:
-			kexists = True
-			print(key,"key exists")
-			break
-			
-	if kexists:
-		#overwrite?
-		if overwrite:
-			key.idname=name
-			
-			#key.type = type
-		
-	else:
-		#create key
-		key = kmap.keymap_items.new(name, type, event, False)
-		key.any = kmod[0]
-		key.shift = kmod[1]
-		key.ctrl = kmod[2]
-		key.alt = kmod[3]
-		key.oskey = kmod[4]
-				
-		if propvalue!="": key.properties.name = propvalue
-
-
-
-
-classes = [Intellisense, Intellioptions, Intellimenu, DebugPanel, TestLine, SetBreakPoint, Debug]
-
-def register():
-	
-	for c in classes:
-		bpy.utils.register_class(c)
-
-	assignKey("Text", "text.intellisense", "SPACE", "Press",  ["ctrl"])
-	assignKey("Text", "text.test_line", "RET", "Press", [],"",1)
-
-def unregister():
-	for c in classes:
-		bpy.utils.unregister_class(c)
-
-if __name__ == "__main__":
-	register()
diff --git a/release/scripts/addons_contrib/wetted_mesh.py b/release/scripts/addons_contrib/wetted_mesh.py
deleted file mode 100644
index e864317..0000000
--- a/release/scripts/addons_contrib/wetted_mesh.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Add Wetted Mesh",
-    "author": "freejack",
-    "version": (0, 2, 1),
-    "blender": (2, 5, 8),
-    "location": "View3D > Tool Shelf > Wetted Mesh Panel",
-    "description": "Adds separated fluid, dry and wetted mesh for selected pair.",
-    "warning": "",
-    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
-        "Scripts/Mesh/Wetted_Mesh",
-    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
-        "func=detail&aid=27156",
-    "category": "Mesh"}
-
-import bpy
-import collections
-import math
-
-### Tool Panel ###
-class VIEW3D_PT_tools_WettedMesh(bpy.types.Panel):
-    '''Wetted Mesh Tool Panel'''
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'TOOLS'
-    bl_label = 'Wetted Mesh'
-    bl_context = 'objectmode'
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-        slcnt = len(context.selected_objects)
-
-        if slcnt != 2:
-            col.label(text = 'Select two mesh objects')
-            col.label(text = 'to generate separated')
-            col.label(text = 'fluid, dry and wetted')
-            col.label(text = 'meshes.')
-        else:
-            (solid, fluid) = getSelectedPair(context)
-            col.label(text = 'solid = '+solid.name)
-            col.label(text = 'fluid = '+fluid.name)
-            col.operator('mesh.primitive_wetted_mesh_add', text='Generate Meshes')
-
-### Operator ###
-class AddWettedMesh(bpy.types.Operator):
-    '''Add wetted mesh for selected mesh pair'''
-    bl_idname = "mesh.primitive_wetted_mesh_add"
-    bl_label = "Add Wetted Mesh"
-    bl_options = {'REGISTER', 'UNDO'}
-    statusMessage = ''
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-        col.label(text = self.statusMessage)
-
-    def execute(self, context):
-        # make sure a pair of objects is selected
-        if len(context.selected_objects) != 2:
-            # should not happen if called from tool panel
-            self.report({'WARNING'}, "no mesh pair selected, operation cancelled")
-            return {'CANCELLED'}
-
-        print("add_wetted_mesh begin")
-        
-        # super-selected object is solid, other object is fluid
-        (solid, fluid) = getSelectedPair(context)
-        print("   solid = "+solid.name)
-        print("   fluid = "+fluid.name)
-            
-        # make a copy of fluid object, convert to mesh if required
-        print("   copy fluid")
-        bpy.ops.object.select_all(action='DESELECT')
-        fluid.select = True
-        context.scene.objects.active = fluid
-        bpy.ops.object.duplicate()
-        bpy.ops.object.convert(target='MESH', keep_original=False)
-        bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
-        fluidCopy = context.object
-        
-        # substract solid from fluidCopy
-        print("   bool: fluidCopy DIFFERENCE solid")
-        bpy.ops.object.modifier_add(type='BOOLEAN')
-        bop = fluidCopy.modifiers.items()[0]
-        bop[1].operation = 'DIFFERENCE'
-        bop[1].object = solid
-        bpy.ops.object.modifier_apply(apply_as='DATA', modifier=bop[0])
-        fluidMinusSolid = fluidCopy
-        fluidMinusSolid.name = "fluidMinusSolid"
-        
-        # make a second copy of fluid object
-        print("   copy fluid")
-        bpy.ops.object.select_all(action='DESELECT')
-        fluid.select = True
-        context.scene.objects.active = fluid
-        bpy.ops.object.duplicate()
-        bpy.ops.object.convert(target='MESH', keep_original=False)
-        bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
-        fluidCopy = context.object
-        
-        # make union from fluidCopy and solid
-        print("   bool: fluidCopy UNION solid")
-        bpy.ops.object.modifier_add(type='BOOLEAN')
-        bop = fluidCopy.modifiers.items()[0]
-        bop[1].operation = 'UNION'
-        bop[1].object = solid
-        bpy.ops.object.modifier_apply(apply_as='DATA', modifier=bop[0])
-        fluidUnionSolid = fluidCopy
-        fluidUnionSolid.name = "fluidUnionSolid"
-        
-        # index meshes
-        print("   KDTree index fluidMinusSolid")
-        fluidMinusSolidKDT = KDTree(3, fluidMinusSolid.data.vertices)
-        print("   KDTree index fluidUnionSolid")
-        fluidUnionSolidKDT = KDTree(3, fluidUnionSolid.data.vertices)
-        kdtrees = (fluidMinusSolidKDT, fluidUnionSolidKDT)
-        
-        # build mesh face sets
-        faceDict = { }
-        vertDict = { }
-        
-        print("   processing fluidMinusSolid faces")
-        cacheDict = { }
-        setFMSfaces = set()
-        numFaces = len(fluidUnionSolid.data.faces)
-        i = 0
-        for f in fluidMinusSolid.data.faces:
-            if i % 500 == 0:
-                print("      ", i, " / ", numFaces)
-            i += 1
-            fuid = unifiedFaceId(kdtrees, f, fluidMinusSolid.data.vertices, \
-                                 faceDict, vertDict, cacheDict)
-            setFMSfaces.add(fuid)
-        
-        print("   processing fluidUnionSolid faces")
-        cacheDict = { }
-        setFUSfaces = set()
-        numFaces = len(fluidUnionSolid.data.faces)
-        i = 0
-        for f in fluidUnionSolid.data.faces:
-            if i % 500 == 0:
-                print("      ", i, " / ", numFaces)
-            i += 1
-            fuid = unifiedFaceId(kdtrees, f, fluidUnionSolid.data.vertices, \
-                                 faceDict, vertDict, cacheDict)
-            setFUSfaces.add(fuid)
-        
-        # remove boolean helpers
-        print("   delete helper objects")
-        bpy.ops.object.select_all(action='DESELECT')
-        fluidUnionSolid.select = True
-        fluidMinusSolid.select = True
-        bpy.ops.object.delete()
-
-        # wetted = FMS - FUS
-        print("   set operation FMS diff FUS")
-        setWetFaces = setFMSfaces.difference(setFUSfaces)
-        print("   build wetted mesh")
-        verts, faces = buildMesh(setWetFaces, faceDict, vertDict)
-        print("   create wetted mesh")
-        wetted = createMesh("Wetted", verts, faces)
-
-        # fluid = FMS x FUS
-        print("   set operation FMS intersect FUS")
-        setFluidFaces = setFMSfaces.intersection(setFUSfaces)
-        print("   build fluid mesh")
-        verts, faces = buildMesh(setFluidFaces, faceDict, vertDict)
-        print("   create fluid mesh")
-        fluid = createMesh("Fluid", verts, faces)
-        
-        # solid = FUS - FMS
-        print("   set operation FUS diff FMS")
-        setSolidFaces = setFUSfaces.difference(setFMSfaces)
-        print("   build solid mesh")
-        verts, faces = buildMesh(setSolidFaces, faceDict, vertDict)
-        print("   create solid mesh")
-        solid = createMesh("Solid", verts, faces)
-        
-        # parent wetted mesh
-        print("   parent mesh")
-        bpy.ops.object.add(type='EMPTY')
-        wettedMesh = context.object
-        solid.select = True
-        fluid.select = True
-        wetted.select = True
-        wettedMesh.select = True
-        bpy.ops.object.parent_set(type='OBJECT')
-        wettedMesh.name = 'WettedMesh'
-        
-        print("add_wetted_mesh done")
-        self.statusMessage = 'created '+wettedMesh.name
-
-        return {'FINISHED'}
-
-
-### Registration ###
-def register():
-    bpy.utils.register_class(VIEW3D_PT_tools_WettedMesh)
-    bpy.utils.register_class(AddWettedMesh)
-
-
-def unregister():
-    bpy.utils.unregister_class(VIEW3D_PT_tools_WettedMesh)
-    bpy.utils.unregister_class(AddWettedMesh)
-
-if __name__ == "__main__":
-    register()
-
-
-#
-# KD tree (used to create a geometric index of mesh vertices)
-#
-
-def distance(a, b):
-    return (a-b).length
-
-Node = collections.namedtuple("Node", 'point axis label left right')
-
-class KDTree(object):
-    """A tree for nearest neighbor search in a k-dimensional space.
-
-    For information about the implementation, see
-    http://en.wikipedia.org/wiki/Kd-tree
-
-    Usage:
-    objects is an iterable of (co, index) tuples (so MeshVertex is useable)
-    k is the number of dimensions (=3)
-    
-    t = KDTree(k, objects)
-    point, label, distance = t.nearest_neighbor(destination)
-    """
-
-    def __init__(self, k, objects=[]):
-
-        def build_tree(objects, axis=0):
-
-            if not objects:
-                return None
-
-            objects.sort(key=lambda o: o.co[axis])
-            median_idx = len(objects) // 2
-            median_point = objects[median_idx].co
-            median_label = objects[median_idx].index
-
-            next_axis = (axis + 1) % k
-            return Node(median_point, axis, median_label,
-                        build_tree(objects[:median_idx], next_axis),
-                        build_tree(objects[median_idx + 1:], next_axis))
-
-        self.root = build_tree(list(objects))
-        self.size = len(objects)
-
-
-    def nearest_neighbor(self, destination):
-
-        best = [None, None, float('inf')]
-        # state of search: best point found, its label,
-        # lowest distance
-
-        def recursive_search(here):
-
-            if here is None:
-                return
-            point, axis, label, left, right = here
-
-            here_sd = distance(point, destination)
-            if here_sd < best[2]:
-                best[:] = point, label, here_sd
-
-            diff = destination[axis] - point[axis]
-            close, away = (left, right) if diff <= 0 else (right, left)
-
-            recursive_search(close)
-            if math.fabs(diff) < best[2]:
-                recursive_search(away)
-
-        recursive_search(self.root)
-        return best[0], best[1], best[2]
-
-
-#
-# helper functions
-#
-
-# get super-selected object and other object from selected pair
-def getSelectedPair(context):
-    objA = context.object
-    objB = context.selected_objects[0]
-    if objA == objB:
-        objB = context.selected_objects[1]
-    return (objA, objB)
-
-# get a unified vertex id for given coordinates
-def unifiedVertexId(kdtrees, location, vertDict):
-    eps = 0.0001
-    offset = 0
-    for t in kdtrees:
-        co, index, d = t.nearest_neighbor(location)
-        if d < eps:
-            uvid = offset + index
-            if uvid not in vertDict:
-                vertDict[uvid] = co
-            return uvid
-        offset += t.size
-    return -1
-
-# get a unified face id tuple
-#    Stores the ordered face id tuple in faceDict
-#    and the used coordinates for vertex id in vertDict.
-#    cacheDict caches the unified vertex id (lookup in kdtree is expensive).
-#    For each mesh (where the face belongs to) a separate cacheDict is expected.
-def unifiedFaceId(kdtrees, face, vertices, faceDict, vertDict, cacheDict):
-    fids = [ ]
-    for v in face.vertices:
-        uvid = cacheDict.get(v)
-        if uvid == None:
-            uvid = unifiedVertexId(kdtrees, vertices[v].co, vertDict)
-            cacheDict[v] = uvid
-        fids.append(uvid)
-    ofids = tuple(fids)
-    fids.sort()
-    fuid = tuple(fids)
-    if fuid not in faceDict:
-        faceDict[fuid] = ofids
-    return fuid
-
-# build vertex and face array from unified face sets
-def buildMesh(unifiedFaceSet, faceDict, vertDict):
-    verts = [ ]
-    nextV = 0
-    myV = { }
-    faces = [ ]
-    for uf in unifiedFaceSet:
-        of = faceDict[uf]
-        myf = [ ]
-        for uV in of:
-            v = myV.get(uV)
-            if v == None:
-                v = nextV
-                myV[uV] = nextV
-                verts.append(vertDict[uV])
-                nextV += 1
-            myf.append(v)
-        faces.append(myf)
-    return verts, faces
-
-# create mesh object and link to scene
-def createMesh(name, verts, faces):
-    me = bpy.data.meshes.new(name+"Mesh")
-    ob = bpy.data.objects.new(name, me)
-    ob.show_name = True
-    bpy.context.scene.objects.link(ob)
-    me.from_pydata(verts, [], faces)
-    me.update(calc_edges=True)
-    return ob
diff --git a/release/scripts/presets/tracking_settings/blurry_movie.py b/release/scripts/presets/tracking_settings/blurry_movie.py
new file mode 100644
index 0000000..8a503be
--- /dev/null
+++ b/release/scripts/presets/tracking_settings/blurry_movie.py
@@ -0,0 +1,11 @@
+import bpy
+settings = bpy.context.edit_movieclip.tracking.settings
+
+settings.default_tracker = 'KLT'
+settings.default_pyramid_levels = 4
+settings.default_correlation_min = 0.75
+settings.default_pattern_size = 11
+settings.default_search_size = 202
+settings.default_frames_limit = 25
+settings.default_pattern_match = 'KEYFRAME'
+settings.default_margin = 0
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 1b7d5e3..6af6488 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -118,16 +118,24 @@ class SaveDirty(Operator):
         unique_paths = set()
         for image in bpy.data.images:
             if image.is_dirty:
-                filepath = bpy.path.abspath(image.filepath)
-                if "\\" not in filepath and "/" not in filepath:
-                    self.report({'WARNING'}, "Invalid path: " + filepath)
-                elif filepath in unique_paths:
-                    self.report({'WARNING'},
-                                "Path used by more then one image: %r" %
-                                filepath)
+                if image.packed_file:
+                    if image.library:
+                        self.report({'WARNING'},
+                                    "Packed library image: %r from library %r can't be re-packed" %
+                                    (image.name, image.library.filepath))
+                    else:
+                        image.pack(as_png=True)
                 else:
-                    unique_paths.add(filepath)
-                    image.save()
+                    filepath = bpy.path.abspath(image.filepath, library=image.library)
+                    if "\\" not in filepath and "/" not in filepath:
+                        self.report({'WARNING'}, "Invalid path: " + filepath)
+                    elif filepath in unique_paths:
+                        self.report({'WARNING'},
+                                    "Path used by more then one image: %r" %
+                                    filepath)
+                    else:
+                        unique_paths.add(filepath)
+                        image.save()
         return {'FINISHED'}
 
 
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 3bd0d6f..b184c81 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -157,18 +157,17 @@ class prettyface(object):
                 angles_co.sort()
                 I = [i for a, i in angles_co]
 
-                #~ fuv = f.uv
                 uv_layer = f.id_data.uv_layers.active.data
-                fuv = [uv_layer[i].uv for i in f.loops]  # XXX25
+                fuv = [uv_layer[i].uv for i in f.loop_indices]
 
                 if self.rot:
-                    fuv[I[2]] = p1
-                    fuv[I[1]] = p2
-                    fuv[I[0]] = p3
+                    fuv[I[2]][:] = p1
+                    fuv[I[1]][:] = p2
+                    fuv[I[0]][:] = p3
                 else:
-                    fuv[I[2]] = p1
-                    fuv[I[0]] = p2
-                    fuv[I[1]] = p3
+                    fuv[I[2]][:] = p1
+                    fuv[I[0]][:] = p2
+                    fuv[I[1]][:] = p3
 
             f, lens, lensord = uv[0]
 
@@ -179,10 +178,10 @@ class prettyface(object):
                 set_uv(f, (x2, y2), (x2, y1 + margin_h), (x1 + margin_w, y2))
 
         else:  # 1 QUAD
-            uv[1][0], uv[1][1] = x1, y1
-            uv[2][0], uv[2][1] = x1, y2
-            uv[3][0], uv[3][1] = x2, y2
-            uv[0][0], uv[0][1] = x2, y1
+            uv[1][:] = x1, y1
+            uv[2][:] = x1, y2
+            uv[3][:] = x2, y2
+            uv[0][:] = x2, y1
 
     def __hash__(self):
         # None unique hash
diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py
index 93feb8a..3f25006 100644
--- a/release/scripts/startup/bl_ui/properties_animviz.py
+++ b/release/scripts/startup/bl_ui/properties_animviz.py
@@ -31,16 +31,18 @@ class MotionPathButtonsPanel():
     bl_label = "Motion Paths"
     bl_options = {'DEFAULT_CLOSED'}
 
-    def draw_settings(self, context, avs, bones=False):
+    def draw_settings(self, context, avs, mpath, bones=False):
         layout = self.layout
 
         mps = avs.motion_path
-
+        
+        # Display Range
         layout.prop(mps, "type", expand=True)
 
         split = layout.split()
 
         col = split.column()
+        col.label(text="Display Range:")
         sub = col.column(align=True)
         if (mps.type == 'CURRENT_FRAME'):
             sub.prop(mps, "frame_before", text="Before")
@@ -48,18 +50,46 @@ class MotionPathButtonsPanel():
         elif (mps.type == 'RANGE'):
             sub.prop(mps, "frame_start", text="Start")
             sub.prop(mps, "frame_end", text="End")
-
+            
         sub.prop(mps, "frame_step", text="Step")
+        
+        col = split.column()
         if bones:
-            col.row().prop(mps, "bake_location", expand=True)
-
+            col.label(text="Cache for Bone:")
+        else:
+            col.label(text="Cache:")
+            
+        if mpath:
+            sub = col.column(align=True)
+            sub.enabled = False
+            sub.prop(mpath, "frame_start", text="From")
+            sub.prop(mpath, "frame_end", text="To")
+            
+            sub = col.column() # align=True
+            sub.operator_context = 'EXEC_DEFAULT'
+            if bones:
+                col.operator("pose.paths_calculate", text="Update", icon='BONE_DATA')
+            else:
+                col.operator("object.paths_calculate", text="Update", icon='OBJECT_DATA')
+        else:
+            col.label(text="Not available yet...", icon='ERROR')
+            col.label(text="Calculate Paths first", icon='INFO')
+        
+        
+        # Display Settings
+        split = layout.split()
+        
         col = split.column()
-        col.label(text="Display:")
+        col.label(text="Show:")
         col.prop(mps, "show_frame_numbers", text="Frame Numbers")
+        
+        col = split.column()
         col.prop(mps, "show_keyframe_highlight", text="Keyframes")
+        sub = col.column()
+        sub.enabled = mps.show_keyframe_highlight
         if bones:
-            col.prop(mps, "show_keyframe_action_all", text="+ Non-Grouped Keyframes")
-        col.prop(mps, "show_keyframe_numbers", text="Keyframe Numbers")
+            sub.prop(mps, "show_keyframe_action_all", text="+ Non-Grouped Keyframes")
+        sub.prop(mps, "show_keyframe_numbers", text="Keyframe Numbers")
 
 
 # FIXME: this panel still needs to be ported so that it will work correctly with animviz
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 08529a0..63dc641 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -308,14 +308,12 @@ class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
         layout = self.layout
 
         ob = context.object
-
-        self.draw_settings(context, ob.pose.animation_visualisation, bones=True)
-
-        layout.separator()
-
-        split = layout.split()
-        split.operator("pose.paths_calculate", text="Calculate Paths")
-        split.operator("pose.paths_clear", text="Clear Paths")
+        avs = ob.pose.animation_visualisation
+        
+        pchan = context.active_pose_bone
+        mpath = pchan.motion_path if pchan else None
+        
+        self.draw_settings(context, avs, mpath, bones=True)
 
 
 class DATA_PT_onion_skinning(OnionSkinButtonsPanel):  # , Panel): # inherit from panel when ready
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index d7b4b1a..cdef7e7 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -299,14 +299,10 @@ class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
         layout = self.layout
 
         ob = context.object
-
-        self.draw_settings(context, ob.animation_visualisation)
-
-        layout.separator()
-
-        row = layout.row()
-        row.operator("object.paths_calculate", text="Calculate Paths")
-        row.operator("object.paths_clear", text="Clear Paths")
+        avs = ob.animation_visualisation
+        mpath = ob.motion_path
+        
+        self.draw_settings(context, avs, mpath)
 
 
 class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel):  # , Panel): # inherit from panel when ready
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 7010c4f..78d3ebc 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -637,10 +637,6 @@ class USERPREF_PT_theme(Panel):
             col.label(text="Tooltip:")
             ui_items_general(col, ui)
 
-            ui = theme.user_interface.wcol_tooltip
-            col.label(text="Tooltip:")
-            ui_items_general(col, ui)
-
             ui = theme.user_interface.wcol_menu_item
             col.label(text="Menu Item:")
             ui_items_general(col, ui)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 9cf5205..9dda960 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -69,7 +69,7 @@ class VIEW3D_HT_header(Header):
                 row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
 
             # Occlude geometry
-            if view.viewport_shade in {'SOLID', 'SHADED', 'TEXTURED'} and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')):
+            if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')):
                 row.prop(view, "use_occlude_geometry", text="")
 
             # Proportional editing
@@ -135,7 +135,9 @@ class ShowHideMenu():
         layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
 
 
-class VIEW3D_MT_transform(Menu):
+# Standard transforms which apply to all cases
+# NOTE: this doesn't seem to be able to be used directly
+class VIEW3D_MT_transform_base(Menu):
     bl_label = "Transform"
 
     # TODO: get rid of the custom text strings?
@@ -156,22 +158,38 @@ class VIEW3D_MT_transform(Menu):
         layout.operator("transform.warp", text="Warp")
         layout.operator("transform.push_pull", text="Push/Pull")
 
+
+# Generic transform menu - geometry types
+class VIEW3D_MT_transform(VIEW3D_MT_transform_base):
+    def draw(self, context):
+        # base menu
+        VIEW3D_MT_transform_base.draw(self, context)
+        
+        # generic...
+        layout = self.layout
         layout.separator()
 
         layout.operator("transform.translate", text="Move Texture Space").texture_space = True
         layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
 
-        layout.separator()
 
-        obj = context.object
-        if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'} and obj.data.draw_type in {'BBONE', 'ENVELOPE'}:
-            layout.operator("transform.transform", text="Scale Envelope/BBone").mode = 'BONE_SIZE'
+# Object-specific extensions to Transform menu
+class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base):
+    def draw(self, context):
+        # base menu
+        VIEW3D_MT_transform_base.draw(self, context)
+        
+        # object-specific option follow...
+        layout = self.layout
+        layout.separator()
 
-        if context.edit_object and context.edit_object.type == 'ARMATURE':
-            layout.operator("armature.align")
-        else:
-            layout.operator_context = 'EXEC_REGION_WIN'
-            layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN'  # XXX see alignmenu() in edit.c of b2.4x to get this working
+        layout.operator("transform.translate", text="Move Texture Space").texture_space = True
+        layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
+        
+        layout.separator()
+        
+        layout.operator_context = 'EXEC_REGION_WIN'
+        layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN'  # XXX see alignmenu() in edit.c of b2.4x to get this working
 
         layout.separator()
 
@@ -191,6 +209,25 @@ class VIEW3D_MT_transform(Menu):
         layout.operator("object.anim_transforms_to_deltas")
 
 
+# Armature EditMode extensions to Transform menu
+class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base):
+    def draw(self, context):
+        # base menu
+        VIEW3D_MT_transform_base.draw(self, context)
+        
+        # armature specific extensions follow...
+        layout = self.layout
+        layout.separator()
+
+        obj = context.object
+        if (obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'} and 
+            obj.data.draw_type in {'BBONE', 'ENVELOPE'}):
+            layout.operator("transform.transform", text="Scale Envelope/BBone").mode = 'BONE_SIZE'
+
+        if context.edit_object and context.edit_object.type == 'ARMATURE':
+            layout.operator("armature.align")
+
+
 class VIEW3D_MT_mirror(Menu):
     bl_label = "Mirror"
 
@@ -699,7 +736,7 @@ class VIEW3D_MT_object(Menu):
 
         layout.separator()
 
-        layout.menu("VIEW3D_MT_transform")
+        layout.menu("VIEW3D_MT_transform_object")
         layout.menu("VIEW3D_MT_mirror")
         layout.menu("VIEW3D_MT_object_clear")
         layout.menu("VIEW3D_MT_object_apply")
@@ -1317,7 +1354,7 @@ class VIEW3D_MT_pose(Menu):
 
         layout.separator()
 
-        layout.menu("VIEW3D_MT_transform")
+        layout.menu("VIEW3D_MT_transform_armature")
 
         layout.menu("VIEW3D_MT_pose_transform")
         layout.menu("VIEW3D_MT_pose_apply")
@@ -2071,7 +2108,7 @@ class VIEW3D_MT_edit_armature(Menu):
         edit_object = context.edit_object
         arm = edit_object.data
 
-        layout.menu("VIEW3D_MT_transform")
+        layout.menu("VIEW3D_MT_transform_armature")
         layout.menu("VIEW3D_MT_mirror")
         layout.menu("VIEW3D_MT_snap")
         layout.menu("VIEW3D_MT_edit_armature_roll")
@@ -2378,9 +2415,10 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
 
         col.separator()
         col.label(text="Normals:")
-        row = col.row(align=True)
-        row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
-        row.prop(mesh, "show_normal_face", text="", icon='FACESEL')
+        row = col.row()
+        sub = row.row(align=True)
+        sub.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
+        sub.prop(mesh, "show_normal_face", text="", icon='FACESEL')
         row.prop(context.scene.tool_settings, "normal_size", text="Size")
 
         col.separator()
diff --git a/release/scripts/templates/operator_modal_timer.py b/release/scripts/templates/operator_modal_timer.py
index ec47390..ebbf639 100644
--- a/release/scripts/templates/operator_modal_timer.py
+++ b/release/scripts/templates/operator_modal_timer.py
@@ -14,7 +14,7 @@ class ModalTimerOperator(bpy.types.Operator):
 
         if event.type == 'TIMER':
             # change theme color, silly!
-            color = context.user_preferences.themes[0].view_3d.back
+            color = context.user_preferences.themes[0].view_3d.space.back
             color.s = 1.0
             color.h += 0.01
 
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index f834ad5..b12ab53 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -62,7 +62,7 @@ typedef struct bConstraintOb {
 /* ---------------------------------------------------------------------------- */
 
 /* Callback format for performing operations on ID-pointers for Constraints */
-typedef void (*ConstraintIDFunc)(struct bConstraint *con, struct ID **idpoin, void *userdata);
+typedef void (*ConstraintIDFunc)(struct bConstraint *con, struct ID **idpoin, short isReference, void *userdata);
 
 /* ....... */
 
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 6a3625e..4b52189 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -305,6 +305,7 @@ int CustomData_sizeof(int type);
 
 /* get the name of a layer type */
 const char *CustomData_layertype_name(int type);
+int         CustomData_layertype_is_singleton(int type);
 
 /* make sure the name of layer at index is unique */
 void CustomData_set_layer_unique_name(struct CustomData *data, int index);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9713207..5d69b03 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -80,6 +80,7 @@ int exist_object(struct Object *obtest);
 	
 struct Object *add_only_object(int type, const char *name);
 struct Object *add_object(struct Scene *scene, int type);
+void *add_obdata_from_type(int type);
 
 struct Object *copy_object(struct Object *ob);
 void make_local_object(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 1ec9f7d..c0e214a 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -144,9 +144,11 @@ void animviz_free_motionpath(bMotionPath *mpath)
 /* ------------------- */
 
 /* Setup motion paths for the given data
- *	- scene: current scene (for frame ranges, etc.)
- *	- ob: object to add paths for (must be provided)
- *	- pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
+ * - Only used when explicitly calculating paths on bones which may/may not be consider already
+ *
+ * < scene: current scene (for frame ranges, etc.)
+ * < ob: object to add paths for (must be provided)
+ * < pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
  */
 bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Object *ob, bPoseChannel *pchan)
 {
@@ -180,14 +182,25 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec
 	}
 
 	/* if there is already a motionpath, just return that,
-	 * but provided it's settings are ok 
+	 * provided it's settings are ok (saves extra free+alloc)
 	 */
 	if (*dst != NULL) {
+		int expected_length = avs->path_ef - avs->path_sf;
+		
 		mpath= *dst;
 		
-		/* if range is not invalid, and/or length is set ok, just return */
-		if ((mpath->start_frame != mpath->end_frame) && (mpath->length > 0))
-			return mpath;
+		/* path is "valid" if length is valid, but must also be of the same length as is being requested */
+		if ((mpath->start_frame != mpath->end_frame) && (mpath->length > 0)) {
+			/* outer check ensures that we have some curve data for this path */
+			if (mpath->length == expected_length) {
+				/* return/use this as it is already valid length */
+				return mpath;
+			}
+			else {
+				/* clear the existing path (as the range has changed), and reallocate below */
+				animviz_free_motionpath_cache(mpath);
+			}
+		}
 	}
 	else {
 		/* create a new motionpath, and assign it */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 75b9ae5..873f7f1 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -2039,8 +2039,10 @@ static void animsys_evaluate_nla (ListBase *echannels, PointerRNA *ptr, AnimData
 	
 	/* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack
 	 *	- only do this if we're not exclusively evaluating the 'solo' NLA-track
+	 *	- however, if the 'solo' track houses the current 'tweaking' strip, 
+	 *	  then we should allow this to play, otherwise nothing happens
 	 */
-	if ((adt->action) && !(adt->flag & ADT_NLA_SOLO_TRACK)) {
+	if ((adt->action) && ((adt->flag & ADT_NLA_SOLO_TRACK)==0 || (adt->flag & ADT_NLA_EDIT_ON))) {
 		/* if there are strips, evaluate action as per NLA rules */
 		if ((has_strips) || (adt->actstrip)) {
 			/* make dummy NLA strip, and add that to the stack */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 0f3e27a..597bcb5 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1516,8 +1516,12 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3])
 	 *
 	 * was 0.000001, causes bug [#30438] (which is same as [#27675, imho).
 	 * Reseting it to org value seems to cause no more [#23954]...
+	 *
+	 * was 0.0000000000001, caused bug [#], smaller values give unstable
+	 * roll when toggling editmode again...
+	 * No good value here, trying 0.000000001 as best compromize. :/
 	 */
-	if (dot_v3v3(axis,axis) > 1.0e-13f) {
+	if (dot_v3v3(axis, axis) > 1.0e-9f) {
 		/* if nor is *not* a multiple of target ... */
 		normalize_v3(axis);
 
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 4de7df0..a93772c 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -267,6 +267,8 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
 	if (!cddm->pbvh && ob->type == OB_MESH) {
 		SculptSession *ss= ob->sculpt;
 		Mesh *me= ob->data;
+		int deformed = 0;
+
 		cddm->pbvh = BLI_pbvh_new();
 		cddm->pbvh_draw = can_pbvh_draw(ob, dm);
 
@@ -275,7 +277,9 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
 		BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
 		                    me->totface, me->totvert);
 
-		if (ss->modifiers_active && ob->derivedDeform) {
+		deformed = ss->modifiers_active || me->key;
+
+		if (deformed && ob->derivedDeform) {
 			DerivedMesh *deformdm= ob->derivedDeform;
 			float (*vertCos)[3];
 			int totvert;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 0a6e8a1..a0b8cd3 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -781,7 +781,7 @@ static void childof_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
 	bChildOfConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int childof_get_tars (bConstraint *con, ListBase *list)
@@ -917,7 +917,7 @@ static void trackto_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
 	bTrackToConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int trackto_get_tars (bConstraint *con, ListBase *list)
@@ -1098,10 +1098,10 @@ static void kinematic_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bKinematicConstraint *data= con->data;
 	
 	/* chain target */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 	
 	/* poletarget */
-	func(con, (ID**)&data->poletar, userdata);
+	func(con, (ID**)&data->poletar, FALSE, userdata);
 }
 
 static int kinematic_get_tars (bConstraint *con, ListBase *list)
@@ -1191,7 +1191,7 @@ static void followpath_id_looper (bConstraint *con, ConstraintIDFunc func, void
 	bFollowPathConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int followpath_get_tars (bConstraint *con, ListBase *list)
@@ -1541,7 +1541,7 @@ static void loclike_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
 	bLocateLikeConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int loclike_get_tars (bConstraint *con, ListBase *list)
@@ -1632,7 +1632,7 @@ static void rotlike_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
 	bChildOfConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int rotlike_get_tars (bConstraint *con, ListBase *list)
@@ -1745,7 +1745,7 @@ static void sizelike_id_looper (bConstraint *con, ConstraintIDFunc func, void *u
 	bSizeLikeConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int sizelike_get_tars (bConstraint *con, ListBase *list)
@@ -1835,7 +1835,7 @@ static void translike_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bTransLikeConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int translike_get_tars (bConstraint *con, ListBase *list)
@@ -2007,10 +2007,10 @@ static void pycon_id_looper (bConstraint *con, ConstraintIDFunc func, void *user
 	
 	/* targets */
 	for (ct= data->targets.first; ct; ct= ct->next)
-		func(con, (ID**)&ct->tar, userdata);
+		func(con, (ID**)&ct->tar, FALSE, userdata);
 		
 	/* script */
-	func(con, (ID**)&data->text, userdata);
+	func(con, (ID**)&data->text, TRUE, userdata);
 }
 
 /* Whether this approach is maintained remains to be seen (aligorith) */
@@ -2107,10 +2107,10 @@ static void actcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *use
 	bActionConstraint *data= con->data;
 	
 	/* target */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 	
 	/* action */
-	func(con, (ID**)&data->act, userdata);
+	func(con, (ID**)&data->act, TRUE, userdata);
 }
 
 static int actcon_get_tars (bConstraint *con, ListBase *list)
@@ -2273,7 +2273,7 @@ static void locktrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bLockTrackConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int locktrack_get_tars (bConstraint *con, ListBase *list)
@@ -2584,7 +2584,7 @@ static void distlimit_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bDistLimitConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int distlimit_get_tars (bConstraint *con, ListBase *list)
@@ -2712,7 +2712,7 @@ static void stretchto_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bStretchToConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int stretchto_get_tars (bConstraint *con, ListBase *list)
@@ -2887,7 +2887,7 @@ static void minmax_id_looper (bConstraint *con, ConstraintIDFunc func, void *use
 	bMinMaxConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int minmax_get_tars (bConstraint *con, ListBase *list)
@@ -3030,8 +3030,8 @@ static void rbj_id_looper (bConstraint *con, ConstraintIDFunc func, void *userda
 	bRigidBodyJointConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
-	func(con, (ID**)&data->child, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
+	func(con, (ID**)&data->child, FALSE, userdata);
 }
 
 static int rbj_get_tars (bConstraint *con, ListBase *list)
@@ -3083,7 +3083,7 @@ static void clampto_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
 	bClampToConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int clampto_get_tars (bConstraint *con, ListBase *list)
@@ -3268,7 +3268,7 @@ static void transform_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bTransformConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int transform_get_tars (bConstraint *con, ListBase *list)
@@ -3403,10 +3403,10 @@ static bConstraintTypeInfo CTI_TRANSFORM = {
 
 static void shrinkwrap_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
 {
-	bShrinkwrapConstraint *data= con->data;
+	bShrinkwrapConstraint *data = con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->target, userdata);
+	func(con, (ID**)&data->target, FALSE, userdata);
 }
 
 static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
@@ -3578,7 +3578,7 @@ static void damptrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *
 	bDampTrackConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int damptrack_get_tars (bConstraint *con, ListBase *list)
@@ -3724,7 +3724,7 @@ static void splineik_id_looper (bConstraint *con, ConstraintIDFunc func, void *u
 	bSplineIKConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int splineik_get_tars (bConstraint *con, ListBase *list)
@@ -3797,7 +3797,7 @@ static void pivotcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *u
 	bPivotConstraint *data= con->data;
 	
 	/* target only */
-	func(con, (ID**)&data->tar, userdata);
+	func(con, (ID**)&data->tar, FALSE, userdata);
 }
 
 static int pivotcon_get_tars (bConstraint *con, ListBase *list)
@@ -3929,9 +3929,9 @@ static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void
 {
 	bFollowTrackConstraint *data = con->data;
 
-	func(con, (ID**)&data->clip, userdata);
-	func(con, (ID**)&data->camera, userdata);
-	func(con, (ID**)&data->depth_ob, userdata);
+	func(con, (ID**)&data->clip, TRUE, userdata);
+	func(con, (ID**)&data->camera, FALSE, userdata);
+	func(con, (ID**)&data->depth_ob, FALSE, userdata);
 }
 
 static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4123,7 +4123,7 @@ static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
 {
 	bCameraSolverConstraint *data = con->data;
 
-	func(con, (ID**)&data->clip, userdata);
+	func(con, (ID**)&data->clip, TRUE, userdata);
 }
 
 static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4179,8 +4179,8 @@ static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
 {
 	bObjectSolverConstraint *data= con->data;
 
-	func(con, (ID**)&data->clip, userdata);
-	func(con, (ID**)&data->camera, userdata);
+	func(con, (ID**)&data->clip, FALSE, userdata);
+	func(con, (ID**)&data->camera, FALSE, userdata);
 }
 
 static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4542,12 +4542,20 @@ void id_loop_constraints (ListBase *conlist, ConstraintIDFunc func, void *userda
 /* ......... */
 
 /* helper for copy_constraints(), to be used for making sure that ID's are valid */
-static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, void *UNUSED(userData))
+static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userData))
 {
 	if (*idpoin && (*idpoin)->lib)
 		id_lib_extern(*idpoin);
 }
 
+/* helper for copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
+static void con_fix_copied_refs_cb(bConstraint *con, ID **idpoin, short isReference, void *UNUSED(userData))
+{
+	/* increment usercount if this is a reference type */
+	if ((*idpoin) && (isReference))
+		id_us_plus(*idpoin);
+}
+
 /* duplicate all of the constraints in a constraint stack */
 void copy_constraints (ListBase *dst, const ListBase *src, int do_extern)
 {
@@ -4567,6 +4575,10 @@ void copy_constraints (ListBase *dst, const ListBase *src, int do_extern)
 			/* perform custom copying operations if needed */
 			if (cti->copy_data)
 				cti->copy_data(con, srccon);
+				
+			/* fix usercounts for all referenced data in referenced data */
+			if (cti->id_looper)
+				cti->id_looper(con, con_fix_copied_refs_cb, NULL);
 			
 			/* for proxies we don't want to make extern */
 			if (do_extern) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 1514716..957144b 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -71,7 +71,11 @@ typedef struct LayerTypeInfo {
 	int size;          /* the memory size of one element of this layer's data */
 	const char *structname;  /* name of the struct used, for file writing */
 	int structnum;     /* number of structs per element, for file writing */
-	const char *defaultname; /* default layer name */
+
+	/* default layer name.
+	 * note! when NULL this is a way to ensure there is only ever one item
+	 * see: CustomData_layertype_is_singleton() */
+	const char *defaultname;
 
 	/* a function to copy count elements of this layer's data
 	 * (deep copy if appropriate)
@@ -2598,6 +2602,16 @@ const char *CustomData_layertype_name(int type)
 	return layerType_getName(type);
 }
 
+
+/**
+ * Can only ever be one of these.
+ */
+int CustomData_layertype_is_singleton(int type)
+{
+	const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+	return typeInfo->defaultname == NULL;
+}
+
 static int  CustomData_is_property_layer(int type)
 {
 	if ((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 857f6e7..5f97e02 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -815,7 +815,6 @@ static void emDM_drawFacesTex_common(
 	if (vertexCos) {
 		BM_mesh_elem_index_ensure(bm, BM_VERT);
 
-		glBegin(GL_TRIANGLES);
 		for (i=0; i<em->tottri; i++) {
 			BMLoop **ls = em->looptris[i];
 			MTexPoly *tp= has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
@@ -839,6 +838,7 @@ static void emDM_drawFacesTex_common(
 
 			if (draw_option != DM_DRAW_OPTION_SKIP) {
 
+				glBegin(GL_TRIANGLES);
 				if (!drawSmooth) {
 					glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
 
@@ -880,9 +880,9 @@ static void emDM_drawFacesTex_common(
 					glNormal3fv(vertexNos[BM_elem_index_get(ls[2]->v)]);
 					glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
 				}
+				glEnd();
 			}
 		}
-		glEnd();
 	}
 	else {
 		BM_mesh_elem_index_ensure(bm, BM_VERT);
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index a930818..131f30a 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -78,7 +78,8 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
 	int *tris;
 
 	dm = mesh_create_derived_index_render(scene, ob, CD_MASK_BAREMESH, modifierIndex);
-	//dm = mesh_create_derived_no_deform(ob,NULL);
+
+	DM_ensure_tessface(dm);
 
 	mvert = dm->getVertArray(dm);
 	mface = dm->getTessFaceArray(dm);
@@ -122,3 +123,4 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
 
 	dm->release(dm);
 }
+
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 59dd7db..2bcf17a 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1775,7 +1775,7 @@ void mesh_calc_normals_mapping(MVert *mverts, int numVerts,
 {
 	mesh_calc_normals_mapping_ex(mverts, numVerts, mloop, mpolys,
 	                              numLoops, numPolys, polyNors_r, mfaces, numFaces,
-	                              origIndexFace, faceNors_r, TRUE);
+	                              origIndexFace, faceNors_r, FALSE);
 }
 
 void mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts,
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 9a640bc..7eee478 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1038,7 +1038,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
 
 				scopes->track_disabled = FALSE;
 
-				if (ibuf && ibuf->rect) {
+				if (ibuf && (ibuf->rect || ibuf->rect_float)) {
 					ImBuf *tmpibuf;
 					MovieTrackingMarker undist_marker = *marker;
 
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 7580f2e..ea61332 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -835,7 +835,7 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
 	MDisps *mdisps;
 	int lvl= mmd->totlvl;
 
-	if (totlvl > multires_max_levels)
+	if ((totlvl > multires_max_levels) || (me->totpoly == 0))
 		return;
 
 	multires_force_update(ob);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 2fb3f81..0fac497 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -339,15 +339,15 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp)
 	
 	node_add_sockets_from_type(ntree, node, ntype);
 	
-	if (ntype->initfunc!=NULL)
-		ntype->initfunc(ntree, node, ntemp);
-	
 	/* initialize the node name with the node label */
 	BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR);
 	nodeUniqueName(ntree, node);
 	
 	BLI_addtail(&ntree->nodes, node);
 	
+	if (ntype->initfunc!=NULL)
+		ntype->initfunc(ntree, node, ntemp);
+	
 	ntree->update |= NTREE_UPDATE_NODES;
 	
 	return node;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index bc9411b..beddf74 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -744,7 +744,7 @@ int exist_object(Object *obtest)
 
 /* *************************************************** */
 
-static void *add_obdata_from_type(int type)
+void *add_obdata_from_type(int type)
 {
 	switch (type) {
 	case OB_MESH: return add_mesh("Mesh");
@@ -789,6 +789,9 @@ Object *add_only_object(int type, const char *name)
 {
 	Object *ob;
 
+	if(!name)
+		name = get_obdata_defname(type);
+
 	ob= alloc_libblock(&G.main->object, ID_OB, name);
 
 	/* default object vars */
@@ -877,6 +880,7 @@ Object *add_object(struct Scene *scene, int type)
 	ob->lay= scene->lay;
 	
 	base= scene_add_base(scene, ob);
+	scene_deselect_all(scene);
 	scene_select_base(scene, base);
 	ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
 
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 4ce2495..416b075 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1062,7 +1062,8 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
 		if (part->distr==PART_DISTR_GRID && from != PART_FROM_VERT) {
 			BLI_srandom(31415926 + psys->seed);
 			dm= CDDM_from_mesh((Mesh*)ob->data, ob);
-			distribute_grid(dm,psys);
+			DM_ensure_tessface(dm);
+			distribute_grid(dm, psys);
 			dm->release(dm);
 			return 0;
 		}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 01ab574..04218de 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -888,8 +888,6 @@ void scene_deselect_all(Scene *sce)
 
 void scene_select_base(Scene *sce, Base *selbase)
 {
-	scene_deselect_all(sce);
-
 	selbase->flag |= SELECT;
 	selbase->object->flag= selbase->flag;
 
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 2d4397d..6a845ab 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -515,8 +515,17 @@ void build_seqar_cb(ListBase *seqbase, Sequence  ***seqar, int *totseq,
 	*seqar = tseqar;
 }
 
+static int metaseq_start(Sequence *metaseq)
+{
+	return metaseq->start + metaseq->startofs;
+}
 
-static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+static int metaseq_end(Sequence *metaseq)
+{
+	return metaseq->start + metaseq->len - metaseq->endofs;
+}
+
+static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metaseq, int start, int end)
 {
 	Sequence *seq;
 
@@ -524,23 +533,28 @@ static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
 	 * since sound is played outside of evaluating the imbufs, */
 	for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
 		if (seq->type == SEQ_META) {
-			seq_update_sound_bounds_recursive(scene, seq);
+			seq_update_sound_bounds_recursive_rec(scene, seq, MAX2(start, metaseq_start(seq)), MIN2(end, metaseq_end(seq)));
 		}
 		else if (ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
 			if (seq->scene_sound) {
 				int startofs = seq->startofs;
 				int endofs = seq->endofs;
-				if (seq->startofs + seq->start < metaseq->start + metaseq->startofs)
-					startofs = metaseq->start + metaseq->startofs - seq->start;
+				if (seq->startofs + seq->start < start)
+					startofs = start - seq->start;
 
-				if (seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
-					endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
+				if (seq->start + seq->len - seq->endofs > end)
+					endofs = seq->start + seq->len - end;
 				sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start + seq->len - endofs, startofs);
 			}
 		}
 	}
 }
 
+static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+{
+	seq_update_sound_bounds_recursive_rec(scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
+}
+
 void calc_sequence_disp(Scene *scene, Sequence *seq)
 {
 	if (seq->startofs && seq->startstill) seq->startstill = 0;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 9d13397..4042cb2 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -276,29 +276,6 @@ static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene,
 
 		smd->time = scene->r.cfra;
 
-		if (smd->flow->psys && smd->flow->psys->part && !(smd->flow->flags & MOD_SMOKE_FLOW_INIT))
-		{
-			// update particle lifetime to be one frame
-			smd->flow->psys->part->lifetime = 1; // scene->r.efra + 1;
-
-			// use "unborn" flag as standard setting
-			smd->flow->psys->part->flag |= PART_UNBORN;
-
-			smd->flow->flags |= MOD_SMOKE_FLOW_INIT;
-		}
-
-/*
-		if (!smd->flow->bvh)
-		{
-			// smd->flow->bvh = MEM_callocN(sizeof(BVHTreeFromMesh), "smoke_bvhfromfaces");
-			// bvhtree_from_mesh_faces(smd->flow->bvh, dm, 0.0, 2, 6);
-
-			// copy obmat
-			// copy_m4_m4(smd->flow->mat, ob->obmat);
-			// copy_m4_m4(smd->flow->mat_old, ob->obmat);
-		}
-*/
-
 		return 1;
 	}
 	else if ((smd->type & MOD_SMOKE_TYPE_COLL))
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 01930cc..e3a309f 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -78,6 +78,7 @@ variables on the UI for now
 #include "BKE_DerivedMesh.h"
 #include "BKE_pointcache.h"
 #include "BKE_deform.h"
+#include "BKE_mesh.h" 
 //XXX #include  "BIF_editdeform.h"
 //XXX #include  "BIF_graphics.h"
 #include  "PIL_time.h"
@@ -3267,6 +3268,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
 	BodyPoint *bp;
 	BodySpring *bs;
 	int a, totedge;
+  BKE_mesh_tessface_ensure(me); 
 	if (ob->softflag & OB_SB_EDGES) totedge= me->totedge;
 	else totedge= 0;
 
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 83a24f6..e98f4f6 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2102,7 +2102,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 				}
 			}
 			else {
-				glShadeModel(GL_FLAT);
+				glShadeModel((cp)? GL_SMOOTH: GL_FLAT);
 				glBegin(GL_QUADS);
 				for (y = 0; y < gridFaces; y++) {
 					for (x = 0; x < gridFaces; x++) {
@@ -3132,8 +3132,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
 		float *w2;
 		int s, x, y;
 		
-		origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
-		
 		w = get_ss_weights(&wtable, gridCuts, numVerts);
 
 		ccgdm->faceMap[index].startVert = vertNum;
@@ -3144,6 +3142,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
 		faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
 		faceFlags++;
 
+		origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
+
 		/* set the face base vert */
 		*((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
 
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 1197ec2..746e901 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -956,70 +956,46 @@ void txt_move_right(Text *text, short sel)
 
 void txt_jump_left(Text *text, short sel)
 {
-	TextLine **linep, *oldl;
-	int *charp, oldc, oldflags, i;
-	unsigned char oldu;
-	int pos;
-
+	TextLine **linep;
+	int *charp, oldc;
+	
 	if (!text) return;
 	if (sel) txt_curs_sel(text, &linep, &charp);
 	else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
 	if (!*linep) return;
+	oldc = *charp;
 
-	oldflags = text->flags;
-	text->flags &= ~TXT_TABSTOSPACES;
-
-	oldl= *linep;
-	oldc= *charp;
-	oldu= undoing;
-	undoing= 1; /* Don't push individual moves to undo stack */
-
-	pos = *charp;
 	BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
-	                         &pos, STRCUR_DIR_PREV,
+                             charp, STRCUR_DIR_PREV,
 	                         STRCUR_JUMP_DELIM);
-	for (i = *charp; i > pos; i--) {
-		txt_move_left(text, sel);
+	
+	if (!sel) txt_pop_sel(text);
+	if (!undoing) {
+		int span = txt_get_span(text->lines.first, *linep);
+		txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp);
 	}
-
-	text->flags = oldflags;
-
-	undoing= oldu;
-	if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
 }
 
 void txt_jump_right(Text *text, short sel)
 {
-	TextLine **linep, *oldl;
-	int *charp, oldc, oldflags, i;
-	unsigned char oldu;
-	int pos;
-
+	TextLine **linep;
+	int *charp, oldc;
+	
 	if (!text) return;
 	if (sel) txt_curs_sel(text, &linep, &charp);
 	else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
 	if (!*linep) return;
-
-	oldflags = text->flags;
-	text->flags &= ~TXT_TABSTOSPACES;
-
-	oldl= *linep;
-	oldc= *charp;
-	oldu= undoing;
-	undoing= 1; /* Don't push individual moves to undo stack */
-
-	pos = *charp;
+	oldc = *charp;
+	
 	BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
-	                         &pos, STRCUR_DIR_NEXT,
+                             charp, STRCUR_DIR_NEXT,
 	                         STRCUR_JUMP_DELIM);
-	for (i = *charp; i < pos; i++) {
-		txt_move_right(text, sel);
+	
+	if (!sel) txt_pop_sel(text);
+	if (!undoing) {
+		int span = txt_get_span(text->lines.first, *linep);
+		txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp);
 	}
-
-	text->flags = oldflags;
-
-	undoing= oldu;
-	if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
 }
 
 void txt_move_bol (Text *text, short sel) 
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 7654c36..2d5d47e 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -680,6 +680,8 @@ void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingOb
 	ListBase *tracksbase = BKE_tracking_object_tracks(tracking, object);
 	MovieTrackingTrack *track = tracksbase->first;
 
+	BKE_tracking_free_clipboard();
+
 	while (track) {
 		if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
 			MovieTrackingTrack *new_track = duplicate_track(track);
@@ -1164,7 +1166,13 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki
 	x1 = x-(int)(w * (-min[0] / (max[0] - min[0])));
 	y1 = y-(int)(h * (-min[1] / (max[1] - min[1])));
 
-	tmpibuf = IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect);
+	if (ibuf->rect_float)
+		tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rectfloat);
+	else
+		tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rect);
+
+	tmpibuf->profile = ibuf->profile;
+
 	IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1 - margin, y1 - margin, w + margin * 2, h + margin * 2);
 
 	if (pos != NULL) {
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 73220cb..1bf4efc 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -55,6 +55,7 @@ int    BLI_rename(const char *from, const char *to);
 int    BLI_delete(const char *path, int dir, int recursive);
 int    BLI_move(const char *path, const char *to);
 int    BLI_create_symlink(const char *path, const char *to);
+int    BLI_stat(const char *path, struct stat *buffer);
 
 /* Directories */
 
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 457f098..79089b4 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -144,10 +144,10 @@ int				BLI_ghashutil_intcmp	(const void *a, const void *b);
 
 typedef struct GHashPair {
 	const void *first;
-	int second;
+	const void *second;
 } GHashPair;
 
-GHashPair*		BLI_ghashutil_pairalloc (const void *first, int second);
+GHashPair*		BLI_ghashutil_pairalloc (const void *first, const void *second);
 unsigned int	BLI_ghashutil_pairhash	(const void *ptr);
 int				BLI_ghashutil_paircmp	(const void *a, const void *b);
 void			BLI_ghashutil_pairfree	(void *ptr);
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 00a751f..1d99fd4 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -126,6 +126,8 @@ int is_orthogonal_m4(float mat[4][4]);
 int is_orthonormal_m3(float mat[3][3]);
 int is_orthonormal_m4(float mat[4][4]);
 
+int is_uniform_scaled_m3(float mat[3][3]);
+
 void adjoint_m3_m3(float R[3][3], float A[3][3]);
 void adjoint_m4_m4(float R[4][4], float A[4][4]);
 
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 28b4794..4dba726 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -305,7 +305,7 @@ int BLI_ghashutil_strcmp(const void *a, const void *b)
 	return strcmp(a, b);
 }
 
-GHashPair *BLI_ghashutil_pairalloc(const void *first, int second)
+GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
 {
 	GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair");
 	pair->first = first;
@@ -317,7 +317,7 @@ unsigned int BLI_ghashutil_pairhash(const void *ptr)
 {
 	const GHashPair *pair = ptr;
 	unsigned int hash = BLI_ghashutil_ptrhash(pair->first);
-	return hash ^ BLI_ghashutil_inthash(SET_INT_IN_POINTER(pair->second));
+	return hash ^ BLI_ghashutil_ptrhash(pair->second);
 }
 
 int BLI_ghashutil_paircmp(const void *a, const void *b)
@@ -327,7 +327,7 @@ int BLI_ghashutil_paircmp(const void *a, const void *b)
 
 	int cmp = BLI_ghashutil_ptrcmp(A->first, B->first);
 	if (cmp == 0)
-		return BLI_ghashutil_intcmp(SET_INT_IN_POINTER(A->second), SET_INT_IN_POINTER(B->second));
+		return BLI_ghashutil_ptrcmp(A->second, B->second);
 	return cmp;
 }
 
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 76b986d..739ef47 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -866,6 +866,35 @@ int is_orthonormal_m4(float m[][4])
 	return 0;
 }
 
+int is_uniform_scaled_m3(float m[][3])
+{
+	const float eps = 1e-7;
+	float t[3][3];
+	float l1, l2, l3, l4, l5, l6;
+
+	copy_m3_m3(t, m);
+	transpose_m3(t);
+
+	l1 = len_squared_v3(m[0]);
+	l2 = len_squared_v3(m[1]);
+	l3 = len_squared_v3(m[2]);
+
+	l4 = len_squared_v3(t[0]);
+	l5 = len_squared_v3(t[1]);
+	l6 = len_squared_v3(t[2]);
+
+	if (fabsf(l2 - l1) <= eps &&
+	    fabsf(l3 - l1) <= eps &&
+	    fabsf(l4 - l1) <= eps &&
+	    fabsf(l5 - l1) <= eps &&
+	    fabsf(l6 - l1) <= eps)
+	{
+		return 1;
+	}
+
+	return 0;
+}
+
 void normalize_m3(float mat[][3])
 {
 	normalize_v3(mat[0]);
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 1c55d5b..ca1189e 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -493,6 +493,23 @@ int BLI_exists(const char *name)
 	return(st.st_mode);
 }
 
+
+#ifdef WIN32
+int BLI_stat(const char *path, struct stat *buffer)
+{
+	int r;
+	UTF16_ENCODE(path);
+	r=_wstat(path_16,buffer);
+	UTF16_UN_ENCODE(path);
+	return r;
+}
+#else
+int BLI_stat(const char *path, struct stat *buffer)
+{
+	return stat(path, buffer);
+}
+#endif
+
 /* would be better in fileops.c except that it needs stat.h so add here */
 int BLI_is_dir(const char *file)
 {
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
index 97559d6..422a600 100644
--- a/source/blender/blenlib/intern/string_cursor_utf8.c
+++ b/source/blender/blenlib/intern/string_cursor_utf8.c
@@ -93,6 +93,7 @@ static strCursorDelimType test_special_char(const char *ch_utf8)
 			return STRCUR_DELIM_QUOTE;
 
 		case ' ':
+		case '\t':
 			return STRCUR_DELIM_WHITESPACE;
 
 		case '\\':
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d278d37..4adcf6a 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2458,10 +2458,19 @@ typedef struct tConstraintLinkData {
 	ID *id;
 } tConstraintLinkData;
 /* callback function used to relink constraint ID-links */
-static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, void *userdata)
+static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *userdata)
 {
 	tConstraintLinkData *cld= (tConstraintLinkData *)userdata;
-	*idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin);
+	
+	/* for reference types, we need to increment the usercounts on load... */
+	if (isReference) {
+		/* reference type - with usercount */
+		*idpoin = newlibadr_us(cld->fd, cld->id->lib, *idpoin);
+	}
+	else {
+		/* target type - no usercount needed */
+		*idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin);
+	}
 }
 
 static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
@@ -7697,10 +7706,15 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
 			bNodeSocket *old_image = BLI_findlink(&node->inputs, 0);
 			bNodeSocket *old_z = BLI_findlink(&node->inputs, 1);
 			bNodeSocket *sock;
+			char basepath[FILE_MAXDIR];
+			char filename[FILE_MAXFILE];
 			
 			node->storage= nimf;
 			
-			BLI_strncpy(nimf->base_path, old_data->name, sizeof(nimf->base_path));
+			/* split off filename from the old path, to be used as socket sub-path */
+			BLI_split_dirfile(old_data->name, basepath, filename, sizeof(basepath), sizeof(filename));
+			
+			BLI_strncpy(nimf->base_path, basepath, sizeof(nimf->base_path));
 			nimf->format = old_data->im_format;
 			
 			/* if z buffer is saved, change the image type to multilayer exr.
@@ -7708,21 +7722,32 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
 			 * i'm just assuming here that IRIZ means IRIS with z buffer ...
 			 */
 			if (ELEM(old_data->im_format.imtype, R_IMF_IMTYPE_IRIZ, R_IMF_IMTYPE_OPENEXR)) {
+				char sockpath[FILE_MAX];
+				
 				nimf->format.imtype = R_IMF_IMTYPE_MULTILAYER;
-				sock = ntreeCompositOutputFileAddSocket(ntree, node, old_image->name, &nimf->format);
+				
+				BLI_snprintf(sockpath, sizeof(sockpath), "%s_Image", filename);
+				sock = ntreeCompositOutputFileAddSocket(ntree, node, sockpath, &nimf->format);
+				/* XXX later do_versions copies path from socket name, need to set this explicitely */
+				BLI_strncpy(sock->name, sockpath, sizeof(sock->name));
 				if (old_image->link) {
 					old_image->link->tosock = sock;
 					sock->link = old_image->link;
 				}
-				sock = ntreeCompositOutputFileAddSocket(ntree, node, old_z->name, &nimf->format);
+				
+				BLI_snprintf(sockpath, sizeof(sockpath), "%s_Z", filename);
+				sock = ntreeCompositOutputFileAddSocket(ntree, node, sockpath, &nimf->format);
+				/* XXX later do_versions copies path from socket name, need to set this explicitely */
+				BLI_strncpy(sock->name, sockpath, sizeof(sock->name));
 				if (old_z->link) {
 					old_z->link->tosock = sock;
 					sock->link = old_z->link;
 				}
 			}
 			else {
-				/* saves directly to base path, which is the old image output path */
-				sock = ntreeCompositOutputFileAddSocket(ntree, node, "", &nimf->format);
+				sock = ntreeCompositOutputFileAddSocket(ntree, node, filename, &nimf->format);
+				/* XXX later do_versions copies path from socket name, need to set this explicitely */
+				BLI_strncpy(sock->name, filename, sizeof(sock->name));
 				if (old_image->link) {
 					old_image->link->tosock = sock;
 					sock->link = old_image->link;
@@ -14008,7 +14033,7 @@ typedef struct tConstraintExpandData {
 	Main *mainvar;
 } tConstraintExpandData;
 /* callback function used to expand constraint ID-links */
-static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, void *userdata)
+static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *userdata)
 {
 	tConstraintExpandData *ced= (tConstraintExpandData *)userdata;
 	expand_doit(ced->fd, ced->mainvar, *idpoin);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 61969c7..37e6387 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2698,6 +2698,9 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
 			MovieTrackingObject *object;
 			writestruct(wd, ID_MC, "MovieClip", 1, clip);
 
+			if (clip->id.properties)
+				IDP_WriteProperty(clip->id.properties, wd);
+
 			if (clip->adt)
 				write_animdata(wd, clip->adt);
 
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index cbdd5dd..ac2e31c 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -214,6 +214,9 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
 		BLI_array_append(verts, v);
 		BLI_array_append(edges2, e);
 
+		/* we only flag the verts to check if they are in the face more then once */
+		BM_ELEM_API_FLAG_ENABLE(v, _FLAG_MV);
+
 		do {
 			e2 = bmesh_disk_edge_next(e2, v);
 			if (e2 != e && BM_ELEM_API_FLAG_TEST(e2, _FLAG_MF)) {
@@ -269,6 +272,12 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
 		if (!edges2[i]) {
 			goto err;
 		}
+
+		/* check if vert is in face more then once. if the flag is disabled. we've already visited */
+		if (!BM_ELEM_API_FLAG_TEST(verts[i], _FLAG_MV)) {
+			goto err;
+		}
+		BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
 	}
 
 	f = BM_face_create(bm, verts, edges2, len, nodouble);
@@ -286,6 +295,10 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
 err:
 	for (i = 0; i < len; i++) {
 		BM_ELEM_API_FLAG_DISABLE(edges[i], _FLAG_MF);
+		/* vert count may != len */
+		if (i < BLI_array_count(verts)) {
+			BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
+		}
 	}
 
 	BLI_array_free(verts);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 756fd74..e20eb10 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -184,34 +184,32 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge
 
 BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges)
 {
-	BMEdge **edges = NULL;
 	BMVert **verts = NULL;
-	BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
-	BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+	BMEdge **edges = NULL;
+	BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
+	BLI_array_fixedstack_declare(edges, BM_NGON_STACK_SIZE, f->len, __func__);
 	BMLoop *l_iter;
 	BMLoop *l_first;
 	BMLoop *l_copy;
 	BMFace *f_copy;
 	int i;
 
-	/* BMESH_TODO - grow verts array in one go! (right here) */
 	l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+	i = 0;
 	do {
 		if (copyverts) {
-			BMVert *v = BM_vert_create(bm, l_iter->v->co, l_iter->v);
-			BLI_array_append(verts, v);
+			verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v);
 		}
 		else {
-			BLI_array_append(verts, l_iter->v);
+			verts[i] = l_iter->v;
 		}
+		i++;
 	} while ((l_iter = l_iter->next) != l_first);
 
-	/* BMESH_TODO - grow edges array in one go! (right here) */
 	l_iter = l_first = BM_FACE_FIRST_LOOP(f);
 	i = 0;
 	do {
 		if (copyedges) {
-			BMEdge *e;
 			BMVert *v1, *v2;
 			
 			if (l_iter->e->v1 == verts[i]) {
@@ -223,13 +221,11 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
 				v1 = verts[(i + 1) % f->len];
 			}
 			
-			e = BM_edge_create(bm,  v1, v2, l_iter->e, FALSE);
-			BLI_array_append(edges, e);
+			edges[i] = BM_edge_create(bm,  v1, v2, l_iter->e, FALSE);
 		}
 		else {
-			BLI_array_append(edges, l_iter->e);
+			edges[i] = l_iter->e;
 		}
-		
 		i++;
 	} while ((l_iter = l_iter->next) != l_first);
 	
@@ -243,7 +239,10 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
 		BM_elem_attrs_copy(bm, bm, l_iter, l_copy);
 		l_copy = l_copy->next;
 	} while ((l_iter = l_iter->next) != l_first);
-	
+
+	BLI_array_fixedstack_free(verts);
+	BLI_array_fixedstack_free(edges);
+
 	return f_copy;
 }
 
@@ -583,6 +582,9 @@ void BM_face_verts_kill(BMesh *bm, BMFace *f)
 	BLI_array_free(verts);
 }
 
+/**
+ * Kills \a f and its loops.
+ */
 void BM_face_kill(BMesh *bm, BMFace *f)
 {
 #ifdef USE_BMESH_HOLES
@@ -672,7 +674,10 @@ void BM_vert_kill(BMesh *bm, BMVert *v)
 
 /********** private disk and radial cycle functions ********** */
 
-static int bm_loop_length(BMLoop *l)
+/**
+ * return the length of the face, should always equal \a l->f->len
+ */
+static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
 {
 	BMLoop *l_first = l;
 	int i = 0;
@@ -708,18 +713,15 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
 	BMLoop *l_first = f->l_first;
 #endif
 
+	const int len = f->len;
+	const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
 	BMLoop *l_iter, *oldprev, *oldnext;
 	BMEdge **edar = NULL;
-	MDisps *md;
-	BLI_array_staticdeclare(edar, BM_NGON_STACK_SIZE);
-	int i, j, edok, len = 0, do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
-
-	len = bm_loop_length(l_first);
+	BLI_array_fixedstack_declare(edar, BM_NGON_STACK_SIZE, len, __func__);
+	int i, j, edok;
 
 	for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
-		BMEdge *curedge = l_iter->e;
-		bmesh_radial_loop_remove(l_iter, curedge);
-		BLI_array_append(edar, curedge);
+		bmesh_radial_loop_remove(l_iter, (edar[i] = l_iter->e));
 	}
 
 	/* actually reverse the loop */
@@ -733,6 +735,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
 		if (do_disps) {
 			float (*co)[3];
 			int x, y, sides;
+			MDisps *md;
 			
 			md = CustomData_bmesh_get(&bm->ldata, l_iter->head.data, CD_MDISPS);
 			if (!md->totdisp || !md->disps)
@@ -778,7 +781,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
 		BM_CHECK_ELEMENT(l_iter->f);
 	}
 
-	BLI_array_free(edar);
+	BLI_array_fixedstack_free(edar);
 
 	BM_CHECK_ELEMENT(f);
 
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 5149a54..c774880 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -853,6 +853,52 @@ void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
 	if (olddata.layers) MEM_freeN(olddata.layers);
 }
 
+void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n)
+{
+	BMIter iter;
+
+	if (&bm->vdata == data) {
+		BMVert *eve;
+
+		BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+			void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, dst_n);
+			CustomData_bmesh_set_n(data, eve->head.data, type, src_n, ptr);
+		}
+	}
+	else if (&bm->edata == data) {
+		BMEdge *eed;
+
+		BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+			void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, dst_n);
+			CustomData_bmesh_set_n(data, eed->head.data, type, src_n, ptr);
+		}
+	}
+	else if (&bm->pdata == data) {
+		BMFace *efa;
+
+		BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+			void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, dst_n);
+			CustomData_bmesh_set_n(data, efa->head.data, type, src_n, ptr);
+		}
+	}
+	else if (&bm->ldata == data) {
+		BMIter liter;
+		BMFace *efa;
+		BMLoop *l;
+
+		BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+				void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, dst_n);
+				CustomData_bmesh_set_n(data, l->head.data, type, src_n, ptr);
+			}
+		}
+	}
+	else {
+		/* should never reach this! */
+		BLI_assert(0);
+	}
+}
+
 float BM_elem_float_data_get(CustomData *cd, void *element, int type)
 {
 	float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index 0d97fbc..3380a3e 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -36,6 +36,8 @@ void  BM_data_layer_add(BMesh *em, CustomData *data, int type);
 void  BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
 void  BM_data_layer_free(BMesh *em, CustomData *data, int type);
 void  BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
+void  BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n);
+
 float BM_elem_float_data_get(CustomData *cd, void *element, int type);
 void  BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
 
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 4b5c67c..d74ffdc 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -696,6 +696,7 @@ static BMOpDefine bmo_esubd_def = {
 	{{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
 	 {BMO_OP_SLOT_FLT, "smooth"},
 	 {BMO_OP_SLOT_FLT, "fractal"},
+	 {BMO_OP_SLOT_FLT, "along_normal"},
 	 {BMO_OP_SLOT_INT, "numcuts"},
 	 {BMO_OP_SLOT_INT, "seed"},
 	 {BMO_OP_SLOT_MAPPING, "custompatterns"},
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index f4db13e..b0a647b 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -98,7 +98,7 @@ extern int bmesh_total_ops;
 struct Object;
 
 void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
-                        float smooth, float fractal,
+                        float smooth, float fractal, float along_normal,
                         int numcuts,
                         int seltype, int cornertype,
                         const short use_singleedge, const short use_gridfill,
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index 6297e20..da23812 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -60,6 +60,7 @@ int bmesh_disk_count(BMVert *v);
  * on using these internal flags!*/
 #define _FLAG_JF	1 /* join faces */
 #define _FLAG_MF	2 /* make face */
+#define _FLAG_MV	2 /* make face, vertex */
 
 #define BM_ELEM_API_FLAG_ENABLE(element, f)  ((element)->oflags[0].pflag |=  (f))
 #define BM_ELEM_API_FLAG_DISABLE(element, f) ((element)->oflags[0].pflag &= ~(f))
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 8e7723f..1451625 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -34,14 +34,14 @@
 
 #include "intern/bmesh_operators_private.h" /* own include */
 
-#define FACE_MARK	1
-#define FACE_ORIG	2
-#define FACE_NEW	4
-#define EDGE_MARK	1
+#define FACE_MARK   1
+#define FACE_ORIG   2
+#define FACE_NEW    4
+#define EDGE_MARK   1
 
-#define VERT_MARK	1
+#define VERT_MARK   1
 
-static int UNUSED_FUNCTION(check_hole_in_region)(BMesh *bm, BMFace *f)
+static int UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
 {
 	BMWalker regwalker;
 	BMIter liter2;
@@ -60,8 +60,8 @@ static int UNUSED_FUNCTION(check_hole_in_region)(BMesh *bm, BMFace *f)
 		l2 = BM_iter_new(&liter2, bm, BM_LOOPS_OF_FACE, f2);
 		for ( ; l2; l2 = BM_iter_step(&liter2)) {
 			l3 = l2->radial_next;
-			if ( BMO_elem_flag_test(bm, l3->f, FACE_MARK) !=
-			     BMO_elem_flag_test(bm, l2->f, FACE_MARK))
+			if (BMO_elem_flag_test(bm, l3->f, FACE_MARK) !=
+			    BMO_elem_flag_test(bm, l2->f, FACE_MARK))
 			{
 				if (!BMO_elem_flag_test(bm, l2->e, EDGE_MARK)) {
 					return FALSE;
@@ -433,8 +433,8 @@ void dummy_exec(BMesh *bm, BMOperator *op)
 					fe = l->e;
 					for ( ; l; l = BM_iter_step(&liter)) {
 						f2 = BM_iter_new(&fiter, bm,
-								BM_FACES_OF_EDGE, l->e);
-						for ( ; f2; f2 = BM_iter_step(&fiter)) {
+						                 BM_FACES_OF_EDGE, l->e);
+						for (; f2; f2 = BM_iter_step(&fiter)) {
 							if (f2 != f) {
 								BM_faces_join_pair(bm, f, f2, l->e);
 								found2 = 1;
@@ -478,8 +478,8 @@ void dummy_exec(BMesh *bm, BMOperator *op)
 
 /* Limited Dissolve */
 
-#define UNIT_TO_ANGLE DEG2RADF(90.0)
-#define ANGLE_TO_UNIT (1.0 / UNIT_TO_ANGLE)
+#define UNIT_TO_ANGLE DEG2RADF(90.0f)
+#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE)
 
 /* multiply vertex edge angle by face angle
  * this means we are not left with sharp corners between _almost_ planer faces
@@ -520,14 +520,28 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
 	const float angle_max = (float)M_PI / 2.0f;
 	const float angle_limit = minf(angle_max, BMO_slot_float_get(op, "angle_limit"));
 	DissolveElemWeight *weight_elems = MEM_mallocN(MAX2(einput->len, vinput->len) *
-	                                                 sizeof(DissolveElemWeight), __func__);
+	                                               sizeof(DissolveElemWeight), __func__);
 	int i, tot_found;
 
+	BMIter iter;
+	BMEdge *e_iter;
+	BMEdge **earray;
+
+	int *vert_reverse_lookup;
+
+	BMEdge **einput_arr = (BMEdge **)einput->data.p;
+	BMVert **vinput_arr = (BMVert **)vinput->data.p;
+
 	/* --- first edges --- */
 
+	/* wire -> tag */
+	BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) {
+		BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter));
+	}
+
 	/* go through and split edge */
 	for (i = 0, tot_found = 0; i < einput->len; i++) {
-		BMEdge *e = ((BMEdge **)einput->data.p)[i];
+		BMEdge *e = einput_arr[i];
 		const float angle = BM_edge_calc_face_angle(e);
 
 		if (angle < angle_limit) {
@@ -562,24 +576,53 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
 				}
 			}
 		}
+	}
 
-		/* remove all edges/verts left behind from dissolving */
-		for (i = 0; i < einput->len; i++) {
-			BMEdge *e = (BMEdge *)weight_elems[i].ele;
-			if (BM_edge_is_wire(e)) {
-				BMVert *v1 = e->v1;
-				BMVert *v2 = e->v2;
-				BM_edge_kill(bm, e);
-				if (v1->e == NULL) BM_vert_kill(bm, v1);
-				if (v2->e == NULL) BM_vert_kill(bm, v2);
+	/* prepare for cleanup */
+	BM_mesh_elem_index_ensure(bm, BM_VERT);
+	vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__);
+	fill_vn_i(vert_reverse_lookup, bm->totvert, -1);
+	for (i = 0, tot_found = 0; i < vinput->len; i++) {
+		BMVert *v = vinput_arr[i];
+		vert_reverse_lookup[BM_elem_index_get(v)] = i;
+	}
+
+	/* --- cleanup --- */
+	earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__);
+	BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) {
+		earray[i] = e_iter;
+	}
+	/* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */
+	for (i = bm->totedge - 1; i != -1; i--) {
+		e_iter = earray[i];
+
+		if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == FALSE)) {
+			/* edge has become wire */
+			int vidx_reverse;
+			BMVert *v1 = e_iter->v1;
+			BMVert *v2 = e_iter->v2;
+			BM_edge_kill(bm, e_iter);
+			if (v1->e == NULL) {
+				vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)];
+				if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+				BM_vert_kill(bm, v1);
+			}
+			if (v2->e == NULL) {
+				vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)];
+				if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+				BM_vert_kill(bm, v2);
 			}
 		}
 	}
+	MEM_freeN(vert_reverse_lookup);
+
+	MEM_freeN(earray);
+
 
 	/* --- second verts --- */
 	for (i = 0, tot_found = 0; i < vinput->len; i++) {
-		BMVert *v = ((BMVert **)vinput->data.p)[i];
-		const float angle = bm_vert_edge_face_angle(v);
+		BMVert *v = vinput_arr[i];
+		const float angle = v ? bm_vert_edge_face_angle(v) : angle_limit;
 
 		if (angle < angle_limit) {
 			weight_elems[i].ele = (BMHeader *)v;
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 6fd3c8c..77d1034 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -260,6 +260,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
 	}
 
 	/* extrude and translate */
+	phid = 2.0f / ((float)seg - 1);
 	vec[0] = vec[2] = 0.0f;
 	vec[1] = dia * phid;
 	mul_mat3_m4_v3(mat, vec);
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 7da02a5..92854c9 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -141,23 +141,24 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
 
 	if (params->use_fractal) {
 		float len = len_v3v3(vsta->co, vend->co);
-		float vec2[3] = {0.0f, 0.0f, 0.0f}, co2[3];
+		float normal[3] = {0.0f, 0.0f, 0.0f}, co2[3], base1[3], base2[3];
 
 		fac = params->fractal * len;
 
-		add_v3_v3(vec2, vsta->no);
-		add_v3_v3(vec2, vend->no);
-		mul_v3_fl(vec2, 0.5f);
+		mid_v3_v3v3(normal, vsta->no, vend->no);
+		ortho_basis_v3v3_v3(base1, base2, normal);
 
 		add_v3_v3v3(co2, v->co, params->off);
-		tvec[0] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 1) - 0.5f);
-		tvec[1] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 1) - 0.5f);
-		tvec[2] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 1) - 0.5f);
+		mul_v3_fl(co2, 10.0f);
 
-		mul_v3_v3(vec2, tvec);
+		tvec[0] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f);
+		tvec[1] = fac * (BLI_gTurbulence(1.0, co2[1], co2[0], co2[2], 15, 0, 2) - 0.5f);
+		tvec[2] = fac * (BLI_gTurbulence(1.0, co2[1], co2[2], co2[0], 15, 0, 2) - 0.5f);
 
 		/* add displacement */
-		add_v3_v3v3(co, co, vec2);
+		madd_v3_v3fl(co, normal, tvec[0]);
+		madd_v3_v3fl(co, base1, tvec[1] * (1.0f - params->along_normal));
+		madd_v3_v3fl(co, base2, tvec[2] * (1.0f - params->along_normal));
 	}
 
 	/* apply the new difference to the rest of the shape keys,
@@ -687,7 +688,7 @@ void bmo_esubd_exec(BMesh *bm, BMOperator *op)
 	BLI_array_declare(facedata);
 	BLI_array_declare(edges);
 	BLI_array_declare(verts);
-	float smooth, fractal;
+	float smooth, fractal, along_normal;
 	int use_sphere, cornertype, use_singleedge, use_gridfill;
 	int skey, seed, i, j, matched, a, b, numcuts, totesel;
 	
@@ -697,6 +698,7 @@ void bmo_esubd_exec(BMesh *bm, BMOperator *op)
 	seed = BMO_slot_int_get(op, "seed");
 	smooth = BMO_slot_float_get(op, "smooth");
 	fractal = BMO_slot_float_get(op, "fractal");
+	along_normal = BMO_slot_float_get(op, "along_normal");
 	cornertype = BMO_slot_int_get(op, "quadcornertype");
 
 	use_singleedge = BMO_slot_bool_get(op, "use_singleedge");
@@ -754,6 +756,7 @@ void bmo_esubd_exec(BMesh *bm, BMOperator *op)
 	params.smooth = smooth;
 	params.seed = seed;
 	params.fractal = fractal;
+	params.along_normal = along_normal;
 	params.use_smooth  = (smooth  != 0.0f);
 	params.use_fractal = (fractal != 0.0f);
 	params.use_sphere  = use_sphere;
@@ -1025,7 +1028,7 @@ void bmo_esubd_exec(BMesh *bm, BMOperator *op)
 
 /* editmesh-emulating function */
 void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
-                        float smooth, float fractal,
+                        float smooth, float fractal, float along_normal,
                         int numcuts,
                         int seltype, int cornertype,
                         const short use_singleedge, const short use_gridfill,
@@ -1036,13 +1039,13 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
 	/* use_sphere isnt exposed here since its only used for new primitives */
 	BMO_op_initf(bm, &op,
 	             "esubd edges=%he "
-	             "smooth=%f fractal=%f "
+	             "smooth=%f fractal=%f along_normal=%f "
 	             "numcuts=%i "
 	             "quadcornertype=%i "
 	             "use_singleedge=%b use_gridfill=%b "
 	             "seed=%i",
 	             edge_hflag,
-	             smooth, fractal,
+	             smooth, fractal, along_normal,
 	             numcuts,
 	             cornertype,
 	             use_singleedge, use_gridfill,
diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h
index cc6ced8..d4b926b 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.h
+++ b/source/blender/bmesh/operators/bmo_subdivide.h
@@ -31,6 +31,7 @@ typedef struct SubDParams {
 	int numcuts;
 	float smooth;
 	float fractal;
+	float along_normal;
 	//int beauty;
 	short use_smooth;
 	short use_sphere;
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index e0079fb..8e691c6 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -439,6 +439,16 @@ void AnimationImporter::modify_fcurve(std::vector<FCurve*>* curves , const char*
 	}
 }
 
+void AnimationImporter::unused_fcurve(std::vector<FCurve*>* curves)
+{
+	// when an error happens and we can't actually use curve remove it from unused_curves
+	std::vector<FCurve*>::iterator it;
+	for (it = curves->begin(); it != curves->end(); it++) {
+		FCurve *fcu = *it;
+		unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
+	}
+}
+
 void AnimationImporter::find_frames( std::vector<float>* frames , std::vector<FCurve*>* curves)
 {
 	std::vector<FCurve*>::iterator iter;
@@ -500,6 +510,7 @@ void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation *
 			modify_fcurve(curves, rna_path, -1 );
 			break;
 		default:
+			unused_fcurve(curves);
 			fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
 				binding->animationClass, loc ? "TRANSLATE" : "SCALE");
 				}
@@ -535,10 +546,13 @@ void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation *
 			else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
 				modify_fcurve(curves, rna_path, 2 );
 			}
+			else
+				unused_fcurve(curves);
 			break;
 		case COLLADAFW::AnimationList::AXISANGLE:
 			// TODO convert axis-angle to quat? or XYZ?
 		default:
+			unused_fcurve(curves);
 			fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
 				binding->animationClass);
 				}
@@ -554,9 +568,11 @@ void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation *
 
 			}
 			}*/
+			unused_fcurve(curves);
 			break;
 		case COLLADAFW::Transformation::SKEW:
 		case COLLADAFW::Transformation::LOOKAT:
+			unused_fcurve(curves);
 			fprintf(stderr, "Animation of SKEW and LOOKAT transformations is not supported yet.\n");
 			break;
 	}
@@ -592,6 +608,7 @@ void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& list
 			break;
 
 		default:
+			unused_fcurve(&animcurves);
 			fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
 				bindings[j].animationClass, "COLOR" );
 		}
@@ -1767,9 +1784,7 @@ bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4], float par[4]
 Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job)
 {
 	if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) {
-		Object *job = add_object(scene, OB_EMPTY);
-
-		rename_id((ID*)&job->id, (char*)get_joint_name(node));
+		Object *job = bc_add_object(scene, OB_EMPTY, (char*)get_joint_name(node));
 
 		job->lay = object_in_scene(job, scene)->lay = 2;
 
diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h
index e42a1cc..563f467 100644
--- a/source/blender/collada/AnimationImporter.h
+++ b/source/blender/collada/AnimationImporter.h
@@ -165,6 +165,7 @@ public:
 	int setAnimType ( const COLLADAFW::Animatable * prop , int type, int addition);
 	
 	void modify_fcurve(std::vector<FCurve*>* curves , const char* rna_path , int array_index );
+	void unused_fcurve(std::vector<FCurve*>* curves );
 	// prerequisites:
 	// animlist_map - map animlist id -> animlist
 	// curve_map - map anim id -> curve(s)
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index a978a47..e484fd5 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -368,7 +368,7 @@ Object *ArmatureImporter::get_empty_for_leaves()
 {
 	if (empty) return empty;
 	
-	empty = add_object(scene, OB_EMPTY);
+	empty = bc_add_object(scene, OB_EMPTY, NULL);
 	empty->empty_drawtype = OB_EMPTY_SPHERE;
 
 	return empty;
@@ -413,7 +413,7 @@ void ArmatureImporter::create_armature_bones( )
 		if ( get_armature_for_joint(*ri) != NULL ) continue;
 		
 		//add armature object for current joint
-		//Object *ob_arm = add_object(scene, OB_ARMATURE);
+		//Object *ob_arm = bc_add_object(scene, OB_ARMATURE, NULL);
 
 		Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
 
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index bc06061..68bfeb7 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -121,6 +121,9 @@ bool DocumentImporter::import()
 	
 	loader.registerExtraDataCallbackHandler(ehandler);
 
+	// deselect all to select new objects
+	scene_deselect_all(CTX_data_scene(mContext));
+
 	if (!root.loadDocument(mFilename)) {
 		fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
 		return false;
@@ -144,6 +147,8 @@ bool DocumentImporter::import()
 	
 	delete ehandler;
 
+	mesh_importer.bmeshConversion();
+
 	return true;
 }
 
@@ -157,7 +162,9 @@ void DocumentImporter::cancel(const COLLADAFW::String& errorMessage)
 	// The latter sounds better.
 }
 
-void DocumentImporter::start() {}
+void DocumentImporter::start()
+{
+}
 
 void DocumentImporter::finish()
 {
@@ -298,7 +305,8 @@ Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera
 		fprintf(stderr, "Couldn't find camera by UID.\n");
 		return NULL;
 	}
-	Object *ob = add_object(sce, OB_CAMERA);
+
+	Object *ob = bc_add_object(sce, OB_CAMERA, NULL);
 	Camera *cam = uid_camera_map[cam_uid];
 	Camera *old_cam = (Camera*)ob->data;
 	ob->data = cam;
@@ -315,7 +323,8 @@ Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce
 		fprintf(stderr, "Couldn't find lamp by UID.\n");
 		return NULL;
 	}
-	Object *ob = add_object(sce, OB_LAMP);
+
+	Object *ob = bc_add_object(sce, OB_LAMP, NULL);
 	Lamp *la = uid_lamp_map[lamp_uid];
 	Lamp *old_lamp = (Lamp*)ob->data;
 	ob->data = la;
@@ -395,7 +404,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
 	if (is_joint) {
 		if ( par ) {
 		Object * empty = par;
-		par = add_object(sce, OB_ARMATURE);
+		par = bc_add_object(sce, OB_ARMATURE, NULL);
 		bc_set_parent(par,empty->parent, mContext);
 		//remove empty : todo
 		object_map[parent_node->getUniqueId()] = par;
@@ -455,7 +464,7 @@ void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *paren
 		// if node is empty - create empty object
 		// XXX empty node may not mean it is empty object, not sure about this
 		if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
-			ob = add_object(sce, OB_EMPTY);
+			ob = bc_add_object(sce, OB_EMPTY, NULL);
 		}
 		
 		// XXX: if there're multiple instances, only one is stored
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index ca112ab..3c1c9cb 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -177,7 +177,7 @@ void GeometryExporter::createPolylist(short material_index,
 	// sets material name
 	if (ma) {
 		std::ostringstream ostr;
-		ostr << translate_id(id_name(ma)) << material_index+1;
+		ostr << translate_id(id_name(ma));
 		polylist.setMaterial(ostr.str());
 	}
 			
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index f6dc5a1..9c1d512 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -111,9 +111,10 @@ struct GeometryFunctor {
 		while(base) {
 			Object *ob = base->object;
 			
-			if (ob->type == OB_MESH && ob->data
-				&& !(export_selected && !(ob->flag && SELECT))
-				&& ((sce->lay & ob->lay)!=0)) {
+			if (ob->type == OB_MESH && ob->data &&
+				!(export_selected && !(ob->flag & SELECT)) &&
+				((sce->lay & ob->lay)!=0))
+			{
 				f(ob);
 			}
 			base= base->next;
diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp
index a605bde..f83289f 100644
--- a/source/blender/collada/InstanceWriter.cpp
+++ b/source/blender/collada/InstanceWriter.cpp
@@ -52,7 +52,7 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia
 			std::string matid(get_material_id(ma));
 			matid = translate_id(matid);
 			std::ostringstream ostr;
-			ostr << translate_id(id_name(ma)) << a+1;
+			ostr << translate_id(id_name(ma));
 			COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
 			
 			// create <bind_vertex_input> for each uv map
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 5c01c31..44f9588 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -727,6 +727,22 @@ bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor,
 
 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {}
 
+void MeshImporter::bmeshConversion()
+{
+	for (std::map<COLLADAFW::UniqueId, Mesh*>::iterator m = uid_mesh_map.begin();
+			m != uid_mesh_map.end(); ++m)
+	{
+		if ((*m).second) {
+			Mesh *me = (*m).second;
+			BKE_mesh_convert_mfaces_to_mpolys(me);
+			BKE_mesh_tessface_clear(me);
+
+			mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL);
+		}
+	}
+}
+
+
 Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
 {
 	if (uid_object_map.find(geom_uid) != uid_object_map.end())
@@ -839,13 +855,12 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
 		
 		for (it = prims.begin(); it != prims.end(); it++) {
 			Primitive& prim = *it;
-			i = 0;
-			while (i++ < prim.totface) {
-				prim.mface->mat_nr = mat_index;
-				prim.mface++;
+			MFace *mface = prim.mface;
+
+			for (i = 0; i < prim.totface; i++, mface++) {
+				mface->mat_nr = mat_index;
 				// bind texture images to faces
 				if (texture_face && (*color_texture)) {
-					texture_face->mode = TF_TEX;
 					texture_face->tpage = (Image*)(*color_texture)->tex->ima;
 					texture_face++;
 				}
@@ -856,7 +871,6 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
 	return texture_face;
 }
 
-
 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
 						   bool isController,
 						   std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
@@ -885,16 +899,16 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
 	}
 	if (!uid_mesh_map[*geom_uid]) return NULL;
 	
-	Object *ob = add_object(scene, OB_MESH);
+	// name Object
+	const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
+	const char *name = (id.length())? id.c_str(): NULL;
+	
+	// add object
+	Object *ob = bc_add_object(scene, OB_MESH, name);
 
 	// store object pointer for ArmatureImporter
 	uid_object_map[*geom_uid] = ob;
 	
-	// name Object
-	const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
-	if (id.length())
-		rename_id(&ob->id, (char*)id.c_str());
-	
 	// replace ob->data freeing the old one
 	Mesh *old_mesh = (Mesh*)ob->data;
 
@@ -922,7 +936,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
 			fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
 		}
 	}
-		
+
 	return ob;
 }
 
@@ -949,6 +963,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom)
 	
 	const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
 	Mesh *me = add_mesh((char*)str_geom_id.c_str());
+	me->id.us--; // is already 1 here, but will be set later in set_mesh
 
 	// store the Mesh pointer to link it later with an Object
 	this->uid_mesh_map[mesh->getUniqueId()] = me;
@@ -963,8 +978,5 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom)
 
 	make_edges(me, 0);
 
-	mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL);
-
-	BKE_mesh_convert_mfaces_to_mpolys(me);
 	return true;
 }
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 0c2e600..97ae4d9 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -129,6 +129,8 @@ public:
 
 	MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce);
 
+	void bmeshConversion();
+
 	virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
 	
 	MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index 99a4f02..0727ec2 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -151,7 +151,7 @@ void SkinInfo::set_controller(const COLLADAFW::SkinController* co)
 // called from write_controller
 Object *SkinInfo::create_armature(Scene *scene)
 {
-	ob_arm = add_object(scene, OB_ARMATURE);
+	ob_arm = bc_add_object(scene, OB_ARMATURE, NULL);
 	return ob_arm;
 }
 
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 4aed29d..bd0f82f 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -34,6 +34,7 @@
 
 #include "DNA_customdata_types.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BLI_math.h"
 
@@ -41,6 +42,7 @@
 #include "BKE_customdata.h"
 #include "BKE_depsgraph.h"
 #include "BKE_object.h"
+#include "BKE_scene.h"
 
 #include "WM_api.h" // XXX hrm, see if we can do without this
 #include "WM_types.h"
@@ -110,3 +112,16 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
 	return true;
 }
 
+Object *bc_add_object(Scene *scene, int type, const char *name)
+{
+	Object *ob = add_only_object(type, name);
+
+	ob->data= add_obdata_from_type(type);
+	ob->lay= scene->lay;
+	ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
+
+	scene_select_base(scene, scene_add_base(scene, ob));
+
+	return ob;
+}
+
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index b0c2415..1f5d2b1 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -39,6 +39,7 @@
 #include "DNA_customdata_types.h"
 #include "DNA_texture_types.h"
 #include "BKE_context.h"
+#include "DNA_scene_types.h"
 
 typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > TexIndexTextureArrayMap;
 
@@ -48,5 +49,6 @@ extern int bc_test_parent_loop(Object *par, Object *ob);
 extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true);
 extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n);
 extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type);
+extern Object *bc_add_object(Scene *scene, int type, const char *name);
 
 #endif
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index e5822c7..dad261c 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -137,7 +137,7 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
 				if (ac->obact && ac->obact->adt)
 					saction->action = ac->obact->adt->action;
 				else
-					saction->action= NULL;
+					saction->action = NULL;
 			}
 			
 			ac->datatype= ANIMCONT_ACTION;
@@ -150,6 +150,16 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
 			ac->datatype= ANIMCONT_SHAPEKEY;
 			ac->data= actedit_get_shapekeys(ac);
 			
+			/* if not pinned, sync with active object */
+			if (/*saction->pin == 0*/1) {
+				Key *key = (Key *)ac->data;
+				
+				if (key && key->adt)
+					saction->action = key->adt->action;
+				else
+					saction->action = NULL;
+			}
+			
 			ac->mode= saction->mode;
 			return 1;
 			
@@ -824,11 +834,14 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *own
  
 /* ----------------------------------------- */
 
-/* 'Only Selected' selected data filtering
+/* 'Only Selected' selected data and/or 'Include Hidden' filtering
  * NOTE: when this function returns true, the F-Curve is to be skipped 
  */
-static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
+static short skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
 {
+	/* hidden items should be skipped if we only care about visible data, but we aren't interested in hidden stuff */
+	short skip_hidden = (filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN);
+	
 	if (GS(owner_id->name) == ID_OB) {
 		Object *ob= (Object *)owner_id;
 		
@@ -845,17 +858,22 @@ static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner
 			/* check whether to continue or skip */
 			if ((pchan) && (pchan->bone)) {
 				/* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
-				if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
+				if (skip_hidden) {
 					bArmature *arm= (bArmature *)ob->data;
 					
+					/* skipping - not visible on currently visible layers */
 					if ((arm->layer & pchan->bone->layer) == 0)
 						return 1;
-					// TODO: manually hidden using flags
+					/* skipping - is currently hidden */
+					if (pchan->bone->flag & BONE_HIDDEN_P)
+						return 1;
 				}
 				
 				/* can only add this F-Curve if it is selected */
-				if ((pchan->bone->flag & BONE_SELECTED) == 0)
-					return 1;
+				if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+					if ((pchan->bone->flag & BONE_SELECTED) == 0)
+						return 1;
+				}
 			}
 		}
 	}
@@ -874,14 +892,16 @@ static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner
 			if (seq_name) MEM_freeN(seq_name);
 			
 			/* can only add this F-Curve if it is selected */
-			if (seq==NULL || (seq->flag & SELECT)==0)
-				return 1;
+			if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+				if ((seq == NULL) || (seq->flag & SELECT)==0)
+					return 1;
+			}
 		}
 	}
 	else if (GS(owner_id->name) == ID_NT) {
 		bNodeTree *ntree = (bNodeTree *)owner_id;
 		
-		/* check for selected  nodes */
+		/* check for selected nodes */
 		if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
 			bNode *node;
 			char *node_name;
@@ -892,8 +912,10 @@ static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner
 			if (node_name) MEM_freeN(node_name);
 			
 			/* can only add this F-Curve if it is selected */
-			if ((node) && (node->flag & NODE_SELECT)==0)
-				return 1;
+			if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+				if ((node) && (node->flag & NODE_SELECT)==0)
+					return 1;
+			}
 		}
 	}
 	return 0;
@@ -940,17 +962,19 @@ static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGr
 	 */
 	for (fcu= first; ((fcu) && (fcu->grp==grp)); fcu= fcu->next) {
 		/* special exception for Pose-Channel/Sequence-Strip/Node Based F-Curves:
-		 *	- the 'Only Selected' data filter should be applied to Pose-Channel data too, but those are
-		 *	  represented as F-Curves. The way the filter for objects worked was to be the first check
-		 *	  after 'normal' visibility, so this is done first here too...
+		 *	- the 'Only Selected' and 'Include Hidden' data filters should be applied to sub-ID data which
+		 *	  can be independently selected/hidden, such as Pose-Channels, Sequence Strips, and Nodes.
+		 *	  Since these checks were traditionally done as first check for objects, we do the same here
 		 *	- we currently use an 'approximate' method for getting these F-Curves that doesn't require
 		 *	  carefully checking the entire path
 		 *	- this will also affect things like Drivers, and also works for Bone Constraints
 		 */
-		if ( ((ads) && (ads->filterflag & ADS_FILTER_ONLYSEL)) && (owner_id) ) {
-			if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
-				continue;
-		}
+		if (ads && owner_id) {
+			if ((ads->filterflag & ADS_FILTER_ONLYSEL) || (ads->filterflag & ADS_FILTER_INCL_HIDDEN)==0) {
+				if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
+					continue;
+			}
+		}	
 		
 		/* only include if visible (Graph Editor check, not channels check) */
 		if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
@@ -1452,51 +1476,83 @@ static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data
 	return items;
 }
 
-static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+
+static size_t animdata_filter_ds_material (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Material *ma, int filter_mode)
 {
-	size_t items=0;
-	int a=0;
+	ListBase tmp_data = {NULL, NULL};
+	size_t tmp_items = 0;
+	size_t items = 0;
 	
-	/* firstly check that we actuallly have some materials, by gathering all materials in a temp list */
-	for (a=1; a <= ob->totcol; a++) {
-		Material *ma= give_current_material(ob, a);
-		ListBase tmp_data = {NULL, NULL};
-		size_t tmp_items = 0;
+	/* add material's animation data to temp collection */
+	BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
+	{
+		/* material's animation data */
+		tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
+			
+		/* textures */
+		if (!(ads->filterflag & ADS_FILTER_NOTEX))
+			tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode);
+			
+		/* nodes */
+		if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) 
+			tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
+	}
+	END_ANIMFILTER_SUBCHANNELS;
+	
+	/* did we find anything? */
+	if (tmp_items) {
+		/* include material-expand widget first */
+		// hmm... do we need to store the index of this material in the array anywhere?
+		if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+			/* check if filtering by active status */
+			if (ANIMCHANNEL_ACTIVEOK(ma)) {
+				ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
+			}
+		}
 		
-		/* if no material returned, skip - so that we don't get weird blank entries... */
-		if (ma == NULL) continue;
+		/* now add the list of collected channels */
+		BLI_movelisttolist(anim_data, &tmp_data);
+		BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
+		items += tmp_items;
+	}
+	
+	return items;
+}
+
+static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+{
+	short has_nested = 0;
+	size_t items = 0;
+	int a = 0;
+	
+	/* first pass: take the materials referenced via the Material slots of the object */
+	for (a = 1; a <= ob->totcol; a++) {
+		Material *ma = give_current_material(ob, a);
 		
-		/* add material's animation data to temp collection */
-		BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
-		{
-			/* material's animation data */
-			tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
-				
-			/* textures */
-			if (!(ads->filterflag & ADS_FILTER_NOTEX))
-				tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode);
-				
-			/* nodes */
-			if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) 
-				tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
+		/* if material is valid, try to add relevant contents from here */
+		if (ma) {
+			/* add channels */
+			items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+			
+			/* for optimising second pass - check if there's a nested material here to come back for */
+			if (has_nested == 0)
+				has_nested = give_node_material(ma) != NULL;
 		}
-		END_ANIMFILTER_SUBCHANNELS;
-		
-		/* did we find anything? */
-		if (tmp_items) {
-			/* include material-expand widget first */
-			// hmm... do we need to store the index of this material in the array anywhere?
-			if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
-				/* check if filtering by active status */
-				if (ANIMCHANNEL_ACTIVEOK(ma)) {
-					ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
-				}
-			}
+	}
+	
+	/* second pass: go through a second time looking for "nested" materials (material.material references)
+	 *
+	 * NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are
+	 *       disappearing/not available, since the relationships between these is not that clear
+	 */
+	if (has_nested) {
+		for (a = 1; a <= ob->totcol; a++) {
+			Material *base = give_current_material(ob, a);
+			Material *ma   = give_node_material(base);
 			
-			/* now add the list of collected channels */
-			BLI_movelisttolist(anim_data, &tmp_data);
-			BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
-			items += tmp_items;
+			/* add channels from the nested material if it exists */
+			if (ma)
+				items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
 		}
 	}
 	
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 043383d..0ad4b23 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -197,24 +197,54 @@ void ED_pose_recalculate_paths(Scene *scene, Object *ob)
 	BLI_freelistN(&targets);
 }
 
+/* show popup to determine settings */
+static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+{	
+	Object *ob = object_pose_armature_get(CTX_data_active_object(C));
+	
+	if (ELEM(NULL, ob, ob->pose))
+		return OPERATOR_CANCELLED;
+	
+	/* set default settings from existing/stored settings */
+	{
+		bAnimVizSettings *avs = &ob->pose->avs;
+		PointerRNA avs_ptr;
+		
+		RNA_int_set(op->ptr, "start_frame", avs->path_sf);
+		RNA_int_set(op->ptr, "end_frame", avs->path_ef);
+		
+		RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
+		RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
+	}
+	
+	/* show popup dialog to allow editing of range... */
+	// FIXME: hardcoded dimensions here are just arbitrary
+	return WM_operator_props_dialog_popup(C, op, 200, 200);
+}
+
 /* For the object with pose/action: create path curves for selected bones 
  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
  */
-static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
+static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
 {
-	ScrArea *sa= CTX_wm_area(C);
+	Object *ob = object_pose_armature_get(CTX_data_active_object(C));
 	Scene *scene= CTX_data_scene(C);
-	Object *ob;
 	
-	/* since this call may also be used from the buttons window, we need to check for where to get the object */
-	if (sa->spacetype == SPACE_BUTS) 
-		ob= ED_object_context(C);
-	else
-		ob= object_pose_armature_get(CTX_data_active_object(C));
-		
 	if (ELEM(NULL, ob, ob->pose))
 		return OPERATOR_CANCELLED;
 	
+	/* grab baking settings from operator settings */
+	{
+		bAnimVizSettings *avs = &ob->pose->avs;
+		PointerRNA avs_ptr;
+		
+		avs->path_sf = RNA_int_get(op->ptr, "start_frame");
+		avs->path_ef = RNA_int_get(op->ptr, "end_frame");
+		
+		RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
+		RNA_enum_set(&avs_ptr, "bake_location", RNA_enum_get(op->ptr, "bake_location"));
+	}
+	
 	/* set up path data for bones being calculated */
 	CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
 	{
@@ -228,7 +258,7 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
 	ED_pose_recalculate_paths(scene, ob);
 	
 	/* notifiers for updates */
-	WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+	WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
 	
 	return OPERATOR_FINISHED; 
 }
@@ -241,11 +271,22 @@ void POSE_OT_paths_calculate (wmOperatorType *ot)
 	ot->description = "Calculate paths for the selected bones";
 	
 	/* api callbacks */
+	ot->invoke = pose_calculate_paths_invoke;
 	ot->exec = pose_calculate_paths_exec;
 	ot->poll = ED_operator_posemode;
 	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+	
+	/* properties */
+	RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start", 
+	            "First frame to calculate bone paths on", MINFRAME, MAXFRAME/2.0);
+	RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", 
+	            "Last frame to calculate bone paths on", MINFRAME, MAXFRAME/2.0);
+	
+	RNA_def_enum(ot->srna, "bake_location", motionpath_bake_location_items, 0, 
+	             "Bake Location", 
+				 "Which point on the bones is used when calculating paths");
 }
 
 /* --------- */
@@ -279,14 +320,7 @@ static void ED_pose_clear_paths(Object *ob)
 /* operator callback for this */
 static int pose_clear_paths_exec (bContext *C, wmOperator *UNUSED(op))
 {
-	ScrArea *sa= CTX_wm_area(C);
-	Object *ob;
-	
-	/* since this call may also be used from the buttons window, we need to check for where to get the object */
-	if (sa->spacetype == SPACE_BUTS) 
-		ob= ED_object_context(C);
-	else
-		ob= object_pose_armature_get(CTX_data_active_object(C));
+	Object *ob = object_pose_armature_get(CTX_data_active_object(C));
 		
 	/* only continue if there's an object */
 	if (ELEM(NULL, ob, ob->pose))
@@ -296,7 +330,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *UNUSED(op))
 	ED_pose_clear_paths(ob);
 	
 	/* notifiers for updates */
-	WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+	WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
 	
 	return OPERATOR_FINISHED; 
 }
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 91d3c89..d90d828 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1469,8 +1469,11 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float track_pos[2], int width
 	ImBuf *scaleibuf;
 	const float scalex = ((float)ibuf->x - 2 * margin) / width;
 	const float scaley = ((float)ibuf->y - 2 * margin) / height;
-	float off_x = (int)track_pos[0] - track_pos[0] + 0.5f;
-	float off_y = (int)track_pos[1] - track_pos[1] + 0.5f;
+	/* NOTE: 1.0f = 0.5f for integer coordinate coorrection (center of pixel vs. left bottom corner of bixel)
+	 *       and 0.5f for centering image in preview (cross is draving at exact center of widget so image
+	 *       should be shifted by half of pixel for correct centering) - sergey */
+	float off_x = (int)track_pos[0] - track_pos[0] + 1.0f;
+	float off_y = (int)track_pos[1] - track_pos[1] + 1.0f;
 	int x, y;
 
 	scaleibuf = IMB_allocImBuf(width, height, 32, IB_rect);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index cce0378..c0c80bf 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1047,9 +1047,8 @@ static void ui_text_label_rightclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
 		
 		/* chop off the leading text, starting from the right */
 		while (but->strwidth > okwidth && cp2 > but->drawstr) {
-			int bytes = BLI_str_utf8_size(cp2);
-			if (bytes < 0)
-				bytes = 1;
+			char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, cp2);
+			int bytes = cp2 - prev_utf8;
 
 			/* shift the text after and including cp2 back by 1 char, +1 to include null terminator */
 			memmove(cp2 - bytes, cp2, strlen(cp2) + 1);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index b3bc0a1..5979398 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2684,6 +2684,7 @@ static void knifetool_finish(bContext *C, wmOperator *op)
 	knife_make_cuts(kcd);
 #endif
 
+	EDBM_mesh_normals_update(kcd->em);
 	EDBM_update_generic(C, kcd->em, TRUE);
 }
 
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 12174d5..bbede25 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -314,7 +314,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
 		
 		if (lcd->do_cut) {
 			BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
-			                   0.0f, 0.0f,
+			                   0.0f, 0.0f, 0.0f,
 			                   cuts,
 			                   SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, FALSE, 0);
 
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index f373792..30ae71b 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -87,6 +87,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
 	int cuts = RNA_int_get(op->ptr, "number_cuts");
 	float smooth = 0.292f * RNA_float_get(op->ptr, "smoothness");
 	float fractal = RNA_float_get(op->ptr, "fractal") / 2.5f;
+	float along_normal = RNA_float_get(op->ptr, "fractal_along_normal");
 
 	if (RNA_boolean_get(op->ptr, "quadtri") && 
 	    RNA_enum_get(op->ptr, "quadcorner") == SUBD_STRAIGHT_CUT)
@@ -95,7 +96,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
 	}
 	
 	BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
-	                   smooth, fractal,
+	                   smooth, fractal, along_normal,
 	                   cuts,
 	                   SUBDIV_SELECT_ORIG, RNA_enum_get(op->ptr, "quadcorner"),
 	                   RNA_boolean_get(op->ptr, "quadtri"), TRUE,
@@ -143,6 +144,7 @@ void MESH_OT_subdivide(wmOperatorType *ot)
 	             "Quad Corner Type", "How to subdivide quad corners (anything other than Straight Cut will prevent ngons)");
 
 	RNA_def_float(ot->srna, "fractal", 0.0f, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor", 0.0f, 1000.0f);
+	RNA_def_float(ot->srna, "fractal_along_normal", 0.0f, 0.0f, 1.0f, "Along Normal", "Apply fractal displacement along normal only", 0.0f, 1.0f);
 	RNA_def_int(ot->srna, "seed", 0, 0, 10000, "Random Seed", "Seed for the random number generator", 0, 50);
 }
 
@@ -612,7 +614,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op)
 
 	edbm_extrude_face_indiv(em, op, BM_ELEM_SELECT, nor);
 	
-	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+	EDBM_update_generic(C, em, TRUE);
 	
 	return OPERATOR_FINISHED;
 }
@@ -896,7 +898,7 @@ static EnumPropertyItem prop_mesh_delete_types[] = {
 	{0, "VERT",      0, "Vertices", ""},
 	{1,  "EDGE",      0, "Edges", ""},
 	{2,  "FACE",      0, "Faces", ""},
-	{3,  "EDGE_FACE", 0, "Edges & Faces", ""},
+	{3,  "EDGE_FACE", 0, "Only Edges & Faces", ""},
 	{4,  "ONLY_FACE", 0, "Only Faces", ""},
 	{0, NULL, 0, NULL, NULL}
 };
@@ -3196,11 +3198,45 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BMEdit_FromObject(obedit);
+	BMesh *bm = em->bm;
 	float angle_limit = RNA_float_get(op->ptr, "angle_limit");
 
+	char dissolve_flag;
+
+	if (em->selectmode == SCE_SELECT_FACE) {
+		/* flush selection to tags and untag edges/verts with partially selected faces */
+		BMIter iter;
+		BMIter liter;
+
+		BMElem *ele;
+		BMFace *f;
+		BMLoop *l;
+
+		BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+			BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_SELECT));
+		}
+		BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+			BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_SELECT));
+		}
+
+		BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+			if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+				BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+					BM_elem_flag_disable(l->v, BM_ELEM_TAG);
+					BM_elem_flag_disable(l->e, BM_ELEM_TAG);
+				}
+			}
+		}
+
+		dissolve_flag = BM_ELEM_TAG;
+	}
+	else {
+		dissolve_flag = BM_ELEM_SELECT;
+	}
+
 	if (!EDBM_op_callf(em, op,
 	                   "dissolve_limit edges=%he verts=%hv angle_limit=%f",
-	                   BM_ELEM_SELECT, BM_ELEM_SELECT, angle_limit))
+	                   dissolve_flag, dissolve_flag, angle_limit))
 	{
 		return OPERATOR_CANCELLED;
 	}
@@ -3692,8 +3728,11 @@ static void xsortvert_flag(bContext *C, int flag)
 		}
 	}
 /*	printf("%d verts: %d to be sorted, %d unchanged…\n", totvert, sorted, unchanged);*/
-	if (sorted == 0)
+	if (sorted == 0) {
+		MEM_freeN(sortblock);
+		MEM_freeN(unchangedblock);
 		return;
+	}
 
 	ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
 	mesh_foreachScreenVert(&vc, xsortvert_flag__doSetX, sortblock, V3D_CLIP_TEST_OFF);
@@ -3951,8 +3990,11 @@ static void hashvert_flag(BMEditMesh *em, int flag, unsigned int seed)
 	}
 /*	protected = totvert - randomized;*/
 /*	printf("%d verts: %d to be randomized, %d protected…\n", totvert, randomized, protected);*/
-	if (randomized == 0)
+	if (randomized == 0) {
+		MEM_freeN(block);
+		MEM_freeN(randblock);
 		return;
+	}
 
 	
 	/* Randomize non-protected vertices indices, and create an array mapping old idx to new
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 5aea6f8..fb9b012 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -189,42 +189,6 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
 	}
 }
 
-/* copies from active to 'index' */
-static void editmesh_face_copy_customdata(BMEditMesh *em, int type, int index)
-{
-	BMesh *bm = em->bm;
-	CustomData *pdata = &bm->pdata;
-	BMIter iter;
-	BMFace *efa;
-	const int n = CustomData_get_active_layer(pdata, type);
-
-	/* ensure all current elements follow new customdata layout */
-	BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-		void *data = CustomData_bmesh_get_n(pdata, efa->head.data, type, n);
-		CustomData_bmesh_set_n(pdata, efa->head.data, type, index, data);
-	}
-}
-
-/* copies from active to 'index' */
-static void editmesh_loop_copy_customdata(BMEditMesh *em, int type, int index)
-{
-	BMesh *bm = em->bm;
-	CustomData *ldata = &bm->ldata;
-	BMIter iter;
-	BMIter liter;
-	BMFace *efa;
-	BMLoop *loop;
-	const int n = CustomData_get_active_layer(ldata, type);
-
-	/* ensure all current elements follow new customdata layout */
-	BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-		BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
-			void *data = CustomData_bmesh_get_n(ldata, loop->head.data, type, n);
-			CustomData_bmesh_set_n(ldata, loop->head.data, type, index, data);
-		}
-	}
-}
-
 int ED_mesh_uv_loop_reset_ex(struct bContext *C, struct Mesh *me, const int layernum)
 {
 	BMEditMesh *em = me->edit_btmesh;
@@ -360,7 +324,8 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
 		BM_data_layer_add_named(em->bm, &em->bm->pdata, CD_MTEXPOLY, name);
 		/* copy data from active UV */
 		if (layernum) {
-			editmesh_face_copy_customdata(em, CD_MTEXPOLY, layernum);
+			const int layernum_dst = CustomData_get_active_layer(&em->bm->pdata, CD_MTEXPOLY);
+			BM_data_layer_copy(em->bm, &em->bm->pdata, CD_MTEXPOLY, layernum, layernum_dst);
 		}
 		if (active_set || layernum == 0) {
 			CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
@@ -370,7 +335,9 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
 		BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name);
 		/* copy data from active UV */
 		if (layernum) {
-			editmesh_loop_copy_customdata(em, CD_MLOOPUV, layernum);
+			const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV);
+			BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
+
 			is_init = TRUE;
 		}
 		if (active_set || layernum == 0) {
@@ -457,7 +424,8 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
 		BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPCOL, name);
 		/* copy data from active vertex color layer */
 		if (layernum) {
-			editmesh_loop_copy_customdata(em, CD_MLOOPCOL, layernum);
+			const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL);
+			BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
 		}
 		if (active_set || layernum == 0) {
 			CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index 71aaacb..e7dd903 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -316,6 +316,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
 	}
 	else {
 		obedit = base->object;
+		scene_deselect_all(scene);
 		scene_select_base(scene, base);
 		copy_v3_v3(obedit->loc, co);
 		copy_v3_v3(obedit->rot, rot);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 3717591..96703d4 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1100,7 +1100,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
 		if (dupli_gh)
 			BLI_ghash_insert(dupli_gh, dob, ob);
 		if (parent_gh)
-			BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, dob->index), ob);
+			BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->index)), ob);
 	}
 	
 	if (use_hierarchy) {
@@ -1114,7 +1114,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
 
 			/* find parent that was also made real */
 			if (ob_src_par) {
-				GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, dob->index);
+				GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, SET_INT_IN_POINTER(dob->index));
 				ob_dst_par = BLI_ghash_lookup(parent_gh, pair);
 				BLI_ghashutil_pairfree(pair);
 			}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 2fbc296..e48c2eb 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1121,17 +1121,44 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
 	BLI_freelistN(&targets);
 }
 
-/* For the object with pose/action: create path curves for selected bones 
- * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
- */
-static int object_calculate_paths_exec (bContext *C, wmOperator *op)
+/* show popup to determine settings */
+static int object_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+{
+	Object *ob = CTX_data_active_object(C);
+	
+	if (ob == NULL)
+		return OPERATOR_CANCELLED;
+	
+	/* set default settings from existing/stored settings */
+	{
+		bAnimVizSettings *avs = &ob->avs;
+		
+		RNA_int_set(op->ptr, "start_frame", avs->path_sf);
+		RNA_int_set(op->ptr, "end_frame", avs->path_ef);
+	}
+	
+	/* show popup dialog to allow editing of range... */
+	// FIXME: hardcoded dimensions here are just arbitrary
+	return WM_operator_props_dialog_popup(C, op, 200, 200);
+}
+
+/* Calculate/recalculate whole paths (avs.path_sf to avs.path_ef) */
+static int object_calculate_paths_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene= CTX_data_scene(C);
+	int start = RNA_int_get(op->ptr, "start_frame");
+	int end = RNA_int_get(op->ptr, "end_frame");
 	
 	/* set up path data for bones being calculated */
 	CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)  
 	{
-		/* verify makes sure that the selected bone has a bone with the appropriate settings */
+		bAnimVizSettings *avs = &ob->avs;
+		
+		/* grab baking settings from operator settings */
+		avs->path_sf = start;
+		avs->path_ef = end;
+		
+		/* verify that the selected object has the appropriate settings */
 		animviz_verify_motionpaths(op->reports, scene, ob, NULL);
 	}
 	CTX_DATA_END;
@@ -1154,11 +1181,18 @@ void OBJECT_OT_paths_calculate (wmOperatorType *ot)
 	ot->description = "Calculate paths for the selected bones";
 	
 	/* api callbacks */
+	ot->invoke = object_calculate_paths_invoke;
 	ot->exec = object_calculate_paths_exec;
 	ot->poll = ED_operator_object_active_editable;
 	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+	
+	/* properties */
+	RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start", 
+	            "First frame to calculate object paths on", MINFRAME, MAXFRAME/2.0);
+	RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", 
+	            "Last frame to calculate object paths on", MINFRAME, MAXFRAME/2.0);
 }
 
 /* --------- */
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index ef428b5..f847616 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -313,6 +313,9 @@ static int object_hook_index_array(Scene *scene, Object *obedit, int *tot, int *
 
 			em = me->edit_btmesh;
 
+			EDBM_mesh_normals_update(em);
+			BMEdit_RecalcTessellation(em);
+
 			/* check selected vertices first */
 			if ( return_editmesh_indexar(em, tot, indexar, cent_r)) {
 				return 1;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index cd2fa4f..445047a 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1343,6 +1343,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
 		mmd->bindcagecos= NULL;
 		mmd->dyngrid= NULL;
 		mmd->dyninfluences= NULL;
+		mmd->bindinfluences= NULL;
 		mmd->bindoffsets= NULL;
 		mmd->dynverts= NULL;
 		mmd->bindweights= NULL; /* deprecated */
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index f9737b0..695e7ed 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -146,6 +146,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
 			BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y));
 
 			if (ibuf->rect_float == NULL) {
+				/* internally sequencer working in sRGB space and stores both bytes and float
+				 * buffers in sRGB space, but if byte->float onversion doesn't happen in sequencer
+				 * (e.g. when adding image sequence/movie into sequencer) there'll be only
+				 * byte buffer and profile will still indicate sRGB->linear space conversion is needed
+				 * here we're ensure there'll be no conversion happen and float buffer would store
+				 * linear frame (sergey) */
+				ibuf->profile = IB_PROFILE_NONE;
 				IMB_float_from_rect(ibuf);
 			}
 
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index bd448cc..c062d47 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -198,8 +198,8 @@ static void do_shared_vertex_tesscol(Mesh *me)
 {
 	/* if no mcol: do not do */
 	/* if tface: only the involved faces, otherwise all */
+	const int use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK);
 	MFace *mface;
-	MTFace *tface;
 	int a;
 	short *scolmain, *scol;
 	char *mcol;
@@ -208,11 +208,10 @@ static void do_shared_vertex_tesscol(Mesh *me)
 	
 	scolmain = MEM_callocN(4 * sizeof(short) * me->totvert, "colmain");
 	
-	tface = me->mtface;
 	mface = me->mface;
 	mcol = (char *)me->mcol;
 	for (a = me->totface; a > 0; a--, mface++, mcol += 16) {
-		if ((tface && tface->mode & TF_SHAREDCOL) || (me->editflag & ME_EDIT_PAINT_MASK) == 0) {
+		if ((use_face_sel == FALSE) || (mface->flag & ME_FACE_SEL)) {
 			scol = scolmain + 4 * mface->v1;
 			scol[0]++; scol[1] += mcol[1]; scol[2] += mcol[2]; scol[3] += mcol[3];
 			scol = scolmain + 4 * mface->v2;
@@ -224,7 +223,6 @@ static void do_shared_vertex_tesscol(Mesh *me)
 				scol[0]++; scol[1] += mcol[13]; scol[2] += mcol[14]; scol[3] += mcol[15];
 			}
 		}
-		if (tface) tface++;
 	}
 	
 	a = me->totvert;
@@ -237,12 +235,11 @@ static void do_shared_vertex_tesscol(Mesh *me)
 		}
 		scol += 4;
 	}
-	
-	tface = me->mtface;
+
 	mface = me->mface;
 	mcol = (char *)me->mcol;
 	for (a = me->totface; a > 0; a--, mface++, mcol += 16) {
-		if ((tface && tface->mode & TF_SHAREDCOL) || (me->editflag & ME_EDIT_PAINT_MASK) == 0) {
+		if ((use_face_sel == FALSE)|| (mface->flag & ME_FACE_SEL)) {
 			scol = scolmain + 4 * mface->v1;
 			mcol[1] = scol[1]; mcol[2] = scol[2]; mcol[3] = scol[3];
 			scol = scolmain + 4 * mface->v2;
@@ -254,7 +251,6 @@ static void do_shared_vertex_tesscol(Mesh *me)
 				mcol[13] = scol[1]; mcol[14] = scol[2]; mcol[15] = scol[3];
 			}
 		}
-		if (tface) tface++;
 	}
 
 	MEM_freeN(scolmain);
@@ -262,12 +258,12 @@ static void do_shared_vertex_tesscol(Mesh *me)
 
 void do_shared_vertexcol(Mesh *me, int do_tessface)
 {
+	const int use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK);
 	MLoop *ml = me->mloop;
 	MLoopCol *lcol = me->mloopcol;
-	MTexPoly *mtp = me->mtpoly;
-	MPoly *mp = me->mpoly;
-	float (*scol)[5];
-	int i, has_shared = 0;
+	MPoly *mp;
+	float (*scol)[4];
+	int i, j, has_shared = 0;
 
 	/* if no mloopcol: do not do */
 	/* if mtexpoly: only the involved faces, otherwise all */
@@ -276,42 +272,37 @@ void do_shared_vertexcol(Mesh *me, int do_tessface)
 
 	scol = MEM_callocN(sizeof(float) * me->totvert * 5, "scol");
 
-	for (i = 0; i < me->totloop; i++, ml++, lcol++) {
-		if (i >= mp->loopstart + mp->totloop) {
-			mp++;
-			if (mtp) mtp++;
+	for (i = 0, mp = me->mpoly; i < me->totpoly; i++, mp++) {
+		if ((use_face_sel == FALSE) || (mp->flag & ME_FACE_SEL)) {
+			ml = me->mloop + mp->loopstart;
+			lcol = me->mloopcol + mp->loopstart;
+			for (j = 0; j < mp->totloop; j++, ml++, lcol++) {
+				scol[ml->v][0] += lcol->r;
+				scol[ml->v][1] += lcol->g;
+				scol[ml->v][2] += lcol->b;
+				scol[ml->v][3] += 1.0f;
+				has_shared = 1;
+			}
 		}
-
-		if (!(mtp && (mtp->mode & TF_SHAREDCOL)) && (me->editflag & ME_EDIT_PAINT_MASK) != 0)
-			continue;
-
-		scol[ml->v][0] += lcol->r;
-		scol[ml->v][1] += lcol->g;
-		scol[ml->v][2] += lcol->b;
-		scol[ml->v][3] += lcol->a;
-		scol[ml->v][4] += 1.0;
-		has_shared = 1;
 	}
-	
+
 	if (has_shared) {
 		for (i = 0; i < me->totvert; i++) {
-			if (!scol[i][4]) continue;
-
-			scol[i][0] /= scol[i][4];
-			scol[i][1] /= scol[i][4];
-			scol[i][2] /= scol[i][4];
-			scol[i][3] /= scol[i][4];
+			if (scol[i][3] != 0.0f) {
+				mul_v3_fl(scol[i], 1.0f / scol[i][3]);
+			}
 		}
-	
-		ml = me->mloop;
-		lcol = me->mloopcol;
-		for (i = 0; i < me->totloop; i++, ml++, lcol++) {
-			if (!scol[ml->v][4]) continue;
 
-			lcol->r = scol[ml->v][0];
-			lcol->g = scol[ml->v][1];
-			lcol->b = scol[ml->v][2];
-			lcol->a = scol[ml->v][3];
+		for (i = 0, mp = me->mpoly; i < me->totpoly; i++, mp++) {
+			if ((use_face_sel == FALSE) || (mp->flag & ME_FACE_SEL)) {
+				ml = me->mloop + mp->loopstart;
+				lcol = me->mloopcol + mp->loopstart;
+				for (j = 0; j < mp->totloop; j++, ml++, lcol++) {
+					lcol->r = scol[ml->v][0];
+					lcol->g = scol[ml->v][1];
+					lcol->b = scol[ml->v][2];
+				}
+			}
 		}
 	}
 
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index b50c3f1..0ee985a 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -318,6 +318,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
 	char filename[FILE_MAX];
 	Scene *scene;
 	Main *bmain;
+	int split;
 
 	int bitrate, accuracy;
 	AUD_DeviceSpecs specs;
@@ -333,6 +334,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
 	specs.format = RNA_enum_get(op->ptr, "format");
 	container = RNA_enum_get(op->ptr, "container");
 	codec = RNA_enum_get(op->ptr, "codec");
+	split = RNA_boolean_get(op->ptr, "split_channels");
 	scene = CTX_data_scene(C);
 	bmain = CTX_data_main(C);
 	specs.channels = scene->r.ffcodecdata.audio_channels;
@@ -341,8 +343,12 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
 	BLI_strncpy(filename, path, sizeof(filename));
 	BLI_path_abs(filename, bmain->name);
 
-	result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
-						 accuracy, filename, specs, container, codec, bitrate);
+	if(split)
+		result = AUD_mixdown_per_channel(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
+										 accuracy, filename, specs, container, codec, bitrate);
+	else
+		result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
+							 accuracy, filename, specs, container, codec, bitrate);
 
 	if (result) {
 		BKE_report(op->reports, RPT_ERROR, result);
@@ -592,6 +598,7 @@ static void SOUND_OT_mixdown(wmOperatorType *ot)
 	RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
 	RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
 	RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
+	RNA_def_boolean(ot->srna, "split_channels", 0, "Split channels", "Each channel will be rendered into a mono file");
 #endif // WITH_AUDASPACE
 }
 
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 37cdbd4..e485e4e 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -516,6 +516,7 @@ static void graph_refresh(const bContext *C, ScrArea *sa)
 	if (sipo->flag & SIPO_TEMP_NEEDCHANSYNC) {
 		ANIM_sync_animchannels_to_data(C);
 		sipo->flag &= ~SIPO_TEMP_NEEDCHANSYNC;
+		ED_area_tag_redraw(sa);
 	}
 	
 	/* init/adjust F-Curve colors */
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 42aea32..5085085 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1635,9 +1635,14 @@ static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C),
 
 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 {
-	uiLayout *col;
+	uiLayout *col, *row;
 	
 	col = uiLayoutColumn(layout, 1);
+   
+	 uiItemL(layout, "Color Space:", ICON_NONE);
+	row= uiLayoutRow(layout, 0);
+	uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
 	uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
 	uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
 }
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index dda0626..f5ab318 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -243,8 +243,37 @@ static bNode *editnode_get_active(bNodeTree *ntree)
 		return nodeGetActive(ntree);
 }
 
-void snode_dag_update(bContext *UNUSED(C), SpaceNode *snode)
+static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup)
 {
+	bNode *node;
+	
+	if (ntree == lookup)
+		return 1;
+	
+	for (node=ntree->nodes.first; node; node=node->next)
+		if (node->type == NODE_GROUP && node->id)
+			if (has_nodetree((bNodeTree*)node->id, lookup))
+				return 1;
+	
+	return 0;
+}
+
+static void snode_dag_update_group(void *calldata, ID *owner_id, bNodeTree *ntree)
+{
+	if (has_nodetree(ntree, calldata))
+		DAG_id_tag_update(owner_id, 0);
+}
+
+void snode_dag_update(bContext *C, SpaceNode *snode)
+{
+	Main *bmain = CTX_data_main(C);
+
+	/* for groups, update all ID's using this */
+	if (snode->edittree!=snode->nodetree) {
+		bNodeTreeType *tti= ntreeGetType(snode->edittree->type);
+		tti->foreach_nodetree(bmain, snode->edittree, snode_dag_update_group);
+	}
+
 	DAG_id_tag_update(snode->id, 0);
 }
 
@@ -585,21 +614,6 @@ static void snode_update(SpaceNode *snode, bNode *node)
 		nodeUpdateID(snode->nodetree, gnode->id);
 }
 
-static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup)
-{
-	bNode *node;
-	
-	if (ntree == lookup)
-		return 1;
-	
-	for (node=ntree->nodes.first; node; node=node->next)
-		if (node->type == NODE_GROUP && node->id)
-			if (has_nodetree((bNodeTree*)node->id, lookup))
-				return 1;
-	
-	return 0;
-}
-
 void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
 {
 	int was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE);
@@ -2412,7 +2426,8 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
 				/* when linking to group outputs, update the socket type */
 				/* XXX this should all be part of a generic update system */
 				if (!link->tonode) {
-					link->tosock->type = link->fromsock->type;
+					if(link->tosock->type != link->fromsock->type)
+						nodeSocketSetType(link->tosock, link->fromsock->type);
 				}
 			}
 			else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index e1493b5..2594078 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -130,6 +130,11 @@ void ED_operatormacros_node(void)
 	ot = WM_operatortype_append_macro("NODE_OT_move_detach_links", "Detach", OPTYPE_UNDO|OPTYPE_REGISTER);
 	ot->description = "Move a node to detach links";
 	WM_operatortype_macro_define(ot, "NODE_OT_links_detach");
+	WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+
+	ot = WM_operatortype_append_macro("NODE_OT_move_detach_links_release", "Detach", OPTYPE_UNDO|OPTYPE_REGISTER);
+	ot->description = "Move a node to detach links";
+	WM_operatortype_macro_define(ot, "NODE_OT_links_detach");
 	mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
 	RNA_boolean_set(mot->ptr, "release_confirm", TRUE);
 }
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index dfa733d..bb91c17 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -411,7 +411,10 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
 	if (seq_load.flag & SEQ_LOAD_REPLACE_SEL)
 		deselect_all_seq(scene);
 
-	tot_files = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
+	if (RNA_struct_property_is_set(op->ptr, "files"))
+		tot_files = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
+	else
+		tot_files = 0;
 
 	if (tot_files) {
 		/* multiple files */
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index ec340dd..e421ace 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -466,6 +466,7 @@ static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn)
 				case ND_FRAME:
 				case ND_MARKERS:
 				case ND_SEQUENCER:
+				case ND_RENDER_OPTIONS:
 					ED_region_tag_redraw(ar);
 					break;
 			}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index f5f3b4c..524b66c 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -179,7 +179,7 @@ static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int i
 		return DM_DRAW_OPTION_SKIP;
 }
 
-static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
+void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
 {
 	drawMeshFaceSelect_userData data;
 
@@ -593,20 +593,6 @@ static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index)
 	}
 }
 
-static DMDrawOption wpaint__setSolidDrawOptions_material(void *userData, int index)
-{
-	Mesh *me = (Mesh *)userData;
-
-	if (me->mat && me->mpoly) {
-		Material *ma = me->mat[me->mpoly[index].mat_nr];
-		if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
-			return DM_DRAW_OPTION_SKIP;
-		}
-	}
-
-	return DM_DRAW_OPTION_NORMAL;
-}
-
 /* when face select is on, use face hidden flag */
 static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index)
 {
@@ -946,6 +932,10 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
 		draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
 		return;
 	}
+	else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+		draw_mesh_paint(rv3d, ob, dm, draw_flags);
+		return;
+	}
 
 	/* set opengl state for negative scale & color */
 	if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
@@ -953,12 +943,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
 
 	glEnable(GL_LIGHTING);
 
-	if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
-		/* weight paint mode exception */
-		dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_material,
-		                    GPU_enable_material, NULL, ob->data, DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
-	}
-	else {
+	{
 		Mesh *me = ob->data;
 		TexMatCallback data = {scene, ob, me, dm};
 		int (*set_face_cb)(void *, int);
@@ -1015,3 +1000,53 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
 		draw_mesh_face_select(rv3d, ob->data, dm);
 }
 
+/* Vertex Paint and Weight Paint */
+
+void draw_mesh_paint(RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
+{
+	DMSetDrawOptions facemask = NULL;
+	Mesh *me = ob->data;
+
+	/* hide faces in face select mode */
+	if (draw_flags & DRAW_FACE_SELECT)
+		facemask = wpaint__setSolidDrawOptions_facemask;
+
+	if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
+		/* enforce default material settings */
+		GPU_enable_material(0, NULL);
+		
+		/* but set default spec */
+		glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
+		glEnable(GL_COLOR_MATERIAL);    /* according manpages needed */
+		glColor3ub(120, 120, 120);
+		glDisable(GL_COLOR_MATERIAL);
+
+		/* diffuse */
+		glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+		glEnable(GL_LIGHTING);
+		glEnable(GL_COLOR_MATERIAL);
+
+		dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
+							DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
+
+		glDisable(GL_COLOR_MATERIAL);
+		glDisable(GL_LIGHTING);
+
+		GPU_disable_material();
+	}
+	else if (ob->mode & OB_MODE_VERTEX_PAINT) {
+		if (me->mloopcol)
+			dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
+								DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
+		else {
+			glColor3f(1.0f, 1.0f, 1.0f);
+			dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
+								DM_DRAW_ALWAYS_SMOOTH);
+		}
+	}
+
+	/* draw face selection on top */
+	if (draw_flags & DRAW_FACE_SELECT)
+		draw_mesh_face_select(rv3d, me, dm);
+}
+
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 4508dae..2b58b62 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -163,7 +163,10 @@ typedef struct drawDMFacesSel_userData {
 
 typedef struct drawDMNormal_userData {
 	BMEditMesh *em;
+	int uniform_scale;
 	float normalsize;
+	float tmat[3][3];
+	float imat[3][3];
 } drawDMNormal_userData;
 
 typedef struct bbsObmodeMeshVerts_userData {
@@ -2268,25 +2271,56 @@ void nurbs_foreachScreenVert(
  * logic!!!
  */
 
+static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data)
+{
+	float obmat[3][3];
+
+	copy_m3_m4(obmat, ob->obmat);
+
+	data->uniform_scale = is_uniform_scaled_m3(obmat);
+
+	if (!data->uniform_scale) {
+		/* inverted matrix */
+		invert_m3_m3(data->imat, obmat);
+
+		/* transposed inverted matrix */
+		copy_m3_m3(data->tmat, data->imat);
+		transpose_m3(data->tmat);
+	}
+}
+
 static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3])
 {
 	drawDMNormal_userData *data = userData;
 	BMFace *efa = EDBM_face_at_index(data->em, index);
+	float n[3];
 
 	if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+		if (!data->uniform_scale) {
+			mul_v3_m3v3(n, data->tmat, (float *) no);
+			normalize_v3(n);
+			mul_m3_v3(data->imat, n);
+		}
+		else {
+			copy_v3_v3(n, no);
+		}
+
 		glVertex3fv(cent);
-		glVertex3f(cent[0] + no[0] * data->normalsize,
-		           cent[1] + no[1] * data->normalsize,
-		           cent[2] + no[2] * data->normalsize);
+		glVertex3f(cent[0] + n[0] * data->normalsize,
+		           cent[1] + n[1] * data->normalsize,
+		           cent[2] + n[2] * data->normalsize);
 	}
 }
-static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
+
+static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
 {
 	drawDMNormal_userData data;
 
 	data.em = em;
 	data.normalsize = scene->toolsettings->normalsize;
 
+	calcDrawDMNormalScale(ob, &data);
+
 	glBegin(GL_LINES);
 	dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data);
 	glEnd();
@@ -2316,27 +2350,42 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float
 	BMVert *eve = EDBM_vert_at_index(data->em, index);
 
 	if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
-		glVertex3fv(co);
+		float no[3], n[3];
 
 		if (no_f) {
-			glVertex3f(co[0] + no_f[0] * data->normalsize,
-			           co[1] + no_f[1] * data->normalsize,
-			           co[2] + no_f[2] * data->normalsize);
+			copy_v3_v3(no, no_f);
 		}
 		else {
-			glVertex3f(co[0] + no_s[0] * (data->normalsize / 32767.0f),
-			           co[1] + no_s[1] * (data->normalsize / 32767.0f),
-			           co[2] + no_s[2] * (data->normalsize / 32767.0f));
+			no[0] = no_s[0] / 32767.0f;
+			no[1] = no_s[1] / 32767.0f;
+			no[2] = no_s[2] / 32767.0f;
 		}
+
+		if (!data->uniform_scale) {
+			mul_v3_m3v3(n, data->tmat, (float *) no);
+			normalize_v3(n);
+			mul_m3_v3(data->imat, n);
+		}
+		else {
+			copy_v3_v3(n, no);
+		}
+
+		glVertex3fv(co);
+		glVertex3f(co[0] + n[0] * data->normalsize,
+		           co[1] + n[1] * data->normalsize,
+		           co[2] + n[2] * data->normalsize);
 	}
 }
-static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
+
+static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
 {
 	drawDMNormal_userData data;
 
 	data.em = em;
 	data.normalsize = scene->toolsettings->normalsize;
 
+	calcDrawDMNormalScale(ob, &data);
+
 	glBegin(GL_LINES);
 	dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data);
 	glEnd();
@@ -2852,9 +2901,10 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
 
 #define DRAW_EM_MEASURE_STATS_FACEAREA()                                      \
 	if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {                               \
-		mul_v3_fl(vmid, 1.0 / n);                                             \
+		mul_v3_fl(vmid, 1.0f / (float)n);                                     \
 		if (unit->system)                                                     \
-			bUnit_AsString(numstr, sizeof(numstr), area * unit->scale_length, \
+			bUnit_AsString(numstr, sizeof(numstr),                            \
+		                   (double)(area * unit->scale_length),               \
 			               3, unit->system, B_UNIT_LENGTH, do_split, FALSE);  \
 		else                                                                  \
 			BLI_snprintf(numstr, sizeof(numstr), conv_float, area);           \
@@ -3166,11 +3216,11 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
 
 		if (me->drawflag & ME_DRAWNORMALS) {
 			UI_ThemeColor(TH_NORMAL);
-			draw_dm_face_normals(em, scene, cageDM);
+			draw_dm_face_normals(em, scene, ob, cageDM);
 		}
 		if (me->drawflag & ME_DRAW_VNORMALS) {
 			UI_ThemeColor(TH_VNORMAL);
-			draw_dm_vert_normals(em, scene, cageDM);
+			draw_dm_vert_normals(em, scene, ob, cageDM);
 		}
 
 		if ( (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_FACEAREA | ME_DRAWEXTRA_FACEANG)) &&
@@ -3269,7 +3319,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 	else if (dt == OB_WIRE || totface == 0) {
 		draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff  */
 	}
-	else if ( (draw_flags & DRAW_FACE_SELECT || (is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
+	else if ( ((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
 	          check_object_draw_texture(scene, v3d, dt))
 	{
 		if ( (v3d->flag & V3D_SELECT_OUTLINE) &&
@@ -3424,39 +3474,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 		}
 	}
 	else if (dt == OB_PAINT) {
-		if (is_obact) {
-			if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
-				/* enforce default material settings */
-				GPU_enable_material(0, NULL);
-				
-				/* but set default spec */
-				glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
-				glEnable(GL_COLOR_MATERIAL);    /* according manpages needed */
-				glColor3ub(120, 120, 120);
-				glDisable(GL_COLOR_MATERIAL);
-				/* diffuse */
-				glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-				glEnable(GL_LIGHTING);
-				glEnable(GL_COLOR_MATERIAL);
-
-				dm->drawMappedFaces(dm, NULL, GPU_enable_material, NULL, me->mpoly,
-				                    DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
-				glDisable(GL_COLOR_MATERIAL);
-				glDisable(GL_LIGHTING);
-
-				GPU_disable_material();
-			}
-			else if (ob->mode & OB_MODE_VERTEX_PAINT) {
-				if (me->mloopcol)
-					dm->drawMappedFaces(dm, NULL, GPU_enable_material, NULL, NULL,
-					                    DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
-				else {
-					glColor3f(1.0f, 1.0f, 1.0f);
-					dm->drawMappedFaces(dm, NULL, GPU_enable_material, NULL, NULL,
-					                    DM_DRAW_ALWAYS_SMOOTH);
-				}
-			}
-		}
+		draw_mesh_paint(rv3d, ob, dm, draw_flags);
 	}
 	
 	/* set default draw color back for wire or for draw-extra later on */
@@ -6526,8 +6544,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 					zbufoff = 1;
 					dt = OB_SOLID;
 				}
-				else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))
+
+				if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
 					dt = OB_PAINT;
+				}
 
 				glEnable(GL_DEPTH_TEST);
 			}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 168775d..66b8ceb 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -130,6 +130,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in
 
 /* drawmesh.c */
 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, struct DerivedMesh *dm, int faceselect);
+void draw_mesh_paint(RegionView3D *rv3d, struct Object *ob, struct DerivedMesh *dm, int faceselect);
 
 /* view3d_draw.c */
 void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index f3819a1..9a0d5e0 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4395,7 +4395,7 @@ static int createSlideVerts(TransInfo *t)
 	BMVert *v, *v2, *first;
 	BMLoop *l, *l1, *l2;
 	TransDataSlideVert *sv_array;
-	BMBVHTree *btree = BMBVH_NewBVH(em, 0, NULL, NULL);
+	BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL);
 	SmallHash table;
 	SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
 	View3D *v3d = t->sa ? t->sa->spacedata.first : NULL;
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 09078c1..0c8ef20 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -943,7 +943,6 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
 			kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_A, KM_ANY, 0, 0);
 			RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
 			kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
-			RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
 
 			WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
 
@@ -953,7 +952,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
 			WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", DKEY, KM_PRESS, KM_ALT, 0);
 
 			/* XXX release_confirm is set in the macro operator definition */
-			WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_A, KM_ANY, KM_ALT, 0);
+			WM_keymap_add_item(keymap, "NODE_OT_move_detach_links_release", EVT_TWEAK_A, KM_ANY, KM_ALT, 0);
 			WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_S, KM_ANY, KM_ALT, 0);
 			break;
 		case SPACE_SEQ:
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 1c62ce3..db3c994 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -757,7 +757,7 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i
 	BMLoop *l;
 	MLoopUV *luv;
 	BMIter iter;
-	float m[3], v1[3], v2[3], c1, c2, *uv1, /* *uv2, */ /* UNUSED */ *uv3;
+	float m[3], v1[3], v2[3], c1, c2, *uv1 = NULL, /* *uv2, */ /* UNUSED */ *uv3 = NULL;
 	int id1, id2, i;
 
 	id1 = (id + efa->len - 1) % efa->len;
@@ -2282,6 +2282,25 @@ static void UV_OT_unlink_selected(wmOperatorType *ot)
 	ot->poll = ED_operator_uvedit;
 }
 
+static void uv_select_sync_flush(ToolSettings *ts, BMEditMesh *em, const short select)
+{
+	/* bmesh API handles flushing but not on de-select */
+	if (ts->uv_flag & UV_SYNC_SELECTION) {
+		if (ts->selectmode != SCE_SELECT_FACE) {
+			if (select == FALSE) {
+				EDBM_deselect_flush(em);
+			}
+			else {
+				EDBM_select_flush(em);
+			}
+		}
+
+		if (select == FALSE) {
+			BM_select_history_validate(em->bm);
+		}
+	}
+}
+
 /* ******************** border select operator **************** */
 
 /* This function sets the selection on tagged faces, need because settings the
@@ -2512,20 +2531,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
 	}
 
 	if (change) {
-		/* bmesh API habdles flushing but not on de-select */
-		if (ts->uv_flag & UV_SYNC_SELECTION) {
-			if (ts->selectmode != SCE_SELECT_FACE) {
-				if (select == FALSE) {
-					EDBM_deselect_flush(em);
-				}
-			}
-		}
-
-		if (ts->uv_flag & UV_SYNC_SELECTION) {
-			if (select == FALSE) {
-				BM_select_history_validate(em->bm);
-			}
-		}
+		uv_select_sync_flush(ts, em, select);
 
 		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
 		
@@ -2560,13 +2566,12 @@ static void UV_OT_select_border(wmOperatorType *ot)
 
 /* ******************** circle select operator **************** */
 
-static void select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *UNUSED(sima), Scene *scene, int select,
-                                     float *offset, float *ell, BMLoop *l, MLoopUV *luv)
+static int select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *UNUSED(sima), Scene *scene, int select,
+                                    float *offset, float *ell, BMLoop *l, MLoopUV *luv)
 {
 	/* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
 	float x, y, r2, *uv;
-	
-	
+
 	uv = luv->uv;
 
 	x = (uv[0] - offset[0]) * ell[0];
@@ -2575,7 +2580,11 @@ static void select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *UNUSED(sima), S
 	r2 = x * x + y * y;
 	if (r2 < 1.0f) {
 		if (select) uvedit_uv_select_enable(em, scene, l, FALSE);
-		else uvedit_uv_select_disable(em, scene, l);
+		else        uvedit_uv_select_disable(em, scene, l);
+		return TRUE;
+	}
+	else {
+		return FALSE;
 	}
 }
 
@@ -2593,6 +2602,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
 	int x, y, radius, width, height, select;
 	float zoomx, zoomy, offset[2], ellipse[2];
 	int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
+	int change = FALSE;
 
 	/* get operator properties */
 	select = (gesture_mode == GESTURE_MODAL_SELECT);
@@ -2614,15 +2624,15 @@ static int circle_select_exec(bContext *C, wmOperator *op)
 	BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
 		BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
 			luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
-			select_uv_inside_ellipse(em, sima, scene, select, offset, ellipse, l, luv);
+			change |= select_uv_inside_ellipse(em, sima, scene, select, offset, ellipse, l, luv);
 		}
 	}
 
-#if 0 //I think the BM_elem_select_set api stuff handles all this as necessary?
-	if (select) EM_select_flush(em);
-	else EM_deselect_flush(em);
-#endif
-	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	if (change) {
+		uv_select_sync_flush(scene->toolsettings, em, select);
+
+		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+	}
 
 	return OPERATOR_FINISHED;
 }
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 36b1e77..97b4e8f 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1178,13 +1178,13 @@ static int stitch_init(bContext *C, wmOperator *op)
 	}
 	else {
 		BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-			i = 0;
-			BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+			BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
 				if (uvedit_uv_select_test(em, scene, l)) {
 					UvElement *element = ED_uv_element_get(state->element_map, efa, l);
-					stitch_select_uv(element, state, 1);
+					if (element) {
+						stitch_select_uv(element, state, 1);
+					}
 				}
-				i++;
 			}
 		}
 	}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 2a9d472..dbdd63a 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1142,6 +1142,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
 	param_lscm_solve(handle);
 	param_lscm_end(handle);
 
+	param_average(handle);
 	param_pack(handle, scene->toolsettings->uvcalc_margin);
 
 	param_flush(handle);
@@ -1176,7 +1177,8 @@ static int unwrap_exec(bContext *C, wmOperator *op)
 		BKE_report(op->reports, RPT_INFO, "Object scale is not 1.0. Unwrap will operate on a non-scaled version of the mesh.");
 
 	/* remember last method for live unwrap */
-	scene->toolsettings->unwrapper = method;
+	if(RNA_struct_property_is_set(op->ptr, "method"))
+		scene->toolsettings->unwrapper = method;
 	
 	scene->toolsettings->uv_subsurf_level = subsurf_level;
 
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 01f000e..7f94190 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1085,7 +1085,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
 	GMS.gob = ob;
 	GMS.gscene = scene;
 	GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
-	GMS.glay= v3d->lay;
+	GMS.glay= (v3d->localvd)? v3d->localvd->lay: v3d->lay; /* keep lamps visible in local view */
 	GMS.gviewmat= rv3d->viewmat;
 	GMS.gviewinv= rv3d->viewinv;
 
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index ab5f204..ef7e775 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1605,7 +1605,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 	la = ob->data;
 	gpu_lamp_from_blender(scene, ob, par, la, lamp);
 
-	if (la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
+	if ((la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) || (la->type==LA_SUN && (la->mode & LA_SHAD_RAY))) {
 		/* opengl */
 		lamp->fb = GPU_framebuffer_create();
 		if (!lamp->fb) {
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 08b2e60..ff87c22 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -320,8 +320,8 @@ static void scanline_contig_16bit(float *rectf, unsigned short *sbuf, int scanli
 	int i;
 	for (i=0; i < scanline_w; i++) {
 		rectf[i*4 + 0] = sbuf[i*spp + 0] / 65535.0;
-		rectf[i*4 + 1] = sbuf[i*spp + 1] / 65535.0;
-		rectf[i*4 + 2] = sbuf[i*spp + 2] / 65535.0;
+		rectf[i*4 + 1] = (spp>=3)? sbuf[i*spp + 1] / 65535.0: sbuf[i*spp + 0] / 65535.0;
+		rectf[i*4 + 2] = (spp>=3)? sbuf[i*spp + 2] / 65535.0: sbuf[i*spp + 0] / 65535.0;
 		rectf[i*4 + 3] = (spp==4)?(sbuf[i*spp + 3] / 65535.0):1.0;
 	}
 }
@@ -331,8 +331,8 @@ static void scanline_contig_32bit(float *rectf, float *fbuf, int scanline_w, int
 	int i;
 	for (i=0; i < scanline_w; i++) {
 		rectf[i*4 + 0] = fbuf[i*spp + 0];
-		rectf[i*4 + 1] = fbuf[i*spp + 1];
-		rectf[i*4 + 2] = fbuf[i*spp + 2];
+		rectf[i*4 + 1] = (spp>=3)? fbuf[i*spp + 1]: fbuf[i*spp + 0];
+		rectf[i*4 + 2] = (spp>=3)? fbuf[i*spp + 2]: fbuf[i*spp + 0];
 		rectf[i*4 + 3] = (spp==4)?fbuf[i*spp + 3]:1.0f;
 	}
 }
@@ -440,6 +440,8 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
 				if (bitspersample == 32) {
 					if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
 						fill_vn_fl(fbuf, ibuf->x, 1.0f);
+					else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
+						success |= TIFFReadScanline(image, fbuf, row, 0);
 					else
 						success |= TIFFReadScanline(image, fbuf, row, chan);
 					scanline_separate_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, chan);
@@ -448,6 +450,8 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
 				else if (bitspersample == 16) {
 					if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
 						fill_vn_ushort(sbuf, ibuf->x, 65535);
+					else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
+						success |= TIFFReadScanline(image, fbuf, row, 0);
 					else
 						success |= TIFFReadScanline(image, sbuf, row, chan);
 					scanline_separate_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, chan);
@@ -777,22 +781,17 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
 
 			if (pixels16) {
 				/* convert from float source */
-				float rgb[3];
+				float rgb[4];
 				
 				if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
 					linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
 				else
 					copy_v3_v3(rgb, &fromf[from_i]);
 
-				to16[to_i+0] = FTOUSHORT(rgb[0]);
-				to16[to_i+1] = FTOUSHORT(rgb[1]);
-				to16[to_i+2] = FTOUSHORT(rgb[2]);
-				to_i += 3; from_i+=3;
-				
-				if (samplesperpixel == 4) {
-					to16[to_i+3] = FTOUSHORT(fromf[from_i+3]);
-					/*to_i++; from_i++;*/ /*unused, set on each loop */
-				}
+				rgb[3] = fromf[from_i+3];
+
+				for (i = 0; i < samplesperpixel; i++, to_i++)
+					to16[to_i] = FTOUSHORT(rgb[i]);
 			}
 			else {
 				for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index b5fdb89..4694b52 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -40,6 +40,7 @@
 #endif
 
 #include "BLI_blenlib.h"
+#include "BLI_fileops.h"
 
 #include "DNA_userdef_types.h"
 #include "BKE_global.h"
@@ -339,14 +340,14 @@ int imb_get_anim_type(const char * name)
 	/* stat test below fails on large files > 4GB */
 	if (isffmpeg(name)) return (ANIM_FFMPEG);
 #	endif
-	if (stat(name,&st) == -1) return(0);
+	if (BLI_stat(name, &st) == -1) return(0);
 	if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
 
 	if (isavi(name)) return (ANIM_AVI);
 
 	if (ismovie(name)) return (ANIM_MOVIE);
 #else
-	if (stat(name,&st) == -1) return(0);
+	if (BLI_stat(name, &st) == -1) return(0);
 	if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
 
 	if (ismovie(name)) return (ANIM_MOVIE);
@@ -356,6 +357,8 @@ int imb_get_anim_type(const char * name)
 #	ifdef WITH_FFMPEG
 	if (isffmpeg(name)) return (ANIM_FFMPEG);
 #	endif
+
+
 	if (isavi(name)) return (ANIM_AVI);
 #endif
 #ifdef WITH_REDCODE
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index 26b3a3e..4758bfa 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -110,8 +110,6 @@ typedef struct SmokeDomainSettings {
 /* flags */
 #define MOD_SMOKE_FLOW_ABSOLUTE (1<<1) /*old style emission*/
 #define MOD_SMOKE_FLOW_INITVELOCITY (1<<2) /* passes particles speed to the smoke */
-#define MOD_SMOKE_FLOW_INIT  (1 << 3) /* is the flow object already initialized? */
-
 
 typedef struct SmokeFlowSettings {
 	struct SmokeModifierData *smd; /* for fast RNA access */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index afa6a6e..1b8772f 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -70,6 +70,8 @@ extern EnumPropertyItem fmodifier_type_items[];
 extern EnumPropertyItem nla_mode_extend_items[];
 extern EnumPropertyItem nla_mode_blend_items[];
 
+extern EnumPropertyItem motionpath_bake_location_items[];
+
 extern EnumPropertyItem event_value_items[];
 extern EnumPropertyItem event_type_items[];
 extern EnumPropertyItem operator_return_items[];
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 94ea790..06352fd 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -837,7 +837,7 @@ void rna_def_animdata(BlenderRNA *brna)
 	/* Active Action */
 	prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
 		/* this flag as well as the dynamic test must be defined for this to be editable... */
-	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
 	RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL, "rna_Action_id_poll");
 	RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
 	RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock");
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
index f706530..167eb23 100644
--- a/source/blender/makesrna/intern/rna_animviz.c
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -39,6 +39,14 @@
 
 #include "WM_types.h"
 
+/* Which part of bone(s) get baked */
+// TODO: icons?
+EnumPropertyItem motionpath_bake_location_items[] = {
+	{MOTIONPATH_BAKE_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"},
+	{0, "TAILS", 0, "Tails", "Calculate bone paths from tails"},
+	//{MOTIONPATH_BAKE_CENTERS, "CENTROID", 0, "Centers", "Calculate bone paths from center of mass"},
+	{0, NULL, 0, NULL, NULL}};
+
 #ifdef RNA_RUNTIME
 
 static PointerRNA rna_AnimViz_onion_skinning_get(PointerRNA *ptr)
@@ -241,10 +249,6 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
 		                        "Display Paths of poses within a fixed number of frames around the current frame"},
 		{MOTIONPATH_TYPE_RANGE, "RANGE", 0, "In Range", "Display Paths of poses within specified range"},
 		{0, NULL, 0, NULL, NULL}};
-	static const EnumPropertyItem prop_location_items[] = {
-		{MOTIONPATH_BAKE_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"},
-		{0, "TAILS", 0, "Tails", "Calculate bone paths from tails"},
-		{0, NULL, 0, NULL, NULL}};
 	
 	srna = RNA_def_struct(brna, "AnimVizMotionPaths", NULL);
 	RNA_def_struct_sdna(srna, "bAnimVizSettings");
@@ -260,7 +264,7 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
 	
 	prop = RNA_def_property(srna, "bake_location", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_bitflag_sdna(prop, NULL, "path_bakeflag");
-	RNA_def_property_enum_items(prop, prop_location_items);
+	RNA_def_property_enum_items(prop, motionpath_bake_location_items);
 	RNA_def_property_ui_text(prop, "Bake Location", "When calculating Bone Paths, use Head or Tips");
 	RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
 	
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 6d67f0c..7a712b7 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -562,7 +562,7 @@ static void rna_def_constraint_python(BlenderRNA *brna)
 
 	prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE);
 	RNA_def_property_ui_text(prop, "Script", "The text object that contains the Python script");
-	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
 	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 
 	prop = RNA_def_property(srna, "use_targets", PROP_BOOLEAN, PROP_NONE);
@@ -1097,7 +1097,7 @@ static void rna_def_constraint_action(BlenderRNA *brna)
 	prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "act");
 	RNA_def_property_ui_text(prop, "Action", "The constraining action");
-	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
 	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 
 	prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index ca1b3a8..e5d502a 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -282,6 +282,7 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr)
 					part->sta = 1.0f;
 					part->end = 250.0f;
 					part->ren_as = PART_DRAW_NOT;
+					part->flag |= PART_UNBORN;
 					part->draw_as = PART_DRAW_DOT;
 					BLI_strncpy(psys->name, "SmokeParticles", sizeof(psys->name));
 					psys->recalc |= (PSYS_RECALC_RESET|PSYS_RECALC_PHYS);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 8d262c5..7ad13b8 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -459,7 +459,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
 	prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "act");
 	RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll");
-	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
 	RNA_def_property_editable_func(prop, "rna_NlaStrip_action_editable");
 	RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip");
 	RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index a101bca..38b1260 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -328,6 +328,39 @@ static void rna_Matte_t2_set(PointerRNA *ptr, float value)
 	chroma->t2 = value;
 }
 
+static void rna_distance_matte_t1_set(PointerRNA *ptr, float value)
+{
+    bNode *node = (bNode*)ptr->data;
+    NodeChroma *chroma = node->storage;
+
+    chroma->t1 = value;
+}
+
+static void rna_distance_matte_t2_set(PointerRNA *ptr, float value)
+{
+    bNode *node = (bNode*)ptr->data;
+    NodeChroma *chroma = node->storage;
+
+    chroma->t2 = value;
+}
+
+static void rna_difference_matte_t1_set(PointerRNA *ptr, float value)
+{
+    bNode *node = (bNode*)ptr->data;
+    NodeChroma *chroma = node->storage;
+
+    chroma->t1 = value;
+}
+
+static void rna_difference_matte_t2_set(PointerRNA *ptr, float value)
+{
+    bNode *node = (bNode*)ptr->data;
+    NodeChroma *chroma = node->storage;
+
+    chroma->t2 = value;
+}
+
+
 static void rna_Node_scene_set(PointerRNA *ptr, PointerRNA value)
 {
 	bNode *node = (bNode*)ptr->data;
@@ -709,7 +742,8 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports,
 	ret = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
 	
 	if (ret) {
-		nodeUpdate(ntree, tonode);
+		if (tonode)
+			nodeUpdate(ntree, tonode);
 
 		ntreeUpdateTree(ntree);
 
@@ -1891,14 +1925,14 @@ static void def_cmp_diff_matte(StructRNA *srna)
 	
 	prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "t1");
-	RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t1_set", NULL);
+	RNA_def_property_float_funcs(prop, NULL, "rna_difference_matte_t1_set", NULL);
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed");
 	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
 	
 	prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "t2");
-	RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t2_set", NULL);
+	RNA_def_property_float_funcs(prop, NULL, "rna_difference_matte_t2_set", NULL);
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed");
 	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
@@ -1933,18 +1967,30 @@ static void def_cmp_distance_matte(StructRNA *srna)
 {
 	PropertyRNA *prop;
 	
-	RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
+   static EnumPropertyItem color_space_items[] = {
+		{1, "RGB", 0, "RGB", "RGB color space"},
+		{2, "YCC", 0, "YCC", "YCbCr Suppression"},
+		{0, NULL, 0, NULL, NULL}};
+
+   RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
+
+   prop = RNA_def_property(srna, "channel", PROP_ENUM, PROP_NONE);  
+	RNA_def_property_enum_sdna(prop, NULL, "channel");
+	RNA_def_property_enum_items(prop, color_space_items);
+	RNA_def_property_ui_text(prop, "Channel", "");
+	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
 	
 	prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "t1");
-	RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t1_set", NULL);
+	RNA_def_property_float_funcs(prop, NULL, "rna_distance_matte_t1_set", NULL);
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed");
 	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
 	
 	prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "t2");
-	RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t2_set", NULL);
+	RNA_def_property_float_funcs(prop, NULL, "rna_distance_matte_t2_set", NULL);
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed");
 	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
@@ -2071,7 +2117,7 @@ static void def_cmp_chroma_matte(StructRNA *srna)
 	prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "fstrength");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
-	RNA_def_property_ui_text(prop, "Gain", "Alpha gain");
+	RNA_def_property_ui_text(prop, "Falloff", "Alpha falloff");
 	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
 	
 	prop = RNA_def_property(srna, "shadow_adjust", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index bd024ba..183d0e3 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -383,8 +383,11 @@ static void rna_Object_parent_set(PointerRNA *ptr, PointerRNA value)
 {
 	Object *ob = (Object*)ptr->data;
 	Object *par = (Object*)value.data;
-
-	ED_object_parent(ob, par, ob->partype, ob->parsubstr);
+	
+	/* NOTE: this dummy check here prevents this method causing weird runtime errors on mingw 4.6.2 */
+	if (ob) {
+		ED_object_parent(ob, par, ob->partype, ob->parsubstr);
+	}
 }
 
 static void rna_Object_parent_type_set(PointerRNA *ptr, int value)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d2eef1c..eeb31ee 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1077,8 +1077,11 @@ static void rna_RenderSettings_color_management_update(Main *bmain, Scene *UNUSE
 	bNode *node;
 	
 	if (ntree && scene->use_nodes) {
-		/* XXX images are freed here, stop render and preview threads, until Image is threadsafe */
-		WM_jobs_stop_all(bmain->wm.first);
+		/* images are freed here, stop render and preview threads, until
+		 * Image is threadsafe. when we are changing this propery from a
+		 * python script in the render thread, don't stop own thread */
+		if(BLI_thread_is_main())
+			WM_jobs_stop_all(bmain->wm.first);
 		
 		for (node = ntree->nodes.first; node; node = node->next) {
 			if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_IMAGE)) {
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index 1284d5a..09924b5 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -113,7 +113,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
 	float mtx[4][4];
 	int i, j;
 	int a, totshape;
-	int *vtargetmap, *vtmap_a = NULL, *vtmap_b = NULL;
+	int *vtargetmap = NULL, *vtmap_a = NULL, *vtmap_b = NULL;
 
 	/* mtx is the mirror transformation */
 	unit_m4(mtx);
@@ -223,10 +223,11 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
 		MLoop *ml2;
 		int e;
 
-		/* reverse the loop */
-		for (j = 0; j < mp->totloop; j++) {
-			DM_copy_loop_data(result, result, mp->loopstart + j, mp->loopstart + maxLoops + mp->totloop - j - 1, 1);
-		}
+		/* reverse the loop, but we keep the first vertex in the face the same,
+		 * to ensure that quads are split the same way as on the other side */
+		DM_copy_loop_data(result, result, mp->loopstart, mp->loopstart + maxLoops, 1);
+		for (j = 1; j < mp->totloop; j++)
+			DM_copy_loop_data(result, result, mp->loopstart + j, mp->loopstart + maxLoops + mp->totloop - j, 1);
 
 		ml2 = ml + mp->loopstart + maxLoops;
 		e = ml2[0].e;
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index d3e5465..5f9bce9 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -447,8 +447,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 		/* same as EM_solidify() in editmesh_lib.c */
 		float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
 		float *vert_accum= vert_angles + numVerts;
-		float *face_angles = NULL;
-		BLI_array_staticdeclare(face_angles, 16); /* BM_NGON_STACK_SIZE */
 		int j, vidx;
 
 		face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
@@ -469,27 +467,28 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 				mesh_calc_poly_normal(mp, &mloop[mp->loopstart], mvert, face_nors[i]);
 			
 			/* just added, calc the normal */
-			BLI_array_empty(face_angles);
 			for (j=0, ml=mloop+mp->loopstart; j<mp->totloop; j++, ml++) {
 				MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j);
 				MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j);
 
-				float e1[3], e2[3], angle;
-				
+				float e1[3], e2[3];
+				float angle;
+
+				/* TODO - we could speed this up by _not_ normalizing both verts each time
+				 * and always re-usingthe last vector. */
 				sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co);
 				sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co);
-				angle = M_PI - angle_normalized_v3v3(e1, e2);
-				BLI_array_append(face_angles, angle);
-			}
-			
-			for (j=0, ml=mloop+mp->loopstart; j<mp->totloop; j++, ml++) {
+
+				angle = (float)M_PI - angle_v3v3(e1, e2);
+				if (angle < FLT_EPSILON) {
+					angle = FLT_EPSILON;
+				}
+
 				vidx = ml->v;
-				vert_accum[vidx] += face_angles[j];
-				vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * face_angles[j];
+				vert_accum[vidx]+= angle;
+				vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle;
 			}
 		}
-	
-		BLI_array_free(face_angles);
 
 		/* vertex group support */
 		if (dvert) {
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index be1ceee..ebd9599 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -51,7 +51,7 @@
 
 static void initData(ModifierData *md)
 {
-	SubsurfModifierData *smd = (SubsurfModifierData*) md;
+	SubsurfModifierData *smd = (SubsurfModifierData *) md;
 
 	smd->levels = 1;
 	smd->renderLevels = 2;
@@ -60,8 +60,8 @@ static void initData(ModifierData *md)
 
 static void copyData(ModifierData *md, ModifierData *target)
 {
-	SubsurfModifierData *smd = (SubsurfModifierData*) md;
-	SubsurfModifierData *tsmd = (SubsurfModifierData*) target;
+	SubsurfModifierData *smd = (SubsurfModifierData *) md;
+	SubsurfModifierData *tsmd = (SubsurfModifierData *) target;
 
 	tsmd->flags = smd->flags;
 	tsmd->levels = smd->levels;
@@ -71,7 +71,7 @@ static void copyData(ModifierData *md, ModifierData *target)
 
 static void freeData(ModifierData *md)
 {
-	SubsurfModifierData *smd = (SubsurfModifierData*) md;
+	SubsurfModifierData *smd = (SubsurfModifierData *) md;
 
 	if (smd->mCache) {
 		ccgSubSurf_free(smd->mCache);
@@ -83,41 +83,41 @@ static void freeData(ModifierData *md)
 
 static int isDisabled(ModifierData *md, int useRenderParams)
 {
-	SubsurfModifierData *smd = (SubsurfModifierData*) md;
-	int levels= (useRenderParams)? smd->renderLevels: smd->levels;
+	SubsurfModifierData *smd = (SubsurfModifierData *) md;
+	int levels = (useRenderParams) ? smd->renderLevels : smd->levels;
 
 	return get_render_subsurf_level(&md->scene->r, levels) == 0;
 }
 
 static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
-						DerivedMesh *derivedData,
-						int useRenderParams,
-						int isFinalCalc)
+                                  DerivedMesh *derivedData,
+                                  int useRenderParams,
+                                  int isFinalCalc)
 {
-	SubsurfModifierData *smd = (SubsurfModifierData*) md;
+	SubsurfModifierData *smd = (SubsurfModifierData *) md;
 	DerivedMesh *result;
 
 	result = subsurf_make_derived_from_derived(derivedData, smd,
-			useRenderParams, NULL, isFinalCalc, 0, (ob->flag & OB_MODE_EDIT));
+	                                           useRenderParams, NULL, isFinalCalc, 0, (ob->flag & OB_MODE_EDIT));
 	
 	if (useRenderParams || !isFinalCalc) {
-		DerivedMesh *cddm= CDDM_copy(result);
+		DerivedMesh *cddm = CDDM_copy(result);
 		result->release(result);
-		result= cddm;
+		result = cddm;
 	}
 
 	return result;
 }
 
 static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob),
-						struct BMEditMesh *UNUSED(editData),
-						DerivedMesh *derivedData)
+                                    struct BMEditMesh *UNUSED(editData),
+                                    DerivedMesh *derivedData)
 {
-	SubsurfModifierData *smd = (SubsurfModifierData*) md;
+	SubsurfModifierData *smd = (SubsurfModifierData *) md;
 	DerivedMesh *result;
 
 	result = subsurf_make_derived_from_derived(derivedData, smd, 0,
-			NULL, 0, 1, 1);
+	                                           NULL, 0, 1, 1);
 
 	return result;
 }
@@ -128,11 +128,11 @@ ModifierTypeInfo modifierType_Subsurf = {
 	/* structName */        "SubsurfModifierData",
 	/* structSize */        sizeof(SubsurfModifierData),
 	/* type */              eModifierTypeType_Constructive,
-	/* flags */             eModifierTypeFlag_AcceptsMesh
-							| eModifierTypeFlag_SupportsMapping
-							| eModifierTypeFlag_SupportsEditmode
-							| eModifierTypeFlag_EnableInEditmode
-							| eModifierTypeFlag_AcceptsCVs,
+	/* flags */             eModifierTypeFlag_AcceptsMesh |
+	                        eModifierTypeFlag_SupportsMapping |
+	                        eModifierTypeFlag_SupportsEditmode |
+	                        eModifierTypeFlag_EnableInEditmode |
+	                        eModifierTypeFlag_AcceptsCVs,
 
 	/* copyData */          copyData,
 	/* deformVerts */       NULL,
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index b896187..0ef27ed 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -211,7 +211,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 
 	dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
 	/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
-	if (!dvert)
+	if (!dvert) {
 		/* If this modifier is not allowed to add vertices, just return. */
 		if (!do_add)
 			return dm;
@@ -221,6 +221,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 		/* Ultimate security check. */
 		if (!dvert)
 			return dm;
+	}
 
 	/* Get org weights, assuming 0.0 for vertices not in given vgroup. */
 	org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w");
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index b7bbc71..adcabc2 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -258,7 +258,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 
 	dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
 	/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
-	if (!dvert)
+	if (!dvert) {
 		/* If not affecting all vertices, just return. */
 		if (wmd->mix_set != MOD_WVG_SET_ALL)
 			return dm;
@@ -268,7 +268,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 		/* Ultimate security check. */
 		if (!dvert)
 			return dm;
-
+	}
 	/* Find out which vertices to work on. */
 	tidx = MEM_mallocN(sizeof(int) * numVerts, "WeightVGMix Modifier, tidx");
 	tdw1 = MEM_mallocN(sizeof(MDeformWeight*) * numVerts, "WeightVGMix Modifier, tdw1");
diff --git a/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
index 2df8e1b..571720e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
@@ -1,33 +1,33 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. 
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2006 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. 
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2006 Blender Foundation.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL LICENSE BLOCK *****
+*/
 
 /** \file blender/nodes/composite/nodes/node_composite_chromaMatte.c
- *  \ingroup cmpnodes
- */
+*  \ingroup cmpnodes
+*/
 
 
 #include "node_composite_util.h"
@@ -59,9 +59,9 @@ static void do_rgba_to_ycca_normalized(bNode *UNUSED(node), float *out, float *i
 	out[1]=(out[1]*2.0f)-1.0f;
 	out[2]=(out[2]*2.0f)-1.0f;
 
-//	out[0]=((out[0])-16)/255.0;
-//	out[1]=((out[1])-128)/255.0;
-//	out[2]=((out[2])-128)/255.0;
+	//	out[0]=((out[0])-16)/255.0;
+	//	out[1]=((out[1])-128)/255.0;
+	//	out[2]=((out[2])-128)/255.0;
 	out[3]=in[3];
 }
 
@@ -77,8 +77,8 @@ static void do_ycca_to_rgba_normalized(bNode *UNUSED(node), float *out, float *i
 	in[2]=(in[2]*255.0f);
 
 	//	in[0]=(in[0]*255.0)+16;
-//	in[1]=(in[1]*255.0)+128;
-//	in[2]=(in[2]*255.0)+128;
+	//	in[1]=(in[1]*255.0)+128;
+	//	in[2]=(in[2]*255.0)+128;
 	ycc_to_rgb(in[0],in[1],in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
 	out[3]=in[3];
 }
@@ -94,7 +94,7 @@ static void do_chroma_key(bNode *node, float *out, float *in)
 
 	/* Algorithm from book "Video Demistified," does not include the spill reduction part */
 
-	/* find theta, the angle that the color space should be rotated based on key*/
+	/* find theta, the angle that the color space should be rotated based on key chroma values*/
 	theta=atan2(c->key[2], c->key[1]);
 
 	/*rotate the cb and cr into x/z space */
@@ -107,13 +107,9 @@ static void do_chroma_key(bNode *node, float *out, float *in)
 	/* if kfg is <0 then the pixel is outside of the key color */
 	kfg= x-(fabsf(z)/tanf(angle/2.0f));
 
-	out[0]=in[0];
-	out[1]=in[1];
-	out[2]=in[2];
+	copy_v3_v3(out, in);
 
 	if (kfg>0.0f) {  /* found a pixel that is within key color */
-		alpha=(1.0f-kfg)*(c->fstrength);
-
 		beta=atan2(z,x);
 		angle2=c->t2; /* t2 is radians. */
 
@@ -121,6 +117,9 @@ static void do_chroma_key(bNode *node, float *out, float *in)
 		if (fabsf(beta) < (angle2/2.0f)) {
 			alpha=0.0;
 		}
+		else {
+			alpha=1.0f-(kfg/c->fstrength);
+		}
 
 		/* don't make something that was more transparent less transparent */
 		if (alpha<in[3]) {
@@ -130,11 +129,8 @@ static void do_chroma_key(bNode *node, float *out, float *in)
 			out[3]=in[3];
 		}
 	}
-	else { /*pixel is outside key color */
-		out[0]=in[0];
-		out[1]=in[1];
-		out[2]=in[2];
-		out[3]=in[3]; /* make pixel just as transparent as it was before */
+	else { /* make pixel just as transparent as it was before */
+		out[3]=in[3];
 	}
 }
 
@@ -143,32 +139,32 @@ static void node_composit_exec_chroma_matte(void *data, bNode *node, bNodeStack
 	CompBuf *cbuf;
 	CompBuf *chromabuf;
 	NodeChroma *c;
-	
+
 	if (in[0]->hasinput==0) return;
 	if (in[0]->data==NULL) return;
 	if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
-	
+
 	cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
-	
+
 	chromabuf= dupalloc_compbuf(cbuf);
-	
+
 	c=node->storage;
-	
+
 	/*convert rgbbuf to normalized chroma space*/
 	composit1_pixel_processor(node, chromabuf, cbuf, in[0]->vec, do_rgba_to_ycca_normalized, CB_RGBA);
 	/*convert key to normalized chroma color space */
 	do_rgba_to_ycca_normalized(node, c->key, in[1]->vec);
-	
+
 	/*per pixel chroma key*/
 	composit1_pixel_processor(node, chromabuf, chromabuf, in[0]->vec, do_chroma_key, CB_RGBA);
-	
+
 	/*convert back*/
 	composit1_pixel_processor(node, chromabuf, chromabuf, in[0]->vec, do_ycca_to_rgba_normalized, CB_RGBA);
-	
+
 	out[0]->data= chromabuf;
 	if (out[1]->hasoutput)
 		out[1]->data= valbuf_from_rgbabuf(chromabuf, CHAN_A);
-	
+
 	generate_preview(data, node, chromabuf);
 
 	if (cbuf!=in[0]->data)
diff --git a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
index 027786d..5dea0e1 100644
--- a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
@@ -1,33 +1,33 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. 
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2006 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Bob Holcomb
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. 
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2006 Blender Foundation.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): Bob Holcomb
+*
+* ***** END GPL LICENSE BLOCK *****
+*/
 
 /** \file blender/nodes/composite/nodes/node_composite_diffMatte.c
- *  \ingroup cmpnodes
- */
+*  \ingroup cmpnodes
+*/
 
 
 #include "node_composite_util.h"
@@ -49,39 +49,42 @@ static void do_diff_matte(bNode *node, float *outColor, float *inColor1, float *
 {
 	NodeChroma *c= (NodeChroma *)node->storage;
 	float tolerence=c->t1;
-	float falloff=c->t2;
+	float fper=c->t2;
+	/* get falloff amount over tolerence size */
+	float falloff=(1.0f-fper) * tolerence;
 	float difference;
 	float alpha;
+	float maxInputAlpha;
 
+	/* average together the distances */
 	difference= fabs(inColor2[0]-inColor1[0]) +
-	        fabs(inColor2[1]-inColor1[1]) +
-	        fabs(inColor2[2]-inColor1[2]);
-
-	/*average together the distances*/
+		fabs(inColor2[1]-inColor1[1]) +
+		fabs(inColor2[2]-inColor1[2]);
 	difference=difference/3.0f;
 
 	copy_v3_v3(outColor, inColor1);
 
-	/*make 100% transparent*/
-	if (difference < tolerence) {
-		outColor[3]=0.0;
-	}
-	/*in the falloff region, make partially transparent */
-	else if (difference < falloff+tolerence) {
-		difference=difference-tolerence;
-		alpha=difference/falloff;
-		/*only change if more transparent than before */
-		if (alpha < inColor1[3]) {
+	if (difference <= tolerence) {
+		if(difference<=falloff) {
+			alpha=0.0f;
+		}
+		else{
+			/* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
+			alpha=(difference-falloff)/(tolerence-falloff);
+		}
+
+		/*only change if more transparent than either image */
+		maxInputAlpha=maxf(inColor1[3], inColor2[3]);
+		if (alpha < maxInputAlpha) {
+			/*clamp*/
+			if(alpha<0.0f) alpha=0.0f;
+			if(alpha>1.0f) alpha=1.0f;
 			outColor[3]=alpha;
 		}
 		else { /* leave as before */
-			outColor[3]=inColor1[3];
+			outColor[3]=maxInputAlpha;
 		}
 	}
-	else {
-		/*foreground object*/
-		outColor[3]= inColor1[3];
-	}
 }
 
 static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
diff --git a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
index 7aaaa7e..74e0582 100644
--- a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
@@ -1,33 +1,33 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. 
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2006 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Bob Holcomb
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. 
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2006 Blender Foundation.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): Bob Holcomb
+*
+* ***** END GPL LICENSE BLOCK *****
+*/
 
 /** \file blender/nodes/composite/nodes/node_composite_distanceMatte.c
- *  \ingroup cmpnodes
- */
+*  \ingroup cmpnodes
+*/
 
 
 #include "node_composite_util.h"
@@ -51,34 +51,88 @@ static void do_distance_matte(bNode *node, float *out, float *in)
 {
 	NodeChroma *c= (NodeChroma *)node->storage;
 	float tolerence=c->t1;
-	float falloff=c->t2;
+	float fper=c->t2;
+	/* get falloff amount over tolerence size */
+	float falloff=(1.0f-fper) * tolerence;
 	float distance;
 	float alpha;
 
 	distance=sqrt((c->key[0]-in[0])*(c->key[0]-in[0]) +
-				  (c->key[1]-in[1])*(c->key[1]-in[1]) +
-				  (c->key[2]-in[2])*(c->key[2]-in[2]));
+		(c->key[1]-in[1])*(c->key[1]-in[1]) +
+		(c->key[2]-in[2])*(c->key[2]-in[2]));
 
 	copy_v3_v3(out, in);
 
-	/*make 100% transparent */
-	if (distance < tolerence) {
-		out[3]=0.0;
-	}
-	/*in the falloff region, make partially transparent */
-	else if (distance < falloff+tolerence) {
-		distance=distance-tolerence;
-		alpha=distance/falloff;
+	if (distance <= tolerence) {
+		if(distance<=falloff) {
+			alpha=0.0f;
+		}
+		else{
+			/* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
+			alpha=(distance-falloff)/(tolerence-falloff);
+		}
+
 		/*only change if more transparent than before */
 		if (alpha < in[3]) {
+			/*clamp*/
+			if(alpha<0.0f) alpha=0.0f;
+			if(alpha>1.0f) alpha=1.0f;
 			out[3]=alpha;
 		}
 		else { /* leave as before */
 			out[3]=in[3];
 		}
 	}
-	else {
-		out[3]=in[3];
+}
+
+static void do_chroma_distance_matte(bNode *node, float *out, float *in)
+{
+	NodeChroma *c= (NodeChroma *)node->storage;
+	float tolerence=c->t1;
+	float fper=c->t2;
+	/* get falloff amount over tolerence size */
+	float falloff=(1.0f-fper) * tolerence;
+	float y_key, cb_key, cr_key;
+	float y_pix, cb_pix, cr_pix;
+	float distance;
+	float alpha;
+
+	/*convert key to chroma colorspace */
+	rgb_to_ycc(c->key[0], c->key[1], c->key[2], &y_key, &cb_key, &cr_key, BLI_YCC_JFIF_0_255);
+	/* normalize the values */
+	cb_key=cb_key/255.0f;
+	cr_key=cr_key/255.0f;
+
+	/*convert pixel to chroma colorspace */
+	rgb_to_ycc(in[0], in[1], in[2], &y_pix, &cb_pix, &cr_pix, BLI_YCC_JFIF_0_255);
+	/*normalize the values */
+	cb_pix=cb_pix/255.0f;
+	cr_pix=cr_pix/255.0f;
+
+	distance=sqrt((cb_key-cb_pix)*(cb_key-cb_pix) +
+		(cr_key-cr_pix)*(cr_key-cr_pix));
+
+	copy_v3_v3(out, in);
+
+	if (distance <= tolerence) {
+		if(distance<=falloff) {
+			alpha=0.0f;
+		}
+		else{
+			/* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
+			alpha=(distance-falloff)/(tolerence-falloff);
+		}
+
+		/*only change if more transparent than before */
+		if (alpha < in[3]) {
+			/*clamp*/
+			if(alpha<0.0f) alpha=0.0f;
+			if(alpha>1.0f) alpha=1.0f;
+			out[3]=alpha;
+		}
+		else { /* leave as before */
+			out[3]=in[3];
+		}
 	}
 }
 
@@ -91,26 +145,34 @@ static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStac
 	CompBuf *workbuf;
 	CompBuf *inbuf;
 	NodeChroma *c;
-	
+
 	/*is anything connected?*/
 	if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
 	/*must have an image imput*/
 	if (in[0]->data==NULL) return;
-	
+
 	inbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
-	
+
 	c=node->storage;
 	workbuf=dupalloc_compbuf(inbuf);
-	
+
 	/*use the input color*/
 	c->key[0]= in[1]->vec[0];
 	c->key[1]= in[1]->vec[1];
 	c->key[2]= in[1]->vec[2];
-	
-	/* note, processor gets a keyvals array passed on as buffer constant */
-	composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA);
-	
-	
+
+	/* work in RGB color space */
+	if(c->channel==1) {
+		/* note, processor gets a keyvals array passed on as buffer constant */
+		composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA);
+	}
+	/* work in YCbCr color space */
+	else {
+		composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_chroma_distance_matte, CB_RGBA);
+	}
+
+
+
 	out[0]->data=workbuf;
 	if (out[1]->hasoutput)
 		out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A);
@@ -124,6 +186,7 @@ static void node_composit_init_distance_matte(bNodeTree *UNUSED(ntree), bNode* n
 {
 	NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
 	node->storage= c;
+	c->channel=1;
 	c->t1= 0.1f;
 	c->t2= 0.1f;
 }
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 362ed59..6e61dc4 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -551,7 +551,8 @@ static bNodeSocket *group_verify_socket(bNodeTree *ntree, ListBase *lb, int in_o
 		sock->groupsock = gsock;
 		
 		BLI_strncpy(sock->name, gsock->name, sizeof(sock->name));
-		sock->type= gsock->type;
+		if(gsock->type != sock->type)
+			nodeSocketSetType(sock, gsock->type);
 		
 		/* XXX hack: group socket input/output roles are inverted internally,
 		 * need to change the limit value when making actual node sockets from them.
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index f75cecf..df36948 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -73,6 +73,9 @@ static void *group_initexec(bNode *node)
 	bNodeTree *ngroup= (bNodeTree*)node->id;
 	bNodeTreeExec *exec;
 	
+	if (!ngroup)
+		return NULL;
+	
 	/* initialize the internal node tree execution */
 	exec = ntreeShaderBeginExecTree(ngroup, 0);
 	
@@ -121,6 +124,9 @@ static void group_execute(void *data, int thread, struct bNode *node, void *node
 	bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
 	bNodeThreadStack *nts;
 	
+	if (!exec)
+		return;
+	
 	/* XXX same behavior as trunk: all nodes inside group are executed.
 	 * it's stupid, but just makes it work. compo redesign will do this better.
 	 */
diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c
index 9a66ecb..1eaf9b2 100644
--- a/source/blender/nodes/texture/nodes/node_texture_common.c
+++ b/source/blender/nodes/texture/nodes/node_texture_common.c
@@ -58,6 +58,9 @@ static void *group_initexec(bNode *node)
 	bNodeTree *ngroup= (bNodeTree*)node->id;
 	void *exec;
 	
+	if (!ngroup)
+		return NULL;
+	
 	/* initialize the internal node tree execution */
 	exec = ntreeTexBeginExecTree(ngroup, 0);
 	
@@ -107,6 +110,9 @@ static void group_execute(void *data, int thread, struct bNode *node, void *node
 	bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
 	bNodeThreadStack *nts;
 	
+	if (!exec)
+		return;
+	
 	/* XXX same behavior as trunk: all nodes inside group are executed.
 	 * it's stupid, but just makes it work. compo redesign will do this better.
 	 */
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 6a02d8e..f25222c 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -124,7 +124,7 @@ static PyObject *bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void
 
 
 PyDoc_STRVAR(bpy_bmlayercollection_active_doc,
-"This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`"
+"The active layer of this type (read-only).\n\n:type: :class:`BMLayerItem`"
 );
 static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *UNUSED(flag))
 {
@@ -145,6 +145,17 @@ static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *U
 	}
 }
 
+
+PyDoc_STRVAR(bpy_bmlayercollection_is_singleton_doc,
+"This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`"
+);
+static PyObject *bpy_bmlayercollection_is_singleton_get(BPy_BMLayerItem *self, void *UNUSED(flag))
+{
+	BPY_BM_CHECK_OBJ(self);
+
+	return PyBool_FromLong(CustomData_layertype_is_singleton(self->type));
+}
+
 PyDoc_STRVAR(bpy_bmlayercollection_name_doc,
 "The layers unique name (read-only).\n\n:type: string"
 );
@@ -211,7 +222,8 @@ static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = {
 
 static PyGetSetDef bpy_bmlayercollection_getseters[] = {
     /* BMESH_TODO, make writeable */
-    {(char *)"active", (getter)bpy_bmlayercollection_active_get, (setter)NULL, (char *)bpy_bmlayercollection_active_doc, NULL},
+    {(char *)"active",       (getter)bpy_bmlayercollection_active_get,       (setter)NULL, (char *)bpy_bmlayercollection_active_doc, NULL},
+    {(char *)"is_singleton", (getter)bpy_bmlayercollection_is_singleton_get, (setter)NULL, (char *)bpy_bmlayercollection_is_singleton_doc, NULL},
 
     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
 };
@@ -230,6 +242,87 @@ static PyGetSetDef bpy_bmlayeritem_getseters[] = {
 /* BMLayerCollection
  * ----------------- */
 
+PyDoc_STRVAR(bpy_bmlayeritem_copy_from_doc,
+".. method:: copy_from(other)\n"
+"\n"
+"   Return a copy of the layer\n"
+"\n"
+"   :arg other: Another layer to copy from.\n"
+"   :arg other: :class:`BMLayerItem`\n"
+);
+static PyObject *bpy_bmlayeritem_copy_from(BPy_BMLayerItem *self, BPy_BMLayerItem *value)
+{
+	CustomData *data;
+
+	if (!BPy_BMLayerItem_Check(value)) {
+		PyErr_Format(PyExc_TypeError,
+		             "layer.copy_from(x): expected BMLayerItem, not '%.200s'",
+		             Py_TYPE(value)->tp_name);
+		return NULL;
+	}
+
+	BPY_BM_CHECK_OBJ(self);
+	BPY_BM_CHECK_OBJ(value);
+
+	if (self->bm != value->bm) {
+		PyErr_SetString(PyExc_ValueError,
+		                "layer.copy_from(): layer is from another mesh");
+		return NULL;
+	}
+
+	else if ((self->htype != value->htype) ||
+	         (self->type  != value->type) ||
+	         (self->index != value->index))
+	{
+		PyErr_SetString(PyExc_ValueError,
+		                "layer.copy_from(other): layer type mismatch");
+	}
+
+	data = bpy_bm_customdata_get(self->bm, self->htype);
+
+	if ((bpy_bmlayeritem_get(self) == NULL) ||
+	    (bpy_bmlayeritem_get(value) == NULL))
+	{
+		return NULL;
+	}
+
+	BM_data_layer_copy(self->bm, data, self->type, value->index, self->index);
+
+	Py_RETURN_NONE;
+}
+
+/* similar to new(), but no name arg. */
+PyDoc_STRVAR(bpy_bmlayercollection_verify_doc,
+".. method:: verify()\n"
+"\n"
+"   Create a new layer or return an existing active layer\n"
+"\n"
+"   :return: The newly verified layer.\n"
+"   :rtype: :class:`BMLayerItem`\n"
+);
+static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
+{
+	int index;
+	CustomData *data;
+
+	BPY_BM_CHECK_OBJ(self);
+
+	data = bpy_bm_customdata_get(self->bm, self->htype);
+
+	index = CustomData_get_layer_index(data, self->type);
+
+	if (index == -1) {
+		BM_data_layer_add(self->bm, data, self->type);
+		index = 0;
+	}
+	else {
+		index = CustomData_get_active_layer_index(data, self->type) - index; /* make relative */
+	}
+
+	BLI_assert(index >= 0);
+
+	return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
+}
 
 PyDoc_STRVAR(bpy_bmlayercollection_new_doc,
 ".. method:: new(name)\n"
@@ -255,6 +348,14 @@ static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject
 
 	data = bpy_bm_customdata_get(self->bm, self->htype);
 
+	if (CustomData_layertype_is_singleton(self->type) &&
+	    CustomData_has_layer(data, self->type))
+	{
+		PyErr_SetString(PyExc_ValueError,
+		                "layers.new(): is a singleton, use verify() instead");
+		return NULL;
+	}
+
 	if (name) {
 		BM_data_layer_add_named(self->bm, data, self->type, name);
 	}
@@ -451,7 +552,13 @@ static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject
 	return Py_INCREF(def), def;
 }
 
+static struct PyMethodDef bpy_bmlayeritem_methods[] = {
+    {"copy_from", (PyCFunction)bpy_bmlayeritem_copy_from,    METH_O,       bpy_bmlayeritem_copy_from_doc},
+    {NULL, NULL, 0, NULL}
+};
+
 static struct PyMethodDef bpy_bmelemseq_methods[] = {
+    {"verify",  (PyCFunction)bpy_bmlayercollection_verify,   METH_NOARGS,  bpy_bmlayercollection_verify_doc},
     {"new",     (PyCFunction)bpy_bmlayercollection_new,      METH_VARARGS, bpy_bmlayercollection_new_doc},
     {"remove",  (PyCFunction)bpy_bmlayercollection_remove,   METH_O,       bpy_bmlayercollection_remove_doc},
 
@@ -462,8 +569,6 @@ static struct PyMethodDef bpy_bmelemseq_methods[] = {
     {NULL, NULL, 0, NULL}
 };
 
-
-
 /* Sequences
  * ========= */
 
@@ -763,6 +868,7 @@ void BPy_BM_init_types_customdata(void)
 
 //	BPy_BMLayerAccess_Type.tp_methods     = bpy_bmeditselseq_methods;
 	BPy_BMLayerCollection_Type.tp_methods = bpy_bmelemseq_methods;
+	BPy_BMLayerItem_Type.tp_methods       = bpy_bmlayeritem_methods;
 
 	BPy_BMLayerCollection_Type.tp_as_sequence = &bpy_bmlayercollection_as_sequence;
 
@@ -883,8 +989,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
 		}
 		case CD_MTEXPOLY:
 		{
-			ret = Py_NotImplemented; /* TODO */
-			Py_INCREF(ret);
+			ret = BPy_BMTexPoly_CreatePyObject(value);
 			break;
 		}
 		case CD_MLOOPUV:
@@ -977,8 +1082,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
 		}
 		case CD_MTEXPOLY:
 		{
-			PyErr_SetString(PyExc_AttributeError, "readonly"); /* could make this writeable later */
-			ret = -1;
+			ret = BPy_BMTexPoly_AssignPyObject(value, py_value);
 			break;
 		}
 		case CD_MLOOPUV:
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 9972ff2..aa78dc6 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -34,15 +34,107 @@
 
 #include "../mathutils/mathutils.h"
 
+#include "DNA_object_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "BLI_utildefines.h"
 #include "BLI_math_vector.h"
 
 #include "BKE_deform.h"
+#include "BKE_library.h"
 
 #include "bmesh_py_types_meshdata.h"
 
+
+/* Mesh BMTexPoly
+ * ************** */
+
+#define BPy_BMTexPoly_Check(v)  (Py_TYPE(v) == &BPy_BMTexPoly_Type)
+
+typedef struct BPy_BMTexPoly {
+	PyObject_VAR_HEAD
+	MTexPoly *data;
+} BPy_BMTexPoly;
+
+extern PyObject *pyrna_id_CreatePyObject(ID *id);
+extern int       pyrna_id_FromPyObject(PyObject *obj, ID **id);
+
+PyDoc_STRVAR(bpy_bmtexpoly_image_doc,
+"Image or None.\n\n:type: :class:`bpy.types.Image`"
+);
+static PyObject *bpy_bmtexpoly_image_get(BPy_BMTexPoly *self, void *UNUSED(closure))
+{
+	return pyrna_id_CreatePyObject((ID *)self->data->tpage);
+}
+
+static int bpy_bmtexpoly_image_set(BPy_BMTexPoly *self, PyObject *value, void *UNUSED(closure))
+{
+	ID *id;
+
+	if (value == Py_None) {
+		id = NULL;
+	}
+	else if (pyrna_id_FromPyObject(value, &id) && id && GS(id->name) == ID_IM) {
+		/* pass */
+	}
+	else {
+		PyErr_Format(PyExc_KeyError, "BMTexPoly.image = x"
+		             "expected an image or None, not '%.200s'",
+		             Py_TYPE(value)->tp_name);
+		return -1;
+	}
+
+	id_lib_extern(id);
+	self->data->tpage = (struct Image *)id;
+
+	return 0;
+}
+
+static PyGetSetDef bpy_bmtexpoly_getseters[] = {
+    /* attributes match rna_def_mtpoly  */
+    {(char *)"image", (getter)bpy_bmtexpoly_image_get, (setter)bpy_bmtexpoly_image_set, (char *)bpy_bmtexpoly_image_doc, NULL},
+
+    {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+PyTypeObject BPy_BMTexPoly_Type = {{{0}}}; /* bm.loops.layers.uv.active */
+
+static void bm_init_types_bmtexpoly(void)
+{
+	BPy_BMTexPoly_Type.tp_basicsize = sizeof(BPy_BMTexPoly);
+
+	BPy_BMTexPoly_Type.tp_name = "BMTexPoly";
+
+	BPy_BMTexPoly_Type.tp_doc = NULL; // todo
+
+	BPy_BMTexPoly_Type.tp_getset = bpy_bmtexpoly_getseters;
+
+	BPy_BMTexPoly_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+
+	PyType_Ready(&BPy_BMTexPoly_Type);
+}
+
+int BPy_BMTexPoly_AssignPyObject(struct MTexPoly *mtpoly, PyObject *value)
+{
+	if (UNLIKELY(!BPy_BMTexPoly_Check(value))) {
+		PyErr_Format(PyExc_TypeError, "expected BMTexPoly, not a %.200s", Py_TYPE(value)->tp_name);
+		return -1;
+	}
+	else {
+		*((MTexPoly *)mtpoly) = *(((BPy_BMTexPoly *)value)->data);
+		return 0;
+	}
+}
+
+PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mtpoly)
+{
+	BPy_BMTexPoly *self = PyObject_New(BPy_BMTexPoly, &BPy_BMTexPoly_Type);
+	self->data = mtpoly;
+	return (PyObject *)self;
+}
+
+/* --- End Mesh BMTexPoly --- */
+
 /* Mesh Loop UV
  * ************ */
 
@@ -596,6 +688,7 @@ PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert)
 /* call to init all types */
 void BPy_BM_init_types_meshdata(void)
 {
+	bm_init_types_bmtexpoly();
 	bm_init_types_bmloopuv();
 	bm_init_types_bmloopcol();
 	bm_init_types_bmdvert();
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
index 4636f80..c9e8dce 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
@@ -40,10 +40,17 @@ typedef struct BPy_BMGenericMeshData {
 	void *data;
 } BPy_BMGenericMeshData;
 
+struct MTexPoly;
 struct MLoopUV;
 struct MLoopCol;
 struct MDeformVert;
 
+int       BPy_BMTexPoly_AssignPyObject(struct MTexPoly *mloopuv, PyObject *value);
+PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mloopuv);
+
+int       BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
+PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
+
 int       BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
 PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
 
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 4d0c05f..dbb25eb 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -1071,8 +1071,8 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
 		else {
 			MEM_freeN(items);
 			PyErr_SetString(PyExc_TypeError,
-			                "EnumProperty(...): expected an tuple containing "
-			                "(identifier, name description) and optionally a "
+			                "EnumProperty(...): expected a tuple containing "
+			                "(identifier, name, description) and optionally a "
 			                "unique number");
 			return NULL;
 		}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 7259ea8..47134cd 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -6246,6 +6246,31 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
 	return (PyObject *)pyrna;
 }
 
+/* utility func to be used by external modules, *sneaky!* */
+PyObject *pyrna_id_CreatePyObject(ID *id)
+{
+	if (id) {
+		PointerRNA ptr;
+		RNA_id_pointer_create(id, &ptr);
+		return pyrna_struct_CreatePyObject(&ptr);
+	}
+	else {
+		Py_RETURN_NONE;
+	}
+}
+
+int pyrna_id_FromPyObject(PyObject *obj, ID **id)
+{
+	if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) {
+		*id = ((BPy_StructRNA *)obj)->ptr.id.data;
+		return TRUE;
+	}
+	else {
+		*id = NULL;
+		return FALSE;
+	}
+}
+
 void BPY_rna_init(void)
 {
 #ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once.
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
index 5094b64..7482b4d 100644
--- a/source/blender/render/intern/include/strand.h
+++ b/source/blender/render/intern/include/strand.h
@@ -101,7 +101,7 @@ void free_strand_surface(struct Render *re);
 struct StrandShadeCache *strand_shade_cache_create(void);
 void strand_shade_cache_free(struct StrandShadeCache *cache);
 void strand_shade_segment(struct Render *re, struct StrandShadeCache *cache, struct StrandSegment *sseg, struct ShadeSample *ssamp, float t, float s, int addpassflag);
-void strand_shade_unref(struct StrandShadeCache *cache, struct StrandVert *svert);
+void strand_shade_unref(struct StrandShadeCache *cache, struct ObjectInstanceRen *obi, struct StrandVert *svert);
 
 #endif
 
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index b2f85e8..9899461 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -130,7 +130,7 @@ MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRe
 
 MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *UNUSED(vlr))
 {
-	return (obi->obr->ob != is->userdata);
+	return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT);
 }
 
 /* Ray Triangle/Quad Intersection */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index a4a244d..0398204 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1803,6 +1803,28 @@ static int check_valid_camera(Scene *scene, Object *camera_override)
 	return 1;
 }
 
+static int node_tree_has_composite_output(bNodeTree *ntree)
+{
+	bNode *node;
+
+	for (node = ntree->nodes.first; node; node = node->next) {
+		if (node->type == CMP_NODE_COMPOSITE) {
+			return TRUE;
+		}
+		else if (node->type == NODE_GROUP) {
+			if (node_tree_has_composite_output((bNodeTree *)node->id))
+				return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static int check_composite_output(Scene *scene)
+{
+	return node_tree_has_composite_output(scene->nodetree);
+}
+
 int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *reports)
 {
 	SceneRenderLayer *srl;
@@ -1837,19 +1859,12 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r
 	
 	if (scene->r.scemode & R_DOCOMP) {
 		if (scene->use_nodes) {
-			bNodeTree *ntree= scene->nodetree;
-			bNode *node;
-		
-			if (ntree==NULL) {
+			if (!scene->nodetree) {
 				BKE_report(reports, RPT_ERROR, "No Nodetree in Scene");
 				return 0;
 			}
 			
-			for (node= ntree->nodes.first; node; node= node->next)
-				if (node->type==CMP_NODE_COMPOSITE)
-					break;
-			
-			if (node==NULL) {
+			if (!check_composite_output(scene)) {
 				BKE_report(reports, RPT_ERROR, "No Render Output Node in Scene");
 				return 0;
 			}
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index ea6b099..e8fcbe4 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -323,13 +323,18 @@ struct StrandShadeCache {
 	MemArena *memarena;
 };
 
+typedef struct StrandCacheEntry {
+	GHashPair pair;
+	ShadeResult shr;
+} StrandCacheEntry;
+
 StrandShadeCache *strand_shade_cache_create(void)
 {
 	StrandShadeCache *cache;
 
 	cache= MEM_callocN(sizeof(StrandShadeCache), "StrandShadeCache");
-	cache->resulthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "strand_shade_cache_create1 gh");
-	cache->refcounthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "strand_shade_cache_create2 gh");
+	cache->resulthash= BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "strand_shade_cache_create1 gh");
+	cache->refcounthash= BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "strand_shade_cache_create2 gh");
 	cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand shade cache arena");
 	
 	return cache;
@@ -338,39 +343,47 @@ StrandShadeCache *strand_shade_cache_create(void)
 void strand_shade_cache_free(StrandShadeCache *cache)
 {
 	BLI_ghash_free(cache->refcounthash, NULL, NULL);
-	BLI_ghash_free(cache->resulthash, NULL, (GHashValFreeFP)MEM_freeN);
+	BLI_ghash_free(cache->resulthash, (GHashKeyFreeFP)MEM_freeN, NULL);
 	BLI_memarena_free(cache->memarena);
 	MEM_freeN(cache);
 }
 
+static GHashPair strand_shade_hash_pair(ObjectInstanceRen *obi, StrandVert *svert)
+{
+	GHashPair pair = {obi, svert};
+	return pair;
+}
+
 static void strand_shade_get(Render *re, StrandShadeCache *cache, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert)
 {
-	ShadeResult *hashshr;
+	StrandCacheEntry *entry;
 	StrandPoint p;
 	int *refcount;
+	GHashPair pair = strand_shade_hash_pair(sseg->obi, svert);
 
-	hashshr= BLI_ghash_lookup(cache->resulthash, svert);
-	refcount= BLI_ghash_lookup(cache->refcounthash, svert);
+	entry= BLI_ghash_lookup(cache->resulthash, &pair);
+	refcount= BLI_ghash_lookup(cache->refcounthash, &pair);
 
-	if (!hashshr) {
+	if (!entry) {
 		/* not shaded yet, shade and insert into hash */
 		p.t= (sseg->v[1] == svert)? 0.0f: 1.0f;
 		strand_eval_point(sseg, &p);
 		strand_shade_point(re, ssamp, sseg, svert, &p);
 
-		hashshr= MEM_callocN(sizeof(ShadeResult), "HashShadeResult");
-		*hashshr= ssamp->shr[0];
-		BLI_ghash_insert(cache->resulthash, svert, hashshr);
+		entry= MEM_callocN(sizeof(StrandCacheEntry), "StrandCacheEntry");
+		entry->pair = pair;
+		entry->shr = ssamp->shr[0];
+		BLI_ghash_insert(cache->resulthash, entry, entry);
 	}
 	else
 		/* already shaded, just copy previous result from hash */
-		ssamp->shr[0]= *hashshr;
+		ssamp->shr[0]= entry->shr;
 	
 	/* lower reference count and remove if not needed anymore by any samples */
 	(*refcount)--;
 	if (*refcount == 0) {
-		BLI_ghash_remove(cache->resulthash, svert, NULL, (GHashValFreeFP)MEM_freeN);
-		BLI_ghash_remove(cache->refcounthash, svert, NULL, NULL);
+		BLI_ghash_remove(cache->resulthash, &pair, (GHashKeyFreeFP)MEM_freeN, NULL);
+		BLI_ghash_remove(cache->refcounthash, &pair, NULL, NULL);
 	}
 }
 
@@ -388,34 +401,39 @@ void strand_shade_segment(Render *re, StrandShadeCache *cache, StrandSegment *ss
 
 	/* apply alpha along width */
 	if (sseg->buffer->widthfade != 0.0f) {
-		s = 1.0f - pow(fabs(s), sseg->buffer->widthfade);
+		s = 1.0f - powf(fabsf(s), sseg->buffer->widthfade);
 
 		strand_apply_shaderesult_alpha(ssamp->shr, s);
 	}
 }
 
-void strand_shade_unref(StrandShadeCache *cache, StrandVert *svert)
+void strand_shade_unref(StrandShadeCache *cache, ObjectInstanceRen *obi, StrandVert *svert)
 {
+	GHashPair pair = strand_shade_hash_pair(obi, svert);
 	int *refcount;
 
 	/* lower reference count and remove if not needed anymore by any samples */
-	refcount= BLI_ghash_lookup(cache->refcounthash, svert);
+	refcount= BLI_ghash_lookup(cache->refcounthash, &pair);
 
 	(*refcount)--;
 	if (*refcount == 0) {
-		BLI_ghash_remove(cache->resulthash, svert, NULL, (GHashValFreeFP)MEM_freeN);
-		BLI_ghash_remove(cache->refcounthash, svert, NULL, NULL);
+		BLI_ghash_remove(cache->resulthash, &pair, (GHashKeyFreeFP)MEM_freeN, NULL);
+		BLI_ghash_remove(cache->refcounthash, &pair, NULL, NULL);
 	}
 }
 
-static void strand_shade_refcount(StrandShadeCache *cache, StrandVert *svert)
+static void strand_shade_refcount(StrandShadeCache *cache, StrandSegment *sseg, StrandVert *svert)
 {
-	int *refcount= BLI_ghash_lookup(cache->refcounthash, svert);
+	GHashPair pair = strand_shade_hash_pair(sseg->obi, svert);
+	GHashPair *key;
+	int *refcount= BLI_ghash_lookup(cache->refcounthash, &pair);
 
 	if (!refcount) {
+		key= BLI_memarena_alloc(cache->memarena, sizeof(GHashPair));
+		*key = pair;
 		refcount= BLI_memarena_alloc(cache->memarena, sizeof(int));
 		*refcount= 1;
-		BLI_ghash_insert(cache->refcounthash, svert, refcount);
+		BLI_ghash_insert(cache->refcounthash, key, refcount);
 	}
 	else
 		(*refcount)++;
@@ -580,8 +598,8 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float
 			}
 
 			if (cache) {
-				strand_shade_refcount(cache, sseg->v[1]);
-				strand_shade_refcount(cache, sseg->v[2]);
+				strand_shade_refcount(cache, sseg, sseg->v[1]);
+				strand_shade_refcount(cache, sseg, sseg->v[2]);
 			}
 			spart->totapixbuf[offset]++;
 		}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 74c4bf1..9836382 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -3748,8 +3748,8 @@ static void unref_strand_samples(StrandShadeCache *cache, ZTranspRow *row, int t
 			strand= RE_findOrAddStrand(obr, row[totface].p-1);
 			svert= strand->vert + row[totface].segment;
 
-			strand_shade_unref(cache, svert);
-			strand_shade_unref(cache, svert+1);
+			strand_shade_unref(cache, obi, svert);
+			strand_shade_unref(cache, obi, svert+1);
 		}
 	}
 }
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 514c159..aae2560 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -84,6 +84,7 @@
 
 #include "ED_screen.h"
 #include "ED_util.h"
+#include "ED_object.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -2129,7 +2130,12 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED
 {	
 	if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
 		char filepath[FILE_MAX];
-		BLI_strncpy(filepath, G.main->name, sizeof(filepath));
+
+		if (G.main->name[0] == 0)
+			BLI_strncpy(filepath, "untitled", sizeof(filepath));
+		else
+			BLI_strncpy(filepath, G.main->name, sizeof(filepath));
+
 		BLI_replace_extension(filepath, sizeof(filepath), ".dae");
 		RNA_string_set(op->ptr, "filepath", filepath);
 	}
@@ -2153,6 +2159,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
 	RNA_string_get(op->ptr, "filepath", filename);
 	selected = RNA_boolean_get(op->ptr, "selected");
 	second_life = RNA_boolean_get(op->ptr, "second_life");
+
+	/* get editmode results */
+	ED_object_exit_editmode(C, 0);  /* 0 = does not exit editmode */
+
 	if (collada_export(CTX_data_scene(C), filename, selected, second_life)) {
 		return OPERATOR_FINISHED;
 	}
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 90d490d..f3485d8 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -499,6 +499,8 @@ float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime) {retur
 void BPY_DECREF(void *pyob_ptr) {}
 void BPY_pyconstraint_exec(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets) {}
 void macro_wrapper(struct wmOperatorType *ot, void *userdata) {}
+int pyrna_id_FromPyObject(struct PyObject *obj, struct ID **id){ return 0; }
+struct PyObject *pyrna_id_CreatePyObject(struct ID *id) {return NULL; }
 
 /* intern/dualcon */
 struct DualConMesh;
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 13daeec..d663b4f 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -1101,7 +1101,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
 #ifdef WITH_FFMPEG
 	BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
 #endif
-	BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
+	BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
 	BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
 	BLI_argsAdd(ba, 1, NULL, "--debug-wm",     "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
 	BLI_argsAdd(ba, 1, NULL, "--debug-all",    "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index 5a73047..96b5676 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -32,7 +32,7 @@ set(INC
 )
 
 set(INC_SYS
-
+	${PTHREADS_INCLUDE_DIRS}
 )
 
 set(SRC
diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript
index 8f59ec0..998396a 100644
--- a/source/gameengine/BlenderRoutines/SConscript
+++ b/source/gameengine/BlenderRoutines/SConscript
@@ -35,4 +35,7 @@ if env['WITH_BF_CXX_GUARDEDALLOC']:
 incs += ' ' + env['BF_BULLET_INC']
 incs += ' ' + env['BF_OPENGL_INC']
 
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+    incs += ' ' + env['BF_PTHREADS_INC']
+
 env.BlenderLib ( 'ge_blen_routines', sources, Split(incs), defs, libtype=['core','player'], priority=[300,35] , cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index b570489..1826f1a 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -59,6 +59,7 @@ set(INC
 )
 
 set(INC_SYS
+	${PTHREADS_INCLUDE_DIRS}
 
 )
 
diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript
index 4e2adbd..e95ae54 100644
--- a/source/gameengine/Converter/SConscript
+++ b/source/gameengine/Converter/SConscript
@@ -39,4 +39,7 @@ if env['WITH_BF_CXX_GUARDEDALLOC']:
 if env['WITH_BF_BULLET']:
     defs.append('USE_BULLET')
 
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+    incs += ' ' + env['BF_PTHREADS_INC']
+
 env.BlenderLib ( 'ge_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,40], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
index eccfefe..f4224b9 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
@@ -88,6 +88,12 @@ void GPC_Canvas::Resize(int width, int height)
 {
 	m_width = width;
 	m_height = height;
+
+	// initialize area so that it's available for game logic on frame 1 (ImageViewport)
+	m_displayarea.m_x1 = 0;
+	m_displayarea.m_y1 = 0;
+	m_displayarea.m_x2 = width;
+	m_displayarea.m_y2 = height;
 }
 
 void GPC_Canvas::EndFrame()
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 8ed2d2f..c7f5483 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -55,6 +55,7 @@ set(INC
 )
 
 set(INC_SYS
+	${PTHREADS_INCLUDE_DIRS}
 	${GLEW_INCLUDE_PATH}
 	../../../extern/recastnavigation/Recast/Include
 	../../../extern/recastnavigation/Detour/Include
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 9940b40..f592681 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -121,8 +121,8 @@ void	KX_BulletPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool l
 
 void	KX_BulletPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local)
 {
-	float	rotval[12];
-	drot.getValue(rotval);
+	float	rotval[9];
+	drot.getValue3x3(rotval);
 	CcdPhysicsController::RelativeRotate(rotval,local);
 }
 
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 2943acd..5fdf250 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -47,4 +47,7 @@ if env['WITH_BF_BULLET']:
     defs.append('USE_BULLET')
     incs += ' #source/gameengine/Physics/Bullet'
 
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+    incs += ' ' + env['BF_PTHREADS_INC']
+
 env.BlenderLib ( 'ge_logic_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320,45], cxx_compileflags=env['BGE_CXXFLAGS'])

-- 
blender packaging



More information about the pkg-multimedia-commits mailing list