diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-07-26 07:55:23 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-07-26 07:55:23 +0400 |
commit | fc95382a977163a1d499c732960e7501cc065833 (patch) | |
tree | 3bbbe419ba513f030f95715c04a8adb39c6e6579 /source/blender/python | |
parent | ac2dd4099167d9ab6306f3fcb83610a5d01ffae1 (diff) | |
parent | ce0ad0b40b93fc6074daaba6ead0e0e82867d4d2 (diff) |
svn merge -r38400:38500 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/python/SConscript | 11 | ||||
-rw-r--r-- | source/blender/python/generic/CMakeLists.txt | 18 | ||||
-rw-r--r-- | source/blender/python/generic/bgl.c | 248 | ||||
-rw-r--r-- | source/blender/python/intern/CMakeLists.txt | 9 | ||||
-rw-r--r-- | source/blender/python/intern/bpy.c | 4 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 8 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 4 | ||||
-rw-r--r-- | source/blender/python/mathutils/CMakeLists.txt | 52 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils.c (renamed from source/blender/python/generic/mathutils.c) | 6 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils.h (renamed from source/blender/python/generic/mathutils.h) | 4 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Color.c (renamed from source/blender/python/generic/mathutils_Color.c) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Color.h (renamed from source/blender/python/generic/mathutils_Color.h) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Euler.c (renamed from source/blender/python/generic/mathutils_Euler.c) | 8 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Euler.h (renamed from source/blender/python/generic/mathutils_Euler.h) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Matrix.c (renamed from source/blender/python/generic/mathutils_Matrix.c) | 17 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Matrix.h (renamed from source/blender/python/generic/mathutils_Matrix.h) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Quaternion.c (renamed from source/blender/python/generic/mathutils_Quaternion.c) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Quaternion.h (renamed from source/blender/python/generic/mathutils_Quaternion.h) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Vector.c (renamed from source/blender/python/generic/mathutils_Vector.c) | 3 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_Vector.h (renamed from source/blender/python/generic/mathutils_Vector.h) | 2 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_geometry.c (renamed from source/blender/python/generic/mathutils_geometry.c) | 569 | ||||
-rw-r--r-- | source/blender/python/mathutils/mathutils_geometry.h (renamed from source/blender/python/generic/mathutils_geometry.h) | 4 |
23 files changed, 559 insertions, 421 deletions
diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt index fe9e0307703..8071edb378f 100644 --- a/source/blender/python/CMakeLists.txt +++ b/source/blender/python/CMakeLists.txt @@ -18,3 +18,4 @@ add_subdirectory(intern) add_subdirectory(generic) +add_subdirectory(mathutils) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index de6b859d259..dec0de4a6ab 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -1,6 +1,6 @@ #!/usr/bin/python -# TODO, split into 2 files. +# TODO, split into 3 files. Import ('env') @@ -18,7 +18,14 @@ if is_debug: defs.append('_DEBUG') sources = env.Glob('generic/*.c') -env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360 +env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [363,165]) # ketsji is 360 + + +# mathutils +defs = [] + +sources = env.Glob('mathutils/*.c') +env.BlenderLib( libname = 'bf_python_mathutils', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # bpy diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt index 0889c77f9ad..8dfbf476995 100644 --- a/source/blender/python/generic/CMakeLists.txt +++ b/source/blender/python/generic/CMakeLists.txt @@ -20,10 +20,10 @@ set(INC . - ../../blenlib - ../../makesdna ../../blenkernel + ../../blenlib ../../blenloader + ../../makesdna ../../../../intern/guardedalloc ) @@ -37,13 +37,6 @@ set(SRC bgl.c blf_py_api.c bpy_internal_import.c - mathutils.c - mathutils_Color.c - mathutils_Euler.c - mathutils_Matrix.c - mathutils_Quaternion.c - mathutils_Vector.c - mathutils_geometry.c noise_py_api.c py_capi_utils.c @@ -51,13 +44,6 @@ set(SRC bgl.h blf_py_api.h bpy_internal_import.h - mathutils.h - mathutils_Color.h - mathutils_Euler.h - mathutils_Matrix.h - mathutils_Quaternion.h - mathutils_Vector.h - mathutils_geometry.h noise_py_api.h py_capi_utils.h ) diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index 18d01f45015..09432e0b316 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -48,12 +48,15 @@ static PyObject *Buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* Buffer sequence methods */ -static int Buffer_len(PyObject *self); -static PyObject *Buffer_item(PyObject *self, int i); -static PyObject *Buffer_slice(PyObject *self, int begin, int end); -static int Buffer_ass_item(PyObject *self, int i, PyObject *v); -static int Buffer_ass_slice(PyObject *self, int begin, int end, +static int Buffer_len(Buffer *self); +static PyObject *Buffer_item(Buffer *self, int i); +static PyObject *Buffer_slice(Buffer *self, int begin, int end); +static int Buffer_ass_item(Buffer *self, int i, PyObject *v); +static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq); +static PyObject *Buffer_subscript(Buffer *self, PyObject *item); +static int Buffer_ass_subscript(Buffer *self, PyObject *item, + PyObject *value); static PySequenceMethods Buffer_SeqMethods = { (lenfunc) Buffer_len, /*sq_length */ @@ -68,12 +71,19 @@ static PySequenceMethods Buffer_SeqMethods = { (ssizeargfunc) NULL, /* sq_inplace_repeat */ }; -static void Buffer_dealloc(PyObject *self); -static PyObject *Buffer_repr(PyObject *self); -static PyObject *Buffer_to_list(PyObject *self) +static PyMappingMethods Buffer_AsMapping = { + (lenfunc)Buffer_len, + (binaryfunc)Buffer_subscript, + (objobjargproc)Buffer_ass_subscript +}; + +static void Buffer_dealloc(Buffer *self); +static PyObject *Buffer_repr(Buffer *self); + +static PyObject *Buffer_to_list(Buffer *self) { - int i, len= ((Buffer *)self)->dimensions[0]; + int i, len= self->dimensions[0]; PyObject *list= PyList_New(len); for (i=0; i<len; i++) { @@ -83,26 +93,54 @@ static PyObject *Buffer_to_list(PyObject *self) return list; } -static PyObject *Buffer_dimensions(PyObject *self, void *UNUSED(arg)) +static PyObject *Buffer_to_list_recursive(Buffer *self) +{ + PyObject *list; + + if(self->ndimensions > 1) { + int i, len= self->dimensions[0]; + list= PyList_New(len); + + for (i=0; i<len; i++) { + Buffer *sub= (Buffer *)Buffer_item(self, i); + PyList_SET_ITEM(list, i, Buffer_to_list_recursive(sub)); + Py_DECREF(sub); + } + } + else { + list= Buffer_to_list(self); + } + + return list; +} + +/* *DEPRECATED* 2011/7/17 bgl.Buffer.list */ +static PyObject *Buffer_list(Buffer *self, void *UNUSED(arg)) { - Buffer *buffer= (Buffer *) self; - PyObject *list= PyList_New(buffer->ndimensions); + fprintf(stderr, "Warning: 'Buffer.list' deprecated, use '[:]' instead\n"); + return Buffer_to_list(self); +} + +static PyObject *Buffer_dimensions(Buffer *self, void *UNUSED(arg)) +{ + PyObject *list= PyList_New(self->ndimensions); int i; - for (i= 0; i<buffer->ndimensions; i++) { - PyList_SET_ITEM(list, i, PyLong_FromLong(buffer->dimensions[i])); + for (i= 0; i<self->ndimensions; i++) { + PyList_SET_ITEM(list, i, PyLong_FromLong(self->dimensions[i])); } return list; } static PyMethodDef Buffer_methods[] = { - {"to_list", (PyCFunction)Buffer_to_list, METH_NOARGS, + {"to_list", (PyCFunction)Buffer_to_list_recursive, METH_NOARGS, "return the buffer as a list"}, {NULL, NULL, 0, NULL} }; static PyGetSetDef Buffer_getseters[] = { + {(char *)"list", (getter)Buffer_list, NULL, NULL, NULL}, {(char *)"dimensions", (getter)Buffer_dimensions, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL, NULL} }; @@ -121,7 +159,7 @@ PyTypeObject BGL_bufferType = { (reprfunc) Buffer_repr, /*tp_repr */ NULL, /*tp_as_number */ &Buffer_SeqMethods, /*tp_as_sequence */ - NULL, /* PyMappingMethods *tp_as_mapping; */ + &Buffer_AsMapping, /* PyMappingMethods *tp_as_mapping; */ /* More standard operations (here for binary compatibility) */ @@ -262,7 +300,8 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject int ndimensions = 0; if(kwds && PyDict_Size(kwds)) { - PyErr_SetString(PyExc_TypeError, "bgl.Buffer(): takes no keyword args"); + PyErr_SetString(PyExc_TypeError, + "bgl.Buffer(): takes no keyword args"); return NULL; } @@ -319,7 +358,7 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject buffer= BGL_MakeBuffer(type, ndimensions, dimensions, NULL); if (init && ndimensions) { - if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], init)) { + if (Buffer_ass_slice(buffer, 0, dimensions[0], init)) { Py_DECREF(buffer); return NULL; } @@ -330,51 +369,48 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject /*@ Buffer sequence methods */ -static int Buffer_len(PyObject *self) +static int Buffer_len(Buffer *self) { - Buffer *buf= (Buffer *) self; - return buf->dimensions[0]; + return self->dimensions[0]; } -static PyObject *Buffer_item(PyObject *self, int i) +static PyObject *Buffer_item(Buffer *self, int i) { - Buffer *buf= (Buffer *) self; - - if (i >= buf->dimensions[0]) { + if (i >= self->dimensions[0] || i < 0) { PyErr_SetString(PyExc_IndexError, "array index out of range"); return NULL; } - if (buf->ndimensions==1) { - switch (buf->type) { - case GL_BYTE: return Py_BuildValue("b", buf->buf.asbyte[i]); - case GL_SHORT: return Py_BuildValue("h", buf->buf.asshort[i]); - case GL_INT: return Py_BuildValue("i", buf->buf.asint[i]); - case GL_FLOAT: return PyFloat_FromDouble(buf->buf.asfloat[i]); - case GL_DOUBLE: return Py_BuildValue("d", buf->buf.asdouble[i]); + if (self->ndimensions==1) { + switch (self->type) { + case GL_BYTE: return Py_BuildValue("b", self->buf.asbyte[i]); + case GL_SHORT: return Py_BuildValue("h", self->buf.asshort[i]); + case GL_INT: return Py_BuildValue("i", self->buf.asint[i]); + case GL_FLOAT: return PyFloat_FromDouble(self->buf.asfloat[i]); + case GL_DOUBLE: return Py_BuildValue("d", self->buf.asdouble[i]); } } else { Buffer *newbuf; int j, length, size; - + length= 1; - for (j=1; j<buf->ndimensions; j++) { - length*= buf->dimensions[j]; + for (j=1; j < self->ndimensions; j++) { + length *= self->dimensions[j]; } - size= BGL_typeSize(buf->type); + size= BGL_typeSize(self->type); newbuf= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType); Py_INCREF(self); - newbuf->parent= self; + newbuf->parent= (PyObject *)self; - newbuf->ndimensions= buf->ndimensions-1; - newbuf->type= buf->type; - newbuf->buf.asvoid= buf->buf.asbyte + i*length*size; + newbuf->ndimensions= self->ndimensions - 1; + newbuf->type= self->type; + newbuf->buf.asvoid= self->buf.asbyte + i*length*size; newbuf->dimensions= MEM_mallocN(newbuf->ndimensions*sizeof(int), "Buffer dimensions"); - memcpy(newbuf->dimensions, buf->dimensions+1, + memcpy(newbuf->dimensions, self->dimensions+1, newbuf->ndimensions*sizeof(int)); return (PyObject *) newbuf; @@ -383,16 +419,14 @@ static PyObject *Buffer_item(PyObject *self, int i) return NULL; } -static PyObject *Buffer_slice(PyObject *self, int begin, int end) +static PyObject *Buffer_slice(Buffer *self, int begin, int end) { - Buffer *buf= (Buffer *) self; PyObject *list; int count; - if (begin<0) begin= 0; - if (end>buf->dimensions[0]) - end= buf->dimensions[0]; - if (begin>end) begin= end; + if (begin < 0) begin= 0; + if (end > self->dimensions[0]) end= self->dimensions[0]; + if (begin > end) begin= end; list= PyList_New(end-begin); @@ -402,21 +436,19 @@ static PyObject *Buffer_slice(PyObject *self, int begin, int end) return list; } -static int Buffer_ass_item(PyObject *self, int i, PyObject *v) +static int Buffer_ass_item(Buffer *self, int i, PyObject *v) { - Buffer *buf= (Buffer *) self; - - if (i >= buf->dimensions[0]) { + if (i >= self->dimensions[0] || i < 0) { PyErr_SetString(PyExc_IndexError, "array assignment index out of range"); return -1; } - if (buf->ndimensions!=1) { - PyObject *row= Buffer_item(self, i); + if (self->ndimensions!=1) { + Buffer *row= (Buffer *)Buffer_item(self, i); if (row) { - int ret= Buffer_ass_slice(row, 0, buf->dimensions[1], v); + int ret= Buffer_ass_slice(row, 0, self->dimensions[1], v); Py_DECREF(row); return ret; } @@ -425,31 +457,30 @@ static int Buffer_ass_item(PyObject *self, int i, PyObject *v) } } - switch(buf->type) { + switch(self->type) { case GL_BYTE: - return PyArg_Parse(v, "b:Expected ints", &buf->buf.asbyte[i]) ? 0:-1; + return PyArg_Parse(v, "b:Expected ints", &self->buf.asbyte[i]) ? 0:-1; case GL_SHORT: - return PyArg_Parse(v, "h:Expected ints", &buf->buf.asshort[i]) ? 0:-1; + return PyArg_Parse(v, "h:Expected ints", &self->buf.asshort[i]) ? 0:-1; case GL_INT: - return PyArg_Parse(v, "i:Expected ints", &buf->buf.asint[i]) ? 0:-1; + return PyArg_Parse(v, "i:Expected ints", &self->buf.asint[i]) ? 0:-1; case GL_FLOAT: - return PyArg_Parse(v, "f:Expected floats", &buf->buf.asfloat[i]) ? 0:-1; + return PyArg_Parse(v, "f:Expected floats", &self->buf.asfloat[i]) ? 0:-1; case GL_DOUBLE: - return PyArg_Parse(v, "d:Expected floats", &buf->buf.asdouble[i]) ? 0:-1; + return PyArg_Parse(v, "d:Expected floats", &self->buf.asdouble[i]) ? 0:-1; default: return 0; /* should never happen */ } } -static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq) +static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq) { - Buffer *buf= (Buffer *) self; PyObject *item; int count, err=0; - if (begin<0) begin= 0; - if (end>buf->dimensions[0]) end= buf->dimensions[0]; - if (begin>end) begin= end; + if (begin < 0) begin= 0; + if (end > self->dimensions[0]) end= self->dimensions[0]; + if (begin > end) begin= end; if (!PySequence_Check(seq)) { PyErr_Format(PyExc_TypeError, @@ -481,27 +512,94 @@ static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq) return err; } -static void Buffer_dealloc(PyObject *self) +static PyObject *Buffer_subscript(Buffer *self, PyObject *item) { - Buffer *buf = (Buffer *)self; + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->dimensions[0]; + return Buffer_item(self, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; - if (buf->parent) Py_DECREF(buf->parent); - else MEM_freeN (buf->buf.asvoid); + if (PySlice_GetIndicesEx((void *)item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyTuple_New(0); + } + else if (step == 1) { + return Buffer_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_IndexError, + "slice steps not supported with vectors"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "buffer indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return NULL; + } +} + +static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->dimensions[0]; + return Buffer_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((void *)item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return Buffer_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_IndexError, + "slice steps not supported with vectors"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "buffer indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return -1; + } +} + + +static void Buffer_dealloc(Buffer *self) +{ + if (self->parent) Py_DECREF(self->parent); + else MEM_freeN (self->buf.asvoid); + + MEM_freeN(self->dimensions); - MEM_freeN (buf->dimensions); - PyObject_DEL(self); } -static PyObject *Buffer_repr(PyObject *self) +static PyObject *Buffer_repr(Buffer *self) { - PyObject *list= Buffer_to_list(self); + PyObject *list= Buffer_to_list_recursive(self); PyObject *repr; const char *typestr= "UNKNOWN"; - Buffer *buffer= (Buffer *)self; - switch(buffer->type) { + switch(self->type) { case GL_BYTE: typestr= "GL_BYTE"; break; case GL_SHORT: typestr= "GL_SHORT"; break; case GL_INT: typestr= "GL_BYTE"; break; diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 287ba45a1cf..93a4b3ec269 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -25,13 +25,13 @@ set(INC .. + ../../blenkernel ../../blenlib + ../../blenloader + ../../editors/include ../../makesdna ../../makesrna - ../../blenkernel - ../../blenloader ../../windowmanager - ../../editors/include ../../../../intern/guardedalloc ) @@ -88,9 +88,6 @@ if(WITH_PYTHON_SAFETY) endif() if(WITH_AUDASPACE) - list(APPEND INC - ../../../intern/audaspace/intern - ) add_definitions(-DWITH_AUDASPACE) endif() diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index fb4c285a458..3f637feadf7 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -55,10 +55,10 @@ #include "MEM_guardedalloc.h" /* external util modules */ -#include "../generic/mathutils.h" +#include "../generic/IDProp.h" #include "../generic/bgl.h" #include "../generic/blf_py_api.h" -#include "../generic/IDProp.h" +#include "../mathutils/mathutils.h" PyObject *bpy_package_py= NULL; diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index f091a511e93..8bd6e6c611c 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -66,10 +66,10 @@ #include "../generic/py_capi_utils.h" /* inittab initialization functions */ -#include "../generic/noise_py_api.h" -#include "../generic/mathutils.h" #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 */ @@ -175,8 +175,8 @@ extern PyObject *AUD_initPython(void); static struct _inittab bpy_internal_modules[]= { {(char *)"noise", BPyInit_noise}, - {(char *)"mathutils", BPyInit_mathutils}, -// {(char *)"mathutils.geometry", BPyInit_mathutils_geometry}, + {(char *)"mathutils", PyInit_mathutils}, +// {(char *)"mathutils.geometry", PyInit_mathutils_geometry}, {(char *)"bgl", BPyInit_bgl}, {(char *)"blf", BPyInit_blf}, #ifdef WITH_AUDASPACE diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 4f6edb02a7c..6e1b9c807f3 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -346,7 +346,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item); #ifdef USE_MATHUTILS -#include "../generic/mathutils.h" /* so we can have mathutils callbacks */ +#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 short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback); @@ -4548,7 +4548,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type= { NULL, /* printfunc tp_print; */ NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ - NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */ + NULL, /* tp_compare */ /* deprecated in python 3.0! */ NULL, /* tp_repr */ /* Method suites for standard classes */ diff --git a/source/blender/python/mathutils/CMakeLists.txt b/source/blender/python/mathutils/CMakeLists.txt new file mode 100644 index 00000000000..b28496d612e --- /dev/null +++ b/source/blender/python/mathutils/CMakeLists.txt @@ -0,0 +1,52 @@ +# ***** 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. +# +# Contributor(s): Campbell Barton +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + ../../blenlib + ../../blenkernel + ../../makesdna + ../../../../intern/guardedalloc +) + +set(INC_SYS + ${PYTHON_INCLUDE_DIRS} +) + +set(SRC + mathutils.c + mathutils_Color.c + mathutils_Euler.c + mathutils_Matrix.c + mathutils_Quaternion.c + mathutils_Vector.c + mathutils_geometry.c + + mathutils.h + mathutils_Color.h + mathutils_Euler.h + mathutils_Matrix.h + mathutils_Quaternion.h + mathutils_Vector.h + mathutils_geometry.h +) + + +blender_add_lib(bf_python_mathutils "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/python/generic/mathutils.c b/source/blender/python/mathutils/mathutils.c index 1ff33d5a6bb..4a0fa509a0d 100644 --- a/source/blender/python/generic/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils.c 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -345,7 +345,7 @@ static struct PyModuleDef M_Mathutils_module_def = { NULL, /* m_free */ }; -PyMODINIT_FUNC BPyInit_mathutils(void) +PyMODINIT_FUNC PyInit_mathutils(void) { PyObject *submodule; PyObject *item; @@ -371,7 +371,7 @@ PyMODINIT_FUNC BPyInit_mathutils(void) PyModule_AddObject(submodule, "Color", (PyObject *)&color_Type); /* submodule */ - PyModule_AddObject(submodule, "geometry", (item=BPyInit_mathutils_geometry())); + PyModule_AddObject(submodule, "geometry", (item=PyInit_mathutils_geometry())); /* XXX, python doesnt do imports with this usefully yet * 'from mathutils.geometry import PolyFill' * ...fails without this. */ diff --git a/source/blender/python/generic/mathutils.h b/source/blender/python/mathutils/mathutils.h index 449708d1ac1..90ef768c3ec 100644 --- a/source/blender/python/generic/mathutils.h +++ b/source/blender/python/mathutils/mathutils.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils.h 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -67,7 +67,7 @@ int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg); int BaseMathObject_clear(BaseMathObject *self); void BaseMathObject_dealloc(BaseMathObject * self); -PyMODINIT_FUNC BPyInit_mathutils(void); +PyMODINIT_FUNC PyInit_mathutils(void); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); diff --git a/source/blender/python/generic/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index d0c7ec72cea..37730ba4649 100644 --- a/source/blender/python/generic/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Color.c 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h index 0fc880363f4..0afb0ee4dc1 100644 --- a/source/blender/python/generic/mathutils_Color.h +++ b/source/blender/python/mathutils/mathutils_Color.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Color.h 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c index a7d6d921d16..afff9275aa0 100644 --- a/source/blender/python/generic/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Euler.c 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -38,10 +38,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#ifndef int32_t -#include "BLO_sys_types.h" -#endif - #define EULER_SIZE 3 //----------------------------------mathutils.Euler() ------------------- @@ -89,7 +85,7 @@ static const char *euler_order_str(EulerObject *self) short euler_order_from_string(const char *str, const char *error_prefix) { if((str[0] && str[1] && str[2] && str[3]=='\0')) { - switch(*((int32_t *)str)) { + switch(*((PY_INT32_T *)str)) { case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ; case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY; case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ; diff --git a/source/blender/python/generic/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h index 849e16c2bb7..2df3d6198b8 100644 --- a/source/blender/python/generic/mathutils_Euler.h +++ b/source/blender/python/mathutils/mathutils_Euler.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Euler.h 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index c5ed1e32ee8..d0483fbf3df 100644 --- a/source/blender/python/generic/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Matrix.c 38527 2011-07-20 06:41:51Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,7 +35,6 @@ #include "mathutils.h" #include "BLI_math.h" -#include "BLI_blenlib.h" #include "BLI_utildefines.h" static PyObject *Matrix_copy(MatrixObject *self); @@ -1588,31 +1587,25 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) if(mat1 && mat2) { /*MATRIX * MATRIX*/ - if(mat1->row_size != mat2->col_size){ + if(mat2->row_size != mat1->col_size){ PyErr_SetString(PyExc_ValueError, "Matrix multiplication: " "matrix A rowsize must equal matrix B colsize"); return NULL; } else { - float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - double dot = 0.0f; + float mat[16]= {0.0f}; int x, y, z; for(x = 0; x < mat2->row_size; x++) { for(y = 0; y < mat1->col_size; y++) { for(z = 0; z < mat1->row_size; z++) { - dot += (mat1->matrix[z][y] * mat2->matrix[x][z]); + mat[x * mat2->col_size + y] += (mat2->matrix[x][z] * mat1->matrix[z][y]); } - mat[((x * mat1->col_size) + y)] = (float)dot; - dot = 0.0f; } } - return newMatrixObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return newMatrixObject(mat, mat1->row_size, mat2->col_size, Py_NEW, Py_TYPE(mat1)); } } else if(mat2) { diff --git a/source/blender/python/generic/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h index aa736d1e959..84a92bae2be 100644 --- a/source/blender/python/generic/mathutils_Matrix.h +++ b/source/blender/python/mathutils/mathutils_Matrix.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Matrix.h 38409 2011-07-15 04:01:47Z campbellbarton $ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/python/generic/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 3b05b9a250b..62e2fb48103 100644 --- a/source/blender/python/generic/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Quaternion.c 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h index d606621390a..4ba70895680 100644 --- a/source/blender/python/generic/mathutils_Quaternion.h +++ b/source/blender/python/mathutils/mathutils_Quaternion.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Quaternion.h 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index a834e8f2ba4..e1a96f278d7 100644 --- a/source/blender/python/generic/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Vector.c 38409 2011-07-15 04:01:47Z campbellbarton $ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -34,7 +34,6 @@ #include "mathutils.h" -#include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/python/generic/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h index 0ede836ce44..e430a100836 100644 --- a/source/blender/python/generic/mathutils_Vector.h +++ b/source/blender/python/mathutils/mathutils_Vector.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_Vector.h 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index d2724f6603e..acfb8a91416 100644 --- a/source/blender/python/generic/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_geometry.c 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -37,16 +37,16 @@ #include "mathutils_geometry.h" /* Used for PolyFill */ -#include "MEM_guardedalloc.h" +#ifndef MATH_STANDALONE /* define when building outside blender */ +# include "MEM_guardedalloc.h" +# include "BLI_blenlib.h" +# include "BLI_boxpack2d.h" +# include "BKE_displist.h" +# include "BKE_curve.h" +#endif -#include "BLI_blenlib.h" -#include "BLI_boxpack2d.h" #include "BLI_math.h" #include "BLI_utildefines.h" - -#include "BKE_displist.h" - -#include "BKE_curve.h" #define SWAP_FLOAT(a, b, tmp) tmp=a; a=b; b=tmp #define eps 0.000001 @@ -346,132 +346,6 @@ static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args) } } -/*----------------------------------geometry.PolyFill() -------------------*/ -PyDoc_STRVAR(M_Geometry_tesselate_polygon_doc, -".. function:: tesselate_polygon(veclist_list)\n" -"\n" -" Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.\n" -"\n" -" :arg veclist_list: list of polylines\n" -" :rtype: list\n" -); -/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */ -static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *polyLineSeq) -{ - PyObject *tri_list; /*return this list of tri's */ - PyObject *polyLine, *polyVec; - int i, len_polylines, len_polypoints, ls_error= 0; - - /* display listbase */ - ListBase dispbase={NULL, NULL}; - DispList *dl; - float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */ - int index, *dl_face, totpoints=0; - - if(!PySequence_Check(polyLineSeq)) { - PyErr_SetString(PyExc_TypeError, - "expected a sequence of poly lines"); - return NULL; - } - - len_polylines= PySequence_Size(polyLineSeq); - - for(i= 0; i < len_polylines; ++i) { - polyLine= PySequence_GetItem(polyLineSeq, i); - if (!PySequence_Check(polyLine)) { - freedisplist(&dispbase); - Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/ - PyErr_SetString(PyExc_TypeError, - "One or more of the polylines is not a sequence of mathutils.Vector's"); - return NULL; - } - - len_polypoints= PySequence_Size(polyLine); - if (len_polypoints>0) { /* dont bother adding edges as polylines */ -#if 0 - if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) { - freedisplist(&dispbase); - Py_DECREF(polyLine); - PyErr_SetString(PyExc_TypeError, - "A point in one of the polylines is not a mathutils.Vector type"); - return NULL; - } -#endif - dl= MEM_callocN(sizeof(DispList), "poly disp"); - BLI_addtail(&dispbase, dl); - dl->type= DL_INDEX3; - dl->nr= len_polypoints; - dl->type= DL_POLY; - dl->parts= 1; /* no faces, 1 edge loop */ - dl->col= 0; /* no material */ - dl->verts= fp= MEM_callocN(sizeof(float)*3*len_polypoints, "dl verts"); - dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index"); - - for(index= 0; index<len_polypoints; ++index, fp+=3) { - polyVec= PySequence_GetItem(polyLine, index); - if(VectorObject_Check(polyVec)) { - - if(BaseMath_ReadCallback((VectorObject *)polyVec) == -1) - ls_error= 1; - - fp[0]= ((VectorObject *)polyVec)->vec[0]; - fp[1]= ((VectorObject *)polyVec)->vec[1]; - if(((VectorObject *)polyVec)->size > 2) - fp[2]= ((VectorObject *)polyVec)->vec[2]; - else - fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ - } - else { - ls_error= 1; - } - - totpoints++; - Py_DECREF(polyVec); - } - } - Py_DECREF(polyLine); - } - - if(ls_error) { - freedisplist(&dispbase); /* possible some dl was allocated */ - PyErr_SetString(PyExc_TypeError, - "A point in one of the polylines " - "is not a mathutils.Vector type"); - return NULL; - } - else if (totpoints) { - /* now make the list to return */ - filldisplist(&dispbase, &dispbase, 0); - - /* The faces are stored in a new DisplayList - thats added to the head of the listbase */ - dl= dispbase.first; - - tri_list= PyList_New(dl->parts); - if(!tri_list) { - freedisplist(&dispbase); - PyErr_SetString(PyExc_RuntimeError, - "failed to make a new list"); - return NULL; - } - - index= 0; - dl_face= dl->index; - while(index < dl->parts) { - PyList_SET_ITEM(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2])); - dl_face+= 3; - index++; - } - freedisplist(&dispbase); - } - else { - /* no points, do this so scripts dont barf */ - freedisplist(&dispbase); /* possible some dl was allocated */ - tri_list= PyList_New(0); - } - - return tri_list; -} PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc, ".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n" @@ -844,25 +718,288 @@ static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyOb return PyLong_FromLong(isect_point_quad_v2(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec)); } +PyDoc_STRVAR(M_Geometry_barycentric_transform_doc, +".. function:: barycentric_transform(point, tri_a1, tri_a2, tri_a3, tri_b1, tri_b2, tri_b3)\n" +"\n" +" Return a transformed point, the transformation is defined by 2 triangles.\n" +"\n" +" :arg point: The point to transform.\n" +" :type point: :class:`mathutils.Vector`\n" +" :arg tri_a1: source triangle vertex.\n" +" :type tri_a1: :class:`mathutils.Vector`\n" +" :arg tri_a2: source triangle vertex.\n" +" :type tri_a2: :class:`mathutils.Vector`\n" +" :arg tri_a3: source triangle vertex.\n" +" :type tri_a3: :class:`mathutils.Vector`\n" +" :arg tri_a1: target triangle vertex.\n" +" :type tri_a1: :class:`mathutils.Vector`\n" +" :arg tri_a2: target triangle vertex.\n" +" :type tri_a2: :class:`mathutils.Vector`\n" +" :arg tri_a3: target triangle vertex.\n" +" :type tri_a3: :class:`mathutils.Vector`\n" +" :return: The transformed point\n" +" :rtype: :class:`mathutils.Vector`'s\n" +); +static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args) +{ + VectorObject *vec_pt; + VectorObject *vec_t1_tar, *vec_t2_tar, *vec_t3_tar; + VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src; + float vec[3]; + + if(!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!:barycentric_transform", + &vector_Type, &vec_pt, + &vector_Type, &vec_t1_src, + &vector_Type, &vec_t2_src, + &vector_Type, &vec_t3_src, + &vector_Type, &vec_t1_tar, + &vector_Type, &vec_t2_tar, + &vector_Type, &vec_t3_tar) + ) { + return NULL; + } + + if( vec_pt->size != 3 || + vec_t1_src->size != 3 || + vec_t2_src->size != 3 || + vec_t3_src->size != 3 || + vec_t1_tar->size != 3 || + vec_t2_tar->size != 3 || + vec_t3_tar->size != 3) + { + PyErr_SetString(PyExc_ValueError, + "One of more of the vector arguments wasn't a 3D vector"); + return NULL; + } + + barycentric_transform(vec, vec_pt->vec, + vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec, + vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec); + + return newVectorObject(vec, 3, Py_NEW, NULL); +} + +#ifndef MATH_STANDALONE + +PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc, +".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n" +"\n" +" Interpolate a bezier spline segment.\n" +"\n" +" :arg knot1: First bezier spline point.\n" +" :type knot1: :class:`mathutils.Vector`\n" +" :arg handle1: First bezier spline handle.\n" +" :type handle1: :class:`mathutils.Vector`\n" +" :arg handle2: Second bezier spline handle.\n" +" :type handle2: :class:`mathutils.Vector`\n" +" :arg knot2: Second bezier spline point.\n" +" :type knot2: :class:`mathutils.Vector`\n" +" :arg resolution: Number of points to return.\n" +" :type resolution: int\n" +" :return: The interpolated points\n" +" :rtype: list of :class:`mathutils.Vector`'s\n" +); +static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args) +{ + VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2; + int resolu; + int dims; + int i; + float *coord_array, *fp; + PyObject *list; + + float k1[4]= {0.0, 0.0, 0.0, 0.0}; + float h1[4]= {0.0, 0.0, 0.0, 0.0}; + float k2[4]= {0.0, 0.0, 0.0, 0.0}; + float h2[4]= {0.0, 0.0, 0.0, 0.0}; + + + if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier", + &vector_Type, &vec_k1, + &vector_Type, &vec_h1, + &vector_Type, &vec_h2, + &vector_Type, &vec_k2, &resolu) + ) { + return NULL; + } + + if(resolu <= 1) { + PyErr_SetString(PyExc_ValueError, + "resolution must be 2 or over"); + return NULL; + } + + if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1) + return NULL; + + dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); + + for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; + for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i]; + for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i]; + for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i]; + + coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier"); + for(i=0; i<dims; i++) { + forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims); + } + + list= PyList_New(resolu); + fp= coord_array; + for(i=0; i<resolu; i++, fp= fp+dims) { + PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL)); + } + MEM_freeN(coord_array); + return list; +} + + +PyDoc_STRVAR(M_Geometry_tesselate_polygon_doc, +".. function:: tesselate_polygon(veclist_list)\n" +"\n" +" Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.\n" +"\n" +" :arg veclist_list: list of polylines\n" +" :rtype: list\n" +); +/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */ +static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *polyLineSeq) +{ + PyObject *tri_list; /*return this list of tri's */ + PyObject *polyLine, *polyVec; + int i, len_polylines, len_polypoints, ls_error= 0; + + /* display listbase */ + ListBase dispbase={NULL, NULL}; + DispList *dl; + float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */ + int index, *dl_face, totpoints=0; + + if(!PySequence_Check(polyLineSeq)) { + PyErr_SetString(PyExc_TypeError, + "expected a sequence of poly lines"); + return NULL; + } + + len_polylines= PySequence_Size(polyLineSeq); + + for(i= 0; i < len_polylines; ++i) { + polyLine= PySequence_GetItem(polyLineSeq, i); + if (!PySequence_Check(polyLine)) { + freedisplist(&dispbase); + Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/ + PyErr_SetString(PyExc_TypeError, + "One or more of the polylines is not a sequence of mathutils.Vector's"); + return NULL; + } + + len_polypoints= PySequence_Size(polyLine); + if (len_polypoints>0) { /* dont bother adding edges as polylines */ +#if 0 + if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) { + freedisplist(&dispbase); + Py_DECREF(polyLine); + PyErr_SetString(PyExc_TypeError, + "A point in one of the polylines is not a mathutils.Vector type"); + return NULL; + } +#endif + dl= MEM_callocN(sizeof(DispList), "poly disp"); + BLI_addtail(&dispbase, dl); + dl->type= DL_INDEX3; + dl->nr= len_polypoints; + dl->type= DL_POLY; + dl->parts= 1; /* no faces, 1 edge loop */ + dl->col= 0; /* no material */ + dl->verts= fp= MEM_callocN(sizeof(float)*3*len_polypoints, "dl verts"); + dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index"); + + for(index= 0; index<len_polypoints; ++index, fp+=3) { + polyVec= PySequence_GetItem(polyLine, index); + if(VectorObject_Check(polyVec)) { + + if(BaseMath_ReadCallback((VectorObject *)polyVec) == -1) + ls_error= 1; + + fp[0]= ((VectorObject *)polyVec)->vec[0]; + fp[1]= ((VectorObject *)polyVec)->vec[1]; + if(((VectorObject *)polyVec)->size > 2) + fp[2]= ((VectorObject *)polyVec)->vec[2]; + else + fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ + } + else { + ls_error= 1; + } + + totpoints++; + Py_DECREF(polyVec); + } + } + Py_DECREF(polyLine); + } + + if(ls_error) { + freedisplist(&dispbase); /* possible some dl was allocated */ + PyErr_SetString(PyExc_TypeError, + "A point in one of the polylines " + "is not a mathutils.Vector type"); + return NULL; + } + else if (totpoints) { + /* now make the list to return */ + filldisplist(&dispbase, &dispbase, 0); + + /* The faces are stored in a new DisplayList + thats added to the head of the listbase */ + dl= dispbase.first; + + tri_list= PyList_New(dl->parts); + if(!tri_list) { + freedisplist(&dispbase); + PyErr_SetString(PyExc_RuntimeError, + "failed to make a new list"); + return NULL; + } + + index= 0; + dl_face= dl->index; + while(index < dl->parts) { + PyList_SET_ITEM(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2])); + dl_face+= 3; + index++; + } + freedisplist(&dispbase); + } + else { + /* no points, do this so scripts dont barf */ + freedisplist(&dispbase); /* possible some dl was allocated */ + tri_list= PyList_New(0); + } + + return tri_list; +} + + static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray) { int len, i; PyObject *list_item, *item_1, *item_2; boxPack *box; - - + + /* Error checking must already be done */ if(!PyList_Check(value)) { PyErr_SetString(PyExc_TypeError, "can only back a list of [x, y, w, h]"); return -1; } - + len= PyList_Size(value); - + (*boxarray)= MEM_mallocN(len*sizeof(boxPack), "boxPack box"); - - + + for(i= 0; i < len; i++) { list_item= PyList_GET_ITEM(value, i); if(!PyList_Check(list_item) || PyList_Size(list_item) < 4) { @@ -871,12 +1008,12 @@ static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray) "can only pack a list of [x, y, w, h]"); return -1; } - + box= (*boxarray)+i; - + item_1= PyList_GET_ITEM(list_item, 2); item_2= PyList_GET_ITEM(list_item, 3); - + box->w= (float)PyFloat_AsDouble(item_1); box->h= (float)PyFloat_AsDouble(item_2); box->index= i; @@ -900,9 +1037,9 @@ static void boxPack_ToPyObject(PyObject *value, boxPack **boxarray) int len, i; PyObject *list_item; boxPack *box; - + len= PyList_Size(value); - + for(i= 0; i < len; i++) { box= (*boxarray)+i; list_item= PyList_GET_ITEM(value, box->index); @@ -928,7 +1065,7 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis int len; PyObject *ret; - + if(!PyList_Check(boxlist)) { PyErr_SetString(PyExc_TypeError, "expected a list of boxes [[x, y, w, h], ... ]"); @@ -954,138 +1091,8 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis return ret; } -PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc, -".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n" -"\n" -" Interpolate a bezier spline segment.\n" -"\n" -" :arg knot1: First bezier spline point.\n" -" :type knot1: :class:`mathutils.Vector`\n" -" :arg handle1: First bezier spline handle.\n" -" :type handle1: :class:`mathutils.Vector`\n" -" :arg handle2: Second bezier spline handle.\n" -" :type handle2: :class:`mathutils.Vector`\n" -" :arg knot2: Second bezier spline point.\n" -" :type knot2: :class:`mathutils.Vector`\n" -" :arg resolution: Number of points to return.\n" -" :type resolution: int\n" -" :return: The interpolated points\n" -" :rtype: list of :class:`mathutils.Vector`'s\n" -); -static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2; - int resolu; - int dims; - int i; - float *coord_array, *fp; - PyObject *list; - - float k1[4]= {0.0, 0.0, 0.0, 0.0}; - float h1[4]= {0.0, 0.0, 0.0, 0.0}; - float k2[4]= {0.0, 0.0, 0.0, 0.0}; - float h2[4]= {0.0, 0.0, 0.0, 0.0}; - - - if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier", - &vector_Type, &vec_k1, - &vector_Type, &vec_h1, - &vector_Type, &vec_h2, - &vector_Type, &vec_k2, &resolu) - ) { - return NULL; - } - - if(resolu <= 1) { - PyErr_SetString(PyExc_ValueError, - "resolution must be 2 or over"); - return NULL; - } - - if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1) - return NULL; - - dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); - - for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; - for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i]; - for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i]; - for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i]; - - coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier"); - for(i=0; i<dims; i++) { - forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims); - } - - list= PyList_New(resolu); - fp= coord_array; - for(i=0; i<resolu; i++, fp= fp+dims) { - PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL)); - } - MEM_freeN(coord_array); - return list; -} - -PyDoc_STRVAR(M_Geometry_barycentric_transform_doc, -".. function:: barycentric_transform(point, tri_a1, tri_a2, tri_a3, tri_b1, tri_b2, tri_b3)\n" -"\n" -" Return a transformed point, the transformation is defined by 2 triangles.\n" -"\n" -" :arg point: The point to transform.\n" -" :type point: :class:`mathutils.Vector`\n" -" :arg tri_a1: source triangle vertex.\n" -" :type tri_a1: :class:`mathutils.Vector`\n" -" :arg tri_a2: source triangle vertex.\n" -" :type tri_a2: :class:`mathutils.Vector`\n" -" :arg tri_a3: source triangle vertex.\n" -" :type tri_a3: :class:`mathutils.Vector`\n" -" :arg tri_a1: target triangle vertex.\n" -" :type tri_a1: :class:`mathutils.Vector`\n" -" :arg tri_a2: target triangle vertex.\n" -" :type tri_a2: :class:`mathutils.Vector`\n" -" :arg tri_a3: target triangle vertex.\n" -" :type tri_a3: :class:`mathutils.Vector`\n" -" :return: The transformed point\n" -" :rtype: :class:`mathutils.Vector`'s\n" -); -static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args) -{ - VectorObject *vec_pt; - VectorObject *vec_t1_tar, *vec_t2_tar, *vec_t3_tar; - VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src; - float vec[3]; +#endif /* MATH_STANDALONE */ - if(!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!:barycentric_transform", - &vector_Type, &vec_pt, - &vector_Type, &vec_t1_src, - &vector_Type, &vec_t2_src, - &vector_Type, &vec_t3_src, - &vector_Type, &vec_t1_tar, - &vector_Type, &vec_t2_tar, - &vector_Type, &vec_t3_tar) - ) { - return NULL; - } - - if( vec_pt->size != 3 || - vec_t1_src->size != 3 || - vec_t2_src->size != 3 || - vec_t3_src->size != 3 || - vec_t1_tar->size != 3 || - vec_t2_tar->size != 3 || - vec_t3_tar->size != 3) - { - PyErr_SetString(PyExc_ValueError, - "One of more of the vector arguments wasn't a 3D vector"); - return NULL; - } - - barycentric_transform(vec, vec_pt->vec, - vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec, - vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec); - - return newVectorObject(vec, 3, Py_NEW, NULL); -} static PyMethodDef M_Geometry_methods[]= { {"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc}, @@ -1097,12 +1104,14 @@ static PyMethodDef M_Geometry_methods[]= { {"intersect_line_plane", (PyCFunction) M_Geometry_intersect_line_plane, METH_VARARGS, M_Geometry_intersect_line_plane_doc}, {"intersect_line_sphere", (PyCFunction) M_Geometry_intersect_line_sphere, METH_VARARGS, M_Geometry_intersect_line_sphere_doc}, {"intersect_line_sphere_2d", (PyCFunction) M_Geometry_intersect_line_sphere_2d, METH_VARARGS, M_Geometry_intersect_line_sphere_2d_doc}, - {"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc}, {"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc}, {"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc}, + {"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc}, +#ifndef MATH_STANDALONE + {"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc}, {"tesselate_polygon", (PyCFunction) M_Geometry_tesselate_polygon, METH_O, M_Geometry_tesselate_polygon_doc}, {"box_pack_2d", (PyCFunction) M_Geometry_box_pack_2d, METH_O, M_Geometry_box_pack_2d_doc}, - {"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc}, +#endif {NULL, NULL, 0, NULL} }; @@ -1119,7 +1128,7 @@ static struct PyModuleDef M_Geometry_module_def= { }; /*----------------------------MODULE INIT-------------------------*/ -PyMODINIT_FUNC BPyInit_mathutils_geometry(void) +PyMODINIT_FUNC PyInit_mathutils_geometry(void) { PyObject *submodule= PyModule_Create(&M_Geometry_module_def); return submodule; diff --git a/source/blender/python/generic/mathutils_geometry.h b/source/blender/python/mathutils/mathutils_geometry.h index 929b8cc8d75..0b07fc12c69 100644 --- a/source/blender/python/generic/mathutils_geometry.h +++ b/source/blender/python/mathutils/mathutils_geometry.h @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: mathutils_geometry.h 38409 2011-07-15 04:01:47Z campbellbarton $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -38,6 +38,6 @@ #include "mathutils.h" -PyMODINIT_FUNC BPyInit_mathutils_geometry(void); +PyMODINIT_FUNC PyInit_mathutils_geometry(void); #endif /* MATHUTILS_GEOMETRY_H */ |