[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42702] trunk/blender/source/blender: Support for arbitrary sized vectors - (was limited by 2-4 previously)
Campbell Barton
ideasman42 at gmail.com
Sun Dec 18 08:27:28 CET 2011
Revision: 42702
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42702
Author: campbellbarton
Date: 2011-12-18 07:27:11 +0000 (Sun, 18 Dec 2011)
Log Message:
-----------
Support for arbitrary sized vectors - (was limited by 2-4 previously)
patch http://codereview.appspot.com/5482043
from Andrew Hale
* Text from the submission *
This patch adds the ability to use arbitrary sized vectors from mathutils.
Currently vectors are only of size 2, 3 or 4 since they are generally restricted
to geometric applications. However, we can use arbitrary sized vectors for
efficient calculations and data manipulation.
Modified Paths:
--------------
trunk/blender/source/blender/blenlib/BLI_math_vector.h
trunk/blender/source/blender/blenlib/intern/math_vector.c
trunk/blender/source/blender/python/mathutils/mathutils.c
trunk/blender/source/blender/python/mathutils/mathutils.h
trunk/blender/source/blender/python/mathutils/mathutils_Vector.c
trunk/blender/source/blender/python/mathutils/mathutils_Vector.h
Modified: trunk/blender/source/blender/blenlib/BLI_math_vector.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_vector.h 2011-12-18 07:11:18 UTC (rev 42701)
+++ trunk/blender/source/blender/blenlib/BLI_math_vector.h 2011-12-18 07:27:11 UTC (rev 42702)
@@ -198,6 +198,7 @@
float normalize_vn_vn(float *array_tar, const float *array_src, const int size);
float normalize_vn(float *array_tar, const int size);
void range_vn_i(int *array_tar, const int size, const int start);
+void range_vn_fl(float *array_tar, const int size, const float start, const float step);
void negate_vn(float *array_tar, const int size);
void negate_vn_vn(float *array_tar, const float *array_src, const int size);
void mul_vn_fl(float *array_tar, const int size, const float f);
Modified: trunk/blender/source/blender/blenlib/intern/math_vector.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_vector.c 2011-12-18 07:11:18 UTC (rev 42701)
+++ trunk/blender/source/blender/blenlib/intern/math_vector.c 2011-12-18 07:27:11 UTC (rev 42702)
@@ -416,6 +416,15 @@
while(i--) { *(array_pt--) = j--; }
}
+void range_vn_fl(float *array_tar, const int size, const float start, const float step)
+{
+ float *array_pt= array_tar + (size-1);
+ int i= size;
+ while(i--) {
+ *(array_pt--) = start + step * (float)(i);
+ }
+}
+
void negate_vn(float *array_tar, const int size)
{
float *array_pt= array_tar + (size-1);
Modified: trunk/blender/source/blender/python/mathutils/mathutils.c
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils.c 2011-12-18 07:11:18 UTC (rev 42701)
+++ trunk/blender/source/blender/python/mathutils/mathutils.c 2011-12-18 07:27:11 UTC (rev 42702)
@@ -40,37 +40,14 @@
"This module provides access to matrices, eulers, quaternions and vectors."
);
static int mathutils_array_parse_fast(float *array,
- int array_min, int array_max,
- PyObject *value, const char *error_prefix)
+ int size,
+ PyObject *value_fast,
+ const char *error_prefix)
{
- PyObject *value_fast= NULL;
PyObject *item;
- int i, size;
+ int i;
- /* non list/tuple cases */
- if (!(value_fast=PySequence_Fast(value, error_prefix))) {
- /* PySequence_Fast sets the error */
- return -1;
- }
-
- size= PySequence_Fast_GET_SIZE(value_fast);
-
- if (size > array_max || size < array_min) {
- if (array_max == array_min) {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected %d",
- error_prefix, size, array_max);
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected [%d - %d]",
- error_prefix, size, array_min, array_max);
- }
- Py_DECREF(value_fast);
- return -1;
- }
-
i= size;
do {
i--;
@@ -93,9 +70,10 @@
/* 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)
{
-#if 1 /* approx 6x speedup for mathutils types */
int size;
+#if 1 /* approx 6x speedup for mathutils types */
+
if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
(size= EulerObject_Check(value) ? 3 : 0) ||
(size= QuaternionObject_Check(value) ? 4 : 0) ||
@@ -125,10 +103,88 @@
else
#endif
{
- return mathutils_array_parse_fast(array, array_min, array_max, value, error_prefix);
+ PyObject *value_fast= NULL;
+
+ /* non list/tuple cases */
+ if (!(value_fast=PySequence_Fast(value, error_prefix))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
+
+ size= PySequence_Fast_GET_SIZE(value_fast);
+
+ if (size > array_max || size < array_min) {
+ if (array_max == array_min) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected %d",
+ error_prefix, size, array_max);
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected [%d - %d]",
+ error_prefix, size, array_min, array_max);
+ }
+ Py_DECREF(value_fast);
+ return -1;
+ }
+
+ return mathutils_array_parse_fast(array, size, value_fast, error_prefix);
}
}
+int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix)
+{
+ int size;
+
+#if 1 /* approx 6x speedup for mathutils types */
+
+ if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
+ (size= EulerObject_Check(value) ? 3 : 0) ||
+ (size= QuaternionObject_Check(value) ? 4 : 0) ||
+ (size= ColorObject_Check(value) ? 3 : 0))
+ {
+ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
+ return -1;
+ }
+
+ if (size < array_min) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected > %d",
+ error_prefix, size, array_min);
+ return -1;
+ }
+
+ *array= PyMem_Malloc(size * sizeof(float));
+ memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
+ return size;
+ }
+ else
+#endif
+ {
+ PyObject *value_fast= NULL;
+ //*array= NULL;
+
+ /* non list/tuple cases */
+ if (!(value_fast=PySequence_Fast(value, error_prefix))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
+
+ size= PySequence_Fast_GET_SIZE(value_fast);
+
+ if (size < array_min) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected > %d",
+ error_prefix, size, array_min);
+ return -1;
+ }
+
+ *array= PyMem_Malloc(size * sizeof(float));
+
+ return mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
+ }
+}
+
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
{
if (EulerObject_Check(value)) {
Modified: trunk/blender/source/blender/python/mathutils/mathutils.h
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils.h 2011-12-18 07:11:18 UTC (rev 42701)
+++ trunk/blender/source/blender/python/mathutils/mathutils.h 2011-12-18 07:27:11 UTC (rev 42702)
@@ -115,6 +115,7 @@
/* utility func */
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
+int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
Modified: trunk/blender/source/blender/python/mathutils/mathutils_Vector.c
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils_Vector.c 2011-12-18 07:11:18 UTC (rev 42701)
+++ trunk/blender/source/blender/python/mathutils/mathutils_Vector.c 2011-12-18 07:27:11 UTC (rev 42702)
@@ -54,15 +54,29 @@
*/
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
{
- float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+ float *vec= NULL;
int size= 3; /* default to a 3D vector */
switch(PyTuple_GET_SIZE(args)) {
case 0:
+ vec= PyMem_Malloc(size * sizeof(float));
+
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ fill_vn_fl(vec, size, 0.0f);
break;
case 1:
- if ((size=mathutils_array_parse(vec, 2, 4, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1)
+ if ((size=mathutils_array_parse_alloc(&vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
+ if (vec) {
+ PyMem_Free(vec);
+ }
return NULL;
+ }
break;
default:
PyErr_SetString(PyExc_TypeError,
@@ -87,6 +101,215 @@
}
}
+/*-----------------------CLASS-METHODS----------------------------*/
+PyDoc_STRVAR(C_Vector_Fill_doc,
+".. classmethod:: Fill(size, fill=0.0)\n"
+"\n"
+" Create a vector of length size with all values set to fill.\n"
+"\n"
+" :arg size: The length of the vector to be created.\n"
+" :type size: int\n"
+" :arg fill: The value used to fill the vector.\n"
+" :type fill: float\n"
+);
+static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args)
+{
+ float *vec;
+ int size;
+ float fill= 0.0f;
+
+ if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) {
+ return NULL;
+ }
+
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Vector(): invalid size");
+ return NULL;
+ }
+
+ vec= PyMem_Malloc(size * sizeof(float));
+
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Fill(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ fill_vn_fl(vec, size, fill);
+
+ return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+}
+
+PyDoc_STRVAR(C_Vector_Range_doc,
+".. classmethod:: Range(start=0, stop, step=1)\n"
+"\n"
+" Create a filled with a range of values.\n"
+"\n"
+" :arg start: The start of the range used to fill the vector.\n"
+" :type start: int\n"
+" :arg stop: The end of the range used to fill the vector.\n"
+" :type stop: int\n"
+" :arg step: The step between successive values in the vector.\n"
+" :type step: int\n"
+);
+static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
+{
+ float *vec;
+ int stop, size;
+ int start= 0;
+ int step= 1;
+
+ if (!PyArg_ParseTuple(args, "i|ii:Vector.Range", &start, &stop, &step)) {
+ return NULL;
+ }
+
+ switch(PyTuple_GET_SIZE(args)){
+ case 1:
+ size = start;
+ start= 0;
+ break;
+ case 2:
+ if (start >= stop) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Start value is larger"
+ "than the stop value");
+ return NULL;
+ }
+
+ size= stop - start;
+ break;
+ default:
+ if (start >= stop) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Start value is larger"
+ "than the stop value");
+ return NULL;
+ }
+ size= (stop - start)/step;
+ if (size%step)
+ size++;
+ break;
+ }
+
+ vec= PyMem_Malloc(size * sizeof(float));
+
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Range(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list