move mathutils into its own lib.

This commit is contained in:
Campbell Barton 2011-07-15 04:01:47 +00:00
parent 5ff9acfd28
commit 3a6158a8bf
28 changed files with 410 additions and 357 deletions

View File

@ -18,3 +18,4 @@
add_subdirectory(intern)
add_subdirectory(generic)
add_subdirectory(mathutils)

View File

@ -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 = [361,165])
# bpy

View File

@ -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
)

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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}")

View File

@ -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. */

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -34,7 +34,6 @@
#include "mathutils.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"

View File

@ -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,188 +718,6 @@ 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));
}
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) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError,
"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;
/* accounts for error case too and overwrites with own error */
if (box->w < 0.0f || box->h < 0.0f) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError,
"error parsing width and height values from list: "
"[x, y, w, h], not numbers or below zero");
return -1;
}
/* verts will be added later */
}
return 0;
}
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);
PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x));
PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y));
}
MEM_freeN(*boxarray);
}
PyDoc_STRVAR(M_Geometry_box_pack_2d_doc,
".. function:: box_pack_2d(boxes)\n"
"\n"
" Returns the normal of the 3D tri or quad.\n"
"\n"
" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n"
" :type boxes: list\n"
" :return: the width and height of the packed bounding box\n"
" :rtype: tuple, pair of floats\n"
);
static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist)
{
float tot_width= 0.0f, tot_height= 0.0f;
int len;
PyObject *ret;
if(!PyList_Check(boxlist)) {
PyErr_SetString(PyExc_TypeError,
"expected a list of boxes [[x, y, w, h], ... ]");
return NULL;
}
len= PyList_GET_SIZE(boxlist);
if (len) {
boxPack *boxarray= NULL;
if(boxPack_FromPyObject(boxlist, &boxarray) == -1) {
return NULL; /* exception set */
}
/* Non Python function */
boxPack2D(boxarray, len, &tot_width, &tot_height);
boxPack_ToPyObject(boxlist, &boxarray);
}
ret= PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
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"
@ -1087,6 +779,321 @@ static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObje
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) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError,
"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;
/* accounts for error case too and overwrites with own error */
if (box->w < 0.0f || box->h < 0.0f) {
MEM_freeN(*boxarray);
PyErr_SetString(PyExc_TypeError,
"error parsing width and height values from list: "
"[x, y, w, h], not numbers or below zero");
return -1;
}
/* verts will be added later */
}
return 0;
}
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);
PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x));
PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y));
}
MEM_freeN(*boxarray);
}
PyDoc_STRVAR(M_Geometry_box_pack_2d_doc,
".. function:: box_pack_2d(boxes)\n"
"\n"
" Returns the normal of the 3D tri or quad.\n"
"\n"
" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n"
" :type boxes: list\n"
" :return: the width and height of the packed bounding box\n"
" :rtype: tuple, pair of floats\n"
);
static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist)
{
float tot_width= 0.0f, tot_height= 0.0f;
int len;
PyObject *ret;
if(!PyList_Check(boxlist)) {
PyErr_SetString(PyExc_TypeError,
"expected a list of boxes [[x, y, w, h], ... ]");
return NULL;
}
len= PyList_GET_SIZE(boxlist);
if (len) {
boxPack *boxarray= NULL;
if(boxPack_FromPyObject(boxlist, &boxarray) == -1) {
return NULL; /* exception set */
}
/* Non Python function */
boxPack2D(boxarray, len, &tot_width, &tot_height);
boxPack_ToPyObject(boxlist, &boxarray);
}
ret= PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
return ret;
}
#endif /* MATH_STANDALONE */
static PyMethodDef M_Geometry_methods[]= {
{"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc},
{"intersect_point_line", (PyCFunction) M_Geometry_intersect_point_line, METH_VARARGS, M_Geometry_intersect_point_line_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;

View File

@ -38,6 +38,6 @@
#include "mathutils.h"
PyMODINIT_FUNC BPyInit_mathutils_geometry(void);
PyMODINIT_FUNC PyInit_mathutils_geometry(void);
#endif /* MATHUTILS_GEOMETRY_H */

View File

@ -121,6 +121,7 @@ endif()
bf_intern_guardedalloc
bf_intern_memutil
bf_python_ext
bf_python_mathutils
bf_blenlib
bf_imbuf_cineon
bf_imbuf_openexr

View File

@ -768,6 +768,7 @@ endif()
bf_intern_opennl
bf_python
bf_python_ext
bf_python_mathutils
bf_ikplugin
bf_modifiers
bf_blenkernel

View File

@ -54,7 +54,7 @@
#ifdef WITH_PYTHON
#ifdef USE_MATHUTILS
extern "C" {
#include "../../blender/python/generic/mathutils.h" /* so we can have mathutils callbacks */
#include "../../blender/python/mathutils/mathutils.h" /* so we can have mathutils callbacks */
}
#endif

View File

@ -40,6 +40,7 @@ set(INC
../../../source/blender/blenkernel
../../../source/blender/python
../../../source/blender/python/generic
../../../source/blender/python/mathutils
../../../source/blender
../../../source/blender/makesdna
../../../source/gameengine/Rasterizer

View File

@ -49,7 +49,7 @@
#ifdef WITH_PYTHON
#ifdef USE_MATHUTILS
extern "C" {
#include "../../blender/python/generic/mathutils.h" /* so we can have mathutils callbacks */
#include "../../blender/python/mathutils/mathutils.h" /* so we can have mathutils callbacks */
}
#endif

View File

@ -54,7 +54,7 @@
extern "C" {
#include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */
#include "py_capi_utils.h"
#include "mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use.
#include "mathutils.h" // 'mathutils' module copied here so the blenderlayer can use.
#include "bgl.h"
#include "blf_py_api.h"
@ -1749,7 +1749,7 @@ static void restorePySysObjects(void)
// Copied from bpy_interface.c
static struct _inittab bge_internal_modules[]= {
{(char *)"mathutils", BPyInit_mathutils},
{(char *)"mathutils", PyInit_mathutils},
{(char *)"bgl", BPyInit_bgl},
{(char *)"blf", BPyInit_blf},
{(char *)"aud", AUD_initPython},

View File

@ -6,7 +6,8 @@ Import ('env')
sources = env.Glob('*.cpp')
defs = [ 'GLEW_STATIC' ]
incs = '. #source/blender/python/generic' # Only for Mathutils! and bpy_internal_import.h, be very careful
incs = '. #source/blender/python/generic' # Only for bpy_internal_import.h, be very careful
incs += ' #source/blender/python/mathutils' # Only for mathutils, be very careful
incs += ' #intern/string #intern/guardedalloc #intern/container'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'