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:
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
911
source/blender/python/mathutils/mathutils_noise.c
Normal file
911
source/blender/python/mathutils/mathutils_noise.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user