- added GCC warning -Wstrict-prototypes
[blender.git] / source / blender / python / generic / noise.c
1 /**
2  * $Id$
3  *
4  * Blender.Noise BPython module implementation.
5  * This submodule has functions to generate noise of various types.
6  * 
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): eeshlo
29  *
30  * ***** END GPL LICENSE BLOCK *****
31 */
32
33 /************************/
34 /* Blender Noise Module */
35 /************************/
36
37 #include <Python.h>
38 #include "structseq.h"
39
40 #include "BLI_blenlib.h"
41 #include "DNA_texture_types.h"
42
43 #include "BKE_utildefines.h"
44 /*-----------------------------------------*/
45 /* 'mersenne twister' random number generator */
46
47 /* 
48    A C-program for MT19937, with initialization improved 2002/2/10.
49    Coded by Takuji Nishimura and Makoto Matsumoto.
50    This is a faster version by taking Shawn Cokus's optimization,
51    Matthe Bellew's simplification, Isaku Wada's real version.
52
53    Before using, initialize the state by using init_genrand(seed) 
54    or init_by_array(init_key, key_length).
55
56    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
57    All rights reserved.                          
58
59    Redistribution and use in source and binary forms, with or without
60    modification, are permitted provided that the following conditions
61    are met:
62
63      1. Redistributions of source code must retain the above copyright
64         notice, this list of conditions and the following disclaimer.
65
66      2. Redistributions in binary form must reproduce the above copyright
67         notice, this list of conditions and the following disclaimer in the
68         documentation and/or other materials provided with the distribution.
69
70      3. The names of its contributors may not be used to endorse or promote 
71         products derived from this software without specific prior written 
72         permission.
73
74    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
75    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
76    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
77    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
78    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
79    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
80    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
81    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
82    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
83    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85
86
87    Any feedback is very welcome.
88    http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
89    email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
90 */
91
92 /* 2.5 update
93  * Noise.setRandomSeed --> seed_set
94  * Noise.randuvec --> random_unit_vector
95  * Noise.vNoise --> noise_vector
96  * Noise.vTurbulence --> turbulence_vector
97  * Noise.multiFractal --> multi_fractal
98  * Noise.cellNoise --> cell
99  * Noise.cellNoiseV --> cell_vector
100  * Noise.vlNoise --> vl_vector
101  * Noise.heteroTerrain --> hetero_terrain
102  * Noise.hybridMFractal --> hybrid_multi_fractal
103  * Noise.fBm --> fractal
104  * Noise.ridgedMFractal --> ridged_multi_fractal
105  *
106  * Const's *
107  * Noise.NoiseTypes --> types
108  * Noise.DistanceMetrics --> distance_metrics
109  */
110
111 /* Period parameters */
112 #define N 624
113 #define M 397
114 #define MATRIX_A 0x9908b0dfUL   /* constant vector a */
115 #define UMASK 0x80000000UL      /* most significant w-r bits */
116 #define LMASK 0x7fffffffUL      /* least significant r bits */
117 #define MIXBITS(u,v) (((u) & UMASK) | ((v) & LMASK))
118 #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
119
120 static unsigned long state[N];  /* the array for the state vector  */
121 static int left = 1;
122 static int initf = 0;
123 static unsigned long *next;
124
125 /* initializes state[N] with a seed */
126 static void init_genrand(unsigned long s)
127 {
128         int j;
129         state[0] = s & 0xffffffffUL;
130         for(j = 1; j < N; j++) {
131                 state[j] =
132                         (1812433253UL *
133                           (state[j - 1] ^ (state[j - 1] >> 30)) + j);
134                 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
135                 /* In the previous versions, MSBs of the seed affect   */
136                 /* only MSBs of the array state[].                        */
137                 /* 2002/01/09 modified by Makoto Matsumoto             */
138                 state[j] &= 0xffffffffUL;       /* for >32 bit machines */
139         }
140         left = 1;
141         initf = 1;
142 }
143
144 static void next_state(void)
145 {
146         unsigned long *p = state;
147         int j;
148
149         /* if init_genrand() has not been called, */
150         /* a default initial seed is used         */
151         if(initf == 0)
152                 init_genrand(5489UL);
153
154         left = N;
155         next = state;
156
157         for(j = N - M + 1; --j; p++)
158                 *p = p[M] ^ TWIST(p[0], p[1]);
159
160         for(j = M; --j; p++)
161                 *p = p[M - N] ^ TWIST(p[0], p[1]);
162
163         *p = p[M - N] ^ TWIST(p[0], state[0]);
164 }
165
166 /*------------------------------------------------------------*/
167
168 static void setRndSeed(int seed)
169 {
170         if(seed == 0)
171                 init_genrand(time(NULL));
172         else
173                 init_genrand(seed);
174 }
175
176 /* float number in range [0, 1) using the mersenne twister rng */
177 static float frand(void)
178 {
179         unsigned long y;
180
181         if(--left == 0)
182                 next_state();
183         y = *next++;
184
185         /* Tempering */
186         y ^= (y >> 11);
187         y ^= (y << 7) & 0x9d2c5680UL;
188         y ^= (y << 15) & 0xefc60000UL;
189         y ^= (y >> 18);
190
191         return (float) y / 4294967296.f;
192 }
193
194 /*------------------------------------------------------------*/
195
196 /* returns random unit vector */
197 static void randuvec(float v[3])
198 {
199         float r;
200         v[2] = 2.f * frand() - 1.f;
201         if((r = 1.f - v[2] * v[2]) > 0.f) {
202                 float a = (float)(6.283185307f * frand());
203                 r = (float)sqrt(r);
204                 v[0] = (float)(r * cos(a));
205                 v[1] = (float)(r * sin(a));
206         } else
207                 v[2] = 1.f;
208 }
209
210 static PyObject *Noise_random(PyObject *UNUSED(self))
211 {
212         return PyFloat_FromDouble(frand());
213 }
214
215 static PyObject *Noise_random_unit_vector(PyObject *UNUSED(self))
216 {
217         float v[3] = {0.0f, 0.0f, 0.0f};
218         randuvec(v);
219         return Py_BuildValue("[fff]", v[0], v[1], v[2]);
220 }
221
222 /*---------------------------------------------------------------------*/
223
224 /* Random seed init. Only used for MT random() & randuvec() */
225
226 static PyObject *Noise_seed_set(PyObject *UNUSED(self), PyObject *args)
227 {
228         int s;
229         if(!PyArg_ParseTuple(args, "i:seed_set", &s))
230                 return NULL;
231         setRndSeed(s);
232         Py_RETURN_NONE;
233 }
234
235 /*-------------------------------------------------------------------------*/
236
237 /* General noise */
238
239 static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args)
240 {
241         float x, y, z;
242         int nb = 1;
243         if(!PyArg_ParseTuple(args, "(fff)|i:noise", &x, &y, &z, &nb))
244                 return NULL;
245
246         return PyFloat_FromDouble((2.0 * BLI_gNoise(1.0, x, y, z, 0, nb) - 1.0));
247 }
248
249 /*-------------------------------------------------------------------------*/
250
251 /* General Vector noise */
252
253 static void noise_vector(float x, float y, float z, int nb, float v[3])
254 {
255         /* Simply evaluate noise at 3 different positions */
256         v[0] = (float)(2.0 * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0,
257                                  nb) - 1.0);
258         v[1] = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0);
259         v[2] = (float)(2.0 * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0,
260                                  nb) - 1.0);
261 }
262
263 static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args)
264 {
265         float x, y, z, v[3];
266         int nb = 1;
267         if(!PyArg_ParseTuple(args, "(fff)|i:vector", &x, &y, &z, &nb))
268                 return NULL;
269         noise_vector(x, y, z, nb, v);
270         return Py_BuildValue("[fff]", v[0], v[1], v[2]);
271 }
272
273 /*---------------------------------------------------------------------------*/
274
275 /* General turbulence */
276
277 static float turb(float x, float y, float z, int oct, int hard, int nb,
278                    float ampscale, float freqscale)
279 {
280         float amp, out, t;
281         int i;
282         amp = 1.f;
283         out = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0);
284         if(hard)
285                 out = (float)fabs(out);
286         for(i = 1; i < oct; i++) {
287                 amp *= ampscale;
288                 x *= freqscale;
289                 y *= freqscale;
290                 z *= freqscale;
291                 t = (float)(amp * (2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0));
292                 if(hard)
293                         t = (float)fabs(t);
294                 out += t;
295         }
296         return out;
297 }
298
299 static PyObject *Noise_turbulence(PyObject *UNUSED(self), PyObject *args)
300 {
301         float x, y, z;
302         int oct, hd, nb = 1;
303         float as = 0.5, fs = 2.0;
304         if(!PyArg_ParseTuple(args, "(fff)ii|iff:turbulence", &x, &y, &z, &oct, &hd, &nb, &as, &fs))
305                 return NULL;
306
307         return PyFloat_FromDouble(turb(x, y, z, oct, hd, nb, as, fs));
308 }
309
310 /*--------------------------------------------------------------------------*/
311
312 /* Turbulence Vector */
313
314 static void vTurb(float x, float y, float z, int oct, int hard, int nb,
315                    float ampscale, float freqscale, float v[3])
316 {
317         float amp, t[3];
318         int i;
319         amp = 1.f;
320         noise_vector(x, y, z, nb, v);
321         if(hard) {
322                 v[0] = (float)fabs(v[0]);
323                 v[1] = (float)fabs(v[1]);
324                 v[2] = (float)fabs(v[2]);
325         }
326         for(i = 1; i < oct; i++) {
327                 amp *= ampscale;
328                 x *= freqscale;
329                 y *= freqscale;
330                 z *= freqscale;
331                 noise_vector(x, y, z, nb, t);
332                 if(hard) {
333                         t[0] = (float)fabs(t[0]);
334                         t[1] = (float)fabs(t[1]);
335                         t[2] = (float)fabs(t[2]);
336                 }
337                 v[0] += amp * t[0];
338                 v[1] += amp * t[1];
339                 v[2] += amp * t[2];
340         }
341 }
342
343 static PyObject *Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args)
344 {
345         float x, y, z, v[3];
346         int oct, hd, nb = 1;
347         float as = 0.5, fs = 2.0;
348         if(!PyArg_ParseTuple(args, "(fff)ii|iff:turbulence_vector", &x, &y, &z, &oct, &hd, &nb, &as, &fs))
349                 return NULL;
350         vTurb(x, y, z, oct, hd, nb, as, fs, v);
351         return Py_BuildValue("[fff]", v[0], v[1], v[2]);
352 }
353
354 /*---------------------------------------------------------------------*/
355
356 /* F. Kenton Musgrave's fractal functions */
357
358 static PyObject *Noise_fractal(PyObject *UNUSED(self), PyObject *args)
359 {
360         float x, y, z, H, lac, oct;
361         int nb = 1;
362         if(!PyArg_ParseTuple(args, "(fff)fff|i:fractal", &x, &y, &z, &H, &lac, &oct, &nb))
363                 return NULL;
364         return PyFloat_FromDouble(mg_fBm(x, y, z, H, lac, oct, nb));
365 }
366
367 /*------------------------------------------------------------------------*/
368
369 static PyObject *Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args)
370 {
371         float x, y, z, H, lac, oct;
372         int nb = 1;
373         if(!PyArg_ParseTuple(args, "(fff)fff|i:multi_fractal", &x, &y, &z, &H, &lac, &oct, &nb))
374                 return NULL;
375
376         return PyFloat_FromDouble(mg_MultiFractal(x, y, z, H, lac, oct, nb));
377 }
378
379 /*------------------------------------------------------------------------*/
380
381 static PyObject *Noise_vl_vector(PyObject *UNUSED(self), PyObject *args)
382 {
383         float x, y, z, d;
384         int nt1 = 1, nt2 = 1;
385         if(!PyArg_ParseTuple(args, "(fff)f|ii:vl_vector", &x, &y, &z, &d, &nt1, &nt2))
386                 return NULL;
387         return PyFloat_FromDouble(mg_VLNoise(x, y, z, d, nt1, nt2));
388 }
389
390 /*-------------------------------------------------------------------------*/
391
392 static PyObject *Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args)
393 {
394         float x, y, z, H, lac, oct, ofs;
395         int nb = 1;
396         if(!PyArg_ParseTuple(args, "(fff)ffff|i:hetero_terrain", &x, &y, &z, &H, &lac, &oct, &ofs, &nb))
397                 return NULL;
398
399         return PyFloat_FromDouble(mg_HeteroTerrain(x, y, z, H, lac, oct, ofs, nb));
400 }
401
402 /*-------------------------------------------------------------------------*/
403
404 static PyObject *Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args)
405 {
406         float x, y, z, H, lac, oct, ofs, gn;
407         int nb = 1;
408         if(!PyArg_ParseTuple(args, "(fff)fffff|i:hybrid_multi_fractal", &x, &y, &z, &H, &lac, &oct, &ofs, &gn, &nb))
409                 return NULL;
410         
411         return PyFloat_FromDouble(mg_HybridMultiFractal(x, y, z, H, lac, oct, ofs, gn, nb));
412 }
413
414 /*------------------------------------------------------------------------*/
415
416 static PyObject *Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args)
417 {
418         float x, y, z, H, lac, oct, ofs, gn;
419         int nb = 1;
420         if(!PyArg_ParseTuple(args, "(fff)fffff|i:ridged_multi_fractal", &x, &y, &z, &H, &lac, &oct, &ofs, &gn, &nb))
421                 return NULL;
422         return PyFloat_FromDouble(mg_RidgedMultiFractal(x, y, z, H, lac, oct, ofs, gn, nb));
423 }
424
425 /*-------------------------------------------------------------------------*/
426
427 static PyObject *Noise_voronoi(PyObject *UNUSED(self), PyObject *args)
428 {
429         float x, y, z, da[4], pa[12];
430         int dtype = 0;
431         float me = 2.5;         /* default minkovsky exponent */
432         if(!PyArg_ParseTuple(args, "(fff)|if:voronoi", &x, &y, &z, &dtype, &me))
433                 return NULL;
434         voronoi(x, y, z, da, pa, me, dtype);
435         return Py_BuildValue("[[ffff][[fff][fff][fff][fff]]]",
436                               da[0], da[1], da[2], da[3],
437                               pa[0], pa[1], pa[2],
438                               pa[3], pa[4], pa[5],
439                               pa[6], pa[7], pa[8], pa[9], pa[10], pa[11]);
440 }
441
442 /*-------------------------------------------------------------------------*/
443
444 static PyObject *Noise_cell(PyObject *UNUSED(self), PyObject *args)
445 {
446         float x, y, z;
447         if(!PyArg_ParseTuple(args, "(fff):cell", &x, &y, &z))
448                 return NULL;
449
450         return PyFloat_FromDouble(cellNoise(x, y, z));
451 }
452
453 /*--------------------------------------------------------------------------*/
454
455 static PyObject *Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
456 {
457         float x, y, z, ca[3];
458         if(!PyArg_ParseTuple(args, "(fff):cell_vector", &x, &y, &z))
459                 return NULL;
460         cellNoiseV(x, y, z, ca);
461         return Py_BuildValue("[fff]", ca[0], ca[1], ca[2]);
462 }
463
464 /*--------------------------------------------------------------------------*/
465 /* For all other Blender modules, this stuff seems to be put in a header file.
466    This doesn't seem really appropriate to me, so I just put it here, feel free to change it.
467    In the original module I actually kept the docs stings with the functions themselves,
468    but I grouped them here so that it can easily be moved to a header if anyone thinks that is necessary. */
469
470 static char random__doc__[] = "() No arguments.\n\n\
471 Returns a random floating point number in the range [0, 1)";
472
473 static char random_unit_vector__doc__[] =
474         "() No arguments.\n\nReturns a random unit vector (3-float list).";
475
476 static char seed_set__doc__[] = "(seed value)\n\n\
477 Initializes random number generator.\n\
478 if seed is zero, the current time will be used instead.";
479
480 static char noise__doc__[] = "((x,y,z) tuple, [noisetype])\n\n\
481 Returns general noise of the optional specified type.\n\
482 Optional argument noisetype determines the type of noise, STDPERLIN by default, see NoiseTypes.";
483
484 static char noise_vector__doc__[] = "((x,y,z) tuple, [noisetype])\n\n\
485 Returns noise vector (3-float list) of the optional specified type.\
486 Optional argument noisetype determines the type of noise, STDPERLIN by default, see NoiseTypes.";
487
488 static char turbulence__doc__[] =
489         "((x,y,z) tuple, octaves, hard, [noisebasis], [ampscale], [freqscale])\n\n\
490 Returns general turbulence value using the optional specified noisebasis function.\n\
491 octaves (integer) is the number of noise values added.\n\
492 hard (bool), when false (0) returns 'soft' noise, when true (1) returns 'hard' noise (returned value always positive).\n\
493 Optional arguments:\n\
494 noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.\n\
495 ampscale sets the amplitude scale value of the noise frequencies added, 0.5 by default.\n\
496 freqscale sets the frequency scale factor, 2.0 by default.";
497
498 static char turbulence_vector__doc__[] =
499         "((x,y,z) tuple, octaves, hard, [noisebasis], [ampscale], [freqscale])\n\n\
500 Returns general turbulence vector (3-float list) using the optional specified noisebasis function.\n\
501 octaves (integer) is the number of noise values added.\n\
502 hard (bool), when false (0) returns 'soft' noise, when true (1) returns 'hard' noise (returned vector always positive).\n\
503 Optional arguments:\n\
504 noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.\n\
505 ampscale sets the amplitude scale value of the noise frequencies added, 0.5 by default.\n\
506 freqscale sets the frequency scale factor, 2.0 by default.";
507
508 static char fractal__doc__[] =
509         "((x,y,z) tuple, H, lacunarity, octaves, [noisebasis])\n\n\
510 Returns Fractal Brownian Motion noise value(fBm).\n\
511 H is the fractal increment parameter.\n\
512 lacunarity is the gap between successive frequencies.\n\
513 octaves is the number of frequencies in the fBm.\n\
514 Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
515
516 static char multi_fractal__doc__[] =
517         "((x,y,z) tuple, H, lacunarity, octaves, [noisebasis])\n\n\
518 Returns Multifractal noise value.\n\
519 H determines the highest fractal dimension.\n\
520 lacunarity is gap between successive frequencies.\n\
521 octaves is the number of frequencies in the fBm.\n\
522 Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
523
524 static char vl_vector__doc__[] =
525         "((x,y,z) tuple, distortion, [noisetype1], [noisetype2])\n\n\
526 Returns Variable Lacunarity Noise value, a distorted variety of noise.\n\
527 distortion sets the amount of distortion.\n\
528 Optional arguments noisetype1 and noisetype2 set the noisetype to distort and the noisetype used for the distortion respectively.\n\
529 See NoiseTypes, both are STDPERLIN by default.";
530
531 static char hetero_terrain__doc__[] =
532         "((x,y,z) tuple, H, lacunarity, octaves, offset, [noisebasis])\n\n\
533 returns Heterogeneous Terrain value\n\
534 H determines the fractal dimension of the roughest areas.\n\
535 lacunarity is the gap between successive frequencies.\n\
536 octaves is the number of frequencies in the fBm.\n\
537 offset raises the terrain from 'sea level'.\n\
538 Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
539
540 static char hybrid_multi_fractal__doc__[] =
541         "((x,y,z) tuple, H, lacunarity, octaves, offset, gain, [noisebasis])\n\n\
542 returns Hybrid Multifractal value.\n\
543 H determines the fractal dimension of the roughest areas.\n\
544 lacunarity is the gap between successive frequencies.\n\
545 octaves is the number of frequencies in the fBm.\n\
546 offset raises the terrain from 'sea level'.\n\
547 gain scales the values.\n\
548 Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
549
550 static char ridged_multi_fractal__doc__[] =
551         "((x,y,z) tuple, H, lacunarity, octaves, offset, gain [noisebasis])\n\n\
552 returns Ridged Multifractal value.\n\
553 H determines the fractal dimension of the roughest areas.\n\
554 lacunarity is the gap between successive frequencies.\n\
555 octaves is the number of frequencies in the fBm.\n\
556 offset raises the terrain from 'sea level'.\n\
557 gain scales the values.\n\
558 Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.";
559
560 static char voronoi__doc__[] =
561         "((x,y,z) tuple, distance_metric, [exponent])\n\n\
562 returns a list, containing a list of distances in order of closest feature,\n\
563 and a list containing the positions of the four closest features\n\
564 Optional arguments:\n\
565 distance_metric: see DistanceMetrics, default is DISTANCE\n\
566 exponent is only used with MINKOVSKY, default is 2.5.";
567
568 static char cell__doc__[] = "((x,y,z) tuple)\n\n\
569 returns cellnoise float value.";
570
571 static char cell_vector__doc__[] = "((x,y,z) tuple)\n\n\
572 returns cellnoise vector/point/color (3-float list).";
573
574 static char Noise__doc__[] = "Blender Noise and Turbulence Module\n\n\
575 This module can be used to generate noise of various types.\n\
576 This can be used for terrain generation, to create textures,\n\
577 make animations more 'animated', object deformation, etc.\n\
578 As an example, this code segment when scriptlinked to a framechanged event,\n\
579 will make the camera sway randomly about, by changing parameters this can\n\
580 look like anything from an earthquake to a very nervous or maybe even drunk cameraman...\n\
581 (the camera needs an ipo with at least one Loc & Rot key for this to work!):\n\
582 \n\
583 \tfrom Blender import Get, Scene, Noise\n\
584 \n\
585 \t####################################################\n\
586 \t# This controls jitter speed\n\
587 \tsl = 0.025\n\
588 \t# This controls the amount of position jitter\n\
589 \tsp = 0.1\n\
590 \t# This controls the amount of rotation jitter\n\
591 \tsr = 0.25\n\
592 \t####################################################\n\
593 \n\
594 \ttime = Get('curtime')\n\
595 \tob = Scene.GetCurrent().getCurrentCamera()\n\
596 \tps = (sl*time, sl*time, sl*time)\n\
597 \t# To add jitter only when the camera moves, use this next line instead\n\
598 \t#ps = (sl*ob.LocX, sl*ob.LocY, sl*ob.LocZ)\n\
599 \trv = Noise.turbulence_vector(ps, 3, 0, Noise.NoiseTypes.NEWPERLIN)\n\
600 \tob.dloc = (sp*rv[0], sp*rv[1], sp*rv[2])\n\
601 \tob.drot = (sr*rv[0], sr*rv[1], sr*rv[2])\n\
602 \n";
603
604 /* Just in case, declarations for a header file */
605 /*
606 static PyObject *Noise_random(PyObject *UNUSED(self));
607 static PyObject *Noise_random_unit_vector(PyObject *UNUSED(self));
608 static PyObject *Noise_seed_set(PyObject *UNUSED(self), PyObject *args);
609 static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args);
610 static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args);
611 static PyObject *Noise_turbulence(PyObject *UNUSED(self), PyObject *args);
612 static PyObject *Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args);
613 static PyObject *Noise_fractal(PyObject *UNUSED(self), PyObject *args);
614 static PyObject *Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args);
615 static PyObject *Noise_vl_vector(PyObject *UNUSED(self), PyObject *args);
616 static PyObject *Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args);
617 static PyObject *Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args);
618 static PyObject *Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args);
619 static PyObject *Noise_voronoi(PyObject *UNUSED(self), PyObject *args);
620 static PyObject *Noise_cell(PyObject *UNUSED(self), PyObject *args);
621 static PyObject *Noise_cell_vector(PyObject *UNUSED(self), PyObject *args);
622 */
623
624 static PyMethodDef NoiseMethods[] = {
625         {"seed_set", (PyCFunction) Noise_seed_set, METH_VARARGS, seed_set__doc__},
626         {"random", (PyCFunction) Noise_random, METH_NOARGS, random__doc__},
627         {"random_unit_vector", (PyCFunction) Noise_random_unit_vector, METH_NOARGS, random_unit_vector__doc__},
628         {"noise", (PyCFunction) Noise_noise, METH_VARARGS, noise__doc__},
629         {"vector", (PyCFunction) Noise_vector, METH_VARARGS, noise_vector__doc__},
630         {"turbulence", (PyCFunction) Noise_turbulence, METH_VARARGS, turbulence__doc__},
631         {"turbulence_vector", (PyCFunction) Noise_turbulence_vector, METH_VARARGS, turbulence_vector__doc__},
632         {"fractal", (PyCFunction) Noise_fractal, METH_VARARGS, fractal__doc__},
633         {"multi_fractal", (PyCFunction) Noise_multi_fractal, METH_VARARGS, multi_fractal__doc__},
634         {"vl_vector", (PyCFunction) Noise_vl_vector, METH_VARARGS, vl_vector__doc__},
635         {"hetero_terrain", (PyCFunction) Noise_hetero_terrain, METH_VARARGS, hetero_terrain__doc__},
636         {"hybrid_multi_fractal", (PyCFunction) Noise_hybrid_multi_fractal, METH_VARARGS, hybrid_multi_fractal__doc__},
637         {"ridged_multi_fractal", (PyCFunction) Noise_ridged_multi_fractal, METH_VARARGS, ridged_multi_fractal__doc__},
638         {"voronoi", (PyCFunction) Noise_voronoi, METH_VARARGS, voronoi__doc__},
639         {"cell", (PyCFunction) Noise_cell, METH_VARARGS, cell__doc__},
640         {"cell_vector", (PyCFunction) Noise_cell_vector, METH_VARARGS, cell_vector__doc__},
641         {NULL, NULL, 0, NULL}
642 };
643
644 /*----------------------------------------------------------------------*/
645
646 static struct PyModuleDef noise_module_def = {
647         PyModuleDef_HEAD_INIT,
648         "noise",  /* m_name */
649         Noise__doc__,  /* m_doc */
650         0,  /* m_size */
651         NoiseMethods,  /* m_methods */
652         0,  /* m_reload */
653         0,  /* m_traverse */
654         0,  /* m_clear */
655         0,  /* m_free */
656 };
657
658 PyObject *BPyInit_noise(void)
659 {
660         PyObject *submodule = PyModule_Create(&noise_module_def);
661
662         /* use current time as seed for random number generator by default */
663         setRndSeed(0);  
664
665         /* Constant noisetype dictionary */
666         if(submodule) {
667                 static PyStructSequence_Field noise_types_fields[] = {
668                         {"BLENDER", ""},
669                         {"STDPERLIN", ""},
670                         {"NEWPERLIN", ""},
671                         {"VORONOI_F1", ""},
672                         {"VORONOI_F2", ""},
673                         {"VORONOI_F3", ""},
674                         {"VORONOI_F4", ""},
675                         {"VORONOI_F2F1", ""},
676                         {"VORONOI_CRACKLE", ""},
677                         {"CELLNOISE", ""},
678                         {0}
679                 };
680
681                 static PyStructSequence_Desc noise_types_info_desc = {
682                         "noise.types",     /* name */
683                         "Noise type",    /* doc */
684                         noise_types_fields,    /* fields */
685                         (sizeof(noise_types_fields)/sizeof(PyStructSequence_Field)) - 1
686                 };
687
688                 static PyTypeObject NoiseType;
689
690                 PyObject *noise_types;
691                 
692                 int pos = 0;
693                 
694                 PyStructSequence_InitType(&NoiseType, &noise_types_info_desc);
695         
696                 noise_types = PyStructSequence_New(&NoiseType);
697                 if (noise_types == NULL) {
698                         return NULL;
699                 }
700
701                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_BLENDER));
702                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_STDPERLIN));
703                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_NEWPERLIN));
704                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F1));
705                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F2));
706                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F3));
707                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F4));
708                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F2F1));
709                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_CRACKLE));
710                 PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_CELLNOISE));
711
712                 PyModule_AddObject(submodule, "types", noise_types);
713         }
714         
715         if(submodule) {
716                 static PyStructSequence_Field distance_metrics_fields[] = {
717                         {"DISTANCE", ""},
718                         {"DISTANCE_SQUARED", ""},
719                         {"MANHATTAN", ""},
720                         {"CHEBYCHEV", ""},
721                         {"MINKOVSKY_HALF", ""},
722                         {"MINKOVSKY_FOUR", ""},
723                         {"MINKOVSKY", ""},
724                         {0}
725                 };
726
727                 static PyStructSequence_Desc noise_types_info_desc = {
728                         "noise.distance_metrics",     /* name */
729                         "Distance Metrics for noise module.",    /* doc */
730                         distance_metrics_fields,    /* fields */
731                         (sizeof(distance_metrics_fields)/sizeof(PyStructSequence_Field)) - 1
732                 };
733                 
734                 static PyTypeObject DistanceMetrics;
735                 
736                 PyObject *distance_metrics;
737                 
738                 int pos = 0;
739                 
740                 PyStructSequence_InitType(&DistanceMetrics, &noise_types_info_desc);
741         
742                 distance_metrics = PyStructSequence_New(&DistanceMetrics);
743                 if (distance_metrics == NULL) {
744                         return NULL;
745                 }
746
747                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_DISTANCE));
748                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_DISTANCE_SQUARED));
749                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MANHATTAN));
750                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_CHEBYCHEV));
751                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY_HALF));
752                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY_FOUR));
753                 PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY));
754
755                 PyModule_AddObject(submodule, "distance_metrics", distance_metrics);
756         }
757
758         return submodule;
759 }