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>2011-01-09 12:16:04 +0300
committerCampbell Barton <ideasman42@gmail.com>2011-01-09 12:16:04 +0300
commitd31ebbe66681cda8e94c6593e4b40c4b4df5809c (patch)
treedbfe940f8cbde15efa5545a21d33c0dbeae91516 /source
parentca89269c227607923bcfd8c137c552bdb0c37c16 (diff)
cleanup for mathutils multiplication functions, a little faster in some cases, raise more informative exceptions.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenlib/BLI_math_vector.h2
-rw-r--r--source/blender/blenlib/intern/math_vector.c18
-rw-r--r--source/blender/python/generic/mathutils_matrix.c102
-rw-r--r--source/blender/python/generic/mathutils_quat.c42
-rw-r--r--source/blender/python/generic/mathutils_vector.c86
5 files changed, 126 insertions, 124 deletions
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 5f6251bf382..43cf612c33c 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -175,6 +175,8 @@ void range_vni(int *array, const int size, const int start);
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_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 2ff1e948317..539d3fb97f6 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -398,6 +398,24 @@ void add_vn_vn(float *array_tar, const float *array_src, const int size)
while(i--) { *(tar--) += *(src--); }
}
+void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
+{
+ float *tar= array_tar + (size-1);
+ const float *src_a= array_src_a + (size-1);
+ const float *src_b= array_src_b + (size-1);
+ int i= size;
+ while(i--) { *(tar--) = *(src_a--) + *(src_b--); }
+}
+
+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);
+ const float *src_a= array_src_a + (size-1);
+ const float *src_b= array_src_b + (size-1);
+ int i= size;
+ while(i--) { *(tar--) = *(src_a--) - *(src_b--); }
+}
+
void fill_vni(int *array_tar, const int size, const int val)
{
int *tar= array_tar + (size-1);
diff --git a/source/blender/python/generic/mathutils_matrix.c b/source/blender/python/generic/mathutils_matrix.c
index b67d4c54a7d..df176d4f18d 100644
--- a/source/blender/python/generic/mathutils_matrix.c
+++ b/source/blender/python/generic/mathutils_matrix.c
@@ -1498,9 +1498,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject *
------------------------obj + obj------------------------------*/
static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
{
- int x, y;
- float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+ float mat[16];
MatrixObject *mat1 = NULL, *mat2 = NULL;
mat1 = (MatrixObject*)m1;
@@ -1519,21 +1517,15 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
return NULL;
}
- for(x = 0; x < mat1->rowSize; x++) {
- for(y = 0; y < mat1->colSize; y++) {
- mat[((x * mat1->colSize) + y)] = mat1->matrix[x][y] + mat2->matrix[x][y];
- }
- }
+ add_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->rowSize * mat1->colSize);
- return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL);
+ return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
/*------------------------obj - obj------------------------------
subtraction*/
static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
{
- int x, y;
- float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+ float mat[16];
MatrixObject *mat1 = NULL, *mat2 = NULL;
mat1 = (MatrixObject*)m1;
@@ -1552,23 +1544,23 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
return NULL;
}
- for(x = 0; x < mat1->rowSize; x++) {
- for(y = 0; y < mat1->colSize; y++) {
- mat[((x * mat1->colSize) + y)] = mat1->matrix[x][y] - mat2->matrix[x][y];
- }
- }
+ sub_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->rowSize * mat1->colSize);
- return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL);
+ return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
/*------------------------obj * obj------------------------------
mulplication*/
+static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
+{
+ float tmat[16];
+ mul_vn_vn_fl(tmat, mat->contigPtr, mat->rowSize * mat->colSize, scalar);
+ return newMatrixObject(tmat, mat->rowSize, mat->colSize, Py_NEW, Py_TYPE(mat));
+}
+
static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
{
- int x, y, z;
float scalar;
- float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
- double dot = 0.0f;
+
MatrixObject *mat1 = NULL, *mat2 = NULL;
if(MatrixObject_Check(m1)) {
@@ -1587,54 +1579,42 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize");
return NULL;
}
- for(x = 0; x < mat2->rowSize; x++) {
- for(y = 0; y < mat1->colSize; y++) {
- for(z = 0; z < mat1->rowSize; z++) {
- dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
- }
- mat[((x * mat1->colSize) + y)] = (float)dot;
- dot = 0.0f;
- }
- }
-
- return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
- }
-
- if(mat1==NULL){
- scalar=PyFloat_AsDouble(m1); // may not be a float
- if ((scalar == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX, this line annoys theeth, lets see if he finds it */
+ else {
+ float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
+ double dot = 0.0f;
+ int x, y, z;
+
for(x = 0; x < mat2->rowSize; x++) {
- for(y = 0; y < mat2->colSize; y++) {
- mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y];
+ for(y = 0; y < mat1->colSize; y++) {
+ for(z = 0; z < mat1->rowSize; z++) {
+ dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
+ }
+ mat[((x * mat1->colSize) + y)] = (float)dot;
+ dot = 0.0f;
}
}
- return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW, Py_TYPE(mat2));
+
+ return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
}
-
- PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
- return NULL;
}
- else /* if(mat1) { */ {
- if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */
- PyErr_SetString(PyExc_TypeError, "Matrix multiplication: Only 'vec * matrix' is supported, not the reverse");
- return NULL;
+ else if(mat2) {
+ if (((scalar= PyFloat_AsDouble(m1)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
+ return matrix_mul_float(mat2, scalar);
}
- else {
- scalar= PyFloat_AsDouble(m2);
- if ((scalar == -1.0 && PyErr_Occurred())==0) { /* MATRIX*FLOAT/INT */
- for(x = 0; x < mat1->rowSize; x++) {
- for(y = 0; y < mat1->colSize; y++) {
- mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y];
- }
- }
- return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
- }
+ }
+ else if(mat1) {
+ if (((scalar= PyFloat_AsDouble(m2)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
+ return matrix_mul_float(mat1, scalar);
}
- PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
- return NULL;
+ }
+ else {
+ BKE_assert(!"internal error");
}
- PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
+ PyErr_Format(PyExc_TypeError, "Matrix multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
return NULL;
}
static PyObject* Matrix_inv(MatrixObject *self)
diff --git a/source/blender/python/generic/mathutils_quat.c b/source/blender/python/generic/mathutils_quat.c
index 36fb0ad66bd..1de249205b2 100644
--- a/source/blender/python/generic/mathutils_quat.c
+++ b/source/blender/python/generic/mathutils_quat.c
@@ -641,6 +641,15 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
}
+
+static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
+{
+ float tquat[4];
+ copy_qt_qt(tquat, quat->quat);
+ mul_qt_fl(tquat, scalar);
+ return newQuaternionObject(tquat, Py_NEW, Py_TYPE(quat));
+}
+
//------------------------obj * obj------------------------------
//mulplication
static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
@@ -663,33 +672,22 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
}
-
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
- if(!QuaternionObject_Check(q1)) {
- scalar= PyFloat_AsDouble(q1);
- if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */
- QUATCOPY(quat, quat2->quat);
- mul_qt_fl(quat, scalar);
- return newQuaternionObject(quat, Py_NEW, Py_TYPE(q2));
+ else if(quat2) { /* FLOAT*QUAT */
+ if(((scalar= PyFloat_AsDouble(q1)) == -1.0 && PyErr_Occurred())==0) {
+ return quat_mul_float(quat2, scalar);
}
- PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type");
- return NULL;
}
- else { /* QUAT*SOMETHING */
- if(VectorObject_Check(q2)){ /* QUAT*VEC */
- PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: Only 'vector * quaternion' is supported, not the reverse");
- return NULL;
- }
-
- scalar= PyFloat_AsDouble(q2);
- if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */
- QUATCOPY(quat, quat1->quat);
- mul_qt_fl(quat, scalar);
- return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1));
+ else if (quat1) { /* QUAT*FLOAT */
+ if((((scalar= PyFloat_AsDouble(q2)) == -1.0 && PyErr_Occurred())==0)) {
+ return quat_mul_float(quat1, scalar);
}
}
-
- PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation");
+ else {
+ BKE_assert(!"internal error");
+ }
+
+ PyErr_Format(PyExc_TypeError, "Quaternion multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
return NULL;
}
diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c
index 3d80f6bade4..2208046e6c0 100644
--- a/source/blender/python/generic/mathutils_vector.c
+++ b/source/blender/python/generic/mathutils_vector.c
@@ -1047,6 +1047,17 @@ static int column_vector_multiplication(float *rvec, VectorObject* vec, MatrixOb
return 0;
}
+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;
+ }
+ return newVectorObject(tvec, vec->size, Py_NEW, Py_TYPE(vec));
+}
+
static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
{
VectorObject *vec1 = NULL, *vec2 = NULL;
@@ -1080,55 +1091,48 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
}
return PyFloat_FromDouble(dot);
}
-
- /* swap so vec1 is always the vector */
- /* note: it would seem from this code that the matrix multiplication below
- * is communicative. however the matrix class will always handle the
- * (matrix * vector) case so we can ignore it here.
- * This is NOT so for Quaternions: TODO, check if communicative (vec * quat) is correct */
- if (vec2) {
- vec1= vec2;
- v2= v1;
- }
+ else if (vec1) {
+ if (MatrixObject_Check(v2)) {
+ /* VEC * MATRIX */
+ float tvec[MAX_DIMENSIONS];
+ if(!BaseMath_ReadCallback((MatrixObject *)v2))
+ return NULL;
+ if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
+ return NULL;
+ }
- if (MatrixObject_Check(v2)) {
- /* VEC * MATRIX */
- float tvec[MAX_DIMENSIONS];
- if(!BaseMath_ReadCallback((MatrixObject *)v2))
- return NULL;
- if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
- return NULL;
+ return newVectorObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1));
}
+ else if (QuaternionObject_Check(v2)) {
+ /* VEC * QUAT */
+ QuaternionObject *quat2 = (QuaternionObject*)v2;
+ float tvec[3];
- return newVectorObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1));
- } else if (QuaternionObject_Check(v2)) {
- /* VEC * QUAT */
- QuaternionObject *quat2 = (QuaternionObject*)v2;
- float tvec[3];
-
- if(vec1->size != 3) {
- PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported");
- return NULL;
+ if(vec1->size != 3) {
+ PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported");
+ return NULL;
+ }
+ if(!BaseMath_ReadCallback(quat2)) {
+ return NULL;
+ }
+ copy_v3_v3(tvec, vec1->vec);
+ mul_qt_v3(quat2->quat, tvec);
+ return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
}
- if(!BaseMath_ReadCallback(quat2)) {
- return NULL;
+ else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
+ return vector_mul_float(vec1, scalar);
}
- copy_v3_v3(tvec, vec1->vec);
- mul_qt_v3(quat2->quat, tvec);
- return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
}
- else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
- int i;
- float vec[MAX_DIMENSIONS];
-
- for(i = 0; i < vec1->size; i++) {
- vec[i] = vec1->vec[i] * scalar;
+ else if (vec2) {
+ if (((scalar= PyFloat_AsDouble(v1)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
+ return vector_mul_float(vec2, scalar);
}
- return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(vec1));
-
}
-
- PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation");
+ else {
+ BKE_assert(!"internal error");
+ }
+
+ PyErr_Format(PyExc_TypeError, "Vector multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
return NULL;
}