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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-01-23 11:37:34 +0300
committerCampbell Barton <ideasman42@gmail.com>2011-01-23 11:37:34 +0300
commit552b36733bb2015aa64933bf3c57f1ad90c87b5a (patch)
tree36e68c34de612538b154d9b711aee6e1593ef124 /source/blender
parenta877155a7c2359b1984641ff9225f259de48611c (diff)
bugfix + minor mathutils.Vector edits.
- multiplying a 2D vector by a 3x3 or 4x4 matrix would use un-initialized memory, now throw an exception. - use more variable length array BLI_math functions.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenlib/BLI_math_vector.h1
-rw-r--r--source/blender/blenlib/intern/math_vector.c8
-rw-r--r--source/blender/python/generic/mathutils_vector.c144
-rw-r--r--source/blender/python/generic/mathutils_vector.h2
4 files changed, 67 insertions, 88 deletions
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 35b7939329a..5a5d518940d 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -176,6 +176,7 @@ void mul_vn_fl(float *array, const int size, const float f);
void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f);
void add_vn_vn(float *array_tar, const float *array_src, const int size);
void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size);
+void sub_vn_vn(float *array_tar, const float *array_src, const int size);
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size);
void fill_vni(int *array_tar, const int size, const int val);
void fill_vn(float *array_tar, const int size, const float val);
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 539d3fb97f6..37a68cb0fca 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -407,6 +407,14 @@ void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_
while(i--) { *(tar--) = *(src_a--) + *(src_b--); }
}
+void sub_vn_vn(float *array_tar, const float *array_src, const int size)
+{
+ float *tar= array_tar + (size-1);
+ const float *src= array_src + (size-1);
+ int i= size;
+ while(i--) { *(tar--) -= *(src--); }
+}
+
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
{
float *tar= array_tar + (size-1);
diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c
index a3bf1471813..de6002859d3 100644
--- a/source/blender/python/generic/mathutils_vector.c
+++ b/source/blender/python/generic/mathutils_vector.c
@@ -76,11 +76,8 @@ static char Vector_Zero_doc[] =
static PyObject *Vector_Zero(VectorObject *self)
{
- int i;
- for(i = 0; i < self->size; i++) {
- self->vec[i] = 0.0f;
- }
-
+ fill_vn(self->vec, self->size, 0.0f);
+
(void)BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
@@ -780,7 +777,6 @@ static PyObject *Vector_item(VectorObject *self, int i)
return NULL;
return PyFloat_FromDouble(self->vec[i]);
-
}
/*----------------------------object[]-------------------------
sequence accessor (set)*/
@@ -861,43 +857,34 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end,
addition*/
static PyObject *Vector_add(PyObject * v1, PyObject * v2)
{
- int i;
- float vec[4];
-
VectorObject *vec1 = NULL, *vec2 = NULL;
-
- if VectorObject_Check(v1)
- vec1= (VectorObject *)v1;
-
- if VectorObject_Check(v2)
- vec2= (VectorObject *)v2;
-
- /* make sure v1 is always the vector */
- if (vec1 && vec2 ) {
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
- return NULL;
-
- /*VECTOR + VECTOR*/
- if(vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation");
- return NULL;
- }
- for(i = 0; i < vec1->size; i++) {
- vec[i] = vec1->vec[i] + vec2->vec[i];
- }
- return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(v1));
+ float vec[MAX_DIMENSIONS];
+
+ if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
+ PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation");
+ return NULL;
}
-
- PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation");
- return NULL;
+ vec1 = (VectorObject*)v1;
+ vec2 = (VectorObject*)v2;
+
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
+ return NULL;
+
+ /*VECTOR + VECTOR*/
+ if(vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation");
+ return NULL;
+ }
+
+ add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
+
+ return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(v1));
}
/* ------------------------obj += obj------------------------------
addition in place */
static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
{
- int i;
VectorObject *vec1 = NULL, *vec2 = NULL;
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
@@ -915,12 +902,10 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
- for(i = 0; i < vec1->size; i++) {
- vec1->vec[i] = vec1->vec[i] + vec2->vec[i];
- }
+ add_vn_vn(vec1->vec, vec2->vec, vec1->size);
(void)BaseMath_WriteCallback(vec1);
- Py_INCREF( v1 );
+ Py_INCREF(v1);
return v1;
}
@@ -928,9 +913,8 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
subtraction*/
static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
{
- int i;
- float vec[4];
VectorObject *vec1 = NULL, *vec2 = NULL;
+ float vec[MAX_DIMENSIONS];
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
PyErr_SetString(PyExc_AttributeError, "Vector subtraction: arguments not valid for this operation");
@@ -946,9 +930,8 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation");
return NULL;
}
- for(i = 0; i < vec1->size; i++) {
- vec[i] = vec1->vec[i] - vec2->vec[i];
- }
+
+ sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(v1));
}
@@ -957,8 +940,7 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
subtraction*/
static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
{
- int i;
- VectorObject *vec1 = NULL, *vec2 = NULL;
+ VectorObject *vec1= NULL, *vec2= NULL;
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
PyErr_SetString(PyExc_AttributeError, "Vector subtraction: arguments not valid for this operation");
@@ -975,12 +957,10 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
- for(i = 0; i < vec1->size; i++) {
- vec1->vec[i] = vec1->vec[i] - vec2->vec[i];
- }
+ sub_vn_vn(vec1->vec, vec2->vec, vec1->size);
(void)BaseMath_WriteCallback(vec1);
- Py_INCREF( v1 );
+ Py_INCREF(v1);
return v1;
}
@@ -996,29 +976,29 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
* note: vector/matrix multiplication IS NOT COMMUTATIVE!!!!
* note: assume read callbacks have been done first.
*/
-static int column_vector_multiplication(float *rvec, VectorObject* vec, MatrixObject * mat)
+static int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
{
- float vecCopy[4];
+ float vec_cpy[MAX_DIMENSIONS];
double dot = 0.0f;
int x, y, z = 0;
if(mat->rowSize != vec->size){
- if(mat->rowSize == 4 && vec->size != 3){
- PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same");
+ if(mat->rowSize == 4 && vec->size == 3) {
+ vec_cpy[3] = 1.0f;
+ }
+ else {
+ PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix.row_size and len(vector) must be the same, except for 3D vector * 4x4 matrix.");
return -1;
- }else{
- vecCopy[3] = 1.0f;
}
}
- for(x = 0; x < vec->size; x++){
- vecCopy[x] = vec->vec[x];
- }
+ memcpy(vec_cpy, vec->vec, vec->size * sizeof(float));
+
rvec[3] = 1.0f;
for(x = 0; x < mat->colSize; x++) {
for(y = 0; y < mat->rowSize; y++) {
- dot += mat->matrix[y][x] * vecCopy[y];
+ dot += mat->matrix[y][x] * vec_cpy[y];
}
rvec[z++] = (float)dot;
dot = 0.0f;
@@ -1030,11 +1010,7 @@ static int column_vector_multiplication(float *rvec, VectorObject* vec, MatrixOb
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
{
float tvec[MAX_DIMENSIONS];
- int i;
-
- for(i = 0; i < vec->size; i++) {
- tvec[i] = vec->vec[i] * scalar;
- }
+ mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
return newVectorObject(tvec, vec->size, Py_NEW, Py_TYPE(vec));
}
@@ -1493,7 +1469,7 @@ static PyObject *Vector_getLength(VectorObject *self, void *UNUSED(closure))
return PyFloat_FromDouble(sqrt(dot));
}
-static int Vector_setLength(VectorObject *self, PyObject * value )
+static int Vector_setLength(VectorObject *self, PyObject *value)
{
double dot = 0.0f, param;
int i;
@@ -1511,9 +1487,7 @@ static int Vector_setLength(VectorObject *self, PyObject * value )
return -1;
}
if (param == 0.0f) {
- for(i = 0; i < self->size; i++){
- self->vec[i]= 0;
- }
+ fill_vn(self->vec, self->size, 0.0f);
return 0;
}
@@ -2052,7 +2026,7 @@ if len(unique) != len(items):
//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat)
{
- float vecCopy[4];
+ float vec_cpy[4];
double dot = 0.0f;
int x, y, z = 0, vec_size = vec->size;
@@ -2061,21 +2035,20 @@ static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObj
PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
return -1;
}else{
- vecCopy[3] = 1.0f;
+ vec_cpy[3] = 1.0f;
}
}
if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
return -1;
-
- for(x = 0; x < vec_size; x++){
- vecCopy[x] = vec->vec[x];
- }
+
+ memcpy(vec_cpy, vec->vec, vec_size * sizeof(float));
+
rvec[3] = 1.0f;
//muliplication
for(x = 0; x < mat->rowSize; x++) {
for(y = 0; y < mat->colSize; y++) {
- dot += mat->matrix[x][y] * vecCopy[y];
+ dot += mat->matrix[x][y] * vec_cpy[y];
}
rvec[z++] = (float)dot;
dot = 0.0f;
@@ -2226,9 +2199,8 @@ PyTypeObject vector_Type = {
(i.e. it was allocated elsewhere by MEM_mallocN())
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
(i.e. it must be created here with PyMEM_malloc())*/
-PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_type)
+PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObject *base_type)
{
- int i;
VectorObject *self;
if(size > 4 || size < 2)
@@ -2247,16 +2219,14 @@ PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_typ
self->vec = vec;
self->wrapped = Py_WRAP;
} else if (type == Py_NEW) {
- self->vec = PyMem_Malloc(size * sizeof(float));
- if(!vec) { /*new empty*/
- for(i = 0; i < size; i++){
- self->vec[i] = 0.0f;
- }
- if(size == 4) /* do the homogenous thing */
+ self->vec= PyMem_Malloc(size * sizeof(float));
+ if(vec) {
+ memcpy(self->vec, vec, size * sizeof(float));
+ }
+ else { /* new empty */
+ fill_vn(self->vec, size, 0.0f);
+ if(size == 4) { /* do the homogenous thing */
self->vec[3] = 1.0f;
- }else{
- for(i = 0; i < size; i++){
- self->vec[i] = vec[i];
}
}
self->wrapped = Py_NEW;
diff --git a/source/blender/python/generic/mathutils_vector.h b/source/blender/python/generic/mathutils_vector.h
index e5d15dbfdb0..2dbe9d9d3fe 100644
--- a/source/blender/python/generic/mathutils_vector.h
+++ b/source/blender/python/generic/mathutils_vector.h
@@ -43,7 +43,7 @@ typedef struct {
} VectorObject;
/*prototypes*/
-PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_type);
+PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObject *base_type);
PyObject *newVectorObject_cb(PyObject *user, int size, int callback_type, int subtype);
#endif /* MATHUTILS_VECTOR_H */