[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33029] trunk/blender/source/blender/ python/generic: bugfix [#24660] (vector * matrix) fails, (matrix * vector) succeeds
Campbell Barton
ideasman42 at gmail.com
Fri Nov 12 02:38:18 CET 2010
Revision: 33029
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33029
Author: campbellbarton
Date: 2010-11-12 02:38:18 +0100 (Fri, 12 Nov 2010)
Log Message:
-----------
bugfix [#24660] (vector * matrix) fails, (matrix * vector) succeeds
- Reverse vector * matrix multiplication order. now this matches how numpy works.
- Disallow 'matrix * vec' and 'quat * vec', now it raises an error.
- Add missing in-place multiply 'vec *= quat'
Many scripts will need to be updated for this but at least it will error rather then failing silently.
Modified Paths:
--------------
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/python/generic/mathutils_matrix.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_matrix.c 2010-11-11 23:36:56 UTC (rev 33028)
+++ trunk/blender/source/blender/python/generic/mathutils_matrix.c 2010-11-12 01:38:18 UTC (rev 33029)
@@ -31,9 +31,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); /* utility func */
-
-
/* matrix vector callbacks */
int mathutils_matrix_vector_cb_index= -1;
@@ -1568,7 +1565,8 @@
}
else /* if(mat1) { */ {
if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */
- return column_vector_multiplication(mat1, (VectorObject *)m2); /* vector update done inside the function */
+ PyErr_SetString(PyExc_TypeError, "Matrix multiplication: Only 'vec * matrix' is supported, not the reverse.");
+ return NULL;
}
else {
scalar= PyFloat_AsDouble(m2);
@@ -1945,42 +1943,3 @@
}
return (PyObject *) self;
}
-
-//----------------column_vector_multiplication (internal)---------
-//COLUMN VECTOR Multiplication (Matrix X Vector)
-// [1][4][7] [a]
-// [2][5][8] * [b]
-// [3][6][9] [c]
-//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
-static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec)
-{
- float vecNew[4], vecCopy[4];
- double dot = 0.0f;
- int x, y, z = 0;
-
- if(!BaseMath_ReadCallback(mat) || !BaseMath_ReadCallback(vec))
- return NULL;
-
- 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");
- return NULL;
- }else{
- vecCopy[3] = 1.0f;
- }
- }
-
- for(x = 0; x < vec->size; x++){
- vecCopy[x] = vec->vec[x];
- }
- vecNew[3] = 1.0f;
-
- for(x = 0; x < mat->colSize; x++) {
- for(y = 0; y < mat->rowSize; y++) {
- dot += mat->matrix[y][x] * vecCopy[y];
- }
- vecNew[z++] = (float)dot;
- dot = 0.0f;
- }
- return newVectorObject(vecNew, vec->size, Py_NEW, NULL);
-}
Modified: trunk/blender/source/blender/python/generic/mathutils_quat.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_quat.c 2010-11-11 23:36:56 UTC (rev 33028)
+++ trunk/blender/source/blender/python/generic/mathutils_quat.c 2010-11-12 01:38:18 UTC (rev 33029)
@@ -647,7 +647,6 @@
{
float quat[QUAT_SIZE], scalar;
QuaternionObject *quat1 = NULL, *quat2 = NULL;
- VectorObject *vec = NULL;
if(QuaternionObject_Check(q1)) {
quat1 = (QuaternionObject*)q1;
@@ -678,19 +677,8 @@
}
else { /* QUAT*SOMETHING */
if(VectorObject_Check(q2)){ /* QUAT*VEC */
- float tvec[3];
- vec = (VectorObject*)q2;
- if(vec->size != 3){
- PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n");
- return NULL;
- }
- if(!BaseMath_ReadCallback(vec)) {
- return NULL;
- }
-
- copy_v3_v3(tvec, vec->vec);
- mul_qt_v3(quat1->quat, tvec);
- return newVectorObject(tvec, 3, Py_NEW, NULL);
+ PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: Only 'vector * quaternion' is supported, not the reverse");
+ return NULL;
}
scalar= PyFloat_AsDouble(q2);
Modified: trunk/blender/source/blender/python/generic/mathutils_vector.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_vector.c 2010-11-11 23:36:56 UTC (rev 33028)
+++ trunk/blender/source/blender/python/generic/mathutils_vector.c 2010-11-12 01:38:18 UTC (rev 33029)
@@ -39,7 +39,6 @@
#define SWIZZLE_VALID_AXIS 0x4
#define SWIZZLE_AXIS 0x3
-static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat); /* utility func */
static PyObject *Vector_ToTupleExt(VectorObject *self, int ndigits);
//----------------------------------mathutils.Vector() ------------------
@@ -1007,6 +1006,47 @@
/*------------------------obj * obj------------------------------
mulplication*/
+
+
+/* COLUMN VECTOR Multiplication (Vector X Matrix)
+ * [a] * [1][4][7]
+ * [b] * [2][5][8]
+ * [c] * [3][6][9]
+ *
+ * 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)
+{
+ float vecCopy[4];
+ 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");
+ return -1;
+ }else{
+ vecCopy[3] = 1.0f;
+ }
+ }
+
+ for(x = 0; x < vec->size; x++){
+ vecCopy[x] = vec->vec[x];
+ }
+ 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];
+ }
+ rvec[z++] = (float)dot;
+ dot = 0.0f;
+ }
+
+ return 0;
+}
+
static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
{
VectorObject *vec1 = NULL, *vec2 = NULL;
@@ -1050,17 +1090,21 @@
vec1= vec2;
v2= v1;
}
-
+
if (MatrixObject_Check(v2)) {
/* VEC * MATRIX */
- float tvec[4];
- if(row_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1)
+ float tvec[MAX_DIMENSIONS];
+ if(!BaseMath_ReadCallback((MatrixObject *)v2))
return NULL;
- return newVectorObject(tvec, vec1->size, Py_NEW, NULL);
+ if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
+ return NULL;
+ }
+
+ return newVectorObject(tvec, 3, Py_NEW, NULL);
} else if (QuaternionObject_Check(v2)) {
/* VEC * QUAT */
QuaternionObject *quat2 = (QuaternionObject*)v2;
- float tvec[4];
+ float tvec[3];
if(vec1->size != 3) {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
@@ -1075,7 +1119,7 @@
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
int i;
- float vec[4];
+ float vec[MAX_DIMENSIONS];
for(i = 0; i < vec1->size; i++) {
vec[i] = vec1->vec[i] * scalar;
@@ -1093,7 +1137,6 @@
static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
{
VectorObject *vec = (VectorObject *)v1;
- int i;
float scalar;
if(!BaseMath_ReadCallback(vec))
@@ -1102,20 +1145,28 @@
/* only support vec*=float and vec*=mat
vec*=vec result is a float so that wont work */
if (MatrixObject_Check(v2)) {
- float tvec[4];
- if(row_vector_multiplication(tvec, vec, (MatrixObject*)v2) == -1)
+ if(!BaseMath_ReadCallback((MatrixObject *)v2))
return NULL;
+
+ if(column_vector_multiplication(vec->vec, vec, (MatrixObject*)v2) == -1)
+ return NULL;
+ }
+ else if (QuaternionObject_Check(v2)) {
+ /* VEC *= QUAT */
+ QuaternionObject *quat2 = (QuaternionObject*)v2;
- i= vec->size - 1;
- do {
- vec->vec[i] = tvec[i];
- } while(i--);
+ if(vec->size != 3) {
+ PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
+ return NULL;
+ }
+
+ if(!BaseMath_ReadCallback(quat2)) {
+ return NULL;
+ }
+ mul_qt_v3(quat2->quat, vec->vec);
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */
- i= vec->size - 1;
- do {
- vec->vec[i] *= scalar;
- } while(i--);
+ mul_vn_fl(vec->vec, vec->size, scalar);
}
else {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n");
@@ -2010,7 +2061,7 @@
print "ERROR"
*/
-//-----------------row_vector_multiplication (internal)-----------
+#if 0
//ROW VECTOR Multiplication - Vector X Matrix
//[x][y][z] * [1][4][7]
// [2][5][8]
@@ -2048,6 +2099,7 @@
}
return 0;
}
+#endif
/*----------------------------Vector.negate() -------------------- */
static char Vector_Negate_doc[] =
More information about the Bf-blender-cvs
mailing list