Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/python/generic/vector.c')
-rw-r--r--source/blender/python/generic/vector.c338
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##############################*/