Merge branch 'blender2.7'
[blender.git] / source / blender / python / mathutils / mathutils_noise.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): eeshlo, Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/mathutils/mathutils_noise.c
24  *  \ingroup mathutils
25  *
26  * This file defines the 'noise' module, a general purpose module to access
27  * blenders noise functions.
28  */
29
30
31 /************************/
32 /* Blender Noise Module */
33 /************************/
34
35 #include <Python.h>
36
37 #include "BLI_math.h"
38 #include "BLI_noise.h"
39 #include "BLI_utildefines.h"
40
41 #include "DNA_texture_types.h"
42
43 #include "../generic/py_capi_utils.h"
44
45 #include "mathutils.h"
46 #include "mathutils_noise.h"
47
48 /*-----------------------------------------*/
49 /* 'mersenne twister' random number generator */
50
51 /*
52  * A C-program for MT19937, with initialization improved 2002/2/10.
53  * Coded by Takuji Nishimura and Makoto Matsumoto.
54  * This is a faster version by taking Shawn Cokus's optimization,
55  * Matthe Bellew's simplification, Isaku Wada's real version.
56  *
57  * Before using, initialize the state by using init_genrand(seed)
58  * or init_by_array(init_key, key_length).
59  *
60  * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
61  * All rights reserved.
62  *
63  * Redistribution and use in source and binary forms, with or without
64  * modification, are permitted provided that the following conditions
65  * are met:
66  *
67  *   1. Redistributions of source code must retain the above copyright
68  *      notice, this list of conditions and the following disclaimer.
69  *
70  *   2. Redistributions in binary form must reproduce the above copyright
71  *      notice, this list of conditions and the following disclaimer in the
72  *      documentation and/or other materials provided with the distribution.
73  *
74  *   3. The names of its contributors may not be used to endorse or promote
75  *      products derived from this software without specific prior written
76  *      permission.
77  *
78  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
79  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
80  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
81  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
82  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
83  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
84  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
85  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
86  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
87  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89  *
90  *
91  * Any feedback is very welcome.
92  * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
93  * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
94  */
95
96 /* Period parameters */
97 #define N 624
98 #define M 397
99 #define MATRIX_A 0x9908b0dfUL   /* constant vector a */
100 #define UMASK 0x80000000UL  /* most significant w-r bits */
101 #define LMASK 0x7fffffffUL  /* least significant r bits */
102 #define MIXBITS(u, v) (((u) & UMASK) | ((v) & LMASK))
103 #define TWIST(u, v) ((MIXBITS(u, v) >> 1) ^ ((v) & 1UL ? MATRIX_A : 0UL))
104
105 static unsigned long state[N];  /* the array for the state vector  */
106 static int left = 1;
107 static int initf = 0;
108 static unsigned long *next;
109 static float state_offset_vector[3 * 3];
110
111 /* initializes state[N] with a seed */
112 static void init_genrand(unsigned long s)
113 {
114         int j;
115         state[0] = s & 0xffffffffUL;
116         for (j = 1; j < N; j++) {
117                 state[j] =
118                     (1812433253UL *
119                      (state[j - 1] ^ (state[j - 1] >> 30)) + j);
120                 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
121                 /* In the previous versions, MSBs of the seed affect   */
122                 /* only MSBs of the array state[].                        */
123                 /* 2002/01/09 modified by Makoto Matsumoto             */
124                 state[j] &= 0xffffffffUL;   /* for >32 bit machines */
125         }
126         left = 1;
127         initf = 1;
128
129         /* update vector offset */
130         {
131                 const unsigned long *state_offset = &state[N - ARRAY_SIZE(state_offset_vector)];
132                 const float range = 32;  /* range in both pos/neg direction */
133                 for (j = 0; j < ARRAY_SIZE(state_offset_vector); j++, state_offset++) {
134                         /* overflow is fine here */
135                         state_offset_vector[j] = (float)(int)(*state_offset) * (1.0f / (INT_MAX / range));
136                 }
137         }
138 }
139
140 static void next_state(void)
141 {
142         unsigned long *p = state;
143         int j;
144
145         /* if init_genrand() has not been called, */
146         /* a default initial seed is used         */
147         if (initf == 0)
148                 init_genrand(5489UL);
149
150         left = N;
151         next = state;
152
153         for (j = N - M + 1; --j; p++)
154                 *p = p[M] ^ TWIST(p[0], p[1]);
155
156         for (j = M; --j; p++)
157                 *p = p[M - N] ^ TWIST(p[0], p[1]);
158
159         *p = p[M - N] ^ TWIST(p[0], state[0]);
160 }
161
162 /*------------------------------------------------------------*/
163
164 static void setRndSeed(int seed)
165 {
166         if (seed == 0)
167                 init_genrand(time(NULL));
168         else
169                 init_genrand(seed);
170 }
171
172 /* float number in range [0, 1) using the mersenne twister rng */
173 static float frand(void)
174 {
175         unsigned long y;
176
177         if (--left == 0)
178                 next_state();
179         y = *next++;
180
181         /* Tempering */
182         y ^= (y >> 11);
183         y ^= (y << 7) & 0x9d2c5680UL;
184         y ^= (y << 15) & 0xefc60000UL;
185         y ^= (y >> 18);
186
187         return (float) y / 4294967296.f;
188 }
189
190 /*------------------------------------------------------------*/
191 /* Utility Functions */
192 /*------------------------------------------------------------*/
193
194 #define BPY_NOISE_BASIS_ENUM_DOC \
195 "   :arg noise_basis: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', 'VORONOI_F1', 'VORONOI_F2', " \
196                                                                         "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
197                                                                         "'CELLNOISE'].\n" \
198 "   :type noise_basis: string\n" \
199
200 #define BPY_NOISE_METRIC_ENUM_DOC \
201 "   :arg distance_metric: Enumerator in ['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', 'CHEBYCHEV', " \
202                                                                                 "'MINKOVSKY', 'MINKOVSKY_HALF', 'MINKOVSKY_FOUR'].\n" \
203 "   :type distance_metric: string\n" \
204
205 /* Noise basis enum */
206 #define DEFAULT_NOISE_TYPE TEX_STDPERLIN
207
208 static PyC_FlagSet bpy_noise_types[] = {
209         {TEX_BLENDER,         "BLENDER"},
210         {TEX_STDPERLIN,       "PERLIN_ORIGINAL"},
211         {TEX_NEWPERLIN,       "PERLIN_NEW"},
212         {TEX_VORONOI_F1,      "VORONOI_F1"},
213         {TEX_VORONOI_F2,      "VORONOI_F2"},
214         {TEX_VORONOI_F3,      "VORONOI_F3"},
215         {TEX_VORONOI_F4,      "VORONOI_F4"},
216         {TEX_VORONOI_F2F1,    "VORONOI_F2F1"},
217         {TEX_VORONOI_CRACKLE, "VORONOI_CRACKLE"},
218         {TEX_CELLNOISE,       "CELLNOISE"},
219         {0, NULL},
220 };
221
222 /* Metric basis enum */
223 #define DEFAULT_METRIC_TYPE TEX_DISTANCE
224
225 static PyC_FlagSet bpy_noise_metrics[] = {
226         {TEX_DISTANCE,         "DISTANCE"},
227         {TEX_DISTANCE_SQUARED, "DISTANCE_SQUARED"},
228         {TEX_MANHATTAN,        "MANHATTAN"},
229         {TEX_CHEBYCHEV,        "CHEBYCHEV"},
230         {TEX_MINKOVSKY,        "MINKOVSKY"},
231         {TEX_MINKOVSKY_HALF,   "MINKOVSKY_HALF"},
232         {TEX_MINKOVSKY_FOUR,   "MINKOVSKY_FOUR"},
233         {0, NULL},
234 };
235
236 /* Fills an array of length size with random numbers in the range (-1, 1)*/
237 static void rand_vn(float *array_tar, const int size)
238 {
239         float *array_pt = array_tar + (size - 1);
240         int i = size;
241         while (i--) { *(array_pt--) = 2.0f * frand() - 1.0f; }
242 }
243
244 /* Fills an array of length 3 with noise values */
245 static void noise_vector(float x, float y, float z, int nb, float v[3])
246 {
247         /* Simply evaluate noise at 3 different positions */
248         const float *ofs = state_offset_vector;
249         for (int j = 0; j < 3; j++) {
250                 v[j] = (2.0f * BLI_gNoise(1.0f, x + ofs[0], y + ofs[1], z + ofs[2], 0, nb) - 1.0f);
251                 ofs += 3;
252         }
253 }
254
255 /* Returns a turbulence value for a given position (x, y, z) */
256 static float turb(
257         float x, float y, float z, int oct, int hard, int nb,
258         float ampscale, float freqscale)
259 {
260         float amp, out, t;
261         int i;
262         amp = 1.f;
263         out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
264         if (hard)
265                 out = fabsf(out);
266         for (i = 1; i < oct; i++) {
267                 amp *= ampscale;
268                 x *= freqscale;
269                 y *= freqscale;
270                 z *= freqscale;
271                 t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f));
272                 if (hard)
273                         t = fabsf(t);
274                 out += t;
275         }
276         return out;
277 }
278
279 /* Fills an array of length 3 with the turbulence vector for a given
280  * position (x, y, z) */
281 static void vTurb(
282         float x, float y, float z, int oct, int hard, int nb,
283         float ampscale, float freqscale, float v[3])
284 {
285         float amp, t[3];
286         int i;
287         amp = 1.f;
288         noise_vector(x, y, z, nb, v);
289         if (hard) {
290                 v[0] = fabsf(v[0]);
291                 v[1] = fabsf(v[1]);
292                 v[2] = fabsf(v[2]);
293         }
294         for (i = 1; i < oct; i++) {
295                 amp *= ampscale;
296                 x *= freqscale;
297                 y *= freqscale;
298                 z *= freqscale;
299                 noise_vector(x, y, z, nb, t);
300                 if (hard) {
301                         t[0] = fabsf(t[0]);
302                         t[1] = fabsf(t[1]);
303                         t[2] = fabsf(t[2]);
304                 }
305                 v[0] += amp * t[0];
306                 v[1] += amp * t[1];
307                 v[2] += amp * t[2];
308         }
309 }
310
311 /*-------------------------DOC STRINGS ---------------------------*/
312 PyDoc_STRVAR(M_Noise_doc,
313 "The Blender noise module"
314 );
315
316 /*------------------------------------------------------------*/
317 /* Python Functions */
318 /*------------------------------------------------------------*/
319
320 PyDoc_STRVAR(M_Noise_random_doc,
321 ".. function:: random()\n"
322 "\n"
323 "   Returns a random number in the range [0, 1).\n"
324 "\n"
325 "   :return: The random number.\n"
326 "   :rtype: float\n"
327 );
328 static PyObject *M_Noise_random(PyObject *UNUSED(self))
329 {
330         return PyFloat_FromDouble(frand());
331 }
332
333 PyDoc_STRVAR(M_Noise_random_unit_vector_doc,
334 ".. function:: random_unit_vector(size=3)\n"
335 "\n"
336 "   Returns a unit vector with random entries.\n"
337 "\n"
338 "   :arg size: The size of the vector to be produced, in the range [2, 4].\n"
339 "   :type size: int\n"
340 "   :return: The random unit vector.\n"
341 "   :rtype: :class:`mathutils.Vector`\n"
342 );
343 static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
344 {
345         static const char *kwlist[] = {"size", NULL};
346         float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
347         float norm = 2.0f;
348         int size = 3;
349
350         if (!PyArg_ParseTupleAndKeywords(
351                     args, kw, "|$i:random_unit_vector", (char **)kwlist,
352                     &size))
353         {
354                 return NULL;
355         }
356
357         if (size > 4 || size < 2) {
358                 PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
359                 return NULL;
360         }
361
362         while (norm == 0.0f || norm > 1.0f) {
363                 rand_vn(vec, size);
364                 norm = normalize_vn(vec, size);
365         }
366
367         return Vector_CreatePyObject(vec, size, NULL);
368 }
369
370 PyDoc_STRVAR(M_Noise_random_vector_doc,
371 ".. function:: random_vector(size=3)\n"
372 "\n"
373 "   Returns a vector with random entries in the range (-1, 1).\n"
374 "\n"
375 "   :arg size: The size of the vector to be produced.\n"
376 "   :type size: int\n"
377 "   :return: The random vector.\n"
378 "   :rtype: :class:`mathutils.Vector`\n"
379 );
380 static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
381 {
382         static const char *kwlist[] = {"size", NULL};
383         float *vec = NULL;
384         int size = 3;
385
386         if (!PyArg_ParseTupleAndKeywords(
387                     args, kw, "|$i:random_vector", (char **)kwlist,
388                     &size))
389         {
390                 return NULL;
391         }
392
393         if (size < 2) {
394                 PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
395                 return NULL;
396         }
397
398         vec = PyMem_New(float, size);
399
400         rand_vn(vec, size);
401
402         return Vector_CreatePyObject_alloc(vec, size, NULL);
403 }
404
405 PyDoc_STRVAR(M_Noise_seed_set_doc,
406 ".. function:: seed_set(seed)\n"
407 "\n"
408 "   Sets the random seed used for random_unit_vector, and random.\n"
409 "\n"
410 "   :arg seed: Seed used for the random generator.\n"
411 "      When seed is zero, the current time will be used instead.\n"
412 "   :type seed: int\n"
413 );
414 static PyObject *M_Noise_seed_set(PyObject *UNUSED(self), PyObject *args)
415 {
416         int s;
417         if (!PyArg_ParseTuple(args, "i:seed_set", &s))
418                 return NULL;
419         setRndSeed(s);
420         Py_RETURN_NONE;
421 }
422
423 PyDoc_STRVAR(M_Noise_noise_doc,
424 ".. function:: noise(position, noise_basis='PERLIN_ORIGINAL')\n"
425 "\n"
426 "   Returns noise value from the noise basis at the position specified.\n"
427 "\n"
428 "   :arg position: The position to evaluate the selected noise function.\n"
429 "   :type position: :class:`mathutils.Vector`\n"
430 BPY_NOISE_BASIS_ENUM_DOC
431 "   :return: The noise value.\n"
432 "   :rtype: float\n"
433 );
434 static PyObject *M_Noise_noise(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
435 {
436         static const char *kwlist[] = {"", "noise_basis", NULL};
437         PyObject *value;
438         float vec[3];
439         const char *noise_basis_str = NULL;
440         int noise_basis_enum = DEFAULT_NOISE_TYPE;
441
442         if (!PyArg_ParseTupleAndKeywords(
443                     args, kw, "O|$s:noise", (char **)kwlist,
444                     &value, &noise_basis_str))
445         {
446                 return NULL;
447         }
448
449         if (!noise_basis_str) {
450                 /* pass through */
451         }
452         else if (PyC_FlagSet_ValueFromID(
453                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "noise") == -1)
454         {
455                 return NULL;
456         }
457
458         if (mathutils_array_parse(vec, 3, 3, value, "noise: invalid 'position' arg") == -1)
459                 return NULL;
460
461         return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, vec[0], vec[1], vec[2], 0, noise_basis_enum) - 1.0f));
462 }
463
464 PyDoc_STRVAR(M_Noise_noise_vector_doc,
465 ".. function:: noise_vector(position, noise_basis='PERLIN_ORIGINAL')\n"
466 "\n"
467 "   Returns the noise vector from the noise basis at the specified position.\n"
468 "\n"
469 "   :arg position: The position to evaluate the selected noise function.\n"
470 "   :type position: :class:`mathutils.Vector`\n"
471 BPY_NOISE_BASIS_ENUM_DOC
472 "   :return: The noise vector.\n"
473 "   :rtype: :class:`mathutils.Vector`\n"
474 );
475 static PyObject *M_Noise_noise_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
476 {
477         static const char *kwlist[] = {"", "noise_basis", NULL};
478         PyObject *value;
479         float vec[3], r_vec[3];
480         const char *noise_basis_str = NULL;
481         int noise_basis_enum = DEFAULT_NOISE_TYPE;
482
483         if (!PyArg_ParseTupleAndKeywords(
484                     args, kw, "O|$s:noise_vector", (char **)kwlist,
485                     &value, &noise_basis_str))
486         {
487                 return NULL;
488         }
489
490         if (!noise_basis_str) {
491                 /* pass through */
492         }
493         else if (PyC_FlagSet_ValueFromID(
494                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "noise_vector") == -1)
495         {
496                 return NULL;
497         }
498
499         if (mathutils_array_parse(vec, 3, 3, value, "noise_vector: invalid 'position' arg") == -1)
500                 return NULL;
501
502         noise_vector(vec[0], vec[1], vec[2], noise_basis_enum, r_vec);
503
504         return Vector_CreatePyObject(r_vec, 3, NULL);
505 }
506
507 PyDoc_STRVAR(M_Noise_turbulence_doc,
508 ".. function:: turbulence(position, octaves, hard, noise_basis='PERLIN_ORIGINAL', amplitude_scale=0.5, frequency_scale=2.0)\n"
509 "\n"
510 "   Returns the turbulence value from the noise basis at the specified position.\n"
511 "\n"
512 "   :arg position: The position to evaluate the selected noise function.\n"
513 "   :type position: :class:`mathutils.Vector`\n"
514 "   :arg octaves: The number of different noise frequencies used.\n"
515 "   :type octaves: int\n"
516 "   :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
517 "   :type hard: boolean\n"
518 BPY_NOISE_BASIS_ENUM_DOC
519 "   :arg amplitude_scale: The amplitude scaling factor.\n"
520 "   :type amplitude_scale: float\n"
521 "   :arg frequency_scale: The frequency scaling factor\n"
522 "   :type frequency_scale: float\n"
523 "   :return: The turbulence value.\n"
524 "   :rtype: float\n"
525 );
526 static PyObject *M_Noise_turbulence(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
527 {
528         static const char *kwlist[] = {"", "", "", "noise_basis", "amplitude_scale", "frequency_scale", NULL};
529         PyObject *value;
530         float vec[3];
531         const char *noise_basis_str = NULL;
532         int oct, hd, noise_basis_enum = DEFAULT_NOISE_TYPE;
533         float as = 0.5f, fs = 2.0f;
534
535         if (!PyArg_ParseTupleAndKeywords(
536                     args, kw, "Oii|$sff:turbulence", (char **)kwlist,
537                     &value, &oct, &hd, &noise_basis_str, &as, &fs))
538         {
539                 return NULL;
540         }
541
542         if (!noise_basis_str) {
543                 /* pass through */
544         }
545         else if (PyC_FlagSet_ValueFromID(
546                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "turbulence") == -1)
547         {
548                 return NULL;
549         }
550
551         if (mathutils_array_parse(vec, 3, 3, value, "turbulence: invalid 'position' arg") == -1)
552                 return NULL;
553
554         return PyFloat_FromDouble(turb(vec[0], vec[1], vec[2], oct, hd, noise_basis_enum, as, fs));
555 }
556
557 PyDoc_STRVAR(M_Noise_turbulence_vector_doc,
558 ".. function:: turbulence_vector(position, octaves, hard, noise_basis='PERLIN_ORIGINAL', amplitude_scale=0.5, frequency_scale=2.0)\n"
559 "\n"
560 "   Returns the turbulence vector from the noise basis at the specified position.\n"
561 "\n"
562 "   :arg position: The position to evaluate the selected noise function.\n"
563 "   :type position: :class:`mathutils.Vector`\n"
564 "   :arg octaves: The number of different noise frequencies used.\n"
565 "   :type octaves: int\n"
566 "   :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
567 "   :type hard: :boolean\n"
568 BPY_NOISE_BASIS_ENUM_DOC
569 "   :arg amplitude_scale: The amplitude scaling factor.\n"
570 "   :type amplitude_scale: float\n"
571 "   :arg frequency_scale: The frequency scaling factor\n"
572 "   :type frequency_scale: float\n"
573 "   :return: The turbulence vector.\n"
574 "   :rtype: :class:`mathutils.Vector`\n"
575 );
576 static PyObject *M_Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
577 {
578         static const char *kwlist[] = {"", "", "", "noise_basis", "amplitude_scale", "frequency_scale", NULL};
579         PyObject *value;
580         float vec[3], r_vec[3];
581         const char *noise_basis_str = NULL;
582         int oct, hd, noise_basis_enum = DEFAULT_NOISE_TYPE;
583         float as = 0.5f, fs = 2.0f;
584
585         if (!PyArg_ParseTupleAndKeywords(
586                     args, kw, "Oii|$sff:turbulence_vector", (char **)kwlist,
587                     &value, &oct, &hd, &noise_basis_str, &as, &fs))
588         {
589                 return NULL;
590         }
591
592         if (!noise_basis_str) {
593                 /* pass through */
594         }
595         else if (PyC_FlagSet_ValueFromID(
596                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "turbulence_vector") == -1)
597         {
598                 return NULL;
599         }
600
601         if (mathutils_array_parse(vec, 3, 3, value, "turbulence_vector: invalid 'position' arg") == -1)
602                 return NULL;
603
604         vTurb(vec[0], vec[1], vec[2], oct, hd, noise_basis_enum, as, fs, r_vec);
605
606         return Vector_CreatePyObject(r_vec, 3, NULL);
607 }
608
609 /* F. Kenton Musgrave's fractal functions */
610 PyDoc_STRVAR(M_Noise_fractal_doc,
611 ".. function:: fractal(position, H, lacunarity, octaves, noise_basis='PERLIN_ORIGINAL')\n"
612 "\n"
613 "   Returns the fractal Brownian motion (fBm) noise value from the noise basis at the specified position.\n"
614 "\n"
615 "   :arg position: The position to evaluate the selected noise function.\n"
616 "   :type position: :class:`mathutils.Vector`\n"
617 "   :arg H: The fractal increment factor.\n"
618 "   :type H: float\n"
619 "   :arg lacunarity: The gap between successive frequencies.\n"
620 "   :type lacunarity: float\n"
621 "   :arg octaves: The number of different noise frequencies used.\n"
622 "   :type octaves: int\n"
623 BPY_NOISE_BASIS_ENUM_DOC
624 "   :return: The fractal Brownian motion noise value.\n"
625 "   :rtype: float\n"
626 );
627 static PyObject *M_Noise_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
628 {
629         static const char *kwlist[] = {"", "", "", "", "noise_basis", NULL};
630         PyObject *value;
631         float vec[3];
632         const char *noise_basis_str = NULL;
633         float H, lac, oct;
634         int noise_basis_enum = DEFAULT_NOISE_TYPE;
635
636         if (!PyArg_ParseTupleAndKeywords(
637                     args, kw, "Offf|$s:fractal", (char **)kwlist,
638                     &value, &H, &lac, &oct, &noise_basis_str))
639         {
640                 return NULL;
641         }
642
643         if (!noise_basis_str) {
644                 /* pass through */
645         }
646         else if (PyC_FlagSet_ValueFromID(
647                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "fractal") == -1)
648         {
649                 return NULL;
650         }
651
652         if (mathutils_array_parse(vec, 3, 3, value, "fractal: invalid 'position' arg") == -1)
653                 return NULL;
654
655         return PyFloat_FromDouble(mg_fBm(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum));
656 }
657
658 PyDoc_STRVAR(M_Noise_multi_fractal_doc,
659 ".. function:: multi_fractal(position, H, lacunarity, octaves, noise_basis='PERLIN_ORIGINAL')\n"
660 "\n"
661 "   Returns multifractal noise value from the noise basis at the specified position.\n"
662 "\n"
663 "   :arg position: The position to evaluate the selected noise function.\n"
664 "   :type position: :class:`mathutils.Vector`\n"
665 "   :arg H: The fractal increment factor.\n"
666 "   :type H: float\n"
667 "   :arg lacunarity: The gap between successive frequencies.\n"
668 "   :type lacunarity: float\n"
669 "   :arg octaves: The number of different noise frequencies used.\n"
670 "   :type octaves: int\n"
671 BPY_NOISE_BASIS_ENUM_DOC
672 "   :return: The multifractal noise value.\n"
673 "   :rtype: float\n"
674 );
675 static PyObject *M_Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
676 {
677         static const char *kwlist[] = {"", "", "", "", "noise_basis", NULL};
678         PyObject *value;
679         float vec[3];
680         const char *noise_basis_str = NULL;
681         float H, lac, oct;
682         int noise_basis_enum = DEFAULT_NOISE_TYPE;
683
684         if (!PyArg_ParseTupleAndKeywords(
685                     args, kw, "Offf|$s:multi_fractal", (char **)kwlist,
686                     &value, &H, &lac, &oct, &noise_basis_str))
687         {
688                 return NULL;
689         }
690
691         if (!noise_basis_str) {
692                 /* pass through */
693         }
694         else if (PyC_FlagSet_ValueFromID(
695                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "multi_fractal") == -1)
696         {
697                 return NULL;
698         }
699
700         if (mathutils_array_parse(vec, 3, 3, value, "multi_fractal: invalid 'position' arg") == -1)
701                 return NULL;
702
703         return PyFloat_FromDouble(mg_MultiFractal(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum));
704 }
705
706 PyDoc_STRVAR(M_Noise_variable_lacunarity_doc,
707 ".. function:: variable_lacunarity(position, distortion, noise_type1='PERLIN_ORIGINAL', noise_type2='PERLIN_ORIGINAL')\n"
708 "\n"
709 "   Returns variable lacunarity noise value, a distorted variety of noise, from noise type 1 distorted by noise type 2 at the specified position.\n"
710 "\n"
711 "   :arg position: The position to evaluate the selected noise function.\n"
712 "   :type position: :class:`mathutils.Vector`\n"
713 "   :arg distortion: The amount of distortion.\n"
714 "   :type distortion: float\n"
715 "   :arg noise_type1: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', 'VORONOI_F1', 'VORONOI_F2', " \
716                                                                         "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
717                                                                         "'CELLNOISE'].\n"
718 "   :type noise_type1: string\n"
719 "   :arg noise_type2: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', 'VORONOI_F1', 'VORONOI_F2', " \
720                                                                         "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
721                                                                         "'CELLNOISE'].\n"
722 "   :type noise_type2: string\n"
723 "   :return: The variable lacunarity noise value.\n"
724 "   :rtype: float\n"
725 );
726 static PyObject *M_Noise_variable_lacunarity(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
727 {
728         static const char *kwlist[] = {"", "", "noise_type1", "noise_type2", NULL};
729         PyObject *value;
730         float vec[3];
731         const char *noise_type1_str = NULL, *noise_type2_str = NULL;
732         float d;
733         int noise_type1_enum = DEFAULT_NOISE_TYPE, noise_type2_enum = DEFAULT_NOISE_TYPE;
734
735         if (!PyArg_ParseTupleAndKeywords(
736                     args, kw, "Of|$ss:variable_lacunarity", (char **)kwlist,
737                     &value, &d, &noise_type1_str, &noise_type2_str))
738         {
739                 return NULL;
740         }
741
742         if (!noise_type1_str) {
743                 /* pass through */
744         }
745         else if (PyC_FlagSet_ValueFromID(
746                          bpy_noise_types, noise_type1_str, &noise_type1_enum, "variable_lacunarity") == -1)
747         {
748                 return NULL;
749         }
750
751         if (!noise_type2_str) {
752                 /* pass through */
753         }
754         else if (PyC_FlagSet_ValueFromID(
755                          bpy_noise_types, noise_type2_str, &noise_type2_enum, "variable_lacunarity") == -1)
756         {
757                 return NULL;
758         }
759
760         if (mathutils_array_parse(vec, 3, 3, value, "variable_lacunarity: invalid 'position' arg") == -1)
761                 return NULL;
762
763         return PyFloat_FromDouble(mg_VLNoise(vec[0], vec[1], vec[2], d, noise_type1_enum, noise_type2_enum));
764 }
765
766 PyDoc_STRVAR(M_Noise_hetero_terrain_doc,
767 ".. function:: hetero_terrain(position, H, lacunarity, octaves, offset, noise_basis='PERLIN_ORIGINAL')\n"
768 "\n"
769 "   Returns the heterogeneous terrain value from the noise basis at the specified position.\n"
770 "\n"
771 "   :arg position: The position to evaluate the selected noise function.\n"
772 "   :type position: :class:`mathutils.Vector`\n"
773 "   :arg H: The fractal dimension of the roughest areas.\n"
774 "   :type H: float\n"
775 "   :arg lacunarity: The gap between successive frequencies.\n"
776 "   :type lacunarity: float\n"
777 "   :arg octaves: The number of different noise frequencies used.\n"
778 "   :type octaves: int\n"
779 "   :arg offset: The height of the terrain above 'sea level'.\n"
780 "   :type offset: float\n"
781 BPY_NOISE_BASIS_ENUM_DOC
782 "   :return: The heterogeneous terrain value.\n"
783 "   :rtype: float\n"
784 );
785 static PyObject *M_Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
786 {
787         static const char *kwlist[] = {"", "", "", "", "", "noise_basis", NULL};
788         PyObject *value;
789         float vec[3];
790         const char *noise_basis_str = NULL;
791         float H, lac, oct, ofs;
792         int noise_basis_enum = DEFAULT_NOISE_TYPE;
793
794         if (!PyArg_ParseTupleAndKeywords(
795                     args, kw, "Offff|$s:hetero_terrain", (char **)kwlist,
796                     &value, &H, &lac, &oct, &ofs, &noise_basis_str))
797         {
798                 return NULL;
799         }
800
801         if (!noise_basis_str) {
802                 /* pass through */
803         }
804         else if (PyC_FlagSet_ValueFromID(
805                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "hetero_terrain") == -1)
806         {
807                 return NULL;
808         }
809
810         if (mathutils_array_parse(vec, 3, 3, value, "hetero_terrain: invalid 'position' arg") == -1)
811                 return NULL;
812
813         return PyFloat_FromDouble(mg_HeteroTerrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, noise_basis_enum));
814 }
815
816 PyDoc_STRVAR(M_Noise_hybrid_multi_fractal_doc,
817 ".. function:: hybrid_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis='PERLIN_ORIGINAL')\n"
818 "\n"
819 "   Returns hybrid multifractal value from the noise basis at the specified position.\n"
820 "\n"
821 "   :arg position: The position to evaluate the selected noise function.\n"
822 "   :type position: :class:`mathutils.Vector`\n"
823 "   :arg H: The fractal dimension of the roughest areas.\n"
824 "   :type H: float\n"
825 "   :arg lacunarity: The gap between successive frequencies.\n"
826 "   :type lacunarity: float\n"
827 "   :arg octaves: The number of different noise frequencies used.\n"
828 "   :type octaves: int\n"
829 "   :arg offset: The height of the terrain above 'sea level'.\n"
830 "   :type offset: float\n"
831 "   :arg gain: Scaling applied to the values.\n"
832 "   :type gain: float\n"
833 BPY_NOISE_BASIS_ENUM_DOC
834 "   :return: The hybrid multifractal value.\n"
835 "   :rtype: float\n"
836 );
837 static PyObject *M_Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
838 {
839         static const char *kwlist[] = {"", "", "", "", "", "", "noise_basis", NULL};
840         PyObject *value;
841         float vec[3];
842         const char *noise_basis_str = NULL;
843         float H, lac, oct, ofs, gn;
844         int noise_basis_enum = DEFAULT_NOISE_TYPE;
845
846         if (!PyArg_ParseTupleAndKeywords(
847                     args, kw, "Offfff|$s:hybrid_multi_fractal", (char **)kwlist,
848                     &value, &H, &lac, &oct, &ofs, &gn, &noise_basis_str))
849         {
850                 return NULL;
851         }
852
853         if (!noise_basis_str) {
854                 /* pass through */
855         }
856         else if (PyC_FlagSet_ValueFromID(
857                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "hybrid_multi_fractal") == -1)
858         {
859                 return NULL;
860         }
861
862         if (mathutils_array_parse(vec, 3, 3, value, "hybrid_multi_fractal: invalid 'position' arg") == -1)
863                 return NULL;
864
865         return PyFloat_FromDouble(mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum));
866 }
867
868 PyDoc_STRVAR(M_Noise_ridged_multi_fractal_doc,
869 ".. function:: ridged_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis='PERLIN_ORIGINAL')\n"
870 "\n"
871 "   Returns ridged multifractal value from the noise basis at the specified position.\n"
872 "\n"
873 "   :arg position: The position to evaluate the selected noise function.\n"
874 "   :type position: :class:`mathutils.Vector`\n"
875 "   :arg H: The fractal dimension of the roughest areas.\n"
876 "   :type H: float\n"
877 "   :arg lacunarity: The gap between successive frequencies.\n"
878 "   :type lacunarity: float\n"
879 "   :arg octaves: The number of different noise frequencies used.\n"
880 "   :type octaves: int\n"
881 "   :arg offset: The height of the terrain above 'sea level'.\n"
882 "   :type offset: float\n"
883 "   :arg gain: Scaling applied to the values.\n"
884 "   :type gain: float\n"
885 BPY_NOISE_BASIS_ENUM_DOC
886 "   :return: The ridged multifractal value.\n"
887 "   :rtype: float\n"
888 );
889 static PyObject *M_Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
890 {
891         static const char *kwlist[] = {"", "", "", "", "", "", "noise_basis", NULL};
892         PyObject *value;
893         float vec[3];
894         const char *noise_basis_str = NULL;
895         float H, lac, oct, ofs, gn;
896         int noise_basis_enum = DEFAULT_NOISE_TYPE;
897
898         if (!PyArg_ParseTupleAndKeywords(
899                     args, kw, "Offfff|$s:ridged_multi_fractal", (char **)kwlist,
900                     &value, &H, &lac, &oct, &ofs, &gn, &noise_basis_str))
901         {
902                 return NULL;
903         }
904
905         if (!noise_basis_str) {
906                 /* pass through */
907         }
908         else if (PyC_FlagSet_ValueFromID(
909                          bpy_noise_types, noise_basis_str, &noise_basis_enum, "ridged_multi_fractal") == -1)
910         {
911                 return NULL;
912         }
913
914         if (mathutils_array_parse(vec, 3, 3, value, "ridged_multi_fractal: invalid 'position' arg") == -1)
915                 return NULL;
916
917         return PyFloat_FromDouble(mg_RidgedMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum));
918 }
919
920 PyDoc_STRVAR(M_Noise_voronoi_doc,
921 ".. function:: voronoi(position, distance_metric='DISTANCE', exponent=2.5)\n"
922 "\n"
923 "   Returns a list of distances to the four closest features and their locations.\n"
924 "\n"
925 "   :arg position: The position to evaluate the selected noise function.\n"
926 "   :type position: :class:`mathutils.Vector`\n"
927 BPY_NOISE_METRIC_ENUM_DOC
928 "   :arg exponent: The exponent for Minkowski distance metric.\n"
929 "   :type exponent: float\n"
930 "   :return: A list of distances to the four closest features and their locations.\n"
931 "   :rtype: list of four floats, list of four :class:`mathutils.Vector` types\n"
932 );
933 static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
934 {
935         static const char *kwlist[] = {"", "distance_metric", "exponent", NULL};
936         PyObject *value;
937         PyObject *list;
938         PyObject *ret;
939         float vec[3];
940         const char *metric_str = NULL;
941         float da[4], pa[12];
942         int metric_enum = DEFAULT_METRIC_TYPE;
943         float me = 2.5f;  /* default minkowski exponent */
944
945         int i;
946
947         if (!PyArg_ParseTupleAndKeywords(
948                     args, kw, "O|$sf:voronoi", (char **)kwlist,
949                     &value, &metric_str, &me))
950         {
951                 return NULL;
952         }
953
954         if (!metric_str) {
955                 /* pass through */
956         }
957         else if (PyC_FlagSet_ValueFromID(
958                          bpy_noise_metrics, metric_str, &metric_enum, "voronoi") == -1)
959         {
960                 return NULL;
961         }
962
963         if (mathutils_array_parse(vec, 3, 3, value, "voronoi: invalid 'position' arg") == -1)
964                 return NULL;
965
966         list = PyList_New(4);
967
968         voronoi(vec[0], vec[1], vec[2], da, pa, me, metric_enum);
969
970         for (i = 0; i < 4; i++) {
971                 PyObject *v = Vector_CreatePyObject(pa + 3 * i, 3, NULL);
972                 PyList_SET_ITEM(list, i, v);
973         }
974
975         ret = Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list);
976         Py_DECREF(list);
977         return ret;
978 }
979
980 PyDoc_STRVAR(M_Noise_cell_doc,
981 ".. function:: cell(position)\n"
982 "\n"
983 "   Returns cell noise value at the specified position.\n"
984 "\n"
985 "   :arg position: The position to evaluate the selected noise function.\n"
986 "   :type position: :class:`mathutils.Vector`\n"
987 "   :return: The cell noise value.\n"
988 "   :rtype: float\n"
989 );
990 static PyObject *M_Noise_cell(PyObject *UNUSED(self), PyObject *args)
991 {
992         PyObject *value;
993         float vec[3];
994
995         if (!PyArg_ParseTuple(args, "O:cell", &value))
996                 return NULL;
997
998         if (mathutils_array_parse(vec, 3, 3, value, "cell: invalid 'position' arg") == -1)
999                 return NULL;
1000
1001         return PyFloat_FromDouble(cellNoise(vec[0], vec[1], vec[2]));
1002 }
1003
1004 PyDoc_STRVAR(M_Noise_cell_vector_doc,
1005 ".. function:: cell_vector(position)\n"
1006 "\n"
1007 "   Returns cell noise vector at the specified position.\n"
1008 "\n"
1009 "   :arg position: The position to evaluate the selected noise function.\n"
1010 "   :type position: :class:`mathutils.Vector`\n"
1011 "   :return: The cell noise vector.\n"
1012 "   :rtype: :class:`mathutils.Vector`\n"
1013 );
1014 static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
1015 {
1016         PyObject *value;
1017         float vec[3], r_vec[3];
1018
1019         if (!PyArg_ParseTuple(args, "O:cell_vector", &value))
1020                 return NULL;
1021
1022         if (mathutils_array_parse(vec, 3, 3, value, "cell_vector: invalid 'position' arg") == -1)
1023                 return NULL;
1024
1025         cellNoiseV(vec[0], vec[1], vec[2], r_vec);
1026         return Vector_CreatePyObject(r_vec, 3, NULL);
1027 }
1028
1029 static PyMethodDef M_Noise_methods[] = {
1030         {"seed_set", (PyCFunction) M_Noise_seed_set, METH_VARARGS, M_Noise_seed_set_doc},
1031         {"random", (PyCFunction) M_Noise_random, METH_NOARGS, M_Noise_random_doc},
1032         {"random_unit_vector", (PyCFunction) M_Noise_random_unit_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_random_unit_vector_doc},
1033         {"random_vector", (PyCFunction) M_Noise_random_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_random_vector_doc},
1034         {"noise", (PyCFunction) M_Noise_noise, METH_VARARGS | METH_KEYWORDS, M_Noise_noise_doc},
1035         {"noise_vector", (PyCFunction) M_Noise_noise_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_noise_vector_doc},
1036         {"turbulence", (PyCFunction) M_Noise_turbulence, METH_VARARGS | METH_KEYWORDS, M_Noise_turbulence_doc},
1037         {"turbulence_vector", (PyCFunction) M_Noise_turbulence_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_turbulence_vector_doc},
1038         {"fractal", (PyCFunction) M_Noise_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_fractal_doc},
1039         {"multi_fractal", (PyCFunction) M_Noise_multi_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_multi_fractal_doc},
1040         {"variable_lacunarity", (PyCFunction) M_Noise_variable_lacunarity, METH_VARARGS | METH_KEYWORDS, M_Noise_variable_lacunarity_doc},
1041         {"hetero_terrain", (PyCFunction) M_Noise_hetero_terrain, METH_VARARGS | METH_KEYWORDS, M_Noise_hetero_terrain_doc},
1042         {"hybrid_multi_fractal", (PyCFunction) M_Noise_hybrid_multi_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_hybrid_multi_fractal_doc},
1043         {"ridged_multi_fractal", (PyCFunction) M_Noise_ridged_multi_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_ridged_multi_fractal_doc},
1044         {"voronoi", (PyCFunction) M_Noise_voronoi, METH_VARARGS | METH_KEYWORDS, M_Noise_voronoi_doc},
1045         {"cell", (PyCFunction) M_Noise_cell, METH_VARARGS, M_Noise_cell_doc},
1046         {"cell_vector", (PyCFunction) M_Noise_cell_vector, METH_VARARGS, M_Noise_cell_vector_doc},
1047         {NULL, NULL, 0, NULL},
1048 };
1049
1050 static struct PyModuleDef M_Noise_module_def = {
1051         PyModuleDef_HEAD_INIT,
1052         "mathutils.noise",  /* m_name */
1053         M_Noise_doc,  /* m_doc */
1054         0,     /* m_size */
1055         M_Noise_methods,  /* m_methods */
1056         NULL,  /* m_reload */
1057         NULL,  /* m_traverse */
1058         NULL,  /* m_clear */
1059         NULL,  /* m_free */
1060 };
1061
1062 /*----------------------------MODULE INIT-------------------------*/
1063 PyMODINIT_FUNC PyInit_mathutils_noise(void)
1064 {
1065         PyObject *submodule = PyModule_Create(&M_Noise_module_def);
1066
1067         /* use current time as seed for random number generator by default */
1068         setRndSeed(0);
1069
1070         return submodule;
1071 }