[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34188] trunk/blender/source/blender: cleanup for mathutils multiplication functions, a little faster in some cases, raise more informative exceptions.

Campbell Barton ideasman42 at gmail.com
Sun Jan 9 10:16:05 CET 2011


Revision: 34188
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=34188
Author:   campbellbarton
Date:     2011-01-09 09:16:04 +0000 (Sun, 09 Jan 2011)
Log Message:
-----------
cleanup for mathutils multiplication functions, a little faster in some cases, raise more informative exceptions.

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/generic/mathutils_matrix.c
    trunk/blender/source/blender/python/generic/mathutils_quat.c
    trunk/blender/source/blender/python/generic/mathutils_vector.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_vector.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_vector.h	2011-01-09 07:46:26 UTC (rev 34187)
+++ trunk/blender/source/blender/blenlib/BLI_math_vector.h	2011-01-09 09:16:04 UTC (rev 34188)
@@ -175,6 +175,8 @@
 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);
 

Modified: trunk/blender/source/blender/blenlib/intern/math_vector.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_vector.c	2011-01-09 07:46:26 UTC (rev 34187)
+++ trunk/blender/source/blender/blenlib/intern/math_vector.c	2011-01-09 09:16:04 UTC (rev 34188)
@@ -398,6 +398,24 @@
 	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);

Modified: trunk/blender/source/blender/python/generic/mathutils_matrix.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_matrix.c	2011-01-09 07:46:26 UTC (rev 34187)
+++ trunk/blender/source/blender/python/generic/mathutils_matrix.c	2011-01-09 09:16:04 UTC (rev 34188)
@@ -1498,9 +1498,7 @@
   ------------------------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 @@
 		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 @@
 		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 @@
 			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]);
+		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 < 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;
 				}
-				mat[((x * mat1->colSize) + y)] = (float)dot;
-				dot = 0.0f;
 			}
+
+			return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, Py_TYPE(mat1));
 		}
-		
-		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 */
-			for(x = 0; x < mat2->rowSize; x++) {
-				for(y = 0; y < mat2->colSize; y++) {
-					mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y];
-				}
-			}
-			return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW, Py_TYPE(mat2));
+	else if(mat2) {
+		if (((scalar= PyFloat_AsDouble(m1)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
+			return matrix_mul_float(mat2, scalar);
 		}
-		
-		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(mat1) {
+		if (((scalar= PyFloat_AsDouble(m2)) == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */
+			return matrix_mul_float(mat1, 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));
-			}
-		}
-		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)

Modified: trunk/blender/source/blender/python/generic/mathutils_quat.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_quat.c	2011-01-09 07:46:26 UTC (rev 34187)
+++ trunk/blender/source/blender/python/generic/mathutils_quat.c	2011-01-09 09:16:04 UTC (rev 34188)
@@ -641,6 +641,15 @@
 
 	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 @@
 		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;
+	else if (quat1) { /* QUAT*FLOAT */
+		if((((scalar= PyFloat_AsDouble(q2)) == -1.0 && PyErr_Occurred())==0)) {
+			return quat_mul_float(quat1, scalar);
 		}
-		
-		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));
-		}
 	}
-	
-	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;
 }
 

Modified: trunk/blender/source/blender/python/generic/mathutils_vector.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_vector.c	2011-01-09 07:46:26 UTC (rev 34187)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list