diff options
Diffstat (limited to 'source/blender/python/generic/vector.c')
-rw-r--r-- | source/blender/python/generic/vector.c | 338 |
1 files changed, 232 insertions, 106 deletions
diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index 562413c6967..dea5bc93898 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -1,5 +1,5 @@ /* - * $Id: vector.c 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -39,6 +39,8 @@ #define SWIZZLE_VALID_AXIS 0x4 #define SWIZZLE_AXIS 0x3 +static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); /* utility func */ + /*-------------------------DOC STRINGS ---------------------------*/ static char Vector_Zero_doc[] = "() - set all values in the vector to 0"; static char Vector_Normalize_doc[] = "() - normalize the vector"; @@ -60,7 +62,7 @@ static PyObject *Vector_Resize2D( VectorObject * self ); static PyObject *Vector_Resize3D( VectorObject * self ); static PyObject *Vector_Resize4D( VectorObject * self ); static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); -static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ); +static PyObject *Vector_Reflect( VectorObject *self, VectorObject *value ); static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ); static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ); static PyObject *Vector_copy( VectorObject * self ); @@ -70,8 +72,8 @@ static struct PyMethodDef Vector_methods[] = { {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc}, {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc}, {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, + {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize3D_doc}, + {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize4D_doc}, {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc}, {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Dot_doc}, @@ -141,6 +143,8 @@ static PyObject *Vector_Zero(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] = 0.0f; } + + Vector_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -151,6 +155,9 @@ static PyObject *Vector_Normalize(VectorObject * self) int i; float norm = 0.0f; + if(!Vector_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++) { norm += self->vec[i] * self->vec[i]; } @@ -158,6 +165,8 @@ static PyObject *Vector_Normalize(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] /= norm; } + + Vector_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -171,6 +180,11 @@ static PyObject *Vector_Resize2D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize2d(): problem allocating pointer space\n\n"); @@ -189,6 +203,11 @@ static PyObject *Vector_Resize3D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize3d(): problem allocating pointer space\n\n"); @@ -210,6 +229,11 @@ static PyObject *Vector_Resize4D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize4d(): problem allocating pointer space\n\n"); @@ -241,6 +265,9 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only for 3D vectors\n" ); return NULL; } + + if(!Vector_ReadCallback(self)) + return NULL; if (strack) { if (strlen(strack) == 2) { @@ -342,9 +369,8 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) return a reflected vector on the mirror normal ((2 * DotVecs(vec, mirror)) * mirror) - vec using arithb.c would be nice here */ -static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) +static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value ) { - VectorObject *mirrvec; float mirror[3]; float vec[3]; float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -358,11 +384,13 @@ static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" ); return NULL; } - mirrvec = (VectorObject *)value; - mirror[0] = mirrvec->vec[0]; - mirror[1] = mirrvec->vec[1]; - if (mirrvec->size > 2) mirror[2] = mirrvec->vec[2]; + if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value)) + return NULL; + + mirror[0] = value->vec[0]; + mirror[1] = value->vec[1]; + if (value->size > 2) mirror[2] = value->vec[2]; else mirror[2] = 0.0; /* normalize, whos idea was it not to use arithb.c? :-/ */ @@ -403,6 +431,9 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) return NULL; } + if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value)) + return NULL; + vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW); Crossf(vecCross->vec, self->vec, value->vec); return (PyObject *)vecCross; @@ -423,6 +454,9 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) return NULL; } + if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value)) + return NULL; + for(x = 0; x < self->size; x++) { dot += self->vec[x] * value->vec[x]; } @@ -433,6 +467,9 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) return a copy of the vector */ static PyObject *Vector_copy(VectorObject * self) { + if(!Vector_ReadCallback(self)) + return NULL; + return newVectorObject(self->vec, self->size, Py_NEW); } @@ -441,9 +478,10 @@ static PyObject *Vector_copy(VectorObject * self) static void Vector_dealloc(VectorObject * self) { /* only free non wrapped */ - if(self->wrapped != Py_WRAP){ + if(self->wrapped != Py_WRAP) PyMem_Free(self->vec); - } + + Py_XDECREF(self->cb_user); PyObject_DEL(self); } @@ -454,6 +492,9 @@ static PyObject *Vector_repr(VectorObject * self) int i; char buffer[48], str[1024]; + if(!Vector_ReadCallback(self)) + return NULL; + BLI_strncpy(str,"[",1024); for(i = 0; i < self->size; i++){ if(i < (self->size - 1)){ @@ -484,6 +525,9 @@ static PyObject *Vector_item(VectorObject * self, int i) return NULL; } + if(!Vector_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->vec[i]); } @@ -502,6 +546,9 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob) return -1; } self->vec[i] = scalar; + + if(!Vector_WriteIndexCallback(self, i)) + return -1; return 0; } @@ -512,6 +559,9 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!Vector_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, self->size); if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); @@ -534,6 +584,9 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, float vec[4], scalar; PyObject *v; + if(!Vector_ReadCallback(self)) + return -1; + CLAMP(begin, 0, self->size); if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); @@ -566,6 +619,10 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, for(y = 0; y < size; y++){ self->vec[begin + y] = vec[y]; } + + if(!Vector_WriteCallback(self)) + return -1; + return 0; } /*------------------------NUMERIC PROTOCOLS---------------------- @@ -586,6 +643,10 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; + /*VECTOR + VECTOR*/ if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); @@ -617,6 +678,10 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; + /*VECTOR + VECTOR*/ if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); @@ -629,6 +694,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) return v1; } + Vector_WriteCallback(vec1); PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); return NULL; } @@ -648,6 +714,9 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) vec1 = (VectorObject*)v1; vec2 = (VectorObject*)v2; + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; + if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); return NULL; @@ -663,7 +732,7 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) subtraction*/ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) { - int i, size; + int i; VectorObject *vec1 = NULL, *vec2 = NULL; if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { @@ -677,12 +746,15 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); return NULL; } + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; - size = vec1->size; for(i = 0; i < vec1->size; i++) { vec1->vec[i] = vec1->vec[i] - vec2->vec[i]; } + Vector_WriteCallback(vec1); Py_INCREF( v1 ); return v1; } @@ -694,11 +766,17 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) VectorObject *vec1 = NULL, *vec2 = NULL; float scalar; - if VectorObject_Check(v1) + if VectorObject_Check(v1) { vec1= (VectorObject *)v1; - - if VectorObject_Check(v2) + if(!Vector_ReadCallback(vec1)) + return NULL; + } + if VectorObject_Check(v2) { vec2= (VectorObject *)v2; + if(!Vector_ReadCallback(vec2)) + return NULL; + } + /* make sure v1 is always the vector */ if (vec1 && vec2 ) { @@ -757,6 +835,9 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) int i; float scalar; + if(!Vector_ReadCallback(vec)) + return NULL; + /* only support vec*=float and vec*=mat vec*=vec result is a float so that wont work */ if (MatrixObject_Check(v2)) { @@ -764,6 +845,9 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) int x,y, size = vec->size; MatrixObject *mat= (MatrixObject*)v2; + if(!Vector_ReadCallback(mat)) + 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"); @@ -787,22 +871,21 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) } vec->vec[i] = (float)dot; } - Py_INCREF( v1 ); - return v1; } else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */ for(i = 0; i < vec->size; i++) { vec->vec[i] *= scalar; } - - Py_INCREF( v1 ); - return v1; - + } + else { + PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); + return NULL; } - PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); - return NULL; + Vector_WriteCallback(vec); + Py_INCREF( v1 ); + return v1; } /*------------------------obj / obj------------------------------ @@ -819,6 +902,9 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) } vec1 = (VectorObject*)v1; /* vector */ + if(!Vector_ReadCallback(vec1)) + return NULL; + scalar = (float)PyFloat_AsDouble(v2); if(scalar== -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); @@ -842,14 +928,10 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) { int i; float scalar; - VectorObject *vec1 = NULL; + VectorObject *vec1 = (VectorObject*)v1; - /*if(!VectorObject_Check(v1)) { - PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); - return -1; - }*/ - - vec1 = (VectorObject*)v1; /* vector */ + if(!Vector_ReadCallback(vec1)) + return NULL; scalar = (float)PyFloat_AsDouble(v2); if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ @@ -864,6 +946,9 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec1->vec[i] /= scalar; } + + Vector_WriteCallback(vec1); + Py_INCREF( v1 ); return v1; } @@ -874,6 +959,10 @@ static PyObject *Vector_neg(VectorObject *self) { int i; float vec[4]; + + if(!Vector_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++){ vec[i] = -self->vec[i]; } @@ -919,6 +1008,9 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa vecA = (VectorObject*)objectA; vecB = (VectorObject*)objectB; + if(!Vector_ReadCallback(vecA) || !Vector_ReadCallback(vecB)) + return NULL; + if (vecA->size != vecB->size){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; @@ -1045,66 +1137,12 @@ static PyNumberMethods Vector_NumMethods = { static PyObject *Vector_getAxis( VectorObject * self, void *type ) { - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - return PyFloat_FromDouble(self->vec[0]); - case 'Y': - return PyFloat_FromDouble(self->vec[1]); - case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); - return NULL; - } - else { - return PyFloat_FromDouble(self->vec[2]); - } - case 'W': - if(self->size < 4) { - PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); - return NULL; - } - - return PyFloat_FromDouble(self->vec[3]); - default: - { - PyErr_SetString( PyExc_RuntimeError, "undefined type in Vector_getAxis" ); - return NULL; - } - } + return Vector_item(self, (int)type); } static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); - return -1; - } - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - self->vec[0]= param; - break; - case 'Y': - self->vec[1]= param; - break; - case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); - return -1; - } - self->vec[2]= param; - break; - case 'W': - if(self->size < 4) { - PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); - return -1; - } - self->vec[3]= param; - break; - } - - return 0; + return Vector_ass_item(self, (int)type, value); } /* vector.length */ @@ -1113,6 +1151,9 @@ static PyObject *Vector_getLength( VectorObject * self, void *type ) double dot = 0.0f; int i; + if(!Vector_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++){ dot += (self->vec[i] * self->vec[i]); } @@ -1124,6 +1165,9 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) double dot = 0.0f, param; int i; + if(!Vector_ReadCallback(self)) + return -1; + param= PyFloat_AsDouble( value ); if(param==-1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "length must be set to a number"); @@ -1159,6 +1203,8 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) self->vec[i]= self->vec[i] / (float)dot; } + Vector_WriteCallback(self); /* checked alredy */ + return 0; } @@ -1170,6 +1216,16 @@ static PyObject *Vector_getWrapped( VectorObject * self, void *type ) Py_RETURN_FALSE; } +static PyObject *Vector_getOwner( VectorObject * self, void *type ) +{ + if(self->cb_user==NULL) { + Py_RETURN_NONE; + } + else { + Py_INCREF(self->cb_user); + return self->cb_user; + } +} /* Get a new Vector according to the provided swizzle. This function has little error checking, as we are in control of the inputs: the closure is set by us @@ -1181,6 +1237,9 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) float vec[MAX_DIMENSIONS]; unsigned int swizzleClosure; + if(!Vector_ReadCallback(self)) + return NULL; + /* Unpack the axes from the closure into an array. */ axisA = 0; swizzleClosure = (unsigned int) closure; @@ -1218,6 +1277,9 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur float vecTemp[MAX_DIMENSIONS]; + if(!Vector_ReadCallback(self)) + return -1; + /* Check that the closure can be used with this vector: even 2D vectors have swizzles defined for axes z and w, but they would be invalid. */ swizzleClosure = (unsigned int) closure; @@ -1247,7 +1309,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur axisB++; } memcpy(self->vec, vecTemp, axisB * sizeof(float)); - return 0; + /* continue with Vector_WriteCallback at the end */ } else if (PyList_Check(value)) { @@ -1273,7 +1335,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur axisB++; } memcpy(self->vec, vecTemp, axisB * sizeof(float)); - return 0; + /* continue with Vector_WriteCallback at the end */ } else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0) { @@ -1286,13 +1348,17 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; } - return 0; + /* continue with Vector_WriteCallback at the end */ } - else - { + else { PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." ); return -1; } + + if(!Vector_WriteCallback(vecVal)) + return -1; + else + return 0; } /*****************************************************************************/ @@ -1302,19 +1368,19 @@ static PyGetSetDef Vector_getseters[] = { {"x", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector X axis", - (void *)'X'}, + (void *)0}, {"y", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Y axis", - (void *)'Y'}, + (void *)1}, {"z", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis", - (void *)'Z'}, + (void *)2}, {"w", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis", - (void *)'W'}, + (void *)3}, {"length", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length", @@ -1327,6 +1393,10 @@ static PyGetSetDef Vector_getseters[] = { (getter)Vector_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", + (getter)Vector_getOwner, (setter)NULL, + "Read only owner for vectors that depend on another object", + NULL}, /* autogenerated swizzle attrs, see python script below */ {"xx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, Vector_swizzle_doc, (void *)((unsigned int)((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, /* 36 */ @@ -1819,6 +1889,10 @@ PyObject *newVectorObject(float *vec, int size, int type) if(size > 4 || size < 2) return NULL; self->size = size; + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP) { self->vec = vec; @@ -1843,20 +1917,72 @@ PyObject *newVectorObject(float *vec, int size, int type) return (PyObject *) self; } -/* - #############################DEPRECATED################################ - ####################################################################### - ----------------------------Vector.negate() -------------------- +PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype) +{ + float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */ + VectorObject *self= newVectorObject(dummy, size, Py_NEW); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return self; +} + +//-----------------row_vector_multiplication (internal)----------- +//ROW VECTOR Multiplication - Vector X Matrix +//[x][y][z] * [1][2][3] +// [4][5][6] +// [7][8][9] +//vector/matrix multiplication IS NOT COMMUTATIVE!!!! +static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) +{ + float vecNew[4], vecCopy[4]; + double dot = 0.0f; + int x, y, z = 0, vec_size = vec->size; + + if(mat->colSize != vec_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; + } + } + + if(!Vector_ReadCallback(vec) || !Matrix_ReadCallback(mat)) + return NULL; + + for(x = 0; x < vec_size; x++){ + vecCopy[x] = vec->vec[x]; + } + + //muliplication + 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); +} + +/*----------------------------Vector.negate() -------------------- set the vector to it's negative -x, -y, -z */ static PyObject *Vector_Negate(VectorObject * self) { int i; - for(i = 0; i < self->size; i++) { + if(!Vector_ReadCallback(self)) + return NULL; + + for(i = 0; i < self->size; i++) self->vec[i] = -(self->vec[i]); - } - /*printf("Vector.negate(): Deprecated: use -vector instead\n");*/ + + Vector_WriteCallback(self); // alredy checked for error + Py_INCREF(self); return (PyObject*)self; } -/*################################################################### - ###########################DEPRECATED##############################*/ |