Merged changes in the trunk up to revision 42425.

Conflicts resolved:
doc/python_api/sphinx_doc_gen.py
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/space_view3d/drawobject.c
This commit is contained in:
2011-12-05 02:12:49 +00:00
343 changed files with 8806 additions and 6318 deletions

View File

@@ -37,14 +37,12 @@ set(SRC
blf_py_api.c
bpy_internal_import.c
idprop_py_api.c
noise_py_api.c
py_capi_utils.c
bgl.h
blf_py_api.h
bpy_internal_import.h
idprop_py_api.h
noise_py_api.h
py_capi_utils.h
)

View File

@@ -151,9 +151,9 @@ PyObject *BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent)
case IDP_GROUP:
return idprop_py_from_idp_group(id, prop, parent);
case IDP_ARRAY:
return idprop_py_from_idp_idparray(id, prop);
return idprop_py_from_idp_array(id, prop);
case IDP_IDPARRAY: /* this could be better a internal type */
idprop_py_from_idp_array(id, prop);
return idprop_py_from_idp_idparray(id, prop);
default:
Py_RETURN_NONE;
}

View File

@@ -1,792 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* This is a new part of Blender.
*
* Contributor(s): eeshlo, Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/noise_py_api.c
* \ingroup pygen
*
* This file defines the 'noise' module, a general purpose module to access
* blenders noise functions.
*/
/************************/
/* Blender Noise Module */
/************************/
#include <Python.h>
#include "structseq.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "DNA_texture_types.h"
#include "noise_py_api.h"
/*-----------------------------------------*/
/* 'mersenne twister' random number generator */
/*
A C-program for MT19937, with initialization improved 2002/2/10.
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
/* 2.5 update
* Noise.setRandomSeed --> seed_set
* Noise.randuvec --> random_unit_vector
* Noise.vNoise --> noise_vector
* Noise.vTurbulence --> turbulence_vector
* Noise.multiFractal --> multi_fractal
* Noise.cellNoise --> cell
* Noise.cellNoiseV --> cell_vector
* Noise.vlNoise --> vl_vector
* Noise.heteroTerrain --> hetero_terrain
* Noise.hybridMFractal --> hybrid_multi_fractal
* Noise.fBm --> fractal
* Noise.ridgedMFractal --> ridged_multi_fractal
*
* Const's *
* Noise.NoiseTypes --> types
* Noise.DistanceMetrics --> distance_metrics
*/
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) (((u) & UMASK) | ((v) & LMASK))
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
static unsigned long state[N]; /* the array for the state vector */
static int left = 1;
static int initf = 0;
static unsigned long *next;
/* initializes state[N] with a seed */
static void init_genrand(unsigned long s)
{
int j;
state[0] = s & 0xffffffffUL;
for (j = 1; j < N; j++) {
state[j] =
(1812433253UL *
(state[j - 1] ^ (state[j - 1] >> 30)) + j);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array state[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
state[j] &= 0xffffffffUL; /* for >32 bit machines */
}
left = 1;
initf = 1;
}
static void next_state(void)
{
unsigned long *p = state;
int j;
/* if init_genrand() has not been called, */
/* a default initial seed is used */
if (initf == 0)
init_genrand(5489UL);
left = N;
next = state;
for (j = N - M + 1; --j; p++)
*p = p[M] ^ TWIST(p[0], p[1]);
for (j = M; --j; p++)
*p = p[M - N] ^ TWIST(p[0], p[1]);
*p = p[M - N] ^ TWIST(p[0], state[0]);
}
/*------------------------------------------------------------*/
static void setRndSeed(int seed)
{
if (seed == 0)
init_genrand(time(NULL));
else
init_genrand(seed);
}
/* float number in range [0, 1) using the mersenne twister rng */
static float frand(void)
{
unsigned long y;
if (--left == 0)
next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (float) y / 4294967296.f;
}
/*------------------------------------------------------------*/
/* returns random unit vector */
static void randuvec(float v[3])
{
float r;
v[2] = 2.f * frand() - 1.f;
if ((r = 1.f - v[2] * v[2]) > 0.f) {
float a = (float)(6.283185307f * frand());
r = (float)sqrt(r);
v[0] = (float)(r * cosf(a));
v[1] = (float)(r * sinf(a));
}
else {
v[2] = 1.f;
}
}
static PyObject *Noise_random(PyObject *UNUSED(self))
{
return PyFloat_FromDouble(frand());
}
static PyObject *Noise_random_unit_vector(PyObject *UNUSED(self))
{
float v[3] = {0.0f, 0.0f, 0.0f};
randuvec(v);
return Py_BuildValue("[fff]", v[0], v[1], v[2]);
}
/*---------------------------------------------------------------------*/
/* Random seed init. Only used for MT random() & randuvec() */
static PyObject *Noise_seed_set(PyObject *UNUSED(self), PyObject *args)
{
int s;
if (!PyArg_ParseTuple(args, "i:seed_set", &s))
return NULL;
setRndSeed(s);
Py_RETURN_NONE;
}
/*-------------------------------------------------------------------------*/
/* General noise */
static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z;
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)|i:noise", &x, &y, &z, &nb))
return NULL;
return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, x, y, z, 0, nb) - 1.0f));
}
/*-------------------------------------------------------------------------*/
/* General Vector noise */
static void noise_vector(float x, float y, float z, int nb, float v[3])
{
/* Simply evaluate noise at 3 different positions */
v[0]= (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0,
nb) - 1.0f);
v[1]= (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
v[2]= (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0,
nb) - 1.0f);
}
static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, v[3];
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)|i:vector", &x, &y, &z, &nb))
return NULL;
noise_vector(x, y, z, nb, v);
return Py_BuildValue("[fff]", v[0], v[1], v[2]);
}
/*---------------------------------------------------------------------------*/
/* General turbulence */
static float turb(float x, float y, float z, int oct, int hard, int nb,
float ampscale, float freqscale)
{
float amp, out, t;
int i;
amp = 1.f;
out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
if (hard)
out = fabsf(out);
for (i = 1; i < oct; i++) {
amp *= ampscale;
x *= freqscale;
y *= freqscale;
z *= freqscale;
t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f));
if (hard)
t = fabsf(t);
out += t;
}
return out;
}
static PyObject *Noise_turbulence(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z;
int oct, hd, nb = 1;
float as = 0.5, fs = 2.0;
if (!PyArg_ParseTuple(args, "(fff)ii|iff:turbulence", &x, &y, &z, &oct, &hd, &nb, &as, &fs))
return NULL;
return PyFloat_FromDouble(turb(x, y, z, oct, hd, nb, as, fs));
}
/*--------------------------------------------------------------------------*/
/* Turbulence Vector */
static void vTurb(float x, float y, float z, int oct, int hard, int nb,
float ampscale, float freqscale, float v[3])
{
float amp, t[3];
int i;
amp = 1.f;
noise_vector(x, y, z, nb, v);
if (hard) {
v[0] = fabsf(v[0]);
v[1] = fabsf(v[1]);
v[2] = fabsf(v[2]);
}
for (i = 1; i < oct; i++) {
amp *= ampscale;
x *= freqscale;
y *= freqscale;
z *= freqscale;
noise_vector(x, y, z, nb, t);
if (hard) {
t[0] = fabsf(t[0]);
t[1] = fabsf(t[1]);
t[2] = fabsf(t[2]);
}
v[0] += amp * t[0];
v[1] += amp * t[1];
v[2] += amp * t[2];
}
}
static PyObject *Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, v[3];
int oct, hd, nb = 1;
float as = 0.5, fs = 2.0;
if (!PyArg_ParseTuple(args, "(fff)ii|iff:turbulence_vector", &x, &y, &z, &oct, &hd, &nb, &as, &fs))
return NULL;
vTurb(x, y, z, oct, hd, nb, as, fs, v);
return Py_BuildValue("[fff]", v[0], v[1], v[2]);
}
/*---------------------------------------------------------------------*/
/* F. Kenton Musgrave's fractal functions */
static PyObject *Noise_fractal(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, H, lac, oct;
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)fff|i:fractal", &x, &y, &z, &H, &lac, &oct, &nb))
return NULL;
return PyFloat_FromDouble(mg_fBm(x, y, z, H, lac, oct, nb));
}
/*------------------------------------------------------------------------*/
static PyObject *Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, H, lac, oct;
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)fff|i:multi_fractal", &x, &y, &z, &H, &lac, &oct, &nb))
return NULL;
return PyFloat_FromDouble(mg_MultiFractal(x, y, z, H, lac, oct, nb));
}
/*------------------------------------------------------------------------*/
static PyObject *Noise_vl_vector(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, d;
int nt1 = 1, nt2 = 1;
if (!PyArg_ParseTuple(args, "(fff)f|ii:vl_vector", &x, &y, &z, &d, &nt1, &nt2))
return NULL;
return PyFloat_FromDouble(mg_VLNoise(x, y, z, d, nt1, nt2));
}
/*-------------------------------------------------------------------------*/
static PyObject *Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, H, lac, oct, ofs;
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)ffff|i:hetero_terrain", &x, &y, &z, &H, &lac, &oct, &ofs, &nb))
return NULL;
return PyFloat_FromDouble(mg_HeteroTerrain(x, y, z, H, lac, oct, ofs, nb));
}
/*-------------------------------------------------------------------------*/
static PyObject *Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, H, lac, oct, ofs, gn;
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)fffff|i:hybrid_multi_fractal", &x, &y, &z, &H, &lac, &oct, &ofs, &gn, &nb))
return NULL;
return PyFloat_FromDouble(mg_HybridMultiFractal(x, y, z, H, lac, oct, ofs, gn, nb));
}
/*------------------------------------------------------------------------*/
static PyObject *Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, H, lac, oct, ofs, gn;
int nb = 1;
if (!PyArg_ParseTuple(args, "(fff)fffff|i:ridged_multi_fractal", &x, &y, &z, &H, &lac, &oct, &ofs, &gn, &nb))
return NULL;
return PyFloat_FromDouble(mg_RidgedMultiFractal(x, y, z, H, lac, oct, ofs, gn, nb));
}
/*-------------------------------------------------------------------------*/
static PyObject *Noise_voronoi(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, da[4], pa[12];
int dtype = 0;
float me = 2.5; /* default minkovsky exponent */
if (!PyArg_ParseTuple(args, "(fff)|if:voronoi", &x, &y, &z, &dtype, &me))
return NULL;
voronoi(x, y, z, da, pa, me, dtype);
return Py_BuildValue("[[ffff][[fff][fff][fff][fff]]]",
da[0], da[1], da[2], da[3],
pa[0], pa[1], pa[2],
pa[3], pa[4], pa[5],
pa[6], pa[7], pa[8], pa[9], pa[10], pa[11]);
}
/*-------------------------------------------------------------------------*/
static PyObject *Noise_cell(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z;
if (!PyArg_ParseTuple(args, "(fff):cell", &x, &y, &z))
return NULL;
return PyFloat_FromDouble(cellNoise(x, y, z));
}
/*--------------------------------------------------------------------------*/
static PyObject *Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
{
float x, y, z, ca[3];
if (!PyArg_ParseTuple(args, "(fff):cell_vector", &x, &y, &z))
return NULL;
cellNoiseV(x, y, z, ca);
return Py_BuildValue("[fff]", ca[0], ca[1], ca[2]);
}
/*--------------------------------------------------------------------------*/
/* For all other Blender modules, this stuff seems to be put in a header file.
This doesn't seem really appropriate to me, so I just put it here, feel free to change it.
In the original module I actually kept the docs stings with the functions themselves,
but I grouped them here so that it can easily be moved to a header if anyone thinks that is necessary. */
PyDoc_STRVAR(random__doc__,
"() No arguments.\n\n\
Returns a random floating point number in the range [0, 1)"
);
PyDoc_STRVAR(random_unit_vector__doc__,
"() No arguments.\n\nReturns a random unit vector (3-float list)."
);
PyDoc_STRVAR(seed_set__doc__,
"(seed value)\n\n\
Initializes random number generator.\n\
if seed is zero, the current time will be used instead."
);
PyDoc_STRVAR(noise__doc__,
"((x,y,z) tuple, [noisetype])\n\n\
Returns general noise of the optional specified type.\n\
Optional argument noisetype determines the type of noise, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(noise_vector__doc__,
"((x,y,z) tuple, [noisetype])\n\n\
Returns noise vector (3-float list) of the optional specified type.\
Optional argument noisetype determines the type of noise, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(turbulence__doc__,
"((x,y,z) tuple, octaves, hard, [noisebasis], [ampscale], [freqscale])\n\n\
Returns general turbulence value using the optional specified noisebasis function.\n\
octaves (integer) is the number of noise values added.\n\
hard (bool), when false (0) returns 'soft' noise, when true (1) returns 'hard' noise (returned value always positive).\n\
Optional arguments:\n\
noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.\n\
ampscale sets the amplitude scale value of the noise frequencies added, 0.5 by default.\n\
freqscale sets the frequency scale factor, 2.0 by default."
);
PyDoc_STRVAR(turbulence_vector__doc__,
"((x,y,z) tuple, octaves, hard, [noisebasis], [ampscale], [freqscale])\n\n\
Returns general turbulence vector (3-float list) using the optional specified noisebasis function.\n\
octaves (integer) is the number of noise values added.\n\
hard (bool), when false (0) returns 'soft' noise, when true (1) returns 'hard' noise (returned vector always positive).\n\
Optional arguments:\n\
noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes.\n\
ampscale sets the amplitude scale value of the noise frequencies added, 0.5 by default.\n\
freqscale sets the frequency scale factor, 2.0 by default."
);
PyDoc_STRVAR(fractal__doc__,
"((x,y,z) tuple, H, lacunarity, octaves, [noisebasis])\n\n\
Returns Fractal Brownian Motion noise value(fBm).\n\
H is the fractal increment parameter.\n\
lacunarity is the gap between successive frequencies.\n\
octaves is the number of frequencies in the fBm.\n\
Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(multi_fractal__doc__,
"((x,y,z) tuple, H, lacunarity, octaves, [noisebasis])\n\n\
Returns Multifractal noise value.\n\
H determines the highest fractal dimension.\n\
lacunarity is gap between successive frequencies.\n\
octaves is the number of frequencies in the fBm.\n\
Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(vl_vector__doc__,
"((x,y,z) tuple, distortion, [noisetype1], [noisetype2])\n\n\
Returns Variable Lacunarity Noise value, a distorted variety of noise.\n\
distortion sets the amount of distortion.\n\
Optional arguments noisetype1 and noisetype2 set the noisetype to distort and the noisetype used for the distortion respectively.\n\
See NoiseTypes, both are STDPERLIN by default."
);
PyDoc_STRVAR(hetero_terrain__doc__,
"((x,y,z) tuple, H, lacunarity, octaves, offset, [noisebasis])\n\n\
returns Heterogeneous Terrain value\n\
H determines the fractal dimension of the roughest areas.\n\
lacunarity is the gap between successive frequencies.\n\
octaves is the number of frequencies in the fBm.\n\
offset raises the terrain from 'sea level'.\n\
Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(hybrid_multi_fractal__doc__,
"((x,y,z) tuple, H, lacunarity, octaves, offset, gain, [noisebasis])\n\n\
returns Hybrid Multifractal value.\n\
H determines the fractal dimension of the roughest areas.\n\
lacunarity is the gap between successive frequencies.\n\
octaves is the number of frequencies in the fBm.\n\
offset raises the terrain from 'sea level'.\n\
gain scales the values.\n\
Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(ridged_multi_fractal__doc__,
"((x,y,z) tuple, H, lacunarity, octaves, offset, gain [noisebasis])\n\n\
returns Ridged Multifractal value.\n\
H determines the fractal dimension of the roughest areas.\n\
lacunarity is the gap between successive frequencies.\n\
octaves is the number of frequencies in the fBm.\n\
offset raises the terrain from 'sea level'.\n\
gain scales the values.\n\
Optional argument noisebasis determines the type of noise used for the turbulence, STDPERLIN by default, see NoiseTypes."
);
PyDoc_STRVAR(voronoi__doc__,
"((x,y,z) tuple, distance_metric, [exponent])\n\n\
returns a list, containing a list of distances in order of closest feature,\n\
and a list containing the positions of the four closest features\n\
Optional arguments:\n\
distance_metric: see DistanceMetrics, default is DISTANCE\n\
exponent is only used with MINKOVSKY, default is 2.5."
);
PyDoc_STRVAR(cell__doc__,
"((x,y,z) tuple)\n\n\
returns cellnoise float value."
);
PyDoc_STRVAR(cell_vector__doc__,
"((x,y,z) tuple)\n\n\
returns cellnoise vector/point/color (3-float list)."
);
PyDoc_STRVAR(Noise__doc__,
"Blender Noise and Turbulence Module\n\n\
This module can be used to generate noise of various types.\n\
This can be used for terrain generation, to create textures,\n\
make animations more 'animated', object deformation, etc.\n\
As an example, this code segment when scriptlinked to a framechanged event,\n\
will make the camera sway randomly about, by changing parameters this can\n\
look like anything from an earthquake to a very nervous or maybe even drunk cameraman...\n\
(the camera needs an ipo with at least one Loc & Rot key for this to work!):\n\
\n\
\tfrom Blender import Get, Scene, Noise\n\
\n\
\t####################################################\n\
\t# This controls jitter speed\n\
\tsl = 0.025\n\
\t# This controls the amount of position jitter\n\
\tsp = 0.1\n\
\t# This controls the amount of rotation jitter\n\
\tsr = 0.25\n\
\t####################################################\n\
\n\
\ttime = Get('curtime')\n\
\tob = Scene.GetCurrent().getCurrentCamera()\n\
\tps = (sl*time, sl*time, sl*time)\n\
\t# To add jitter only when the camera moves, use this next line instead\n\
\t#ps = (sl*ob.LocX, sl*ob.LocY, sl*ob.LocZ)\n\
\trv = Noise.turbulence_vector(ps, 3, 0, Noise.NoiseTypes.NEWPERLIN)\n\
\tob.dloc = (sp*rv[0], sp*rv[1], sp*rv[2])\n\
\tob.drot = (sr*rv[0], sr*rv[1], sr*rv[2])\n\
\n"
);
/* Just in case, declarations for a header file */
/*
static PyObject *Noise_random(PyObject *UNUSED(self));
static PyObject *Noise_random_unit_vector(PyObject *UNUSED(self));
static PyObject *Noise_seed_set(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_turbulence(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_fractal(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_vl_vector(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_voronoi(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_cell(PyObject *UNUSED(self), PyObject *args);
static PyObject *Noise_cell_vector(PyObject *UNUSED(self), PyObject *args);
*/
static PyMethodDef NoiseMethods[] = {
{"seed_set", (PyCFunction) Noise_seed_set, METH_VARARGS, seed_set__doc__},
{"random", (PyCFunction) Noise_random, METH_NOARGS, random__doc__},
{"random_unit_vector", (PyCFunction) Noise_random_unit_vector, METH_NOARGS, random_unit_vector__doc__},
{"noise", (PyCFunction) Noise_noise, METH_VARARGS, noise__doc__},
{"vector", (PyCFunction) Noise_vector, METH_VARARGS, noise_vector__doc__},
{"turbulence", (PyCFunction) Noise_turbulence, METH_VARARGS, turbulence__doc__},
{"turbulence_vector", (PyCFunction) Noise_turbulence_vector, METH_VARARGS, turbulence_vector__doc__},
{"fractal", (PyCFunction) Noise_fractal, METH_VARARGS, fractal__doc__},
{"multi_fractal", (PyCFunction) Noise_multi_fractal, METH_VARARGS, multi_fractal__doc__},
{"vl_vector", (PyCFunction) Noise_vl_vector, METH_VARARGS, vl_vector__doc__},
{"hetero_terrain", (PyCFunction) Noise_hetero_terrain, METH_VARARGS, hetero_terrain__doc__},
{"hybrid_multi_fractal", (PyCFunction) Noise_hybrid_multi_fractal, METH_VARARGS, hybrid_multi_fractal__doc__},
{"ridged_multi_fractal", (PyCFunction) Noise_ridged_multi_fractal, METH_VARARGS, ridged_multi_fractal__doc__},
{"voronoi", (PyCFunction) Noise_voronoi, METH_VARARGS, voronoi__doc__},
{"cell", (PyCFunction) Noise_cell, METH_VARARGS, cell__doc__},
{"cell_vector", (PyCFunction) Noise_cell_vector, METH_VARARGS, cell_vector__doc__},
{NULL, NULL, 0, NULL}
};
/*----------------------------------------------------------------------*/
static struct PyModuleDef noise_module_def = {
PyModuleDef_HEAD_INIT,
"noise", /* m_name */
Noise__doc__, /* m_doc */
0, /* m_size */
NoiseMethods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyObject *BPyInit_noise(void)
{
PyObject *submodule = PyModule_Create(&noise_module_def);
/* use current time as seed for random number generator by default */
setRndSeed(0);
/* Constant noisetype dictionary */
if (submodule) {
static PyStructSequence_Field noise_types_fields[] = {
{(char *)"BLENDER", NULL},
{(char *)"STDPERLIN", NULL},
{(char *)"NEWPERLIN", NULL},
{(char *)"VORONOI_F1", NULL},
{(char *)"VORONOI_F2", NULL},
{(char *)"VORONOI_F3", NULL},
{(char *)"VORONOI_F4", NULL},
{(char *)"VORONOI_F2F1", NULL},
{(char *)"VORONOI_CRACKLE", NULL},
{(char *)"CELLNOISE", NULL},
{NULL}
};
static PyStructSequence_Desc noise_types_info_desc = {
(char *)"noise.types", /* name */
(char *)"Noise type", /* doc */
noise_types_fields, /* fields */
(sizeof(noise_types_fields)/sizeof(PyStructSequence_Field)) - 1
};
static PyTypeObject NoiseType;
PyObject *noise_types;
int pos = 0;
PyStructSequence_InitType(&NoiseType, &noise_types_info_desc);
noise_types = PyStructSequence_New(&NoiseType);
if (noise_types == NULL) {
return NULL;
}
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_BLENDER));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_STDPERLIN));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_NEWPERLIN));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F1));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F2));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F3));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F4));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_F2F1));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_VORONOI_CRACKLE));
PyStructSequence_SET_ITEM(noise_types, pos++, PyLong_FromLong(TEX_CELLNOISE));
PyModule_AddObject(submodule, "types", noise_types);
}
if (submodule) {
static PyStructSequence_Field distance_metrics_fields[] = {
{(char *)"DISTANCE", NULL},
{(char *)"DISTANCE_SQUARED", NULL},
{(char *)"MANHATTAN", NULL},
{(char *)"CHEBYCHEV", NULL},
{(char *)"MINKOVSKY_HALF", NULL},
{(char *)"MINKOVSKY_FOUR", NULL},
{(char *)"MINKOVSKY", NULL},
{NULL}
};
static PyStructSequence_Desc noise_types_info_desc = {
(char *)"noise.distance_metrics", /* name */
(char *)"Distance Metrics for noise module.", /* doc */
distance_metrics_fields, /* fields */
(sizeof(distance_metrics_fields)/sizeof(PyStructSequence_Field)) - 1
};
static PyTypeObject DistanceMetrics;
PyObject *distance_metrics;
int pos = 0;
PyStructSequence_InitType(&DistanceMetrics, &noise_types_info_desc);
distance_metrics = PyStructSequence_New(&DistanceMetrics);
if (distance_metrics == NULL) {
return NULL;
}
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_DISTANCE));
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_DISTANCE_SQUARED));
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MANHATTAN));
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_CHEBYCHEV));
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY_HALF));
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY_FOUR));
PyStructSequence_SET_ITEM(distance_metrics, pos++, PyLong_FromLong(TEX_MINKOVSKY));
PyModule_AddObject(submodule, "distance_metrics", distance_metrics);
}
return submodule;
}

