Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-12-30 14:47:56 +0300
committerCampbell Barton <ideasman42@gmail.com>2014-12-30 14:49:52 +0300
commitcefb76426980b763bbf68f022fc0df8aec8a25bd (patch)
tree2fcd4f3329109a96fd46eb7cbec7e4631b24c4fc /source
parent68600920ced198eaa1524993f988f26118402e50 (diff)
PyAPI: geometry.normal, support polygons
Previously this only supported tri/quads, now arbitrary size poly lines are supported.
Diffstat (limited to 'source')
-rw-r--r--source/blender/python/mathutils/mathutils.c7
-rw-r--r--source/blender/python/mathutils/mathutils.h2
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c90
3 files changed, 30 insertions, 69 deletions
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 5c3f38e2c12..8aaf47f090f 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -72,7 +72,7 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
const int flag = array_max;
int size;
- array_max &= ~(MU_ARRAY_ZERO | MU_ARRAY_SPILL);
+ array_max &= ~MU_ARRAY_FLAGS;
#if 1 /* approx 6x speedup for mathutils types */
@@ -217,6 +217,7 @@ int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, c
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
{
PyObject *value_fast = NULL;
+ const int array_dim_flag = array_dim;
int i, size;
/* non list/tuple cases */
@@ -230,12 +231,14 @@ int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value,
if (size != 0) {
float *fp;
+ array_dim &= ~MU_ARRAY_FLAGS;
+
fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
for (i = 0; i < size; i++, fp += array_dim) {
PyObject *item = PySequence_Fast_GET_ITEM(value, i);
- if (mathutils_array_parse(fp, array_dim, array_dim, item, error_prefix) == -1) {
+ if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
PyMem_Free(*array);
*array = NULL;
size = -1;
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index 5f89c78b9cd..be2b45d349f 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -115,6 +115,8 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
* handy when using 3d vectors as 2d */
#define MU_ARRAY_SPILL (1 << 31)
+#define MU_ARRAY_FLAGS (MU_ARRAY_ZERO | MU_ARRAY_SPILL)
+
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
#ifndef MATH_STANDALONE
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 2a570edce93..49f1253af95 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -293,86 +293,42 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P
}
PyDoc_STRVAR(M_Geometry_normal_doc,
-".. function:: normal(v1, v2, v3, v4=None)\n"
+".. function:: normal(vectors)\n"
"\n"
-" Returns the normal of the 3D tri or quad.\n"
+" Returns the normal of a 3D polygon.\n"
"\n"
-" :arg v1: Point1\n"
-" :type v1: :class:`mathutils.Vector`\n"
-" :arg v2: Point2\n"
-" :type v2: :class:`mathutils.Vector`\n"
-" :arg v3: Point3\n"
-" :type v3: :class:`mathutils.Vector`\n"
-" :arg v4: Point4 (optional)\n"
-" :type v4: :class:`mathutils.Vector`\n"
+" :arg vectors: Vectors to calculate normals with\n"
+" :type vectors: sequence of 3 or more 3d vector\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *vec1, *vec2, *vec3, *vec4;
+ float (*coords)[3];
+ int coords_len;
float n[3];
+ PyObject *ret = NULL;
- if (PyTuple_GET_SIZE(args) == 3) {
- if (!PyArg_ParseTuple(args, "O!O!O!:normal",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3))
- {
- return NULL;
- }
-
- if (vec1->size != vec2->size || vec1->size != vec3->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
- if (vec1->size < 3) {
- PyErr_SetString(PyExc_ValueError,
- "2D vectors unsupported");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1)
- {
- return NULL;
- }
-
- normal_tri_v3(n, vec1->vec, vec2->vec, vec3->vec);
+ /* use */
+ if (PyTuple_GET_SIZE(args) == 1) {
+ args = PyTuple_GET_ITEM(args, 0);
}
- else {
- if (!PyArg_ParseTuple(args, "O!O!O!O!:normal",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &vec4))
- {
- return NULL;
- }
- if (vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
- if (vec1->size < 3) {
- PyErr_SetString(PyExc_ValueError,
- "2D vectors unsupported");
- return NULL;
- }
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(vec4) == -1)
- {
- return NULL;
- }
+ if ((coords_len = mathutils_array_parse_alloc_v((float **)&coords, 3 | MU_ARRAY_SPILL, args, "normal")) == -1) {
+ return NULL;
+ }
- normal_quad_v3(n, vec1->vec, vec2->vec, vec3->vec, vec4->vec);
+ if (coords_len < 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Expected 3 or more vectors");
+ goto finally;
}
- return Vector_CreatePyObject(n, 3, Py_NEW, NULL);
+ normal_poly_v3(n, (const float (*)[3])coords, coords_len);
+ ret = Vector_CreatePyObject(n, 3, Py_NEW, NULL);
+
+finally:
+ PyMem_Free(coords);
+ return ret;
}
/* --------------------------------- AREA FUNCTIONS-------------------- */