diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-08-24 02:10:13 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-08-24 02:10:13 +0400 |
commit | 1be4eda552aa97aa5f5fe43fd34196c57425a7c2 (patch) | |
tree | dc2c20bf1354969ace796f473cad977b086be2e3 /source/blender | |
parent | 9b685a4b7848a5ee05b119ec67d3c0b56717f04e (diff) |
bugfix [#23454] vector*matrix not the same as vector*=matrix
- they now share the same code so it wont happen again.
- added id_data to properties so we can do...
matrix = C.object.matrix_world
obj = matrix.owner.id_data # get the original object back.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/python/generic/mathutils_matrix.c | 1 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_vector.c | 69 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 11 |
3 files changed, 33 insertions, 48 deletions
diff --git a/source/blender/python/generic/mathutils_matrix.c b/source/blender/python/generic/mathutils_matrix.c index 24239e1f541..3b8c7d3122a 100644 --- a/source/blender/python/generic/mathutils_matrix.c +++ b/source/blender/python/generic/mathutils_matrix.c @@ -1526,7 +1526,6 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) return NULL; } else /* if(mat1) { */ { - if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */ return column_vector_multiplication(mat1, (VectorObject *)m2); /* vector update done inside the function */ } diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c index 75a695526fc..6cfb5bb207e 100644 --- a/source/blender/python/generic/mathutils_vector.c +++ b/source/blender/python/generic/mathutils_vector.c @@ -39,7 +39,7 @@ #define SWIZZLE_VALID_AXIS 0x4 #define SWIZZLE_AXIS 0x3 -static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); /* utility func */ +static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat); /* utility func */ static PyObject *Vector_ToTupleExt(VectorObject *self, int ndigits); //----------------------------------mathutils.Vector() ------------------ @@ -1002,7 +1002,11 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) return PyFloat_FromDouble(dot); } - /*swap so vec1 is always the vector */ + /* swap so vec1 is always the vector */ + /* note: it would seem from this code that the matrix multiplication below + * is non-communicative. however the matrix object will always handle the + * (matrix * vector) case. + * This is NOT so for Quaternions: TODO, check if communicative (vec * quat) is correct */ if (vec2) { vec1= vec2; v2= v1; @@ -1010,7 +1014,10 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) if (MatrixObject_Check(v2)) { /* VEC * MATRIX */ - return row_vector_multiplication(vec1, (MatrixObject*)v2); + float tvec[4]; + if(row_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) + return NULL; + return newVectorObject(tvec, vec1->size, Py_NEW, NULL); } else if (QuaternionObject_Check(v2)) { /* VEC * QUAT */ QuaternionObject *quat2 = (QuaternionObject*)v2; @@ -1056,42 +1063,20 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) /* only support vec*=float and vec*=mat vec*=vec result is a float so that wont work */ if (MatrixObject_Check(v2)) { - float vecCopy[4]; - int x,y, size = vec->size; - MatrixObject *mat= (MatrixObject*)v2; - - if(!BaseMath_ReadCallback(mat)) + float tvec[4]; + if(row_vector_multiplication(tvec, vec, (MatrixObject*)v2) == -1) return NULL; - - if(mat->colSize != size){ - if(mat->rowSize == 4 && vec->size != 3){ - PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); - return NULL; - } else { - vecCopy[3] = 1.0f; - } - } - - for(i = 0; i < size; i++){ - vecCopy[i] = vec->vec[i]; - } - - size = MIN2(size, mat->colSize); - - /*muliplication*/ - for(x = 0, i = 0; x < size; x++, i++) { - double dot = 0.0f; - for(y = 0; y < mat->rowSize; y++) { - dot += mat->matrix[y][x] * vecCopy[y]; - } - vec->vec[i] = (float)dot; - } + + i= vec->size - 1; + do { + vec->vec[i] = tvec[i]; + } while(i--); } else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */ - - for(i = 0; i < vec->size; i++) { + i= vec->size - 1; + do { vec->vec[i] *= scalar; - } + } while(i--); } else { PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); @@ -1992,37 +1977,37 @@ if len(unique) != len(items): // [2][5][8] // [3][6][9] //vector/matrix multiplication IS NOT COMMUTATIVE!!!! -static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) +static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat) { - float vecNew[4], vecCopy[4]; + float vecCopy[4]; double dot = 0.0f; int x, y, z = 0, vec_size = vec->size; if(mat->colSize != vec_size){ if(mat->colSize == 4 && vec_size != 3){ PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); - return NULL; + return -1; }else{ vecCopy[3] = 1.0f; } } if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat)) - return NULL; + return -1; for(x = 0; x < vec_size; x++){ vecCopy[x] = vec->vec[x]; } - vecNew[3] = 1.0f; + 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]; } - vecNew[z++] = (float)dot; + rvec[z++] = (float)dot; dot = 0.0f; } - return newVectorObject(vecNew, vec_size, Py_NEW, NULL); + return 0; } /*----------------------------Vector.negate() -------------------- */ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 834254a495d..72639ba221c 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2645,8 +2645,9 @@ static PyObject *pyrna_prop_move(BPy_PropertyRNA *self, PyObject *args) return ret; } -static PyObject *pyrna_struct_get_id_data(BPy_StructRNA *self) +static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self) { + /* used for struct and pointer since both have a ptr */ if(self->ptr.id.data) { PointerRNA id_ptr; RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr); @@ -2659,12 +2660,12 @@ static PyObject *pyrna_struct_get_id_data(BPy_StructRNA *self) /*****************************************************************************/ /* Python attributes get/set structure: */ /*****************************************************************************/ -#if 0 + static PyGetSetDef pyrna_prop_getseters[] = { - {"active", (getter)pyrna_prop_get_active, (setter)pyrna_prop_set_active, "", NULL}, + {"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, "The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; -#endif + static PyGetSetDef pyrna_struct_getseters[] = { {"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, "The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL}, @@ -3725,7 +3726,7 @@ PyTypeObject pyrna_prop_Type = { /*** Attribute descriptor and subclassing stuff ***/ pyrna_prop_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ - NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */ + pyrna_prop_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ NULL, /* PyObject *tp_dict; */ NULL, /* descrgetfunc tp_descr_get; */ |