missing files from last
authorJoseph Eagar <joeedh@gmail.com>
Sat, 4 Sep 2010 18:58:47 +0000 (18:58 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sat, 4 Sep 2010 18:58:47 +0000 (18:58 +0000)
merge

release/scripts/modules/rigify/stretch_twist.py
source/blender/blenkernel/BKE_idcode.h [new file with mode: 0755]
source/blender/blenkernel/intern/idcode.c [new file with mode: 0755]
source/blender/blenkernel/intern/seqcache.c [new file with mode: 0755]
source/blender/python/generic/noise.c [new file with mode: 0755]

index ac64d4369cd1bfadd3ecd2b348708a9eb1ec07c9..07ce031967f570f86a56b257a8dd866eb4686f15 100644 (file)
@@ -1,157 +1,3 @@
-<<<<<<< .working
-# ##### 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>
-
-import bpy
-from rigify import RigifyError
-from rigify_utils import copy_bone_simple
-
-METARIG_NAMES = tuple()
-RIG_TYPE = "stretch_twist"
-
-# TODO
-#def metarig_template():
-#    # generated by rigify.write_meta_rig
-#    bpy.ops.object.mode_set(mode='EDIT')
-#    obj = bpy.context.active_object
-#    arm = obj.data
-#    bone = arm.edit_bones.new('Bone')
-#    bone.head[:] = 0.0000, 0.0000, 0.0000
-#    bone.tail[:] = 0.0000, 0.0000, 1.0000
-#    bone.roll = 0.0000
-#    bone.connected = False
-#
-#    bpy.ops.object.mode_set(mode='OBJECT')
-#    pbone = obj.pose.bones['Bone']
-#    pbone['type'] = 'copy'
-
-bool_map = {0:False, 1:True,
-            0.0:False, 1.0:True,
-            "false":False, "true":True,
-            "False":False, "True":True,
-            "no":False, "yes":True,
-            "No":False, "Yes":True}
-
-def metarig_definition(obj, orig_bone_name):
-    return (orig_bone_name,)
-
-
-
-
-def main(obj, bone_definition, base_names, options):
-    """ A dual-bone stretchy bone setup.  Each half follows the twist of the
-        bone on its side.
-        Deformation only (no controls).
-    """
-    # Verify required parameter
-    if "to" not in options:
-        raise RigifyError("'%s' rig type requires a 'to' parameter (bone: %s)" % (RIG_TYPE, base_names[0]))
-    if type(options["to"]) is not str:
-        raise RigifyError("'%s' rig type 'to' parameter must be a string (bone: %s)" % (RIG_TYPE, base_names[0]))
-    if ("ORG-" + options["to"]) not in obj.data.bones:
-        raise RigifyError("'%s' rig type 'to' parameter must name a bone in the metarig (bone: %s)" % (RIG_TYPE, base_names[0]))
-
-    preserve_volume = None
-    # Check optional parameter
-    if "preserve_volume" in options:
-        try:
-            preserve_volume = bool_map[options["preserve_volume"]]
-        except KeyError:
-            preserve_volume = False
-
-    eb = obj.data.edit_bones
-    bb = obj.data.bones
-    pb = obj.pose.bones
-
-    bpy.ops.object.mode_set(mode='EDIT')
-    arm = obj.data
-
-    mbone1 = bone_definition[0]
-    mbone2 = "ORG-" + options["to"]
-
-    bone_e = copy_bone_simple(obj.data, mbone1, "MCH-%s" % base_names[bone_definition[0]])
-    bone_e.connected = False
-    bone_e.parent = None
-    bone_e.head = (eb[mbone1].head + eb[mbone2].head) / 2
-    bone_e.tail = (bone_e.head[0], bone_e.head[1], bone_e.head[2]+0.1)
-    mid_bone = bone_e.name
-
-    bone_e = copy_bone_simple(obj.data, mbone1, "DEF-%s.01" % base_names[bone_definition[0]])
-    bone_e.connected = False
-    bone_e.parent = eb[mbone1]
-    bone_e.tail = eb[mid_bone].head
-    bone1 = bone_e.name
-
-    bone_e = copy_bone_simple(obj.data, mbone2, "DEF-%s.02" % base_names[bone_definition[0]])
-    bone_e.connected = False
-    bone_e.parent = eb[mbone2]
-    bone_e.tail = eb[mid_bone].head
-    bone2 = bone_e.name
-
-
-
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-    # Constraints
-
-    # Mid bone
-    con = pb[mid_bone].constraints.new('COPY_LOCATION')
-    con.target = obj
-    con.subtarget = mbone1
-
-    con = pb[mid_bone].constraints.new('COPY_LOCATION')
-    con.target = obj
-    con.subtarget = mbone2
-    con.influence = 0.5
-
-    # Bone 1
-    con = pb[bone1].constraints.new('DAMPED_TRACK')
-    con.target = obj
-    con.subtarget = mid_bone
-
-    con = pb[bone1].constraints.new('STRETCH_TO')
-    con.target = obj
-    con.subtarget = mid_bone
-    con.original_length = bb[bone1].length
-    if preserve_volume:
-        con.volume = 'VOLUME_XZX'
-    else:
-        con.volume = 'NO_VOLUME'
-
-    # Bone 2
-    con = pb[bone2].constraints.new('DAMPED_TRACK')
-    con.target = obj
-    con.subtarget = mid_bone
-
-    con = pb[bone2].constraints.new('STRETCH_TO')
-    con.target = obj
-    con.subtarget = mid_bone
-    con.original_length = bb[bone2].length
-    if preserve_volume:
-        con.volume = 'VOLUME_XZX'
-    else:
-        con.volume = 'NO_VOLUME'
-
-    return tuple()
-
-=======
 # ##### BEGIN GPL LICENSE BLOCK #####
 #
 #  This program is free software; you can redistribute it and/or
@@ -304,4 +150,3 @@ def main(obj, bone_definition, base_names, options):
 
     return tuple()
 
->>>>>>> .merge-right.r31523
diff --git a/source/blender/blenkernel/BKE_idcode.h b/source/blender/blenkernel/BKE_idcode.h
new file mode 100755 (executable)
index 0000000..364345a
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * $Id: BKE_idcode.h 31221 2010-08-10 20:33:15Z gsrb3d $
+ *
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_ID_INFO_H
+#define BKE_ID_INFO_H
+
+/**
+ * Convert an idcode into a name.
+ * 
+ * @param code The code to convert.
+ * @return A static string representing the name of
+ * the code.
+ */
+const char *BKE_idcode_to_name(int code);
+
+/**
+ * Convert an idcode into a name (plural).
+ * 
+ * @param code The code to convert.
+ * @return A static string representing the name of
+ * the code.
+ */
+const char *BKE_idcode_to_name_plural(int code);
+
+/**
+ * Convert a name into an idcode (ie. ID_SCE)
+ * 
+ * @param name The name to convert.
+ * @return The code for the name, or 0 if invalid.
+ */
+int BKE_idcode_from_name(const char *name);
+
+/**
+ * Return non-zero when an ID type is linkable.
+ * 
+ * @param code The code to check.
+ * @return Boolean, 0 when non linkable.
+ */
+int BKE_idcode_is_linkable(int code);
+
+/**
+ * Return if the ID code is a valid ID code.
+ * 
+ * @param code The code to check.
+ * @return Boolean, 0 when invalid.
+ */
+int BKE_idcode_is_valid(int code);
+
+#endif
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
new file mode 100755 (executable)
index 0000000..a6c7062
--- /dev/null
@@ -0,0 +1,128 @@
+/**
+ * $Id: idcode.c 31437 2010-08-18 07:14:10Z campbellbarton $
+ *
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * return info about ID types
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "DNA_ID.h"
+
+typedef struct {
+       unsigned short code;
+       char *name, *plural;
+       
+       int flags;
+#define IDTYPE_FLAGS_ISLINKABLE        (1<<0)
+} IDType;
+
+/* plural need to match rna_main.c's MainCollectionDef */
+static IDType idtypes[]= {
+       { ID_AC,                "Action",       "actions",              IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_AR,                "Armature", "armatures",        IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_BR,                "Brush",        "brushes",              IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_CA,                "Camera",       "cameras",              IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_CU,                "Curve",        "curves",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_GD,                "GPencil",      "grease_pencil",IDTYPE_FLAGS_ISLINKABLE},  /* rename gpencil */
+       { ID_GR,                "Group",        "groups",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_ID,                "ID",           "ids",                  0}, /* plural is fake */
+       { ID_IM,                "Image",        "images",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_IP,                "Ipo",          "ipos",                 IDTYPE_FLAGS_ISLINKABLE},  /* deprecated */
+       { ID_KE,                "Key",          "keys",                 0}, 
+       { ID_LA,                "Lamp",         "lamps",                IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_LI,                "Library",      "libraries",    0}, 
+       { ID_LT,                "Lattice",      "lattices",             IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_MA,                "Material", "materials",        IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_MB,                "Metaball", "metaballs",        IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_ME,                "Mesh",         "meshes",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_NT,                "NodeTree",     "node_groups",  IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_OB,                "Object",       "objects",              IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_PA,                "ParticleSettings",     "particles", 0},
+       { ID_SCE,               "Scene",        "scenes",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_SCR,               "Screen",       "screens",              0}, 
+       { ID_SEQ,               "Sequence",     "sequences",    0}, /* not actually ID data */
+       { ID_SO,                "Sound",        "sounds",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_TE,                "Texture",      "textures",             IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_TXT,               "Text",         "texts",                IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_VF,                "VFont",        "fonts",                IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_WO,                "World",        "worlds",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_WM,                "WindowManager", "window_managers",     0}, 
+};
+static int nidtypes= sizeof(idtypes)/sizeof(idtypes[0]);
+
+static IDType *idtype_from_name(const char *str) 
+{
+       int i= nidtypes;
+       
+       while (i--)
+               if (strcmp(str, idtypes[i].name)==0)
+                       return &idtypes[i];
+
+       return NULL;
+}
+static IDType *idtype_from_code(int code) 
+{
+       int i= nidtypes;
+       
+       while (i--)
+               if (code==idtypes[i].code)
+                       return &idtypes[i];
+       
+       return NULL;
+}
+
+int BKE_idcode_is_valid(int code) 
+{
+       return idtype_from_code(code)?1:0;
+}
+
+int BKE_idcode_is_linkable(int code) {
+       IDType *idt= idtype_from_code(code);
+       return idt?(idt->flags&IDTYPE_FLAGS_ISLINKABLE):0;
+}
+
+const char *BKE_idcode_to_name(int code) 
+{
+       IDType *idt= idtype_from_code(code);
+       
+       return idt?idt->name:NULL;
+}
+
+int BKE_idcode_from_name(const char *name) 
+{
+       IDType *idt= idtype_from_name(name);
+       
+       return idt?idt->code:0;
+}
+
+const char *BKE_idcode_to_name_plural(int code) 
+{
+       IDType *idt= idtype_from_code(code);
+       
+       return idt?idt->plural:NULL;
+}
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
new file mode 100755 (executable)
index 0000000..37bd398
--- /dev/null
@@ -0,0 +1,267 @@
+/**
+* $Id: seqcache.c 30687 2010-07-24 08:47:14Z schlaile $
+ *
+ * ***** 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.
+ *
+ * Peter Schlaile <peter [at] schlaile [dot] de> 2010
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+#include "MEM_CacheLimiterC-Api.h"
+
+#include "DNA_sequence_types.h"
+#include "BKE_sequencer.h"
+#include "BLI_ghash.h"
+#include "BLI_mempool.h"
+#include <pthread.h>
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+typedef struct seqCacheKey 
+{
+       struct Sequence * seq;
+       int rectx;
+       int recty;
+       float cfra;
+       seq_stripelem_ibuf_t type;
+} seqCacheKey;
+
+typedef struct seqCacheEntry
+{
+       ImBuf * ibuf;
+       MEM_CacheLimiterHandleC * c_handle;
+} seqCacheEntry;
+
+static GHash * hash = 0;
+static MEM_CacheLimiterC * limitor = 0;
+static struct BLI_mempool * entrypool = 0;
+static struct BLI_mempool * keypool = 0;
+static int ibufs_in  = 0;
+static int ibufs_rem = 0;
+
+static unsigned int HashHash(void *key_)
+{
+       seqCacheKey * key = (seqCacheKey*) key_;
+       unsigned int rval = key->rectx + key->recty;
+
+       rval ^= *(unsigned int*) &key->cfra;
+       rval += key->type;
+       rval ^= ((unsigned int) key->seq) << 6;
+
+       return rval;
+}
+
+static int HashCmp(void *a_, void *b_)
+{
+       seqCacheKey * a = (seqCacheKey*) a_;
+       seqCacheKey * b = (seqCacheKey*) b_;
+
+       if (a->seq < b->seq) {
+               return -1;              
+       }
+       if (a->seq > b->seq) {
+               return 1;
+       }
+
+       if (a->cfra < b->cfra) {
+               return -1;
+       }
+       if (a->cfra > b->cfra) {
+               return 1;
+       }
+
+       if (a->type < b->type) {
+               return -1;
+       }
+       if (a->type > b->type) {
+               return 1;
+       }
+
+       if (a->rectx < b->rectx) {
+               return -1;
+       }
+       if (a->rectx > b->rectx) {
+               return 1;
+       }
+
+       if (a->recty < b->recty) {
+               return -1;
+       }
+       if (a->recty > b->recty) {
+               return 1;
+       }
+
+       return 0;
+}
+
+static void HashKeyFree(void *key)
+{
+       BLI_mempool_free(keypool, key);
+}
+
+static void HashValFree(void *val)
+{
+       seqCacheEntry* e = (seqCacheEntry*) val;
+
+       if (e->ibuf) {
+               /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, 
+                  e->ibuf->refcounter); */
+               IMB_freeImBuf(e->ibuf);
+               MEM_CacheLimiter_unmanage(e->c_handle);
+               ibufs_rem++;
+       }
+
+       e->ibuf = 0;
+       e->c_handle = 0;
+
+       BLI_mempool_free(entrypool, e);
+}
+
+static void IMB_seq_cache_destructor(void * p)
+{
+       seqCacheEntry* e = (seqCacheEntry*) p;
+       
+       if (e && e->ibuf) {
+               /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
+                  e->ibuf->refcounter); */
+               IMB_freeImBuf(e->ibuf);
+               ibufs_rem++;
+
+               e->ibuf = 0;
+               e->c_handle = 0;
+       }
+}
+
+void seq_stripelem_cache_init()
+{
+       hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
+       limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor );
+
+       entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0, 0);
+       keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0, 0);
+}
+
+void seq_stripelem_cache_destruct()
+{
+       if (!entrypool) {
+               return;
+       }
+       BLI_ghash_free(hash, HashKeyFree, HashValFree);
+       delete_MEM_CacheLimiter(limitor);
+       BLI_mempool_destroy(entrypool);
+       BLI_mempool_destroy(keypool);
+}
+
+void seq_stripelem_cache_cleanup()
+{
+       if (!entrypool) {
+               seq_stripelem_cache_init();
+       }
+
+       /* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n",
+          ibufs_in, ibufs_rem); */
+
+       BLI_ghash_free(hash, HashKeyFree, HashValFree);
+       hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
+
+       /* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n",
+          ibufs_in, ibufs_rem); */
+
+}
+
+struct ImBuf * seq_stripelem_cache_get(
+       struct Sequence * seq, int rectx, int recty, 
+       float cfra, seq_stripelem_ibuf_t type)
+{
+       seqCacheKey key;
+       seqCacheEntry * e;
+
+       if (!seq) {
+               return 0;
+       }
+
+       if (!entrypool) {
+               seq_stripelem_cache_init();
+       }
+
+       key.seq = seq;
+       key.rectx = rectx;
+       key.recty = recty;
+       key.cfra = cfra - seq->start;
+       key.type = type;
+       
+       e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key);
+
+       if (e && e->ibuf) {
+               IMB_refImBuf(e->ibuf);
+
+               MEM_CacheLimiter_touch(e->c_handle);
+               return e->ibuf;
+       }
+       return 0;
+}
+
+void seq_stripelem_cache_put(
+       struct Sequence * seq, int rectx, int recty, 
+       float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i)
+{
+       seqCacheKey * key;
+       seqCacheEntry * e;
+
+       if (!i) {
+               return;
+       }
+
+       ibufs_in++;
+
+       if (!entrypool) {
+               seq_stripelem_cache_init();
+       }
+
+       key = (seqCacheKey*) BLI_mempool_alloc(keypool);
+
+       key->seq = seq;
+       key->rectx = rectx;
+       key->recty = recty;
+       key->cfra = cfra - seq->start;
+       key->type = type;
+
+       /* we want our own version */
+       IMB_refImBuf(i);
+
+       e = (seqCacheEntry*) BLI_mempool_alloc(entrypool);
+
+       e->ibuf = i;
+       e->c_handle = 0;
+
+       BLI_ghash_remove(hash, key, HashKeyFree, HashValFree);
+       BLI_ghash_insert(hash, key, e);
+
+       e->c_handle = MEM_CacheLimiter_insert(limitor, e);
+
+       MEM_CacheLimiter_ref(e->c_handle);
+       MEM_CacheLimiter_enforce_limits(limitor);
+       MEM_CacheLimiter_unref(e->c_handle);
+}
diff --git a/source/blender/python/generic/noise.c b/source/blender/python/generic/noise.c
new file mode 100755 (executable)
index 0000000..ccdb8f6
--- /dev/null
@@ -0,0 +1,760 @@
+/**
+ * $Id: noise.c 31332 2010-08-14 05:33:20Z campbellbarton $
+ *
+ * Blender.Noise BPython module implementation.
+ * This submodule has functions to generate noise of various types.
+ * 
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * This is a new part of Blender.
+ *
+ * Contributor(s): eeshlo
+ *
+ * ***** END GPL LICENSE BLOCK *****
+*/
+
+/************************/
+/* Blender Noise Module */
+/************************/
+
+#include <Python.h>
+#include "structseq.h"
+
+#include "BLI_blenlib.h"
+#include "DNA_texture_types.h"
+/*-----------------------------------------*/
+/* 'mersenne twister' random number generator */
+
+/* 
+   A C-program for MT19937, with initialization improved 2002/2/10.
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+   This is a faster version by taking Shawn Cokus's optimization,
+   Matthe Bellew's simplification, Isaku Wada's real version.
+
+   Before using, initialize the state by using init_genrand(seed) 
+   or init_by_array(init_key, key_length).
+
+   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+   All rights reserved.                          
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote 
+        products derived from this software without specific prior written 
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+   Any feedback is very welcome.
+   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+*/
+
+/* 2.5 update
+ * Noise.setRandomSeed --> seed_set
+ * Noise.randuvec --> random_unit_vector
+ * Noise.vNoise --> noise_vector
+ * Noise.vTurbulence --> turbulence_vector
+ * Noise.multiFractal --> multi_fractal
+ * Noise.cellNoise --> cell
+ * Noise.cellNoiseV --> cell_vector
+ * Noise.vlNoise --> vl_vector
+ * Noise.heteroTerrain --> hetero_terrain
+ * Noise.hybridMFractal --> hybrid_multi_fractal
+ * Noise.fBm --> fractal
+ * Noise.ridgedMFractal --> ridged_multi_fractal
+ *
+ * Const's *
+ * Noise.NoiseTypes --> types
+ * Noise.DistanceMetrics --> distance_metrics
+ */
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL  /* constant vector a */
+#define UMASK 0x80000000UL     /* most significant w-r bits */
+#define LMASK 0x7fffffffUL     /* least significant r bits */
+#define MIXBITS(u,v) (((u) & UMASK) | ((v) & LMASK))
+#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
+
+static unsigned long state[N]; /* the array for the state vector  */
+static int left = 1;
+static int initf = 0;
+static unsigned long *next;
+
+PyObject *Noise_Init(void);
+
+/* initializes state[N] with a seed */
+static void init_genrand(unsigned long s)
+{
+       int j;
+       state[0] = s & 0xffffffffUL;
+       for(j = 1; j < N; j++) {
+               state[j] =
+                       (1812433253UL *
+                         (state[j - 1] ^ (state[j - 1] >> 30)) + j);
+               /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+               /* In the previous versions, MSBs of the seed affect   */
+               /* only MSBs of the array state[].                        */
+               /* 2002/01/09 modified by Makoto Matsumoto             */
+               state[j] &= 0xffffffffUL;       /* for >32 bit machines */
+       }
+       left = 1;
+       initf = 1;
+}
+
+static void next_state(void)
+{
+       unsigned long *p = state;
+       int j;
+
+       /* if init_genrand() has not been called, */
+       /* a default initial seed is used         */
+       if(initf == 0)
+               init_genrand(5489UL);
+
+       left = N;
+       next = state;
+
+       for(j = N - M + 1; --j; p++)
+               *p = p[M] ^ TWIST(p[0], p[1]);
+
+       for(j = M; --j; p++)
+               *p = p[M - N] ^ TWIST(p[0], p[1]);
+
+       *p = p[M - N] ^ TWIST(p[0], state[0]);
+}
+
+/*------------------------------------------------------------*/
+
+static void setRndSeed(int seed)
+{
+       if(seed == 0)
+               init_genrand(time(NULL));
+       else
+               init_genrand(seed);
+}
+
+/* float number in range [0, 1) using the mersenne twister rng */
+static float frand()
+{
+       unsigned long y;
+
+       if(--left == 0)
+               next_state();
+       y = *next++;
+
+       /* Tempering */
+       y ^= (y >> 11);
+       y ^= (y << 7) & 0x9d2c5680UL;
+       y ^= (y << 15) & 0xefc60000UL;
+       y ^= (y >> 18);
+
+       return (float) y / 4294967296.f;
+}
+
+/*------------------------------------------------------------*/
+
+/* returns random unit vector */
+static void randuvec(float v[3])
+{
+       float r;
+       v[2] = 2.f * frand() - 1.f;
+       if((r = 1.f - v[2] * v[2]) > 0.f) {
+               float a = (float)(6.283185307f * frand());
+               r = (float)sqrt(r);
+               v[0] = (float)(r * cos(a));
+               v[1] = (float)(r * sin(a));
+       } else
+               v[2] = 1.f;
+}
+
+static PyObject *Noise_random(PyObject * self)
+{
+       return PyFloat_FromDouble(frand());
+}
+
+static PyObject *Noise_random_unit_vector(PyObject * self)
+{
+       float v[3] = {0.0f, 0.0f, 0.0f};
+       randuvec(v);
+       return Py_BuildValue("[fff]", v[0], v[1], v[2]);
+}
+
+/*---------------------------------------------------------------------*/
+
+/* Random seed init. Only used for MT random() & randuvec() */
+
+static PyObject *Noise_seed_set(PyObject * self, PyObject * args)
+{
+       int s;
+       if(!PyArg_ParseTuple(args, "i:seed_set", &s))
+               return NULL;
+       setRndSeed(s);
+       Py_RETURN_NONE;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* General noise */
+
+static PyObject *Noise_noise(PyObject * self, PyObject * args)
+{
+       float x, y, z;
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)|i:noise", &x, &y, &z, &nb))
+               return NULL;
+
+       return PyFloat_FromDouble((2.0 * BLI_gNoise(1.0, x, y, z, 0, nb) - 1.0));
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* General Vector noise */
+
+static void noise_vector(float x, float y, float z, int nb, float v[3])
+{
+       /* Simply evaluate noise at 3 different positions */
+       v[0] = (float)(2.0 * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0,
+                                nb) - 1.0);
+       v[1] = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0);
+       v[2] = (float)(2.0 * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0,
+                                nb) - 1.0);
+}
+
+static PyObject *Noise_vector(PyObject * self, PyObject * args)
+{
+       float x, y, z, v[3];
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)|i:vector", &x, &y, &z, &nb))
+               return NULL;
+       noise_vector(x, y, z, nb, v);
+       return Py_BuildValue("[fff]", v[0], v[1], v[2]);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* General turbulence */
+
+static float turb(float x, float y, float z, int oct, int hard, int nb,
+                  float ampscale, float freqscale)
+{
+       float amp, out, t;
+       int i;
+       amp = 1.f;
+       out = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0);
+       if(hard)
+               out = (float)fabs(out);
+       for(i = 1; i < oct; i++) {
+               amp *= ampscale;
+               x *= freqscale;
+               y *= freqscale;
+               z *= freqscale;
+               t = (float)(amp * (2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0));
+               if(hard)
+                       t = (float)fabs(t);
+               out += t;
+       }
+       return out;
+}
+
+static PyObject *Noise_turbulence(PyObject * self, PyObject * args)
+{
+       float x, y, z;
+       int oct, hd, nb = 1;
+       float as = 0.5, fs = 2.0;
+       if(!PyArg_ParseTuple(args, "(fff)ii|iff:turbulence", &x, &y, &z, &oct, &hd, &nb, &as, &fs))
+               return NULL;
+
+       return PyFloat_FromDouble(turb(x, y, z, oct, hd, nb, as, fs));
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Turbulence Vector */
+
+static void vTurb(float x, float y, float z, int oct, int hard, int nb,
+                  float ampscale, float freqscale, float v[3])
+{
+       float amp, t[3];
+       int i;
+       amp = 1.f;
+       noise_vector(x, y, z, nb, v);
+       if(hard) {
+               v[0] = (float)fabs(v[0]);
+               v[1] = (float)fabs(v[1]);
+               v[2] = (float)fabs(v[2]);
+       }
+       for(i = 1; i < oct; i++) {
+               amp *= ampscale;
+               x *= freqscale;
+               y *= freqscale;
+               z *= freqscale;
+               noise_vector(x, y, z, nb, t);
+               if(hard) {
+                       t[0] = (float)fabs(t[0]);
+                       t[1] = (float)fabs(t[1]);
+                       t[2] = (float)fabs(t[2]);
+               }
+               v[0] += amp * t[0];
+               v[1] += amp * t[1];
+               v[2] += amp * t[2];
+       }
+}
+
+static PyObject *Noise_turbulence_vector(PyObject * self, PyObject * args)
+{
+       float x, y, z, v[3];
+       int oct, hd, nb = 1;
+       float as = 0.5, fs = 2.0;
+       if(!PyArg_ParseTuple(args, "(fff)ii|iff:turbulence_vector", &x, &y, &z, &oct, &hd, &nb, &as, &fs))
+               return NULL;
+       vTurb(x, y, z, oct, hd, nb, as, fs, v);
+       return Py_BuildValue("[fff]", v[0], v[1], v[2]);
+}
+
+/*---------------------------------------------------------------------*/
+
+/* F. Kenton Musgrave's fractal functions */
+
+static PyObject *Noise_fractal(PyObject * self, PyObject * args)
+{
+       float x, y, z, H, lac, oct;
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)fff|i:fractal", &x, &y, &z, &H, &lac, &oct, &nb))
+               return NULL;
+       return PyFloat_FromDouble(mg_fBm(x, y, z, H, lac, oct, nb));
+}
+
+/*------------------------------------------------------------------------*/
+
+static PyObject *Noise_multi_fractal(PyObject * self, PyObject * args)
+{
+       float x, y, z, H, lac, oct;
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)fff|i:multi_fractal", &x, &y, &z, &H, &lac, &oct, &nb))
+               return NULL;
+
+       return PyFloat_FromDouble(mg_MultiFractal(x, y, z, H, lac, oct, nb));
+}
+
+/*------------------------------------------------------------------------*/
+
+static PyObject *Noise_vl_vector(PyObject * self, PyObject * args)
+{
+       float x, y, z, d;
+       int nt1 = 1, nt2 = 1;
+       if(!PyArg_ParseTuple(args, "(fff)f|ii:vl_vector", &x, &y, &z, &d, &nt1, &nt2))
+               return NULL;
+       return PyFloat_FromDouble(mg_VLNoise(x, y, z, d, nt1, nt2));
+}
+
+/*-------------------------------------------------------------------------*/
+
+static PyObject *Noise_hetero_terrain(PyObject * self, PyObject * args)
+{
+       float x, y, z, H, lac, oct, ofs;
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)ffff|i:hetero_terrain", &x, &y, &z, &H, &lac, &oct, &ofs, &nb))
+               return NULL;
+
+       return PyFloat_FromDouble(mg_HeteroTerrain(x, y, z, H, lac, oct, ofs, nb));
+}
+
+/*-------------------------------------------------------------------------*/
+
+static PyObject *Noise_hybrid_multi_fractal(PyObject * self, PyObject * args)
+{
+       float x, y, z, H, lac, oct, ofs, gn;
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)fffff|i:hybrid_multi_fractal", &x, &y, &z, &H, &lac, &oct, &ofs, &gn, &nb))
+               return NULL;
+       
+       return PyFloat_FromDouble(mg_HybridMultiFractal(x, y, z, H, lac, oct, ofs, gn, nb));
+}
+
+/*------------------------------------------------------------------------*/
+
+static PyObject *Noise_ridged_multi_fractal(PyObject * self, PyObject * args)
+{
+       float x, y, z, H, lac, oct, ofs, gn;
+       int nb = 1;
+       if(!PyArg_ParseTuple(args, "(fff)fffff|i:ridged_multi_fractal", &x, &y, &z, &H, &lac, &oct, &ofs, &gn, &nb))
+               return NULL;
+       return PyFloat_FromDouble(mg_RidgedMultiFractal(x, y, z, H, lac, oct, ofs, gn, nb));
+}
+
+/*-------------------------------------------------------------------------*/
+
+static PyObject *Noise_voronoi(PyObject * self, PyObject * args)
+{
+       float x, y, z, da[4], pa[12];
+       int dtype = 0;
+       float me = 2.5;         /* default minkovsky exponent */
+       if(!PyArg_ParseTuple(args, "(fff)|if:voronoi", &x, &y, &z, &dtype, &me))
+               return NULL;
+       voronoi(x, y, z, da, pa, me, dtype);
+       return Py_BuildValue("[[ffff][[fff][fff][fff][fff]]]",
+                             da[0], da[1], da[2], da[3],
+                             pa[0], pa[1], pa[2],
+                             pa[3], pa[4], pa[5],
+                             pa[6], pa[7], pa[8], pa[9], pa[10], pa[11]);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static PyObject *Noise_cell(PyObject * self, PyObject * args)
+{
+       float x, y, z;
+       if(!PyArg_ParseTuple(args, "(fff):cell", &x, &y, &z))
+               return NULL;
+
+       return PyFloat_FromDouble(cellNoise(x, y, z));
+}
+
+/*--------------------------------------------------------------------------*/
+
+static PyObject *Noise_cell_vector(PyObject * self, PyObject * args)
+{
+       float x, y, z, ca[3];
+       if(!PyArg_ParseTuple(args, "(fff):cell_vector", &x, &y, &z))
+               return NULL;
+       cellNoiseV(x, y, z, ca);
+       return Py_BuildValue("[fff]", ca[0], ca[1], ca[2]);
+}
+
+/*--------------------------------------------------------------------------*/
+/* For all other Blender modules, this stuff seems to be put in a header file.
+   This doesn't seem really appropriate to me, so I just put it here, feel free to change it.
+   In the original module I actually kept the docs stings with the functions themselves,
+   but I grouped them here so that it can easily be moved to a header if anyone thinks that is necessary. */
+
+static char random__doc__[] = "() No arguments.\n\n\
+Returns a random floating point number in the range [0, 1)";
+
+static char random_unit_vector__doc__[] =
+       "() No arguments.\n\nReturns a random unit vector (3-float list).";
+
+static char seed_set__doc__[] = "(seed value)\n\n\
+Initializes random number generator.\n\
+if seed is zero, the current time will be used instead.";
+
+static char noise__doc__[] = "((x,y,z) tuple, [noisetype])\n\n\
+Returns general noise of the optional specified type.\n\
+Optional argument noisetype determines the type of noise, STDPERLIN by default, see NoiseTypes.";
+
+static char noise_vector__doc__[] = "((x,y,z) tuple, [noisetype])\n\n\
+Returns noise vector (3-float list) of the optional specified type.\
+Optional argument noisetype determines the type of noise, STDPERLIN by default, see NoiseTypes.";
+
+static char turbulence__doc__[] =
+       "((x,y,z) tuple, octaves, hard, [noisebasis], [ampscale], [freqscale])\n\n\
+Returns general turbulence value using the optional specified noisebasis function.\n\
+octaves (integer) is the number of noise values added.\n\
+hard (bool), when false (0) returns 'soft' noise, when true (1) returns 'hard' noise (returned value always positive).\n\
+Optional arguments:\n\
+noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.\n\
+ampscale sets the amplitude scale value of the noise frequencies added, 0.5 by default.\n\
+freqscale sets the frequency scale factor, 2.0 by default.";
+
+static char turbulence_vector__doc__[] =
+       "((x,y,z) tuple, octaves, hard, [noisebasis], [ampscale], [freqscale])\n\n\
+Returns general turbulence vector (3-float list) using the optional specified noisebasis function.\n\
+octaves (integer) is the number of noise values added.\n\
+hard (bool), when false (0) returns 'soft' noise, when true (1) returns 'hard' noise (returned vector always positive).\n\
+Optional arguments:\n\
+noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.\n\
+ampscale sets the amplitude scale value of the noise frequencies added, 0.5 by default.\n\
+freqscale sets the frequency scale factor, 2.0 by default.";
+
+static char fractal__doc__[] =
+       "((x,y,z) tuple, H, lacunarity, octaves, [noisebasis])\n\n\
+Returns Fractal Brownian Motion noise value(fBm).\n\
+H is the fractal increment parameter.\n\
+lacunarity is the gap between successive frequencies.\n\
+octaves is the number of frequencies in the fBm.\n\
+Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
+
+static char multi_fractal__doc__[] =
+       "((x,y,z) tuple, H, lacunarity, octaves, [noisebasis])\n\n\
+Returns Multifractal noise value.\n\
+H determines the highest fractal dimension.\n\
+lacunarity is gap between successive frequencies.\n\
+octaves is the number of frequencies in the fBm.\n\
+Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
+
+static char vl_vector__doc__[] =
+       "((x,y,z) tuple, distortion, [noisetype1], [noisetype2])\n\n\
+Returns Variable Lacunarity Noise value, a distorted variety of noise.\n\
+distortion sets the amount of distortion.\n\
+Optional arguments noisetype1 and noisetype2 set the noisetype to distort and the noisetype used for the distortion respectively.\n\
+See NoiseTypes, both are STDPERLIN by default.";
+
+static char hetero_terrain__doc__[] =
+       "((x,y,z) tuple, H, lacunarity, octaves, offset, [noisebasis])\n\n\
+returns Heterogeneous Terrain value\n\
+H determines the fractal dimension of the roughest areas.\n\
+lacunarity is the gap between successive frequencies.\n\
+octaves is the number of frequencies in the fBm.\n\
+offset raises the terrain from 'sea level'.\n\
+Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
+
+static char hybrid_multi_fractal__doc__[] =
+       "((x,y,z) tuple, H, lacunarity, octaves, offset, gain, [noisebasis])\n\n\
+returns Hybrid Multifractal value.\n\
+H determines the fractal dimension of the roughest areas.\n\
+lacunarity is the gap between successive frequencies.\n\
+octaves is the number of frequencies in the fBm.\n\
+offset raises the terrain from 'sea level'.\n\
+gain scales the values.\n\
+Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
+
+static char ridged_multi_fractal__doc__[] =
+       "((x,y,z) tuple, H, lacunarity, octaves, offset, gain [noisebasis])\n\n\
+returns Ridged Multifractal value.\n\
+H determines the fractal dimension of the roughest areas.\n\
+lacunarity is the gap between successive frequencies.\n\
+octaves is the number of frequencies in the fBm.\n\
+offset raises the terrain from 'sea level'.\n\
+gain scales the values.\n\
+Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
+
+static char voronoi__doc__[] =
+       "((x,y,z) tuple, distance_metric, [exponent])\n\n\
+returns a list, containing a list of distances in order of closest feature,\n\
+and a list containing the positions of the four closest features\n\
+Optional arguments:\n\
+distance_metric: see DistanceMetrics, default is DISTANCE\n\
+exponent is only used with MINKOVSKY, default is 2.5.";
+
+static char cell__doc__[] = "((x,y,z) tuple)\n\n\
+returns cellnoise float value.";
+
+static char cell_vector__doc__[] = "((x,y,z) tuple)\n\n\
+returns cellnoise vector/point/color (3-float list).";
+
+static char Noise__doc__[] = "Blender Noise and Turbulence Module\n\n\
+This module can be used to generate noise of various types.\n\
+This can be used for terrain generation, to create textures,\n\
+make animations more 'animated', object deformation, etc.\n\
+As an example, this code segment when scriptlinked to a framechanged event,\n\
+will make the camera sway randomly about, by changing parameters this can\n\
+look like anything from an earthquake to a very nervous or maybe even drunk cameraman...\n\
+(the camera needs an ipo with at least one Loc & Rot key for this to work!):\n\
+\n\
+\tfrom Blender import Get, Scene, Noise\n\
+\n\
+\t####################################################\n\
+\t# This controls jitter speed\n\
+\tsl = 0.025\n\
+\t# This controls the amount of position jitter\n\
+\tsp = 0.1\n\
+\t# This controls the amount of rotation jitter\n\
+\tsr = 0.25\n\
+\t####################################################\n\
+\n\
+\ttime = Get('curtime')\n\
+\tob = Scene.GetCurrent().getCurrentCamera()\n\
+\tps = (sl*time, sl*time, sl*time)\n\
+\t# To add jitter only when the camera moves, use this next line instead\n\
+\t#ps = (sl*ob.LocX, sl*ob.LocY, sl*ob.LocZ)\n\
+\trv = Noise.turbulence_vector(ps, 3, 0, Noise.NoiseTypes.NEWPERLIN)\n\
+\tob.dloc = (sp*rv[0], sp*rv[1], sp*rv[2])\n\
+\tob.drot = (sr*rv[0], sr*rv[1], sr*rv[2])\n\
+\n";
+
+/* Just in case, declarations for a header file */
+/*
+static PyObject *Noise_random(PyObject *self);
+static PyObject *Noise_random_unit_vector(PyObject *self);
+static PyObject *Noise_seed_set(PyObject *self, PyObject *args);
+static PyObject *Noise_noise(PyObject *self, PyObject *args);
+static PyObject *Noise_vector(PyObject *self, PyObject *args);
+static PyObject *Noise_turbulence(PyObject *self, PyObject *args);
+static PyObject *Noise_turbulence_vector(PyObject *self, PyObject *args);
+static PyObject *Noise_fractal(PyObject *self, PyObject *args);
+static PyObject *Noise_multi_fractal(PyObject *self, PyObject *args);
+static PyObject *Noise_vl_vector(PyObject *self, PyObject *args);
+static PyObject *Noise_hetero_terrain(PyObject *self, PyObject *args);
+static PyObject *Noise_hybrid_multi_fractal(PyObject *self, PyObject *args);
+static PyObject *Noise_ridged_multi_fractal(PyObject *self, PyObject *args);
+static PyObject *Noise_voronoi(PyObject *self, PyObject *args);
+static PyObject *Noise_cell(PyObject *self, PyObject *args);
+static PyObject *Noise_cell_vector(PyObject *self, PyObject *args);
+*/
+
+static PyMethodDef NoiseMethods[] = {
+       {"seed_set", (PyCFunction) Noise_seed_set, METH_VARARGS, seed_set__doc__},
+       {"random", (PyCFunction) Noise_random, METH_NOARGS, random__doc__},
+       {"random_unit_vector", (PyCFunction) Noise_random_unit_vector, METH_NOARGS, random_unit_vector__doc__},
+       {"noise", (PyCFunction) Noise_noise, METH_VARARGS, noise__doc__},
+       {"vector", (PyCFunction) Noise_vector, METH_VARARGS, noise_vector__doc__},
+       {"turbulence", (PyCFunction) Noise_turbulence, METH_VARARGS, turbulence__doc__},
+       {"turbulence_vector", (PyCFunction) Noise_turbulence_vector, METH_VARARGS, turbulence_vector__doc__},
+       {"fractal", (PyCFunction) Noise_fractal, METH_VARARGS, fractal__doc__},
+       {"multi_fractal", (PyCFunction) Noise_multi_fractal, METH_VARARGS, multi_fractal__doc__},
+       {"vl_vector", (PyCFunction) Noise_vl_vector, METH_VARARGS, vl_vector__doc__},
+       {"hetero_terrain", (PyCFunction) Noise_hetero_terrain, METH_VARARGS, hetero_terrain__doc__},
+       {"hybrid_multi_fractal", (PyCFunction) Noise_hybrid_multi_fractal, METH_VARARGS, hybrid_multi_fractal__doc__},
+       {"ridged_multi_fractal", (PyCFunction) Noise_ridged_multi_fractal, METH_VARARGS, ridged_multi_fractal__doc__},
+       {"voronoi", (PyCFunction) Noise_voronoi, METH_VARARGS, voronoi__doc__},
+       {"cell", (PyCFunction) Noise_cell, METH_VARARGS, cell__doc__},
+       {"cell_vector", (PyCFunction) Noise_cell_vector, METH_VARARGS, cell_vector__doc__},
+       {NULL, NULL, 0, NULL}
+};
+
+/*----------------------------------------------------------------------*/
+
+static struct PyModuleDef noise_module_def = {
+       PyModuleDef_HEAD_INIT,
+       "noise",  /* m_name */
+       Noise__doc__,  /* m_doc */
+       0,  /* m_size */
+       NoiseMethods,  /* m_methods */
+       0,  /* m_reload */
+       0,  /* m_traverse */
+       0,  /* m_clear */
+       0,  /* m_free */
+};
+
+PyObject *Noise_Init(void)
+{
+       PyObject *submodule = PyModule_Create(&noise_module_def);
+       PyDict_SetItemString(PyImport_GetModuleDict(), noise_module_def.m_name, submodule);
+
+       /* use current time as seed for random number generator by default */
+       setRndSeed(0);  
+
+       /* Constant noisetype dictionary */
+       if(submodule) {
+               static PyStructSequence_Field noise_types_fields[] = {
+                       {"BLENDER", ""},
+                       {"STDPERLIN", ""},
+                       {"NEWPERLIN", ""},
+                       {"VORONOI_F1", ""},
+                       {"VORONOI_F2", ""},
+                       {"VORONOI_F3", ""},
+                       {"VORONOI_F4", ""},
+                       {"VORONOI_F2F1", ""},
+                       {"VORONOI_CRACKLE", ""},
+                       {"CELLNOISE", ""},
+                       {0}
+               };
+
+               static PyStructSequence_Desc noise_types_info_desc = {
+                       "noise.types",     /* name */
+                       "Noise type",    /* doc */
+                       noise_types_fields,    /* fields */
+                       (sizeof(noise_types_fields)/sizeof(PyStructSequence_Field)) - 1
+               };
+
+               static PyTypeObject NoiseType;
+
+               PyObject *noise_types;
+               
+               int pos = 0;
+               
+               PyStructSequence_InitType(&NoiseType, &noise_types_info_desc);
+       
+               noise_types = PyStructSequence_New(&NoiseType);
+               if (noise_types == NULL) {
+                       return NULL;
+               }
+
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_BLENDER));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_STDPERLIN));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_NEWPERLIN));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F1));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F2));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F3));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F4));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F2F1));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_CRACKLE));
+               PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_CELLNOISE));
+
+               PyModule_AddObject(submodule, "types", noise_types);
+       }
+       
+       if(submodule) {
+               static PyStructSequence_Field distance_metrics_fields[] = {
+                       {"DISTANCE", ""},
+                       {"DISTANCE_SQUARED", ""},
+                       {"MANHATTAN", ""},
+                       {"CHEBYCHEV", ""},
+                       {"MINKOVSKY_HALF", ""},
+                       {"MINKOVSKY_FOUR", ""},
+                       {"MINKOVSKY", ""},
+                       {0}
+               };
+
+               static PyStructSequence_Desc noise_types_info_desc = {
+                       "noise.distance_metrics",     /* name */
+                       "Distance Metrics for noise module.",    /* doc */
+                       distance_metrics_fields,    /* fields */
+                       (sizeof(distance_metrics_fields)/sizeof(PyStructSequence_Field)) - 1
+               };
+               
+               static PyTypeObject DistanceMetrics;
+               
+               PyObject *distance_metrics;
+               
+               int pos = 0;
+               
+               PyStructSequence_InitType(&DistanceMetrics, &noise_types_info_desc);
+       
+               distance_metrics = PyStructSequence_New(&DistanceMetrics);
+               if (distance_metrics == NULL) {
+                       return NULL;
+               }
+
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_DISTANCE));
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_DISTANCE_SQUARED));
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MANHATTAN));
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_CHEBYCHEV));
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY_HALF));
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY_FOUR));
+               PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY));
+
+               PyModule_AddObject(submodule, "distance_metrics", distance_metrics);
+       }
+
+       return submodule;
+}