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.
This commit is contained in:
@@ -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 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
|
||||
}
|
||||
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 @@ PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user