View File

@@ -205,10 +205,14 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return PyUnicode_DecodeFSDefault(path);
}
static PyMethodDef meth_bpy_script_paths= {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
static PyMethodDef meth_bpy_blend_paths= {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
static PyMethodDef meth_bpy_user_resource= {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
static PyMethodDef meth_bpy_resource_path= {"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS|METH_KEYWORDS, bpy_resource_path_doc};
static PyMethodDef meth_bpy_script_paths=
{"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
static PyMethodDef meth_bpy_blend_paths=
{"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
static PyMethodDef meth_bpy_user_resource=
{"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
static PyMethodDef meth_bpy_resource_path=
{"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS|METH_KEYWORDS, bpy_resource_path_doc};
static PyObject *bpy_import_test(const char *modname)
@@ -260,16 +264,21 @@ void BPy_init_modules(void)
/* run first, initializes rna types */
BPY_rna_init();
PyModule_AddObject(mod, "types", BPY_rna_types()); /* needs to be first so bpy_types can run */
PyModule_AddObject(mod, "StructMetaPropGroup", (PyObject *)&pyrna_struct_meta_idprop_Type); /* metaclass for idprop types, bpy_types.py needs access */
/* needs to be first so bpy_types can run */
PyModule_AddObject(mod, "types", BPY_rna_types());
bpy_lib_init(mod); /* adds '_bpy._library_load', must be called before 'bpy_types' which uses it */
/* metaclass for idprop types, bpy_types.py needs access */
PyModule_AddObject(mod, "StructMetaPropGroup", (PyObject *)&pyrna_struct_meta_idprop_Type);
/* needs to be first so bpy_types can run */
bpy_lib_init(mod);
bpy_import_test("bpy_types");
PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
bpy_import_test("bpy_types");
PyModule_AddObject(mod, "props", BPY_rna_props());
PyModule_AddObject(mod, "ops", BPY_operator_module()); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
PyModule_AddObject(mod, "props", BPY_rna_props());
/* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
PyModule_AddObject(mod, "ops", BPY_operator_module());
PyModule_AddObject(mod, "app", BPY_app_struct());
/* bpy context */

View File

@@ -159,6 +159,10 @@ static PyObject *make_app_info(void)
/* a few getsets because it makes sense for them to be in bpy.app even though
* they are not static */
PyDoc_STRVAR(bpy_app_debug_doc,
"Boolean, set when blender is running in debug mode (started with --debug)"
);
static PyObject *bpy_app_debug_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
return PyBool_FromLong(G.f & G_DEBUG);
@@ -179,6 +183,9 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *UNUS
return 0;
}
PyDoc_STRVAR(bpy_app_debug_value_doc,
"Int, number which can be set to non-zero values for testing purposes"
);
static PyObject *bpy_app_debug_value_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
return PyLong_FromSsize_t(G.rt);
@@ -198,11 +205,17 @@ static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void
return 0;
}
PyDoc_STRVAR(bpy_app_tempdir_doc,
"String, the temp directory used by blender (read-only)"
);
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
return PyC_UnicodeFromByte(BLI_temporary_dir());
}
PyDoc_STRVAR(bpy_app_driver_dict_doc,
"Dictionary for drivers namespace, editable in-place, reset on file load (read-only)"
);
static PyObject *bpy_app_driver_dict_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
if (bpy_pydriver_Dict == NULL)
@@ -217,10 +230,10 @@ static PyObject *bpy_app_driver_dict_get(PyObject *UNUSED(self), void *UNUSED(cl
static PyGetSetDef bpy_app_getsets[]= {
{(char *)"debug", bpy_app_debug_get, bpy_app_debug_set, (char *)"Boolean, set when blender is running in debug mode (started with -d)", NULL},
{(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)"Int, number which can be set to non-zero values for testing purposes.", NULL},
{(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)"String, the temp directory used by blender (read-only)", NULL},
{(char *)"driver_namespace", bpy_app_driver_dict_get, NULL, (char *)"Dictionary for drivers namespace, editable in-place, reset on file load (read-only)", NULL},
{(char *)"debug", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, NULL},
{(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)bpy_app_debug_value_doc, NULL},
{(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)bpy_app_tempdir_doc, NULL},
{(char *)"driver_namespace", bpy_app_driver_dict_get, NULL, (char *)bpy_app_driver_dict_doc, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
@@ -253,4 +266,3 @@ PyObject *BPY_app_struct(void)
return ret;
}

View File

@@ -82,7 +82,7 @@ int bpy_pydriver_create_dict(void)
}
/* add noise to global namespace */
mod= PyImport_ImportModuleLevel((char *)"noise", NULL, NULL, NULL, 0);
mod= PyImport_ImportModuleLevel((char *)"mathutils.noise", NULL, NULL, NULL, 0);
if (mod) {
PyDict_SetItemString(bpy_pydriver_Dict, "noise", mod);
Py_DECREF(mod);

View File

@@ -71,7 +71,6 @@
/* inittab initialization functions */
#include "../generic/bgl.h"
#include "../generic/blf_py_api.h"
#include "../generic/noise_py_api.h"
#include "../mathutils/mathutils.h"
/* for internal use, when starting and ending python scripts */
@@ -134,9 +133,12 @@ void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate)
fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
}
else if (py_call_level==0) {
// XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still.
//BPy_SetContext(NULL);
//bpy_import_main_set(NULL);
/* XXX - Calling classes currently wont store the context :\,
* cant set NULL because of this. but this is very flakey still. */
#if 0
BPy_SetContext(NULL);
bpy_import_main_set(NULL);
#endif
#ifdef TIME_PY_RUN
bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run;
@@ -178,9 +180,9 @@ extern PyObject *AUD_initPython(void);
extern PyObject *CYCLES_initPython(void);
static struct _inittab bpy_internal_modules[]= {
{(char *)"noise", BPyInit_noise},
{(char *)"mathutils", PyInit_mathutils},
// {(char *)"mathutils.geometry", PyInit_mathutils_geometry},
// {(char *)"mathutils.noise", PyInit_mathutils_noise},
{(char *)"bgl", BPyInit_bgl},
{(char *)"blf", BPyInit_blf},
#ifdef WITH_AUDASPACE
@@ -329,7 +331,8 @@ typedef struct {
} PyModuleObject;
#endif
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump)
static int python_script_exec(bContext *C, const char *fn, struct Text *text,
struct ReportList *reports, const short do_jump)
{
PyObject *main_mod= NULL;
PyObject *py_dict= NULL, *py_result= NULL;
@@ -717,7 +720,10 @@ void bpy_module_delay_init(PyObject *bpy_proxy)
{
const int argc= 1;
const char *argv[2];
PyObject *filename_obj= PyModule_GetFilenameObject(bpy_proxy); /* updating the module dict below will loose the reference to __file__ */
/* updating the module dict below will loose the reference to __file__ */
PyObject *filename_obj= PyModule_GetFilenameObject(bpy_proxy);
const char *filename_rel= _PyUnicode_AsString(filename_obj); /* can be relative */
char filename_abs[1024];

View File

@@ -265,8 +265,8 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
/* create a dummy */
self_from= PyObject_New(BPy_Library, &bpy_lib_Type);
BLI_strncpy(self_from->relpath, self->relpath, sizeof(BPy_Library));
BLI_strncpy(self_from->abspath, self->abspath, sizeof(BPy_Library));
BLI_strncpy(self_from->relpath, self->relpath, sizeof(self_from->relpath));
BLI_strncpy(self_from->abspath, self->abspath, sizeof(self_from->abspath));
self_from->blo_handle= NULL;
self_from->flag= 0;
@@ -396,6 +396,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
return NULL;
}
else {
Library *lib= mainl->curlib; /* newly added lib, assign before append end */
BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag);
BLO_blendhandle_close(self->blo_handle);
self->blo_handle= NULL;
@@ -406,9 +407,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
/* append, rather than linking */
if ((self->flag & FILE_LINK)==0) {
Library *lib= BLI_findstring(&G.main->library, self->abspath, offsetof(Library, name));
if (lib) BKE_library_make_local(bmain, lib, 1);
else BLI_assert(!"cant find name of just added library!");
BKE_library_make_local(bmain, lib, 1);
}
}
@@ -426,7 +425,10 @@ static PyObject *bpy_lib_dir(BPy_Library *self)
int bpy_lib_init(PyObject *mod_par)
{
static PyMethodDef load_meth= {"load", (PyCFunction)bpy_lib_load, METH_STATIC|METH_VARARGS|METH_KEYWORDS, bpy_lib_load_doc};
static PyMethodDef load_meth= {"load", (PyCFunction)bpy_lib_load,
METH_STATIC|METH_VARARGS|METH_KEYWORDS,
bpy_lib_load_doc};
PyModule_AddObject(mod_par, "_library_load", PyCFunction_New(&load_meth, NULL));
/* some compilers dont like accessing this directly, delay assignment */

View File

@@ -31,11 +31,6 @@
* which fakes exposing operators as modules/functions using its own classes.
*/
/* Note, this module is not to be used directly by the user.
* Internally its exposed as '_bpy.ops', which provides functions for 'bpy.ops', a python package.
* */
#include <Python.h>
#include "RNA_types.h"
@@ -78,7 +73,8 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
int context= WM_OP_EXEC_DEFAULT;
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
bContext *C= (bContext *)BPy_GetContext();
if (C==NULL) {
@@ -152,7 +148,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
/* note that context is an int, python does the conversion in this case */
int context= WM_OP_EXEC_DEFAULT;
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
bContext *C= (bContext *)BPy_GetContext();
if (C==NULL) {

View File

@@ -233,7 +233,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc
static int bpy_prop_callback_check(PyObject *py_func, int argcount)
{
if (py_func) {
if (py_func && py_func != Py_None) {
if (!PyFunction_Check(py_func)) {
PyErr_Format(PyExc_TypeError,
"update keyword: expected a function type, not a %.200s",
@@ -301,7 +301,7 @@ static int py_long_as_int(PyObject *py_long, int *r_int)
if (srna==NULL) { \
if (PyErr_Occurred()) \
return NULL; \
return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \
return bpy_prop_deferred_return(pymeth_##_func, kw); \
} \
/* terse macros for error checks shared between all funcs cant use function
@@ -370,7 +370,8 @@ static int bpy_struct_id_used(StructRNA *srna, char *identifier)
#endif
/* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna along
/* Function that sets RNA, NOTE - self is NULL when called from python,
* but being abused from C so we can pass the srna along.
* This isnt incorrect since its a python object - but be careful */
PyDoc_STRVAR(BPy_BoolProperty_doc,
".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
@@ -392,7 +393,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(BoolProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"options", "subtype", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int def=0;
@@ -459,7 +461,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(BoolVectorProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", "size", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"options", "subtype", "size", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int def[PYRNA_STACK_ARRAY]={0};
@@ -485,7 +488,9 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items)
if (size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "BoolVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
PyErr_Format(PyExc_TypeError,
"BoolVectorProperty(size=%d): size must be between 0 and "
STRINGIFY(PYRNA_STACK_ARRAY), size);
return NULL;
}
@@ -534,7 +539,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(IntProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max", "step", "options", "subtype", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def=0;
@@ -603,7 +609,9 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(IntVectorProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
"step", "options", "subtype", "size", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0};
@@ -631,7 +639,9 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items)
if (size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "IntVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
PyErr_Format(PyExc_TypeError,
"IntVectorProperty(size=%d): size must be between 0 and "
STRINGIFY(PYRNA_STACK_ARRAY), size);
return NULL;
}
@@ -682,7 +692,9 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(FloatProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
"step", "precision", "options", "subtype", "unit", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f;
@@ -761,7 +773,9 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
BPY_PROPDEF_HEAD(FloatVectorProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", "size", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
"step", "precision", "options", "subtype", "unit", "size", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f};
@@ -796,7 +810,9 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
}
if (size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
PyErr_Format(PyExc_TypeError,
"FloatVectorProperty(size=%d): size must be between 0 and "
STRINGIFY(PYRNA_STACK_ARRAY), size);
return NULL;
}
@@ -845,7 +861,8 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
BPY_PROPDEF_HEAD(StringProperty)
if (srna) {
static const char *kwlist[]= {"attr", "name", "description", "default", "maxlen", "options", "subtype", "update", NULL};
static const char *kwlist[]= {"attr", "name", "description", "default",
"maxlen", "options", "subtype", "update", NULL};
const char *id=NULL, *name="", *description="", *def="";
int id_len;
int maxlen=0;
@@ -913,7 +930,10 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
if (is_enum_flag) {
if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
PyErr_SetString(PyExc_TypeError, "EnumProperty(...): maximum " STRINGIFY(RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property");
PyErr_SetString(PyExc_TypeError,
"EnumProperty(...): maximum "
STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
" members for a ENUM_FLAG type property");
return NULL;
}
if (def && !PySet_Check(def)) {
@@ -1026,7 +1046,8 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
* immediately after use, so we need to duplicate them, ugh.
* annoying because it works most of the time without this. */
{
EnumPropertyItem *items_dup= MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), "enum_items_from_py2");
EnumPropertyItem *items_dup= MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
"enum_items_from_py2");
EnumPropertyItem *items_ptr= items_dup;
char *buf= ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
@@ -1077,7 +1098,9 @@ static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *pt
PyObject *items_fast;
int defvalue_dummy=0;
if (!(items_fast= PySequence_Fast(items, "EnumProperty(...): return value from the callback was not a sequence"))) {
if (!(items_fast= PySequence_Fast(items, "EnumProperty(...): "
"return value from the callback was not a sequence")))
{
err= -1;
}
else {
@@ -1137,7 +1160,8 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(EnumProperty)
if (srna) {
static const char *kwlist[]= {"attr", "items", "name", "description", "default", "options", "update", NULL};
static const char *kwlist[]= {"attr", "items", "name", "description", "default",
"options", "update", NULL};
const char *id=NULL, *name="", *description="";
PyObject *def= NULL;
int id_len;
@@ -1187,7 +1211,9 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
eitems= DummyRNA_NULL_items;
}
else {
if (!(items_fast= PySequence_Fast(items, "EnumProperty(...): expected a sequence of tuples for the enum items or a function"))) {
if (!(items_fast= PySequence_Fast(items, "EnumProperty(...): "
"expected a sequence of tuples for the enum items or a function")))
{
return NULL;
}
@@ -1206,7 +1232,10 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (is_itemf) {
RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
RNA_def_enum_py_data(prop, (void *)items);
/* Py_INCREF(items); */ /* watch out!, if user is tricky they can probably crash blender if they manage to free the callback, take care! */
/* watch out!, if a user is tricky they can probably crash blender
* if they manage to free the callback, take care! */
/* Py_INCREF(items); */
}
if (pyopts) {

View File

@@ -367,7 +367,8 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
#ifdef USE_MATHUTILS
#include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
/* bpyrna vector/euler/quat callbacks */
@@ -589,7 +590,15 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_
/* note that PROP_NONE is included as a vector subtype. this is because its handy to
* have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */
#define PROP_ALL_VECTOR_SUBTYPES PROP_COORDS: case PROP_TRANSLATION: case PROP_DIRECTION: case PROP_VELOCITY: case PROP_ACCELERATION: case PROP_XYZ: case PROP_XYZ_LENGTH
#define PROP_ALL_VECTOR_SUBTYPES \
PROP_COORDS: \
case PROP_TRANSLATION: \
case PROP_DIRECTION: \
case PROP_VELOCITY: \
case PROP_ACCELERATION: \
case PROP_XYZ: \
case PROP_XYZ_LENGTH \
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
{
@@ -2098,8 +2107,18 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
/* special case: bpy.data.objects["some_id_name", "//some_lib_name.blend"]
* also for: bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback) */
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key, const char *err_prefix, const short err_not_found)
* also for: bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)
*
* note:
* error codes since this is not to be called directly from python,
* this matches pythons __contains__ values capi.
* -1: exception set
* 0: not found
* 1: found */
int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *self, PyObject *key,
const char *err_prefix, const short err_not_found,
PointerRNA *r_ptr
)
{
char *keyname;
@@ -2108,24 +2127,24 @@ static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *s
PyErr_Format(PyExc_KeyError,
"%s: tuple key must be a pair, not size %d",
err_prefix, PyTuple_GET_SIZE(key));
return NULL;
return -1;
}
else if (self->ptr.type != &RNA_BlendData) {
PyErr_Format(PyExc_KeyError,
"%s: is only valid for bpy.data collections, not %.200s",
err_prefix, RNA_struct_identifier(self->ptr.type));
return NULL;
return -1;
}
else if ((keyname= _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
PyErr_Format(PyExc_KeyError,
"%s: id must be a string, not %.200s",
err_prefix, Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
return NULL;
return -1;
}
else {
PyObject *keylib= PyTuple_GET_ITEM(key, 1);
Library *lib;
PyObject *ret= NULL;
int found= FALSE;
if (keylib == Py_None) {
lib= NULL;
@@ -2140,16 +2159,19 @@ static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *s
"%s: lib name '%.240s' "
"does not reference a valid library",
err_prefix, keylib_str);
return -1;
}
else {
return 0;
}
return NULL;
}
}
else {
PyErr_Format(PyExc_KeyError,
"%s: lib must be a sting or None, not %.200s",
err_prefix, Py_TYPE(keylib)->tp_name);
return NULL;
return -1;
}
/* lib is either a valid poniter or NULL,
@@ -2158,23 +2180,43 @@ static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *s
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
ID *id= itemptr.data; /* always an ID */
if (id->lib == lib && (strncmp(keyname, id->name+2, sizeof(id->name)-2) == 0)) {
ret= pyrna_struct_CreatePyObject(&itemptr);
found= TRUE;
if (r_ptr) {
*r_ptr= itemptr;
}
break;
}
}
RNA_PROP_END;
/* we may want to fail silently as with collection.get() */
if ((ret == NULL) && err_not_found) {
if ((found == FALSE) && err_not_found) {
/* only runs for getitem access so use fixed string */
PyErr_SetString(PyExc_KeyError,
"bpy_prop_collection[key, lib]: not found");
return -1;
}
else {
return found; /* 1 / 0, no exception */
}
return ret;
}
}
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
const char *err_prefix, const short err_not_found)
{
PointerRNA ptr;
const int contains= pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
if (contains == 1) {
return pyrna_struct_CreatePyObject(&ptr);
}
else {
return NULL;
}
}
static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
{
CollectionPropertyIterator rna_macro_iter;
@@ -2188,7 +2230,10 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py
list= PyList_New(0);
/* first loop up-until the start */
for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
for (RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
rna_macro_iter.valid;
RNA_property_collection_next(&rna_macro_iter))
{
/* PointerRNA itemptr= rna_macro_iter.ptr; */
if (count == start) {
break;
@@ -2197,7 +2242,9 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py
}
/* add items until stop */
for (; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
for (; rna_macro_iter.valid;
RNA_property_collection_next(&rna_macro_iter))
{
item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
PyList_Append(list, item);
Py_DECREF(item);
@@ -2217,7 +2264,8 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py
* note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
* since at the moment it reads (and even allocates) the entire array for each index.
*/
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop,
Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
{
int count, totdim;
PyObject *tuple;
@@ -2347,7 +2395,8 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
}
else if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair(self, key, "bpy_prop_collection[id, lib]", TRUE);
return pyrna_prop_collection_subscript_str_lib_pair(self, key,
"bpy_prop_collection[id, lib]", TRUE);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2532,7 +2581,8 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
}
/* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length, PyObject *value_orig)
static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
int start, int stop, int length, PyObject *value_orig)
{
PyObject *value;
int count;
@@ -2540,7 +2590,8 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
int ret= 0;
if (value_orig == NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]= value: deleting with list types is not supported by bpy_struct");
PyErr_SetString(PyExc_TypeError,
"bpy_prop_array[slice]= value: deleting with list types is not supported by bpy_struct");
return -1;
}
@@ -2550,7 +2601,8 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
if (PySequence_Fast_GET_SIZE(value) != stop-start) {
Py_DECREF(value);
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]= value: resizing bpy_struct arrays isn't supported");
PyErr_SetString(PyExc_TypeError,
"bpy_prop_array[slice]= value: resizing bpy_struct arrays isn't supported");
return -1;
}
@@ -2751,22 +2803,30 @@ static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
return pyrna_array_contains_py(&self->ptr, self->prop, value);
}
static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value)
static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
{
PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
/* key in dict style check */
const char *keyname= _PyUnicode_AsString(value);
if (keyname==NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
return -1;
if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
"(id, lib) in bpy_prop_collection", FALSE, NULL);
}
else {
if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
return 1;
/* key in dict style check */
const char *keyname= _PyUnicode_AsString(key);
return 0;
if (keyname==NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string or a typle of strings");
return -1;
}
if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
return 1;
return 0;
}
}
static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
@@ -3459,9 +3519,12 @@ static int pyrna_struct_pydict_contains(PyObject *self, PyObject *pyname)
#endif
//--------------- setattr-------------------------------------------
static int pyrna_is_deferred_prop(PyObject *value)
static int pyrna_is_deferred_prop(const PyObject *value)
{
return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value)==2 && PyCallable_Check(PyTuple_GET_ITEM(value, 0)) && PyDict_CheckExact(PyTuple_GET_ITEM(value, 1));
return PyTuple_CheckExact(value) &&
PyTuple_GET_SIZE(value) == 2 &&
PyCFunction_Check(PyTuple_GET_ITEM(value, 0)) &&
PyDict_CheckExact(PyTuple_GET_ITEM(value, 1));
}
#if 0
@@ -3472,7 +3535,7 @@ static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr
/* Allows:
* >>> bpy.types.Scene.foo= BoolProperty()
* >>> bpy.types.Scene.foo
* <bpy_struct, BooleanProperty("foo")>
* <bpy_struct, BoolProperty("foo")>
* ...rather than returning the deferred class register tuple as checked by pyrna_is_deferred_prop()
*
* Disable for now, this is faking internal behavior in a way thats too tricky to maintain well. */
@@ -3499,8 +3562,9 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
{
StructRNA *srna= srna_from_self(cls, "StructRNA.__setattr__");
const int is_deferred_prop= (value && pyrna_is_deferred_prop(value));
const char *attr_str= _PyUnicode_AsString(attr);
if (srna && !pyrna_write_check() && (is_deferred_prop || RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)))) {
if (srna && !pyrna_write_check() && (is_deferred_prop || RNA_struct_type_find_property(srna, attr_str))) {
PyErr_Format(PyExc_AttributeError,
"pyrna_struct_meta_idprop_setattro() "
"can't set in readonly state '%.200s.%S'",
@@ -3538,14 +3602,12 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
}
else {
/* remove existing property if its set or we also end up with confusion */
const char *attr_str= _PyUnicode_AsString(attr);
RNA_def_property_free_identifier(srna, attr_str); /* ignore on failure */
}
}
else { /* __delattr__ */
/* first find if this is a registered property */
const char *attr_str= _PyUnicode_AsString(attr);
int ret= RNA_def_property_free_identifier(srna, attr_str);
const int ret= RNA_def_property_free_identifier(srna, attr_str);
if (ret == -1) {
PyErr_Format(PyExc_TypeError,
"struct_meta_idprop.detattr(): '%s' not a dynamic property",
@@ -3801,6 +3863,10 @@ static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObje
Py_RETURN_NONE;
}
PyDoc_STRVAR(pyrna_struct_get_id_data_doc,
"The :class:`bpy.types.ID` object this datablock is from or None, (not available for all data types)"
);
static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
{
/* used for struct and pointer since both have a ptr */
@@ -3813,11 +3879,17 @@ static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
Py_RETURN_NONE;
}
PyDoc_STRVAR(pyrna_struct_get_data_doc,
"The data this property is using, *type* :class:`bpy.types.bpy_struct`"
);
static PyObject *pyrna_struct_get_data(BPy_DummyPointerRNA *self)
{
return pyrna_struct_CreatePyObject(&self->ptr);
}
PyDoc_STRVAR(pyrna_struct_get_rna_type_doc,
"The property type for introspection"
);
static PyObject *pyrna_struct_get_rna_type(BPy_PropertyRNA *self)
{
PointerRNA tptr;
@@ -3832,18 +3904,18 @@ static PyObject *pyrna_struct_get_rna_type(BPy_PropertyRNA *self)
/*****************************************************************************/
static PyGetSetDef pyrna_prop_getseters[]= {
{(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`bpy.types.ID` object this datablock is from or None, (not available for all data types)", NULL},
{(char *)"data", (getter)pyrna_struct_get_data, (setter)NULL, (char *)"The data this property is using, *type* :class:`bpy.types.bpy_struct`", NULL},
{(char *)"rna_type", (getter)pyrna_struct_get_rna_type, (setter)NULL, (char *)"The property type for introspection", NULL},
{(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)pyrna_struct_get_id_data_doc, NULL},
{(char *)"data", (getter)pyrna_struct_get_data, (setter)NULL, (char *)pyrna_struct_get_data_doc, NULL},
{(char *)"rna_type", (getter)pyrna_struct_get_rna_type, (setter)NULL, (char *)pyrna_struct_get_rna_type_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef pyrna_struct_getseters[]= {
{(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)"The :class:`bpy.types.ID` object this datablock is from or None, (not available for all data types)", NULL},
{(char *)"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, (char *)pyrna_struct_get_id_data_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
PyDoc_STRVAR(pyrna_prop_collection_keys_doc,
".. method:: keys()\n"
"\n"
@@ -3908,7 +3980,8 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
MEM_freeN(nameptr);
}
else {
PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */
/* a bit strange but better then returning an empty list */
PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i));
}
PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
@@ -4030,7 +4103,8 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
return pyrna_struct_CreatePyObject(&newptr);
}
else if (PyTuple_Check(key_ob)) {
PyObject *ret= pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, "bpy_prop_collection.get((id, lib))", FALSE);
PyObject *ret= pyrna_prop_collection_subscript_str_lib_pair(self, key_ob,
"bpy_prop_collection.get((id, lib))", FALSE);
if (ret) {
return ret;
}
@@ -4066,10 +4140,12 @@ static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr,
/* pyrna_prop_collection_foreach_get/set both use this */
static int foreach_parse_args(
BPy_PropertyRNA *self, PyObject *args,
BPy_PropertyRNA *self, PyObject *args,
/*values to assign */
const char **attr, PyObject **seq, int *tot, int *size, RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
const char **attr, PyObject **seq, int *tot, int *size,
RawPropertyType *raw_type, int *attr_tot, int *attr_signed
)
{
#if 0
int array_tot;
@@ -4748,7 +4824,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
const char *fn;
int lineno;
PyC_FileAndNum(&fn, &lineno);
printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), fn, lineno);
printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n",
RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), fn, lineno);
}
*/
@@ -5899,7 +5976,9 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
// if (!descr) descr= "(no docs)";
// "__doc__", descr
if (RNA_struct_idprops_check(srna) && !PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type)) {
if ( RNA_struct_idprops_check(srna) &&
!PyObject_IsSubclass(py_base, (PyObject *)&pyrna_struct_meta_idprop_Type))
{
metaclass= (PyObject *)&pyrna_struct_meta_idprop_Type;
}
else {
@@ -5907,7 +5986,8 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
}
/* always use O not N when calling, N causes refcount errors */
newclass= PyObject_CallFunction(metaclass, (char *)"s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__");
newclass= PyObject_CallFunction(metaclass, (char *)"s(O){sss()}",
idname, py_base, "__module__","bpy.types", "__slots__");
/* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */
@@ -6535,7 +6615,8 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
arg_count= ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
/* note, the number of args we check for and the number of args we give to
* @classmethods are different (quirk of python), this is why rna_function_arg_count() doesn't return the value -1*/
* @classmethods are different (quirk of python),
* this is why rna_function_arg_count() doesn't return the value -1*/
if (flag & FUNC_NO_SELF)
func_arg_count++;
@@ -6870,7 +6951,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* only useful for single argument returns, we'll need another list loop for multiple */
if (flag & PROP_OUTPUT) {
err= pyrna_py_to_prop(&funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:");
err= pyrna_py_to_prop(&funcptr, parm, iter.data,
PyTuple_GET_ITEM(ret, i++),
"calling class function:");
if (err) {
break;
}
@@ -7069,7 +7152,8 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
identifier= ((PyTypeObject*)py_class)->tp_name;
srna_new= reg(CTX_data_main(C), &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free);
srna_new= reg(CTX_data_main(C), &reports, py_class, identifier,
bpy_class_validate, bpy_class_call, bpy_class_free);
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
@@ -7167,7 +7251,9 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
unreg= RNA_struct_unregister(srna);
if (!unreg) {
PyErr_SetString(PyExc_ValueError, "unregister_class(...): expected a Type subclassed from a registerable rna type (no unregister supported)");
PyErr_SetString(PyExc_ValueError,
"unregister_class(...): "
"expected a Type subclassed from a registerable rna type (no unregister supported)");
return NULL;
}

View File

@@ -55,8 +55,9 @@
#define FALSE 0
/* for keyframes and drivers */
static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
const char **path_full, int *index)
static int pyrna_struct_anim_args_parse(
PointerRNA *ptr, const char *error_prefix, const char *path,
const char **path_full, int *index)
{
const int is_idbase= RNA_struct_is_ID(ptr->type);
PropertyRNA *prop;
@@ -146,8 +147,9 @@ static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefi
}
/* internal use for insert and delete */
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
static int pyrna_struct_keyframe_parse(
PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
{
static const char *kwlist[]= {"data_path", "index", "frame", "group", NULL};
const char *path;

View File

@@ -176,7 +176,8 @@ static int count_items(PyObject *seq, int dim)
}
/* Modifies property array length if needed and PROP_DYNAMIC flag is set. */
static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix)
static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop,
int lvalue_dim, int *totitem, const char *error_prefix)
{
int dimsize[MAX_ARRAY_DIMENSION];
int tot, totdim, len;
@@ -249,7 +250,9 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
return 0;
}
static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix)
static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop,
int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem,
const char *error_prefix)
{
int dimsize[MAX_ARRAY_DIMENSION];
int totdim= RNA_property_array_dimension(ptr, prop, dimsize);
@@ -262,7 +265,9 @@ static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop,
return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix);
}
static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *prop,
char *data, unsigned int item_size, int *index,
ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
{
if (!data) {
char value[sizeof(int)];
@@ -279,7 +284,9 @@ static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *pro
return data;
}
static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop,
int dim, char *data, unsigned int item_size, int *index,
ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
{
int totdim= RNA_property_array_dimension(ptr, prop, NULL);
const Py_ssize_t seq_size= PySequence_Size(seq);
@@ -320,7 +327,9 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int
return data;
}
static int py_to_array(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix)
static int py_to_array(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop,
char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size,
ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix)
{
/*int totdim, dim_size[MAX_ARRAY_DIMENSION];*/
int totitem;
@@ -372,7 +381,10 @@ static int py_to_array(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, char *
return 0;
}
static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix)
static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop,
int lvalue_dim, int arrayoffset, int index,
ItemTypeCheckFunc check_item_type, const char *item_type_str,
ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix)
{
int totdim, dimsize[MAX_ARRAY_DIMENSION];
int totitem, i;
@@ -465,18 +477,22 @@ static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *
RNA_property_boolean_set_index(ptr, prop, index, *(int*)value);
}
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix)
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data,
PyObject *py, const char *error_prefix)
{
int ret;
switch (RNA_property_type(prop)) {
case PROP_FLOAT:
ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix);
ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float),
py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix);
break;
case PROP_INT:
ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix);
ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int),
py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix);
break;
case PROP_BOOLEAN:
ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix);
ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int),
py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix);
break;
default:
PyErr_SetString(PyExc_TypeError, "not an array type");
@@ -486,18 +502,22 @@ int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyOb
return ret;
}
int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix)
int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index,
PyObject *py, const char *error_prefix)
{
int ret;
switch (RNA_property_type(prop)) {
case PROP_FLOAT:
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix);
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index,
py_float_check, "float", py_to_float, float_set_index, error_prefix);
break;
case PROP_INT:
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix);
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index,
py_int_check, "int", py_to_int, int_set_index, error_prefix);
break;
case PROP_BOOLEAN:
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix);
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index,
py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix);
break;
default:
PyErr_SetString(PyExc_TypeError, "not an array type");

View File

@@ -146,7 +146,10 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset)
PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
PyErr_Print();
for (tb= (PyTracebackObject *)PySys_GetObject("last_traceback"); tb && (PyObject *)tb != Py_None; tb= tb->tb_next) {
for (tb= (PyTracebackObject *)PySys_GetObject("last_traceback");
tb && (PyObject *)tb != Py_None;
tb= tb->tb_next)
{
PyObject *coerce;
const char *tb_filepath= traceback_filepath(tb, &coerce);
const int match= strcmp(tb_filepath, filepath) != 0;

View File

@@ -1,21 +1,18 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This shader is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
* of the License, or (at your option) any later version.
*
* This shader is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this shader; if not, write to the Free Software Foundation,
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2005 Blender Foundation.

View File

@@ -38,6 +38,7 @@ set(SRC
mathutils_Quaternion.c
mathutils_Vector.c
mathutils_geometry.c
mathutils_noise.c
mathutils.h
mathutils_Color.h
@@ -46,6 +47,7 @@ set(SRC
mathutils_Quaternion.h
mathutils_Vector.h
mathutils_geometry.h
mathutils_noise.h
)

View File

@@ -39,7 +39,9 @@
PyDoc_STRVAR(M_Mathutils_doc,
"This module provides access to matrices, eulers, quaternions and vectors."
);
static int mathutils_array_parse_fast(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
static int mathutils_array_parse_fast(float *array,
int array_min, int array_max,
PyObject *value, const char *error_prefix)
{
PyObject *value_fast= NULL;
PyObject *item;
@@ -72,7 +74,9 @@ static int mathutils_array_parse_fast(float *array, int array_min, int array_max
i= size;
do {
i--;
if (((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) && PyErr_Occurred()) {
if ( ((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) &&
PyErr_Occurred())
{
PyErr_Format(PyExc_TypeError,
"%.200s: sequence index %d expected a number, "
"found '%.200s' type, ",
@@ -347,6 +351,7 @@ PyMODINIT_FUNC PyInit_mathutils(void)
{
PyObject *submodule;
PyObject *item;
PyObject *sys_modules= PyThreadState_GET()->interp->modules;
if (PyType_Ready(&vector_Type) < 0)
return NULL;
@@ -373,7 +378,12 @@ PyMODINIT_FUNC PyInit_mathutils(void)
/* XXX, python doesnt do imports with this usefully yet
* 'from mathutils.geometry import PolyFill'
* ...fails without this. */
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "mathutils.geometry", item);
PyDict_SetItemString(sys_modules, "mathutils.geometry", item);
Py_INCREF(item);
/* Noise submodule */
PyModule_AddObject(submodule, "noise", (item=PyInit_mathutils_noise()));
PyDict_SetItemString(sys_modules, "mathutils.noise", item);
Py_INCREF(item);
mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb);

View File

@@ -40,24 +40,30 @@
extern char BaseMathObject_Wrapped_doc[];
extern char BaseMathObject_Owner_doc[];
#define BASE_MATH_MEMBERS(_data) \
PyObject_VAR_HEAD \
float *_data; /* array of data (alias), wrapped status depends on wrapped status */ \
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ \
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ \
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ \
unsigned char wrapped; /* wrapped data type? */ \
#define BASE_MATH_MEMBERS(_data) \
PyObject_VAR_HEAD \
float *_data; /* array of data (alias), wrapped status depends on wrapped status */ \
PyObject *cb_user; /* if this vector references another object, otherwise NULL, \
* *Note* this owns its reference */ \
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ \
unsigned char cb_subtype; /* subtype: location, rotation... \
* to avoid defining many new functions for every attribute of the same type */ \
unsigned char wrapped /* wrapped data type? */ \
typedef struct {
BASE_MATH_MEMBERS(data)
BASE_MATH_MEMBERS(data);
} BaseMathObject;
/* types */
#include "mathutils_Vector.h"
#include "mathutils_Matrix.h"
#include "mathutils_Quaternion.h"
#include "mathutils_Euler.h"
#include "mathutils_Color.h"
/* utility submodules */
#include "mathutils_geometry.h"
#include "mathutils_noise.h"
PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
@@ -76,11 +82,11 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
typedef struct Mathutils_Callback Mathutils_Callback;
typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */
typedef int (*BaseMathGetFunc)(BaseMathObject *, int); /* gets the vector from the user */
typedef int (*BaseMathSetFunc)(BaseMathObject *, int); /* sets the users vector values once the vector is modified */
typedef int (*BaseMathGetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */
typedef int (*BaseMathSetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */
typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */
typedef int (*BaseMathGetFunc)(BaseMathObject *, int); /* gets the vector from the user */
typedef int (*BaseMathSetFunc)(BaseMathObject *, int); /* sets the users vector values once its modified */
typedef int (*BaseMathGetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */
typedef int (*BaseMathSetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */
struct Mathutils_Callback {
BaseMathCheckFunc check;
@@ -98,10 +104,14 @@ int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
/* since this is called so often avoid where possible */
#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):0))
#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):0))
#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):0))
#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):0))
#define BaseMath_ReadCallback(_self) \
(((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):0))
#define BaseMath_WriteCallback(_self) \
(((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):0))
#define BaseMath_ReadIndexCallback(_self, _index) \
(((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):0))
#define BaseMath_WriteIndexCallback(_self, _index) \
(((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):0))
/* utility func */
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);

View File

@@ -39,7 +39,7 @@ extern PyTypeObject color_Type;
#define ColorObject_Check(_v) PyObject_TypeCheck((_v), &color_Type)
typedef struct {
BASE_MATH_MEMBERS(col)
BASE_MATH_MEMBERS(col);
} ColorObject;
/*struct data contains a pointer to the actual data that the

View File

@@ -264,8 +264,11 @@ static PyObject *Euler_make_compatible(EulerObject * self, PyObject *value)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
if (mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value, "euler.make_compatible(other), invalid 'other' arg") == -1)
if (mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value,
"euler.make_compatible(other), invalid 'other' arg") == -1)
{
return NULL;
}
compatible_eul(self->eul, teul);

View File

@@ -39,7 +39,7 @@ extern PyTypeObject euler_Type;
#define EulerObject_Check(_v) PyObject_TypeCheck((_v), &euler_Type)
typedef struct {
BASE_MATH_MEMBERS(eul)
BASE_MATH_MEMBERS(eul);
unsigned char order; /* rotation order */
} EulerObject;

View File

@@ -125,7 +125,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
switch(PyTuple_GET_SIZE(args)) {
case 0:
return (PyObject *) Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type);
return Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type);
case 1:
{
PyObject *arg= PyTuple_GET_ITEM(args, 0);
@@ -478,7 +478,9 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
int vec_size= (matSize == 2 ? 2 : 3);
float tvec[4];
if (mathutils_array_parse(tvec, vec_size, vec_size, axis, "Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1) {
if (mathutils_array_parse(tvec, vec_size, vec_size, axis,
"Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1)
{
return NULL;
}
@@ -827,12 +829,12 @@ static PyObject *Matrix_to_4x4(MatrixObject *self)
return NULL;
if (self->col_size==4 && self->row_size==4) {
return (PyObject *)Matrix_CreatePyObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self));
return Matrix_CreatePyObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self));
}
else if (self->col_size==3 && self->row_size==3) {
float mat[4][4];
copy_m4_m3(mat, (float (*)[3])self->contigPtr);
return (PyObject *)Matrix_CreatePyObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self));
return Matrix_CreatePyObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self));
}
/* TODO, 2x2 matrix */
@@ -1133,7 +1135,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
}
return (PyObject*)Matrix_CreatePyObject(mat, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
return Matrix_CreatePyObject(mat, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
}
/*---------------------------matrix.determinant() ----------------*/
@@ -1286,7 +1288,7 @@ static PyObject *Matrix_copy(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
return (PyObject*)Matrix_CreatePyObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
return Matrix_CreatePyObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
}
/*----------------------------print object (internal)-------------*/
@@ -1470,7 +1472,9 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
/*parse each sub sequence*/
PyObject *item= PySequence_Fast_GET_ITEM(value_fast, i);
if (mathutils_array_parse(&mat[i * self->col_size], self->col_size, self->col_size, item, "matrix[begin:end] = value assignment") < 0) {
if (mathutils_array_parse(&mat[i * self->col_size], self->col_size, self->col_size, item,
"matrix[begin:end] = value assignment") < 0)
{
return -1;
}
}
@@ -1956,7 +1960,9 @@ self->matrix[1][1] = self->contigPtr[4] */
(i.e. it was allocated elsewhere by MEM_mallocN())
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
(i.e. it must be created here with PyMEM_malloc())*/
PyObject *Matrix_CreatePyObject(float *mat, const unsigned short rowSize, const unsigned short colSize, int type, PyTypeObject *base_type)
PyObject *Matrix_CreatePyObject(float *mat,
const unsigned short rowSize, const unsigned short colSize,
int type, PyTypeObject *base_type)
{
MatrixObject *self;
int x, row, col;

View File

@@ -39,7 +39,7 @@ extern PyTypeObject matrix_Type;
#define MATRIX_MAX_DIM 4
typedef struct {
BASE_MATH_MEMBERS(contigPtr)
BASE_MATH_MEMBERS(contigPtr);
float *matrix[MATRIX_MAX_DIM]; /* ptr to the contigPtr (accessor) */
unsigned short row_size;
unsigned short col_size;
@@ -51,7 +51,9 @@ be stored in py_data) or be a wrapper for data allocated through
blender (stored in blend_data). This is an either/or struct not both*/
/*prototypes*/
PyObject *Matrix_CreatePyObject(float *mat, const unsigned short row_size, const unsigned short col_size, int type, PyTypeObject *base_type);
PyObject *Matrix_CreatePyObject(float *mat,
const unsigned short row_size, const unsigned short col_size,
int type, PyTypeObject *base_type);
PyObject *Matrix_CreatePyObject_cb(PyObject *user, int row_size, int col_size, int cb_type, int cb_subtype);
extern int mathutils_matrix_vector_cb_index;

View File

@@ -218,8 +218,11 @@ static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.dot(other), invalid 'other' arg") == -1)
if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
"Quaternion.dot(other), invalid 'other' arg") == -1)
{
return NULL;
}
return PyFloat_FromDouble(dot_qtqt(self->quat, tquat));
}
@@ -241,8 +244,11 @@ static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject
if (BaseMath_ReadCallback(self) == -1)
return NULL;
if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.difference(other), invalid 'other' arg") == -1)
if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
"Quaternion.difference(other), invalid 'other' arg") == -1)
{
return NULL;
}
rotation_between_quats_to_quat(quat, self->quat, tquat);
@@ -276,8 +282,11 @@ static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.slerp(other), invalid 'other' arg") == -1)
if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
"Quaternion.slerp(other), invalid 'other' arg") == -1)
{
return NULL;
}
if (fac > 1.0f || fac < 0.0f) {
PyErr_SetString(PyExc_ValueError,
@@ -982,7 +991,7 @@ static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(clos
quat__axis_angle_sanitize(axis, NULL);
return (PyObject *) Vector_CreatePyObject(axis, 3, Py_NEW, NULL);
return Vector_CreatePyObject(axis, 3, Py_NEW, NULL);
}
static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
@@ -1054,7 +1063,7 @@ static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObjec
PyObject *ret_dummy= quat_func(ret);
if (ret_dummy) {
Py_DECREF(ret_dummy);
return (PyObject *)ret;
return ret;
}
else { /* error */
Py_DECREF(ret);

View File

@@ -39,7 +39,7 @@ extern PyTypeObject quaternion_Type;
#define QuaternionObject_Check(_v) PyObject_TypeCheck((_v), &quaternion_Type)
typedef struct {
BASE_MATH_MEMBERS(quat)
BASE_MATH_MEMBERS(quat);
} QuaternionObject;
/*struct data contains a pointer to the actual data that the

View File

@@ -589,10 +589,10 @@ PyDoc_STRVAR(Vector_angle_doc,
);
static PyObject *Vector_angle(VectorObject *self, PyObject *args)
{
const int size= self->size;
const int size= MIN2(self->size, 3); /* 4D angle makes no sense */
float tvec[MAX_DIMENSIONS];
PyObject *value;
double dot = 0.0f, test_v1 = 0.0f, test_v2 = 0.0f;
double dot= 0.0f, dot_self= 0.0f, dot_other= 0.0f;
int x;
PyObject *fallback= NULL;
@@ -602,14 +602,18 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
if (mathutils_array_parse(tvec, size, size, value, "Vector.angle(other), invalid 'other' arg") == -1)
/* don't use clamped size, rule of thumb is vector sizes must match,
* even though n this case 'w' is ignored */
if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1)
return NULL;
for (x = 0; x < size; x++) {
test_v1 += (double)(self->vec[x] * self->vec[x]);
test_v2 += (double)(tvec[x] * tvec[x]);
dot_self += (double)self->vec[x] * (double)self->vec[x];
dot_other += (double)tvec[x] * (double)tvec[x];
dot += (double)self->vec[x] * (double)tvec[x];
}
if (!test_v1 || !test_v2) {
if (!dot_self || !dot_other) {
/* avoid exception */
if (fallback) {
Py_INCREF(fallback);
@@ -623,13 +627,7 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
}
}
//dot product
for (x = 0; x < self->size; x++) {
dot += (double)(self->vec[x] * tvec[x]);
}
dot /= (sqrt(test_v1) * sqrt(test_v2));
return PyFloat_FromDouble(saacos(dot));
return PyFloat_FromDouble(saacos(dot / (sqrt(dot_self) * sqrt(dot_other))));
}
PyDoc_STRVAR(Vector_rotation_difference_doc,
@@ -1755,7 +1753,10 @@ static int Vector_setSwizzle(VectorObject *self, PyObject *value, void *closure)
size_from= axis_from;
}
else if (PyErr_Clear(), (size_from=mathutils_array_parse(vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) {
else if ( (PyErr_Clear()), /* run but ignore the result */
(size_from=mathutils_array_parse(vec_assign, 2, 4, value,
"mathutils.Vector.**** = swizzle assignment")) == -1)
{
return -1;
}

View File

@@ -39,7 +39,7 @@ extern PyTypeObject vector_Type;
#define VectorObject_Check(_v) PyObject_TypeCheck((_v), &vector_Type)
typedef struct {
BASE_MATH_MEMBERS(vec)
BASE_MATH_MEMBERS(vec);
unsigned char size; /* vec size 2,3 or 4 */
} VectorObject;

View File

@@ -0,0 +1,911 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* This is a new part of Blender.
*
* Contributor(s): eeshlo, Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/mathutils/mathutils_noise.c
* \ingroup mathutils
*
* This file defines the 'noise' module, a general purpose module to access
* blenders noise functions.
*/
/************************/
/* Blender Noise Module */
/************************/
#include <Python.h>
#include "structseq.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "MEM_guardedalloc.h"
#include "DNA_texture_types.h"
#include "mathutils.h"
#include "mathutils_noise.h"
/* 2.6 update
* Moved to submodule of mathutils.
* All vector functions now return mathutils.Vector
* Updated docs to be compatible with autodocs generation.
* Updated vector functions to use nD array functions.
* noise.vl_vector --> noise.variable_lacunarity
* noise.vector --> noise.noise_vector
*/
/*-----------------------------------------*/
/* 'mersenne twister' random number generator */
/*
A C-program for MT19937, with initialization improved 2002/2/10.
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) (((u) & UMASK) | ((v) & LMASK))
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
static unsigned long state[N]; /* the array for the state vector */
static int left = 1;
static int initf = 0;
static unsigned long *next;
/* initializes state[N] with a seed */
static void init_genrand(unsigned long s)
{
int j;
state[0] = s & 0xffffffffUL;
for (j = 1; j < N; j++) {
state[j] =
(1812433253UL *
(state[j - 1] ^ (state[j - 1] >> 30)) + j);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array state[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
state[j] &= 0xffffffffUL; /* for >32 bit machines */
}
left = 1;
initf = 1;
}
static void next_state(void)
{
unsigned long *p = state;
int j;
/* if init_genrand() has not been called, */
/* a default initial seed is used */
if (initf == 0)
init_genrand(5489UL);
left = N;
next = state;
for (j = N - M + 1; --j; p++)
*p = p[M] ^ TWIST(p[0], p[1]);
for (j = M; --j; p++)
*p = p[M - N] ^ TWIST(p[0], p[1]);
*p = p[M - N] ^ TWIST(p[0], state[0]);
}
/*------------------------------------------------------------*/
static void setRndSeed(int seed)
{
if (seed == 0)
init_genrand(time(NULL));
else
init_genrand(seed);
}
/* float number in range [0, 1) using the mersenne twister rng */
static float frand(void)
{
unsigned long y;
if (--left == 0)
next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (float) y / 4294967296.f;
}
/*------------------------------------------------------------*/
/* Utility Functions */
/*------------------------------------------------------------*/
/* Fills an array of length size with random numbers in the range (-1, 1)*/
static void rand_vn(float *array_tar, const int size)
{
float *array_pt= array_tar + (size-1);
int i= size;
while(i--) { *(array_pt--) = 2.0f * frand() - 1.0f; }
}
/* Fills an array of length 3 with noise values */
static void noise_vector(float x, float y, float z, int nb, float v[3])
{
/* Simply evaluate noise at 3 different positions */
v[0]= (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, nb) - 1.0f);
v[1]= (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
v[2]= (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, nb) - 1.0f);
}
/* Returns a turbulence value for a given position (x, y, z) */
static float turb(float x, float y, float z, int oct, int hard, int nb,
float ampscale, float freqscale)
{
float amp, out, t;
int i;
amp = 1.f;
out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
if (hard)
out = fabsf(out);
for (i = 1; i < oct; i++) {
amp *= ampscale;
x *= freqscale;
y *= freqscale;
z *= freqscale;
t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f));
if (hard)
t = fabsf(t);
out += t;
}
return out;
}
/* Fills an array of length 3 with the turbulence vector for a given
position (x, y, z) */
static void vTurb(float x, float y, float z, int oct, int hard, int nb,
float ampscale, float freqscale, float v[3])
{
float amp, t[3];
int i;
amp = 1.f;
noise_vector(x, y, z, nb, v);
if (hard) {
v[0] = fabsf(v[0]);
v[1] = fabsf(v[1]);
v[2] = fabsf(v[2]);
}
for (i = 1; i < oct; i++) {
amp *= ampscale;
x *= freqscale;
y *= freqscale;
z *= freqscale;
noise_vector(x, y, z, nb, t);
if (hard) {
t[0] = fabsf(t[0]);
t[1] = fabsf(t[1]);
t[2] = fabsf(t[2]);
}
v[0] += amp * t[0];
v[1] += amp * t[1];
v[2] += amp * t[2];
}
}
/*-------------------------DOC STRINGS ---------------------------*/
PyDoc_STRVAR(M_Noise_doc,
"The Blender noise module"
);
/*------------------------------------------------------------*/
/* Python Functions */
/*------------------------------------------------------------*/
PyDoc_STRVAR(M_Noise_random_doc,
".. function:: random()\n"
"\n"
" Returns a random number in the range [0, 1].\n"
"\n"
" :return: The random number.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_random(PyObject *UNUSED(self))
{
return PyFloat_FromDouble(frand());
}
PyDoc_STRVAR(M_Noise_random_unit_vector_doc,
".. function:: random_unit_vector(size=3)\n"
"\n"
" Returns a unit vector with random entries.\n"
"\n"
" :arg size: The size of the vector to be produced.\n"
" :type size: Int\n"
" :return: The random unit vector.\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *args)
{
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
float norm= 2.0f;
int size= 3;
if (!PyArg_ParseTuple(args, "|i:random_vector", &size))
return NULL;
if (size > 4 || size < 2) {
PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
return NULL;
}
while (norm==0.0f || norm>=1.0f) {
rand_vn(vec, size);
norm= normalize_vn(vec, size);
}
return Vector_CreatePyObject(vec, size, Py_NEW, NULL);
}
/* This is dumb, most people will want a unit vector anyway, since this doesn't have uniform distribution over a sphere*/
/*
PyDoc_STRVAR(M_Noise_random_vector_doc,
".. function:: random_vector(size=3)\n"
"\n"
" Returns a vector with random entries in the range [0, 1).\n"
"\n"
" :arg size: The size of the vector to be produced.\n"
" :type size: Int\n"
" :return: The random vector.\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args)
{
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
int size= 3;
if (!PyArg_ParseTuple(args, "|i:random_vector", &size))
return NULL;
if (size > 4 || size < 2) {
PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
return NULL;
}
rand_vn(vec, size);
return Vector_CreatePyObject(vec, size, Py_NEW, NULL);
}
*/
PyDoc_STRVAR(M_Noise_seed_set_doc,
".. function:: seed_set(seed)\n"
"\n"
" Sets the random seed used for random_unit_vector, random_vector and random.\n"
"\n"
" :arg seed: Seed used for the random generator.\n"
" :type seed: Int\n"
);
static PyObject *M_Noise_seed_set(PyObject *UNUSED(self), PyObject *args)
{
int s;
if (!PyArg_ParseTuple(args, "i:seed_set", &s))
return NULL;
setRndSeed(s);
Py_RETURN_NONE;
}
PyDoc_STRVAR(M_Noise_noise_doc,
".. function:: noise(position, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns noise value from the noise basis at the position specified.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The noise value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_noise(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
int nb= 1;
if (!PyArg_ParseTuple(args, "O|i:noise", &value, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "noise: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, vec[0], vec[1], vec[2], 0, nb) - 1.0f));
}
PyDoc_STRVAR(M_Noise_noise_vector_doc,
".. function:: noise_vector(position, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns the noise vector from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The noise vector.\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Noise_noise_vector(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3], r_vec[3];
int nb= 1;
if (!PyArg_ParseTuple(args, "O|i:noise_vector", &value, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "noise_vector: invalid 'position' arg") == -1)
return NULL;
noise_vector(vec[0], vec[1], vec[2], nb, r_vec);
return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
}
PyDoc_STRVAR(M_Noise_turbulence_doc,
".. function:: turbulence(position, octaves, hard, noise_basis=noise.types.STDPERLIN, amplitude_scale=0.5, frequency_scale=2.0)\n"
"\n"
" Returns the turbulence value from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
" :type hard: :boolean\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in mathutils.noise.types or int\n"
" :arg amplitude_scale: The amplitude scaling factor.\n"
" :type amplitude_scale: float\n"
" :arg frequency_scale: The frequency scaling factor\n"
" :type frequency_scale: Value in noise.types or int\n"
" :return: The turbulence value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_turbulence(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
int oct, hd, nb= 1;
float as= 0.5f, fs= 2.0f;
if (!PyArg_ParseTuple(args, "Oii|iff:turbulence", &value, &oct, &hd, &nb, &as, &fs))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "turbulence: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(turb(vec[0], vec[1], vec[2], oct, hd, nb, as, fs));
}
PyDoc_STRVAR(M_Noise_turbulence_vector_doc,
".. function:: turbulence_vector(position, octaves, hard, noise_basis=noise.types.STDPERLIN, amplitude_scale=0.5, frequency_scale=2.0)\n"
"\n"
" Returns the turbulence vector from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
" :type hard: :boolean\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in mathutils.noise.types or int\n"
" :arg amplitude_scale: The amplitude scaling factor.\n"
" :type amplitude_scale: float\n"
" :arg frequency_scale: The frequency scaling factor\n"
" :type frequency_scale: Value in noise.types or int\n"
" :return: The turbulence vector.\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3], r_vec[3];
int oct, hd, nb= 1;
float as =0.5f, fs= 2.0f;
if (!PyArg_ParseTuple(args, "Oii|iff:turbulence_vector", &value, &oct, &hd, &nb, &as, &fs))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "turbulence_vector: invalid 'position' arg") == -1)
return NULL;
vTurb(vec[0], vec[1], vec[2], oct, hd, nb, as, fs, r_vec);
return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
}
/* F. Kenton Musgrave's fractal functions */
PyDoc_STRVAR(M_Noise_fractal_doc,
".. function:: fractal(position, H, lacunarity, octaves, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns the fractal Brownian motion (fBm) noise value from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg H: The fractal increment factor.\n"
" :type H: float\n"
" :arg lacunarity: The gap between successive frequencies.\n"
" :type lacunarity: float\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The fractal Brownian motion noise value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_fractal(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
float H, lac, oct;
int nb= 1;
if (!PyArg_ParseTuple(args, "Offf|i:fractal", &value, &H, &lac, &oct, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "fractal: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(mg_fBm(vec[0], vec[1], vec[2], H, lac, oct, nb));
}
PyDoc_STRVAR(M_Noise_multi_fractal_doc,
".. function:: multi_fractal(position, H, lacunarity, octaves, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns multifractal noise value from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg H: The fractal increment factor.\n"
" :type H: float\n"
" :arg lacunarity: The gap between successive frequencies.\n"
" :type lacunarity: float\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The multifractal noise value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
float H, lac, oct;
int nb= 1;
if (!PyArg_ParseTuple(args, "Offf|i:multi_fractal", &value, &H, &lac, &oct, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "multi_fractal: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(mg_MultiFractal(vec[0], vec[1], vec[2], H, lac, oct, nb));
}
PyDoc_STRVAR(M_Noise_variable_lacunarity_doc,
".. function:: variable_lacunarity(position, distortion, noise_type1=noise.types.STDPERLIN, noise_type2=noise.types.STDPERLIN)\n"
"\n"
" Returns variable lacunarity noise value, a distorted variety of noise, from noise type 1 distorted by noise type 2 at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg distortion: The amount of distortion.\n"
" :type distortion: float\n"
" :arg noise_type1: The type of noise to be distorted.\n"
" :type noise_type1: Value in noise.types or int\n"
" :arg noise_type2: The type of noise used to distort noise_type1.\n"
" :type noise_type2: Value in noise.types or int\n"
" :return: The variable lacunarity noise value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_variable_lacunarity(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
float d;
int nt1= 1, nt2= 1;
if (!PyArg_ParseTuple(args, "Of|ii:variable_lacunarity", &value, &d, &nt1, &nt2))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "variable_lacunarity: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(mg_VLNoise(vec[0], vec[1], vec[2], d, nt1, nt2));
}
PyDoc_STRVAR(M_Noise_hetero_terrain_doc,
".. function:: hetero_terrain(position, H, lacunarity, octaves, offset, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns the heterogeneous terrain value from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg H: The fractal dimension of the roughest areas.\n"
" :type H: float\n"
" :arg lacunarity: The gap between successive frequencies.\n"
" :type lacunarity: float\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg offset: The height of the terrain above 'sea level'.\n"
" :type offset: float\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The heterogeneous terrain value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
float H, lac, oct, ofs;
int nb= 1;
if (!PyArg_ParseTuple(args, "Offff|i:hetero_terrain", &value, &H, &lac, &oct, &ofs, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "hetero_terrain: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(mg_HeteroTerrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, nb));
}
PyDoc_STRVAR(M_Noise_hybrid_multi_fractal_doc,
".. function:: hybrid_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns hybrid multifractal value from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg H: The fractal dimension of the roughest areas.\n"
" :type H: float\n"
" :arg lacunarity: The gap between successive frequencies.\n"
" :type lacunarity: float\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg offset: The height of the terrain above 'sea level'.\n"
" :type offset: float\n"
" :arg gain: Scaling applied to the values.\n"
" :type gain: float\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The hybrid multifractal value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
float H, lac, oct, ofs, gn;
int nb= 1;
if (!PyArg_ParseTuple(args, "Offfff|i:hybrid_multi_fractal", &value, &H, &lac, &oct, &ofs, &gn, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "hybrid_multi_fractal: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, nb));
}
PyDoc_STRVAR(M_Noise_ridged_multi_fractal_doc,
".. function:: ridged_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis=noise.types.STDPERLIN)\n"
"\n"
" Returns ridged multifractal value from the noise basis at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg H: The fractal dimension of the roughest areas.\n"
" :type H: float\n"
" :arg lacunarity: The gap between successive frequencies.\n"
" :type lacunarity: float\n"
" :arg octaves: The number of different noise frequencies used.\n"
" :type octaves: int\n"
" :arg offset: The height of the terrain above 'sea level'.\n"
" :type offset: float\n"
" :arg gain: Scaling applied to the values.\n"
" :type gain: float\n"
" :arg noise_basis: The type of noise to be evaluated.\n"
" :type noise_basis: Value in noise.types or int\n"
" :return: The ridged multifractal value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
float H, lac, oct, ofs, gn;
int nb= 1;
if (!PyArg_ParseTuple(args, "Offfff|i:ridged_multi_fractal", &value, &H, &lac, &oct, &ofs, &gn, &nb))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "ridged_multi_fractal: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(mg_RidgedMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, nb));
}
PyDoc_STRVAR(M_Noise_voronoi_doc,
".. function:: voronoi(position, distance_metric=noise.distance_metrics.DISTANCE, exponent=2.5)\n"
"\n"
" Returns a list of distances to the four closest features and their locations.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :arg distance_metric: Method of measuring distance.\n"
" :type distance_metric: Value in noise.distance_metrics or int\n"
" :arg exponent: The exponent for Minkovsky distance metric.\n"
" :type exponent: float\n"
" :return: A list of distances to the four closest features and their locations.\n"
" :rtype: [list of four floats, list of four :class:`mathutils.Vector`s]\n"
);
static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
PyObject *list;
float vec[3];
float da[4], pa[12];
int dtype= 0;
float me= 2.5f; /* default minkovsky exponent */
int i;
if (!PyArg_ParseTuple(args, "O|if:voronoi", &value, &dtype, &me))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "voronoi: invalid 'position' arg") == -1)
return NULL;
list= PyList_New(4);
voronoi(vec[0], vec[1], vec[2], da, pa, me, dtype);
for (i=0; i<4; i++) {
PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3*i, 3, Py_NEW, NULL));
}
return Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list);
}
PyDoc_STRVAR(M_Noise_cell_doc,
".. function:: cell(position)\n"
"\n"
" Returns cell noise value at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :return: The cell noise value.\n"
" :rtype: float\n"
);
static PyObject *M_Noise_cell(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3];
if (!PyArg_ParseTuple(args, "O:cell", &value))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "cell: invalid 'position' arg") == -1)
return NULL;
return PyFloat_FromDouble(cellNoise(vec[0], vec[1], vec[2]));
}
PyDoc_STRVAR(M_Noise_cell_vector_doc,
".. function:: cell_vector(position)\n"
"\n"
" Returns cell noise vector at the specified position.\n"
"\n"
" :arg position: The position to evaluate the selected noise function at.\n"
" :type position: :class:`mathutils.Vector`\n"
" :return: The cell noise vector.\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
{
PyObject *value;
float vec[3], r_vec[3];
if (!PyArg_ParseTuple(args, "O:cell_vector", &value))
return NULL;
if (mathutils_array_parse(vec, 3, 3, value, "cell_vector: invalid 'position' arg") == -1)
return NULL;
cellNoiseV(vec[0], vec[1], vec[2], r_vec);
return Vector_CreatePyObject(NULL, 3, Py_NEW, NULL);;
}
static PyMethodDef M_Noise_methods[] = {
{"seed_set", (PyCFunction) M_Noise_seed_set, METH_VARARGS, M_Noise_seed_set_doc},
{"random", (PyCFunction) M_Noise_random, METH_NOARGS, M_Noise_random_doc},
{"random_unit_vector", (PyCFunction) M_Noise_random_unit_vector, METH_VARARGS, M_Noise_random_unit_vector_doc},
/*{"random_vector", (PyCFunction) M_Noise_random_vector, METH_VARARGS, M_Noise_random_vector_doc},*/
{"noise", (PyCFunction) M_Noise_noise, METH_VARARGS, M_Noise_noise_doc},
{"noise_vector", (PyCFunction) M_Noise_noise_vector, METH_VARARGS, M_Noise_noise_vector_doc},
{"turbulence", (PyCFunction) M_Noise_turbulence, METH_VARARGS, M_Noise_turbulence_doc},
{"turbulence_vector", (PyCFunction) M_Noise_turbulence_vector, METH_VARARGS, M_Noise_turbulence_vector_doc},
{"fractal", (PyCFunction) M_Noise_fractal, METH_VARARGS, M_Noise_fractal_doc},
{"multi_fractal", (PyCFunction) M_Noise_multi_fractal, METH_VARARGS, M_Noise_multi_fractal_doc},
{"variable_lacunarity", (PyCFunction) M_Noise_variable_lacunarity, METH_VARARGS, M_Noise_variable_lacunarity_doc},
{"hetero_terrain", (PyCFunction) M_Noise_hetero_terrain, METH_VARARGS, M_Noise_hetero_terrain_doc},
{"hybrid_multi_fractal", (PyCFunction) M_Noise_hybrid_multi_fractal, METH_VARARGS, M_Noise_hybrid_multi_fractal_doc},
{"ridged_multi_fractal", (PyCFunction) M_Noise_ridged_multi_fractal, METH_VARARGS, M_Noise_ridged_multi_fractal_doc},
{"voronoi", (PyCFunction) M_Noise_voronoi, METH_VARARGS, M_Noise_voronoi_doc},
{"cell", (PyCFunction) M_Noise_cell, METH_VARARGS, M_Noise_cell_doc},
{"cell_vector", (PyCFunction) M_Noise_cell_vector, METH_VARARGS, M_Noise_cell_vector_doc},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef M_Noise_module_def = {
PyModuleDef_HEAD_INIT,
"mathutils.noise", /* m_name */
M_Noise_doc, /* m_doc */
0, /* m_size */
M_Noise_methods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
/*----------------------------MODULE INIT-------------------------*/
PyMODINIT_FUNC PyInit_mathutils_noise(void)
{
PyObject *submodule = PyModule_Create(&M_Noise_module_def);
PyObject *item_types, *item_metrics;
/* use current time as seed for random number generator by default */
setRndSeed(0);
PyModule_AddObject(submodule, "types", (item_types=PyInit_mathutils_noise_types()));
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "noise.types", item_types);
Py_INCREF(item_types);
PyModule_AddObject(submodule, "distance_metrics", (item_metrics=PyInit_mathutils_noise_metrics()));
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "noise.distance_metrics", item_metrics);
Py_INCREF(item_metrics);
return submodule;
}
/*----------------------------SUBMODULE INIT-------------------------*/
static struct PyModuleDef M_NoiseTypes_module_def = {
PyModuleDef_HEAD_INIT,
"mathutils.noise.types", /* m_name */
NULL, /* m_doc */
0, /* m_size */
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC PyInit_mathutils_noise_types(void)
{
PyObject *submodule = PyModule_Create(&M_NoiseTypes_module_def);
PyModule_AddIntConstant(submodule, (char *)"BLENDER", TEX_BLENDER);
PyModule_AddIntConstant(submodule, (char *)"STDPERLIN", TEX_STDPERLIN);
PyModule_AddIntConstant(submodule, (char *)"NEWPERLIN", TEX_NEWPERLIN);
PyModule_AddIntConstant(submodule, (char *)"VORONOI_F1", TEX_VORONOI_F1);
PyModule_AddIntConstant(submodule, (char *)"VORONOI_F2", TEX_VORONOI_F2);
PyModule_AddIntConstant(submodule, (char *)"VORONOI_F3", TEX_VORONOI_F3);
PyModule_AddIntConstant(submodule, (char *)"VORONOI_F4", TEX_VORONOI_F4);
PyModule_AddIntConstant(submodule, (char *)"VORONOI_F2F1", TEX_VORONOI_F2F1);
PyModule_AddIntConstant(submodule, (char *)"VORONOI_CRACKLE", TEX_VORONOI_CRACKLE);
PyModule_AddIntConstant(submodule, (char *)"CELLNOISE", TEX_CELLNOISE);
return submodule;
}
static struct PyModuleDef M_NoiseMetrics_module_def = {
PyModuleDef_HEAD_INIT,
"mathutils.noise.distance_metrics", /* m_name */
NULL, /* m_doc */
0, /* m_size */
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC PyInit_mathutils_noise_metrics(void)
{
PyObject *submodule = PyModule_Create(&M_NoiseMetrics_module_def);
PyModule_AddIntConstant(submodule, (char *)"DISTANCE", TEX_DISTANCE);
PyModule_AddIntConstant(submodule, (char *)"DISTANCE_SQUARED", TEX_DISTANCE_SQUARED);
PyModule_AddIntConstant(submodule, (char *)"MANHATTAN", TEX_MANHATTAN);
PyModule_AddIntConstant(submodule, (char *)"CHEBYCHEV", TEX_CHEBYCHEV);
PyModule_AddIntConstant(submodule, (char *)"MINKOVSKY_HALF", TEX_MINKOVSKY_HALF);
PyModule_AddIntConstant(submodule, (char *)"MINKOVSKY_FOUR", TEX_MINKOVSKY_FOUR);
PyModule_AddIntConstant(submodule, (char *)"MINKOVSKY", TEX_MINKOVSKY);
return submodule;
}

View File

@@ -20,13 +20,17 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/generic/noise_py_api.h
* \ingroup pygen
/** \file blender/python/mathutils/mathutils_noise.h
* \ingroup mathutils
*/
#ifndef NOISE_PY_API_H
#define NOISE_PY_API_H
#ifndef MATHUTILS_NOISE_H
#define MATHUTILS_NOISE_H
PyObject *BPyInit_noise(void);
#include "mathutils.h"
#endif // NOISE_PY_API_H
PyMODINIT_FUNC PyInit_mathutils_noise(void);
PyMODINIT_FUNC PyInit_mathutils_noise_types(void);
PyMODINIT_FUNC PyInit_mathutils_noise_metrics(void);
#endif // MATHUTILS_NOISE_H