Blender V2.61 - r43446

mathutils_noise.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * This is a new part of Blender.
00022  *
00023  * Contributor(s): eeshlo, Campbell Barton
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00036 /************************/
00037 /* Blender Noise Module */
00038 /************************/
00039 
00040 #include <Python.h>
00041 
00042 #include "structseq.h"
00043 
00044 #include "BLI_blenlib.h"
00045 #include "BLI_math.h"
00046 #include "BLI_utildefines.h"
00047 
00048 #include "MEM_guardedalloc.h"
00049 
00050 #include "DNA_texture_types.h"
00051 
00052 #include "mathutils.h"
00053 #include "mathutils_noise.h"
00054 
00055 /* 2.6 update
00056  * Moved to submodule of mathutils.
00057  * All vector functions now return mathutils.Vector
00058  * Updated docs to be compatible with autodocs generation.
00059  * Updated vector functions to use nD array functions.
00060  * noise.vl_vector --> noise.variable_lacunarity
00061  * noise.vector --> noise.noise_vector
00062  */
00063 
00064 /*-----------------------------------------*/
00065 /* 'mersenne twister' random number generator */
00066 
00067 /* 
00068    A C-program for MT19937, with initialization improved 2002/2/10.
00069    Coded by Takuji Nishimura and Makoto Matsumoto.
00070    This is a faster version by taking Shawn Cokus's optimization,
00071    Matthe Bellew's simplification, Isaku Wada's real version.
00072 
00073    Before using, initialize the state by using init_genrand(seed) 
00074    or init_by_array(init_key, key_length).
00075 
00076    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
00077    All rights reserved.                          
00078 
00079    Redistribution and use in source and binary forms, with or without
00080    modification, are permitted provided that the following conditions
00081    are met:
00082 
00083      1. Redistributions of source code must retain the above copyright
00084         notice, this list of conditions and the following disclaimer.
00085 
00086      2. Redistributions in binary form must reproduce the above copyright
00087         notice, this list of conditions and the following disclaimer in the
00088         documentation and/or other materials provided with the distribution.
00089 
00090      3. The names of its contributors may not be used to endorse or promote 
00091         products derived from this software without specific prior written 
00092         permission.
00093 
00094    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00095    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00096    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00097    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00098    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00099    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00100    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00101    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00102    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00103    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00104    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00105 
00106 
00107    Any feedback is very welcome.
00108    http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
00109    email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
00110 */
00111 
00112 /* Period parameters */
00113 #define N 624
00114 #define M 397
00115 #define MATRIX_A 0x9908b0dfUL   /* constant vector a */
00116 #define UMASK 0x80000000UL  /* most significant w-r bits */
00117 #define LMASK 0x7fffffffUL  /* least significant r bits */
00118 #define MIXBITS(u,v) (((u) & UMASK) | ((v) & LMASK))
00119 #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
00120 
00121 static unsigned long state[N];  /* the array for the state vector  */
00122 static int left = 1;
00123 static int initf = 0;
00124 static unsigned long *next;
00125 
00126 /* initializes state[N] with a seed */
00127 static void init_genrand(unsigned long s)
00128 {
00129     int j;
00130     state[0] = s & 0xffffffffUL;
00131     for (j = 1; j < N; j++) {
00132         state[j] =
00133             (1812433253UL *
00134               (state[j - 1] ^ (state[j - 1] >> 30)) + j);
00135         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00136         /* In the previous versions, MSBs of the seed affect   */
00137         /* only MSBs of the array state[].                        */
00138         /* 2002/01/09 modified by Makoto Matsumoto             */
00139         state[j] &= 0xffffffffUL;   /* for >32 bit machines */
00140     }
00141     left = 1;
00142     initf = 1;
00143 }
00144 
00145 static void next_state(void)
00146 {
00147     unsigned long *p = state;
00148     int j;
00149 
00150     /* if init_genrand() has not been called, */
00151     /* a default initial seed is used         */
00152     if (initf == 0)
00153         init_genrand(5489UL);
00154 
00155     left = N;
00156     next = state;
00157 
00158     for (j = N - M + 1; --j; p++)
00159         *p = p[M] ^ TWIST(p[0], p[1]);
00160 
00161     for (j = M; --j; p++)
00162         *p = p[M - N] ^ TWIST(p[0], p[1]);
00163 
00164     *p = p[M - N] ^ TWIST(p[0], state[0]);
00165 }
00166 
00167 /*------------------------------------------------------------*/
00168 
00169 static void setRndSeed(int seed)
00170 {
00171     if (seed == 0)
00172         init_genrand(time(NULL));
00173     else
00174         init_genrand(seed);
00175 }
00176 
00177 /* float number in range [0, 1) using the mersenne twister rng */
00178 static float frand(void)
00179 {
00180     unsigned long y;
00181 
00182     if (--left == 0)
00183         next_state();
00184     y = *next++;
00185 
00186     /* Tempering */
00187     y ^= (y >> 11);
00188     y ^= (y << 7) & 0x9d2c5680UL;
00189     y ^= (y << 15) & 0xefc60000UL;
00190     y ^= (y >> 18);
00191 
00192     return (float) y / 4294967296.f;
00193 }
00194 
00195 /*------------------------------------------------------------*/
00196 /* Utility Functions */
00197 /*------------------------------------------------------------*/
00198 
00199 /* Fills an array of length size with random numbers in the range (-1, 1)*/
00200 static void rand_vn(float *array_tar, const int size)
00201 {
00202     float *array_pt = array_tar + (size-1);
00203     int i = size;
00204     while (i--) { *(array_pt--) = 2.0f * frand() - 1.0f; }
00205 }
00206 
00207 /* Fills an array of length 3 with noise values */
00208 static void noise_vector(float x, float y, float z, int nb, float v[3])
00209 {
00210     /* Simply evaluate noise at 3 different positions */
00211     v[0] = (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, nb) - 1.0f);
00212     v[1] = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
00213     v[2] = (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, nb) - 1.0f);
00214 }
00215 
00216 /* Returns a turbulence value for a given position (x, y, z) */
00217 static float turb(float x, float y, float z, int oct, int hard, int nb,
00218            float ampscale, float freqscale)
00219 {
00220     float amp, out, t;
00221     int i;
00222     amp = 1.f;
00223     out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
00224     if (hard)
00225         out = fabsf(out);
00226     for (i = 1; i < oct; i++) {
00227         amp *= ampscale;
00228         x *= freqscale;
00229         y *= freqscale;
00230         z *= freqscale;
00231         t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f));
00232         if (hard)
00233             t = fabsf(t);
00234         out += t;
00235     }
00236     return out;
00237 }
00238 
00239 /* Fills an array of length 3 with the turbulence vector for a given
00240 position (x, y, z) */
00241 static void vTurb(float x, float y, float z, int oct, int hard, int nb,
00242                   float ampscale, float freqscale, float v[3])
00243 {
00244     float amp, t[3];
00245     int i;
00246     amp = 1.f;
00247     noise_vector(x, y, z, nb, v);
00248     if (hard) {
00249         v[0] = fabsf(v[0]);
00250         v[1] = fabsf(v[1]);
00251         v[2] = fabsf(v[2]);
00252     }
00253     for (i = 1; i < oct; i++) {
00254         amp *= ampscale;
00255         x *= freqscale;
00256         y *= freqscale;
00257         z *= freqscale;
00258         noise_vector(x, y, z, nb, t);
00259         if (hard) {
00260             t[0] = fabsf(t[0]);
00261             t[1] = fabsf(t[1]);
00262             t[2] = fabsf(t[2]);
00263         }
00264         v[0] += amp * t[0];
00265         v[1] += amp * t[1];
00266         v[2] += amp * t[2];
00267     }
00268 }
00269 
00270 /*-------------------------DOC STRINGS ---------------------------*/
00271 PyDoc_STRVAR(M_Noise_doc,
00272 "The Blender noise module"
00273 );
00274 
00275 /*------------------------------------------------------------*/
00276 /* Python Functions */
00277 /*------------------------------------------------------------*/
00278 
00279 PyDoc_STRVAR(M_Noise_random_doc,
00280 ".. function:: random()\n"
00281 "\n"
00282 "   Returns a random number in the range [0, 1].\n"
00283 "\n"
00284 "   :return: The random number.\n"
00285 "   :rtype: float\n"
00286 );
00287 static PyObject *M_Noise_random(PyObject *UNUSED(self))
00288 {
00289     return PyFloat_FromDouble(frand());
00290 }
00291 
00292 PyDoc_STRVAR(M_Noise_random_unit_vector_doc,
00293 ".. function:: random_unit_vector(size=3)\n"
00294 "\n"
00295 "   Returns a unit vector with random entries.\n"
00296 "\n"
00297 "   :arg size: The size of the vector to be produced.\n"
00298 "   :type size: Int\n"
00299 "   :return: The random unit vector.\n"
00300 "   :rtype: :class:`mathutils.Vector`\n"
00301 );
00302 static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *args)
00303 {
00304     float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
00305     float norm = 2.0f;
00306     int size = 3;
00307 
00308     if (!PyArg_ParseTuple(args, "|i:random_vector", &size))
00309         return NULL;
00310 
00311     if (size > 4 || size < 2) {
00312         PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
00313         return NULL;
00314     }
00315 
00316     while (norm == 0.0f || norm >= 1.0f) {
00317         rand_vn(vec, size);
00318         norm = normalize_vn(vec, size);
00319     }
00320 
00321     return Vector_CreatePyObject(vec, size, Py_NEW, NULL);
00322 }
00323 /* This is dumb, most people will want a unit vector anyway, since this doesn't have uniform distribution over a sphere*/
00324 /*
00325 PyDoc_STRVAR(M_Noise_random_vector_doc,
00326 ".. function:: random_vector(size=3)\n"
00327 "\n"
00328 "   Returns a vector with random entries in the range [0, 1).\n"
00329 "\n"
00330 "   :arg size: The size of the vector to be produced.\n"
00331 "   :type size: Int\n"
00332 "   :return: The random vector.\n"
00333 "   :rtype: :class:`mathutils.Vector`\n"
00334 );
00335 static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args)
00336 {
00337     float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
00338     int size= 3;
00339 
00340     if (!PyArg_ParseTuple(args, "|i:random_vector", &size))
00341         return NULL;
00342 
00343     if (size > 4 || size < 2) {
00344         PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
00345         return NULL;
00346     }
00347 
00348     rand_vn(vec, size);
00349 
00350     return Vector_CreatePyObject(vec, size, Py_NEW, NULL);
00351 }
00352 */
00353 
00354 PyDoc_STRVAR(M_Noise_seed_set_doc,
00355 ".. function:: seed_set(seed)\n"
00356 "\n"
00357 "   Sets the random seed used for random_unit_vector, random_vector and random.\n"
00358 "\n"
00359 "   :arg seed: Seed used for the random generator.\n"
00360 "   :type seed: Int\n"
00361 );
00362 static PyObject *M_Noise_seed_set(PyObject *UNUSED(self), PyObject *args)
00363 {
00364     int s;
00365     if (!PyArg_ParseTuple(args, "i:seed_set", &s))
00366         return NULL;
00367     setRndSeed(s);
00368     Py_RETURN_NONE;
00369 }
00370 
00371 PyDoc_STRVAR(M_Noise_noise_doc,
00372 ".. function:: noise(position, noise_basis=noise.types.STDPERLIN)\n"
00373 "\n"
00374 "   Returns noise value from the noise basis at the position specified.\n"
00375 "\n"
00376 "   :arg position: The position to evaluate the selected noise function at.\n"
00377 "   :type position: :class:`mathutils.Vector`\n"
00378 "   :arg noise_basis: The type of noise to be evaluated.\n"
00379 "   :type noise_basis: Value in noise.types or int\n"
00380 "   :return: The noise value.\n"
00381 "   :rtype: float\n"
00382 );
00383 static PyObject *M_Noise_noise(PyObject *UNUSED(self), PyObject *args)
00384 {
00385     PyObject *value;
00386     float vec[3];
00387     int nb = 1;
00388     if (!PyArg_ParseTuple(args, "O|i:noise", &value, &nb))
00389         return NULL;
00390 
00391     if (mathutils_array_parse(vec, 3, 3, value, "noise: invalid 'position' arg") == -1)
00392         return NULL;
00393 
00394     return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, vec[0], vec[1], vec[2], 0, nb) - 1.0f));
00395 }
00396 
00397 PyDoc_STRVAR(M_Noise_noise_vector_doc,
00398 ".. function:: noise_vector(position, noise_basis=noise.types.STDPERLIN)\n"
00399 "\n"
00400 "   Returns the noise vector from the noise basis at the specified position.\n"
00401 "\n"
00402 "   :arg position: The position to evaluate the selected noise function at.\n"
00403 "   :type position: :class:`mathutils.Vector`\n"
00404 "   :arg noise_basis: The type of noise to be evaluated.\n"
00405 "   :type noise_basis: Value in noise.types or int\n"
00406 "   :return: The noise vector.\n"
00407 "   :rtype: :class:`mathutils.Vector`\n"
00408 );
00409 static PyObject *M_Noise_noise_vector(PyObject *UNUSED(self), PyObject *args)
00410 {
00411     PyObject *value;
00412     float vec[3], r_vec[3];
00413     int nb = 1;
00414 
00415     if (!PyArg_ParseTuple(args, "O|i:noise_vector", &value, &nb))
00416         return NULL;
00417 
00418     if (mathutils_array_parse(vec, 3, 3, value, "noise_vector: invalid 'position' arg") == -1)
00419         return NULL;
00420 
00421     noise_vector(vec[0], vec[1], vec[2], nb, r_vec);
00422 
00423     return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
00424 }
00425 
00426 PyDoc_STRVAR(M_Noise_turbulence_doc,
00427 ".. function:: turbulence(position, octaves, hard, noise_basis=noise.types.STDPERLIN, amplitude_scale=0.5, frequency_scale=2.0)\n"
00428 "\n"
00429 "   Returns the turbulence value from the noise basis at the specified position.\n"
00430 "\n"
00431 "   :arg position: The position to evaluate the selected noise function at.\n"
00432 "   :type position: :class:`mathutils.Vector`\n"
00433 "   :arg octaves: The number of different noise frequencies used.\n"
00434 "   :type octaves: int\n"
00435 "   :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
00436 "   :type hard: :boolean\n"
00437 "   :arg noise_basis: The type of noise to be evaluated.\n"
00438 "   :type noise_basis: Value in mathutils.noise.types or int\n"
00439 "   :arg amplitude_scale: The amplitude scaling factor.\n"
00440 "   :type amplitude_scale: float\n"
00441 "   :arg frequency_scale: The frequency scaling factor\n"
00442 "   :type frequency_scale: Value in noise.types or int\n"
00443 "   :return: The turbulence value.\n"
00444 "   :rtype: float\n"
00445 );
00446 static PyObject *M_Noise_turbulence(PyObject *UNUSED(self), PyObject *args)
00447 {
00448     PyObject *value;
00449     float vec[3];
00450     int oct, hd, nb = 1;
00451     float as = 0.5f, fs = 2.0f;
00452 
00453     if (!PyArg_ParseTuple(args, "Oii|iff:turbulence", &value, &oct, &hd, &nb, &as, &fs))
00454         return NULL;
00455 
00456     if (mathutils_array_parse(vec, 3, 3, value, "turbulence: invalid 'position' arg") == -1)
00457         return NULL;
00458 
00459     return PyFloat_FromDouble(turb(vec[0], vec[1], vec[2], oct, hd, nb, as, fs));
00460 }
00461 
00462 PyDoc_STRVAR(M_Noise_turbulence_vector_doc,
00463 ".. function:: turbulence_vector(position, octaves, hard, noise_basis=noise.types.STDPERLIN, amplitude_scale=0.5, frequency_scale=2.0)\n"
00464 "\n"
00465 "   Returns the turbulence vector from the noise basis at the specified position.\n"
00466 "\n"
00467 "   :arg position: The position to evaluate the selected noise function at.\n"
00468 "   :type position: :class:`mathutils.Vector`\n"
00469 "   :arg octaves: The number of different noise frequencies used.\n"
00470 "   :type octaves: int\n"
00471 "   :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
00472 "   :type hard: :boolean\n"
00473 "   :arg noise_basis: The type of noise to be evaluated.\n"
00474 "   :type noise_basis: Value in mathutils.noise.types or int\n"
00475 "   :arg amplitude_scale: The amplitude scaling factor.\n"
00476 "   :type amplitude_scale: float\n"
00477 "   :arg frequency_scale: The frequency scaling factor\n"
00478 "   :type frequency_scale: Value in noise.types or int\n"
00479 "   :return: The turbulence vector.\n"
00480 "   :rtype: :class:`mathutils.Vector`\n"
00481 );
00482 static PyObject *M_Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args)
00483 {
00484     PyObject *value;
00485     float vec[3], r_vec[3];
00486     int oct, hd, nb = 1;
00487     float as =0.5f, fs = 2.0f;
00488     if (!PyArg_ParseTuple(args, "Oii|iff:turbulence_vector", &value, &oct, &hd, &nb, &as, &fs))
00489         return NULL;
00490 
00491     if (mathutils_array_parse(vec, 3, 3, value, "turbulence_vector: invalid 'position' arg") == -1)
00492         return NULL;
00493 
00494     vTurb(vec[0], vec[1], vec[2], oct, hd, nb, as, fs, r_vec);
00495     return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
00496 }
00497 
00498 /* F. Kenton Musgrave's fractal functions */
00499 PyDoc_STRVAR(M_Noise_fractal_doc,
00500 ".. function:: fractal(position, H, lacunarity, octaves, noise_basis=noise.types.STDPERLIN)\n"
00501 "\n"
00502 "   Returns the fractal Brownian motion (fBm) noise value from the noise basis at the specified position.\n"
00503 "\n"
00504 "   :arg position: The position to evaluate the selected noise function at.\n"
00505 "   :type position: :class:`mathutils.Vector`\n"
00506 "   :arg H: The fractal increment factor.\n"
00507 "   :type H: float\n"
00508 "   :arg lacunarity: The gap between successive frequencies.\n"
00509 "   :type lacunarity: float\n"
00510 "   :arg octaves: The number of different noise frequencies used.\n"
00511 "   :type octaves: int\n"
00512 "   :arg noise_basis: The type of noise to be evaluated.\n"
00513 "   :type noise_basis: Value in noise.types or int\n"
00514 "   :return: The fractal Brownian motion noise value.\n"
00515 "   :rtype: float\n"
00516 );
00517 static PyObject *M_Noise_fractal(PyObject *UNUSED(self), PyObject *args)
00518 {
00519     PyObject *value;
00520     float vec[3];
00521     float H, lac, oct;
00522     int nb = 1;
00523 
00524     if (!PyArg_ParseTuple(args, "Offf|i:fractal", &value, &H, &lac, &oct, &nb))
00525         return NULL;
00526 
00527     if (mathutils_array_parse(vec, 3, 3, value, "fractal: invalid 'position' arg") == -1)
00528         return NULL;
00529 
00530     return PyFloat_FromDouble(mg_fBm(vec[0], vec[1], vec[2], H, lac, oct, nb));
00531 }
00532 
00533 PyDoc_STRVAR(M_Noise_multi_fractal_doc,
00534 ".. function:: multi_fractal(position, H, lacunarity, octaves, noise_basis=noise.types.STDPERLIN)\n"
00535 "\n"
00536 "   Returns multifractal noise value from the noise basis at the specified position.\n"
00537 "\n"
00538 "   :arg position: The position to evaluate the selected noise function at.\n"
00539 "   :type position: :class:`mathutils.Vector`\n"
00540 "   :arg H: The fractal increment factor.\n"
00541 "   :type H: float\n"
00542 "   :arg lacunarity: The gap between successive frequencies.\n"
00543 "   :type lacunarity: float\n"
00544 "   :arg octaves: The number of different noise frequencies used.\n"
00545 "   :type octaves: int\n"
00546 "   :arg noise_basis: The type of noise to be evaluated.\n"
00547 "   :type noise_basis: Value in noise.types or int\n"
00548 "   :return: The multifractal noise value.\n"
00549 "   :rtype: float\n"
00550 );
00551 static PyObject *M_Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args)
00552 {
00553     PyObject *value;
00554     float vec[3];
00555     float H, lac, oct;
00556     int nb = 1;
00557 
00558     if (!PyArg_ParseTuple(args, "Offf|i:multi_fractal", &value, &H, &lac, &oct, &nb))
00559         return NULL;
00560 
00561     if (mathutils_array_parse(vec, 3, 3, value, "multi_fractal: invalid 'position' arg") == -1)
00562         return NULL;
00563 
00564     return PyFloat_FromDouble(mg_MultiFractal(vec[0], vec[1], vec[2], H, lac, oct, nb));
00565 }
00566 
00567 PyDoc_STRVAR(M_Noise_variable_lacunarity_doc,
00568 ".. function:: variable_lacunarity(position, distortion, noise_type1=noise.types.STDPERLIN, noise_type2=noise.types.STDPERLIN)\n"
00569 "\n"
00570 "   Returns variable lacunarity noise value, a distorted variety of noise, from noise type 1 distorted by noise type 2 at the specified position.\n"
00571 "\n"
00572 "   :arg position: The position to evaluate the selected noise function at.\n"
00573 "   :type position: :class:`mathutils.Vector`\n"
00574 "   :arg distortion: The amount of distortion.\n"
00575 "   :type distortion: float\n"
00576 "   :arg noise_type1: The type of noise to be distorted.\n"
00577 "   :type noise_type1: Value in noise.types or int\n"
00578 "   :arg noise_type2: The type of noise used to distort noise_type1.\n"
00579 "   :type noise_type2: Value in noise.types or int\n"
00580 "   :return: The variable lacunarity noise value.\n"
00581 "   :rtype: float\n"
00582 );
00583 static PyObject *M_Noise_variable_lacunarity(PyObject *UNUSED(self), PyObject *args)
00584 {
00585     PyObject *value;
00586     float vec[3];
00587     float d;
00588     int nt1 = 1, nt2 = 1;
00589 
00590     if (!PyArg_ParseTuple(args, "Of|ii:variable_lacunarity", &value, &d, &nt1, &nt2))
00591         return NULL;
00592 
00593     if (mathutils_array_parse(vec, 3, 3, value, "variable_lacunarity: invalid 'position' arg") == -1)
00594         return NULL;
00595 
00596     return PyFloat_FromDouble(mg_VLNoise(vec[0], vec[1], vec[2], d, nt1, nt2));
00597 }
00598 
00599 PyDoc_STRVAR(M_Noise_hetero_terrain_doc,
00600 ".. function:: hetero_terrain(position, H, lacunarity, octaves, offset, noise_basis=noise.types.STDPERLIN)\n"
00601 "\n"
00602 "   Returns the heterogeneous terrain value from the noise basis at the specified position.\n"
00603 "\n"
00604 "   :arg position: The position to evaluate the selected noise function at.\n"
00605 "   :type position: :class:`mathutils.Vector`\n"
00606 "   :arg H: The fractal dimension of the roughest areas.\n"
00607 "   :type H: float\n"
00608 "   :arg lacunarity: The gap between successive frequencies.\n"
00609 "   :type lacunarity: float\n"
00610 "   :arg octaves: The number of different noise frequencies used.\n"
00611 "   :type octaves: int\n"
00612 "   :arg offset: The height of the terrain above 'sea level'.\n"
00613 "   :type offset: float\n"
00614 "   :arg noise_basis: The type of noise to be evaluated.\n"
00615 "   :type noise_basis: Value in noise.types or int\n"
00616 "   :return: The heterogeneous terrain value.\n"
00617 "   :rtype: float\n"
00618 );
00619 static PyObject *M_Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args)
00620 {
00621     PyObject *value;
00622     float vec[3];
00623     float H, lac, oct, ofs;
00624     int nb = 1;
00625 
00626     if (!PyArg_ParseTuple(args, "Offff|i:hetero_terrain", &value, &H, &lac, &oct, &ofs, &nb))
00627         return NULL;
00628 
00629     if (mathutils_array_parse(vec, 3, 3, value, "hetero_terrain: invalid 'position' arg") == -1)
00630         return NULL;
00631 
00632     return PyFloat_FromDouble(mg_HeteroTerrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, nb));
00633 }
00634 
00635 PyDoc_STRVAR(M_Noise_hybrid_multi_fractal_doc,
00636 ".. function:: hybrid_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis=noise.types.STDPERLIN)\n"
00637 "\n"
00638 "   Returns hybrid multifractal value from the noise basis at the specified position.\n"
00639 "\n"
00640 "   :arg position: The position to evaluate the selected noise function at.\n"
00641 "   :type position: :class:`mathutils.Vector`\n"
00642 "   :arg H: The fractal dimension of the roughest areas.\n"
00643 "   :type H: float\n"
00644 "   :arg lacunarity: The gap between successive frequencies.\n"
00645 "   :type lacunarity: float\n"
00646 "   :arg octaves: The number of different noise frequencies used.\n"
00647 "   :type octaves: int\n"
00648 "   :arg offset: The height of the terrain above 'sea level'.\n"
00649 "   :type offset: float\n"
00650 "   :arg gain: Scaling applied to the values.\n"
00651 "   :type gain: float\n"
00652 "   :arg noise_basis: The type of noise to be evaluated.\n"
00653 "   :type noise_basis: Value in noise.types or int\n"
00654 "   :return: The hybrid multifractal value.\n"
00655 "   :rtype: float\n"
00656 );
00657 static PyObject *M_Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args)
00658 {
00659     PyObject *value;
00660     float vec[3];
00661     float H, lac, oct, ofs, gn;
00662     int nb = 1;
00663 
00664     if (!PyArg_ParseTuple(args, "Offfff|i:hybrid_multi_fractal", &value, &H, &lac, &oct, &ofs, &gn, &nb))
00665         return NULL;
00666 
00667     if (mathutils_array_parse(vec, 3, 3, value, "hybrid_multi_fractal: invalid 'position' arg") == -1)
00668         return NULL;
00669     
00670     return PyFloat_FromDouble(mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, nb));
00671 }
00672 
00673 PyDoc_STRVAR(M_Noise_ridged_multi_fractal_doc,
00674 ".. function:: ridged_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis=noise.types.STDPERLIN)\n"
00675 "\n"
00676 "   Returns ridged multifractal value from the noise basis at the specified position.\n"
00677 "\n"
00678 "   :arg position: The position to evaluate the selected noise function at.\n"
00679 "   :type position: :class:`mathutils.Vector`\n"
00680 "   :arg H: The fractal dimension of the roughest areas.\n"
00681 "   :type H: float\n"
00682 "   :arg lacunarity: The gap between successive frequencies.\n"
00683 "   :type lacunarity: float\n"
00684 "   :arg octaves: The number of different noise frequencies used.\n"
00685 "   :type octaves: int\n"
00686 "   :arg offset: The height of the terrain above 'sea level'.\n"
00687 "   :type offset: float\n"
00688 "   :arg gain: Scaling applied to the values.\n"
00689 "   :type gain: float\n"
00690 "   :arg noise_basis: The type of noise to be evaluated.\n"
00691 "   :type noise_basis: Value in noise.types or int\n"
00692 "   :return: The ridged multifractal value.\n"
00693 "   :rtype: float\n"
00694 );
00695 static PyObject *M_Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args)
00696 {
00697     PyObject *value;
00698     float vec[3];
00699     float H, lac, oct, ofs, gn;
00700     int nb = 1;
00701 
00702     if (!PyArg_ParseTuple(args, "Offfff|i:ridged_multi_fractal", &value, &H, &lac, &oct, &ofs, &gn, &nb))
00703         return NULL;
00704 
00705     if (mathutils_array_parse(vec, 3, 3, value, "ridged_multi_fractal: invalid 'position' arg") == -1)
00706         return NULL;
00707 
00708     return PyFloat_FromDouble(mg_RidgedMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, nb));
00709 }
00710 
00711 PyDoc_STRVAR(M_Noise_voronoi_doc,
00712 ".. function:: voronoi(position, distance_metric=noise.distance_metrics.DISTANCE, exponent=2.5)\n"
00713 "\n"
00714 "   Returns a list of distances to the four closest features and their locations.\n"
00715 "\n"
00716 "   :arg position: The position to evaluate the selected noise function at.\n"
00717 "   :type position: :class:`mathutils.Vector`\n"
00718 "   :arg distance_metric: Method of measuring distance.\n"
00719 "   :type distance_metric: Value in noise.distance_metrics or int\n"
00720 "   :arg exponent: The exponent for Minkovsky distance metric.\n"
00721 "   :type exponent: float\n"
00722 "   :return: A list of distances to the four closest features and their locations.\n"
00723 "   :rtype: list of four floats, list of four :class:`mathutils.Vector`s\n"
00724 );
00725 static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args)
00726 {
00727     PyObject *value;
00728     PyObject *list;
00729     float vec[3];
00730     float da[4], pa[12];
00731     int dtype = 0;
00732     float me = 2.5f;        /* default minkovsky exponent */
00733 
00734     int i;
00735 
00736     if (!PyArg_ParseTuple(args, "O|if:voronoi", &value, &dtype, &me))
00737         return NULL;
00738 
00739     if (mathutils_array_parse(vec, 3, 3, value, "voronoi: invalid 'position' arg") == -1)
00740         return NULL;
00741 
00742     list = PyList_New(4);
00743 
00744     voronoi(vec[0], vec[1], vec[2], da, pa, me, dtype);
00745 
00746     for (i = 0; i < 4; i++) {
00747         PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3 * i, 3, Py_NEW, NULL));
00748     }
00749 
00750     return Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list);
00751 }
00752 
00753 PyDoc_STRVAR(M_Noise_cell_doc,
00754 ".. function:: cell(position)\n"
00755 "\n"
00756 "   Returns cell noise value at the specified position.\n"
00757 "\n"
00758 "   :arg position: The position to evaluate the selected noise function at.\n"
00759 "   :type position: :class:`mathutils.Vector`\n"
00760 "   :return: The cell noise value.\n"
00761 "   :rtype: float\n"
00762 );
00763 static PyObject *M_Noise_cell(PyObject *UNUSED(self), PyObject *args)
00764 {
00765     PyObject *value;
00766     float vec[3];
00767 
00768     if (!PyArg_ParseTuple(args, "O:cell", &value))
00769         return NULL;
00770 
00771     if (mathutils_array_parse(vec, 3, 3, value, "cell: invalid 'position' arg") == -1)
00772         return NULL;
00773 
00774     return PyFloat_FromDouble(cellNoise(vec[0], vec[1], vec[2]));
00775 }
00776 
00777 PyDoc_STRVAR(M_Noise_cell_vector_doc,
00778 ".. function:: cell_vector(position)\n"
00779 "\n"
00780 "   Returns cell noise vector at the specified position.\n"
00781 "\n"
00782 "   :arg position: The position to evaluate the selected noise function at.\n"
00783 "   :type position: :class:`mathutils.Vector`\n"
00784 "   :return: The cell noise vector.\n"
00785 "   :rtype: :class:`mathutils.Vector`\n"
00786 );
00787 static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
00788 {
00789     PyObject *value;
00790     float vec[3], r_vec[3];
00791 
00792     if (!PyArg_ParseTuple(args, "O:cell_vector", &value))
00793         return NULL;
00794 
00795     if (mathutils_array_parse(vec, 3, 3, value, "cell_vector: invalid 'position' arg") == -1)
00796         return NULL;
00797 
00798     cellNoiseV(vec[0], vec[1], vec[2], r_vec);
00799     return Vector_CreatePyObject(NULL, 3, Py_NEW, NULL);;
00800 }
00801 
00802 static PyMethodDef M_Noise_methods[] = {
00803     {"seed_set", (PyCFunction) M_Noise_seed_set, METH_VARARGS, M_Noise_seed_set_doc},
00804     {"random", (PyCFunction) M_Noise_random, METH_NOARGS, M_Noise_random_doc},
00805     {"random_unit_vector", (PyCFunction) M_Noise_random_unit_vector, METH_VARARGS, M_Noise_random_unit_vector_doc},
00806     /*{"random_vector", (PyCFunction) M_Noise_random_vector, METH_VARARGS, M_Noise_random_vector_doc},*/
00807     {"noise", (PyCFunction) M_Noise_noise, METH_VARARGS, M_Noise_noise_doc},
00808     {"noise_vector", (PyCFunction) M_Noise_noise_vector, METH_VARARGS, M_Noise_noise_vector_doc},
00809     {"turbulence", (PyCFunction) M_Noise_turbulence, METH_VARARGS, M_Noise_turbulence_doc},
00810     {"turbulence_vector", (PyCFunction) M_Noise_turbulence_vector, METH_VARARGS, M_Noise_turbulence_vector_doc},
00811     {"fractal", (PyCFunction) M_Noise_fractal, METH_VARARGS, M_Noise_fractal_doc},
00812     {"multi_fractal", (PyCFunction) M_Noise_multi_fractal, METH_VARARGS, M_Noise_multi_fractal_doc},
00813     {"variable_lacunarity", (PyCFunction) M_Noise_variable_lacunarity, METH_VARARGS, M_Noise_variable_lacunarity_doc},
00814     {"hetero_terrain", (PyCFunction) M_Noise_hetero_terrain, METH_VARARGS, M_Noise_hetero_terrain_doc},
00815     {"hybrid_multi_fractal", (PyCFunction) M_Noise_hybrid_multi_fractal, METH_VARARGS, M_Noise_hybrid_multi_fractal_doc},
00816     {"ridged_multi_fractal", (PyCFunction) M_Noise_ridged_multi_fractal, METH_VARARGS, M_Noise_ridged_multi_fractal_doc},
00817     {"voronoi", (PyCFunction) M_Noise_voronoi, METH_VARARGS, M_Noise_voronoi_doc},
00818     {"cell", (PyCFunction) M_Noise_cell, METH_VARARGS, M_Noise_cell_doc},
00819     {"cell_vector", (PyCFunction) M_Noise_cell_vector, METH_VARARGS, M_Noise_cell_vector_doc},
00820     {NULL, NULL, 0, NULL}
00821 };
00822 
00823 static struct PyModuleDef M_Noise_module_def = {
00824     PyModuleDef_HEAD_INIT,
00825     "mathutils.noise",  /* m_name */
00826     M_Noise_doc,  /* m_doc */
00827     0,     /* m_size */
00828     M_Noise_methods,  /* m_methods */
00829     NULL,  /* m_reload */
00830     NULL,  /* m_traverse */
00831     NULL,  /* m_clear */
00832     NULL,  /* m_free */
00833 };
00834 
00835 /*----------------------------MODULE INIT-------------------------*/
00836 PyMODINIT_FUNC PyInit_mathutils_noise(void)
00837 {
00838     PyObject *submodule = PyModule_Create(&M_Noise_module_def);
00839     PyObject *item_types, *item_metrics;
00840 
00841     /* use current time as seed for random number generator by default */
00842     setRndSeed(0);
00843 
00844     PyModule_AddObject(submodule, "types", (item_types = PyInit_mathutils_noise_types()));
00845     PyDict_SetItemString(PyThreadState_GET()->interp->modules, "noise.types", item_types);
00846     Py_INCREF(item_types);
00847 
00848     PyModule_AddObject(submodule, "distance_metrics", (item_metrics = PyInit_mathutils_noise_metrics()));
00849     PyDict_SetItemString(PyThreadState_GET()->interp->modules, "noise.distance_metrics", item_metrics);
00850     Py_INCREF(item_metrics);
00851 
00852     return submodule;
00853 }
00854 
00855 /*----------------------------SUBMODULE INIT-------------------------*/
00856 static struct PyModuleDef M_NoiseTypes_module_def = {
00857     PyModuleDef_HEAD_INIT,
00858     "mathutils.noise.types",  /* m_name */
00859     NULL,  /* m_doc */
00860     0,     /* m_size */
00861     NULL,  /* m_methods */
00862     NULL,  /* m_reload */
00863     NULL,  /* m_traverse */
00864     NULL,  /* m_clear */
00865     NULL,  /* m_free */
00866 };
00867 
00868 PyMODINIT_FUNC PyInit_mathutils_noise_types(void)
00869 {
00870     PyObject *submodule = PyModule_Create(&M_NoiseTypes_module_def);
00871 
00872     PyModule_AddIntConstant(submodule, (char *)"BLENDER", TEX_BLENDER);
00873     PyModule_AddIntConstant(submodule, (char *)"STDPERLIN", TEX_STDPERLIN);
00874     PyModule_AddIntConstant(submodule, (char *)"NEWPERLIN", TEX_NEWPERLIN);
00875     PyModule_AddIntConstant(submodule, (char *)"VORONOI_F1", TEX_VORONOI_F1);
00876     PyModule_AddIntConstant(submodule, (char *)"VORONOI_F2", TEX_VORONOI_F2);
00877     PyModule_AddIntConstant(submodule, (char *)"VORONOI_F3", TEX_VORONOI_F3);
00878     PyModule_AddIntConstant(submodule, (char *)"VORONOI_F4", TEX_VORONOI_F4);
00879     PyModule_AddIntConstant(submodule, (char *)"VORONOI_F2F1", TEX_VORONOI_F2F1);
00880     PyModule_AddIntConstant(submodule, (char *)"VORONOI_CRACKLE", TEX_VORONOI_CRACKLE);
00881     PyModule_AddIntConstant(submodule, (char *)"CELLNOISE", TEX_CELLNOISE);
00882 
00883     return submodule;
00884 }
00885 
00886 static struct PyModuleDef M_NoiseMetrics_module_def = {
00887     PyModuleDef_HEAD_INIT,
00888     "mathutils.noise.distance_metrics",  /* m_name */
00889     NULL,  /* m_doc */
00890     0,     /* m_size */
00891     NULL,  /* m_methods */
00892     NULL,  /* m_reload */
00893     NULL,  /* m_traverse */
00894     NULL,  /* m_clear */
00895     NULL,  /* m_free */
00896 };
00897 
00898 PyMODINIT_FUNC PyInit_mathutils_noise_metrics(void)
00899 {
00900     PyObject *submodule = PyModule_Create(&M_NoiseMetrics_module_def);
00901 
00902     PyModule_AddIntConstant(submodule, (char *)"DISTANCE", TEX_DISTANCE);
00903     PyModule_AddIntConstant(submodule, (char *)"DISTANCE_SQUARED", TEX_DISTANCE_SQUARED);
00904     PyModule_AddIntConstant(submodule, (char *)"MANHATTAN", TEX_MANHATTAN);
00905     PyModule_AddIntConstant(submodule, (char *)"CHEBYCHEV", TEX_CHEBYCHEV);
00906     PyModule_AddIntConstant(submodule, (char *)"MINKOVSKY_HALF", TEX_MINKOVSKY_HALF);
00907     PyModule_AddIntConstant(submodule, (char *)"MINKOVSKY_FOUR", TEX_MINKOVSKY_FOUR);
00908     PyModule_AddIntConstant(submodule, (char *)"MINKOVSKY", TEX_MINKOVSKY);
00909 
00910     return submodule;
00911 }