[Bf-blender-cvs] [6860092] master: PyAPI: allow non-vector args for geometry module
Campbell Barton
noreply at git.blender.org
Tue Dec 30 12:26:00 CET 2014
Commit: 68600920ced198eaa1524993f988f26118402e50
Author: Campbell Barton
Date: Tue Dec 30 21:50:47 2014 +1100
Branches: master
https://developer.blender.org/rB68600920ced198eaa1524993f988f26118402e50
PyAPI: allow non-vector args for geometry module
Previously only vector args were accepted,
now allow generic sequence of numbers.
Was annoying to create vectors just to pass in args.
===================================================================
M source/blender/python/mathutils/mathutils.c
M source/blender/python/mathutils/mathutils.h
M source/blender/python/mathutils/mathutils_geometry.c
===================================================================
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 349f848..5c3f38e 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -69,8 +69,11 @@ static int mathutils_array_parse_fast(float *array,
/* helper functionm returns length of the 'value', -1 on error */
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
{
+ const int flag = array_max;
int size;
+ array_max &= ~(MU_ARRAY_ZERO | MU_ARRAY_SPILL);
+
#if 1 /* approx 6x speedup for mathutils types */
if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
@@ -82,6 +85,10 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
return -1;
}
+ if (flag & MU_ARRAY_SPILL) {
+ CLAMP_MAX(size, array_max);
+ }
+
if (size > array_max || size < array_min) {
if (array_max == array_min) {
PyErr_Format(PyExc_ValueError,
@@ -97,7 +104,6 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
}
memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float));
- return size;
}
else
#endif
@@ -112,6 +118,10 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
size = PySequence_Fast_GET_SIZE(value_fast);
+ if (flag & MU_ARRAY_SPILL) {
+ CLAMP_MAX(size, array_max);
+ }
+
if (size > array_max || size < array_min) {
if (array_max == array_min) {
PyErr_Format(PyExc_ValueError,
@@ -127,8 +137,19 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
return -1;
}
- return mathutils_array_parse_fast(array, size, value_fast, error_prefix);
+ size = mathutils_array_parse_fast(array, size, value_fast, error_prefix);
}
+
+ if (size != -1) {
+ if (flag & MU_ARRAY_ZERO) {
+ int size_left = array_max - size;
+ if (size_left) {
+ memset(&array[size], 0, sizeof(float) * size_left);
+ }
+ }
+ }
+
+ return size;
}
/* on error, -1 is returned and no allocation is made */
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index eb25d9b..5f89c78 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -109,6 +109,12 @@ 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);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
+/* zero remaining unused elements of the array */
+#define MU_ARRAY_ZERO (1 << 30)
+/* ignore larger py sequences than requested (just use first elements),
+ * handy when using 3d vectors as 2d */
+#define MU_ARRAY_SPILL (1 << 31)
+
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 013c874..2a570ed 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -72,48 +72,37 @@ PyDoc_STRVAR(M_Geometry_intersect_ray_tri_doc,
);
static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
- float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
+ const char *error_prefix = "intersect_ray_tri";
+ PyObject *py_ray, *py_ray_off, *py_tri[3];
+ float dir[3], orig[3], tri[3][3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
float det, inv_det, u, v, t;
int clip = 1;
+ int i;
- if (!PyArg_ParseTuple(args,
- "O!O!O!O!O!|i:intersect_ray_tri",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &ray,
- &vector_Type, &ray_off, &clip))
+ if (!PyArg_ParseTuple(
+ args, "OOOOO|i:intersect_ray_tri",
+ UNPACK3_EX(&, py_tri, ), &py_ray, &py_ray_off, &clip))
{
return NULL;
}
- if (vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
- PyErr_SetString(PyExc_ValueError,
- "only 3D vectors for all parameters");
- return NULL;
- }
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(ray) == -1 ||
- BaseMath_ReadCallback(ray_off) == -1)
+ if (((mathutils_array_parse(dir, 3, 3, py_ray, error_prefix) != -1) &&
+ (mathutils_array_parse(orig, 3, 3, py_ray_off, error_prefix) != -1)) == 0)
{
return NULL;
}
- copy_v3_v3(v1, vec1->vec);
- copy_v3_v3(v2, vec2->vec);
- copy_v3_v3(v3, vec3->vec);
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(tri[i], 2, 2 | MU_ARRAY_SPILL, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
- copy_v3_v3(dir, ray->vec);
normalize_v3(dir);
- copy_v3_v3(orig, ray_off->vec);
-
/* find vectors for two edges sharing v1 */
- sub_v3_v3v3(e1, v2, v1);
- sub_v3_v3v3(e2, v3, v1);
+ sub_v3_v3v3(e1, tri[1], tri[0]);
+ sub_v3_v3v3(e2, tri[2], tri[0]);
/* begin calculating determinant - also used to calculated U parameter */
cross_v3_v3v3(pvec, dir, e2);
@@ -128,7 +117,7 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *
inv_det = 1.0f / det;
/* calculate distance from v1 to ray origin */
- sub_v3_v3v3(tvec, orig, v1);
+ sub_v3_v3v3(tvec, orig, tri[0]);
/* calculate U parameter and test bounds */
u = dot_v3v3(tvec, pvec) * inv_det;
@@ -179,82 +168,48 @@ PyDoc_STRVAR(M_Geometry_intersect_line_line_doc,
);
static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject *args)
{
+ const char *error_prefix = "intersect_line_line";
PyObject *tuple;
- VectorObject *vec1, *vec2, *vec3, *vec4;
- float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
-
- if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &vec4))
+ PyObject *py_lines[4];
+ float lines[4][3], i1[3], i2[3];
+ int len;
+ int result;
+
+ if (!PyArg_ParseTuple(
+ args, "OOOO:intersect_line_line",
+ UNPACK4_EX(&, py_lines, )))
{
return NULL;
}
- if (vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(vec4) == -1)
+ if ((((len = mathutils_array_parse(lines[0], 2, 3, py_lines[0], error_prefix)) != -1) &&
+ (mathutils_array_parse(lines[1], len, len, py_lines[1], error_prefix) != -1) &&
+ (mathutils_array_parse(lines[2], len, len, py_lines[2], error_prefix) != -1) &&
+ (mathutils_array_parse(lines[3], len, len, py_lines[3], error_prefix) != -1)) == 0)
{
return NULL;
}
- if (vec1->size == 3 || vec1->size == 2) {
- int result;
-
- if (vec1->size == 3) {
- copy_v3_v3(v1, vec1->vec);
- copy_v3_v3(v2, vec2->vec);
- copy_v3_v3(v3, vec3->vec);
- copy_v3_v3(v4, vec4->vec);
- }
- else {
- v1[0] = vec1->vec[0];
- v1[1] = vec1->vec[1];
- v1[2] = 0.0f;
-
- v2[0] = vec2->vec[0];
- v2[1] = vec2->vec[1];
- v2[2] = 0.0f;
-
- v3[0] = vec3->vec[0];
- v3[1] = vec3->vec[1];
- v3[2] = 0.0f;
-
- v4[0] = vec4->vec[0];
- v4[1] = vec4->vec[1];
- v4[2] = 0.0f;
- }
+ if (len == 2) {
+ lines[0][2] = lines[1][2] = lines[2][2] = lines[3][2] = 0.0f;
+ }
- result = isect_line_line_v3(v1, v2, v3, v4, i1, i2);
- /* The return-code isnt exposed,
- * this way we can check know how close the lines are. */
- if (result == 1) {
- closest_to_line_v3(i2, i1, v3, v4);
- }
+ result = isect_line_line_v3(UNPACK4(lines), i1, i2);
+ /* The return-code isnt exposed,
+ * this way we can check know how close the lines are. */
+ if (result == 1) {
+ closest_to_line_v3(i2, i1, lines[2], lines[3]);
+ }
- if (result == 0) {
- /* colinear */
- Py_RETURN_NONE;
- }
- else {
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, vec1->size, Py_NEW, NULL));
- PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, vec1->size, Py_NEW, NULL));
- return tuple;
- }
+ if (result == 0) {
+ /* colinear */
+ Py_RETURN_NONE;
}
else {
- PyErr_SetString(PyExc_ValueError,
- "2D/3D vectors only");
- return NULL;
+ tuple = PyTuple_New(2);
+ PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, len, Py_NEW, NULL));
+ PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, len, Py_NEW, NULL));
+ return tuple;
}
}
@@ -277,31 +232,30 @@ PyDoc_STRVAR(M_Geometry_intersect_sphere_sphere_2d_doc,
);
static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), PyObject *args)
{
+ const char *error_prefix = "intersect_sphere_sphere_2d";
PyObject *ret;
- VectorObject *vec_a, *vec_b;
- const float *v_a, *v_b;
+ PyObject *py_v_a, *py_v_b;
+ float v_a[2], v_b[2];
float rad_a, rad_b;
float v_ab[2];
float dist;
- if (!PyArg_ParseTuple(args, "O!fO!f:intersect_sphere_sphere_2d",
- &vector_Type, &vec_a, &rad_a,
- &vector_Type, &vec_b, &rad_b))
+ if (!PyArg_ParseTuple(
+ args, "OfOf:intersect_sphere_sphere_2d",
+ &py_v_a, &rad_a,
+ &py_v_b, &rad_b))
{
return NULL;
}
- if (BaseMath_ReadCallback(vec_a) == -1 ||
- BaseMath_ReadCallback(vec_b) == -1)
+ if (((mathutils_array_parse(v_a, 2, 2, py_v_a, error_prefix) != -1) &&
+ (mathutils_array_parse(v_b, 2, 2, py_v_b, error_prefix) != -1)) == 0)
{
return NULL;
}
ret = PyTuple_New(2);
- v_a = vec_a->vec;
- v_b = vec_b->vec;
-
su
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list