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:
authorStephen Swaney <sswaney@centurytel.net>2005-05-22 21:40:00 +0400
committerStephen Swaney <sswaney@centurytel.net>2005-05-22 21:40:00 +0400
commitece00ff04a90aa0aaa37f27185c25b0f7b19e77d (patch)
tree7c1143535c4828b4ca87ddda22df9fd4950e4607 /source/blender/python/api2_2x/vector.c
parent910b0f2cda7b8ca45bf16d429bb8df986e69ce1f (diff)
Roll back changes from Big Mathutils Commit on 2005/05/20.
Diffstat (limited to 'source/blender/python/api2_2x/vector.c')
-rw-r--r--source/blender/python/api2_2x/vector.c1147
1 files changed, 601 insertions, 546 deletions
diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c
index f9dfe47b693..9e65de3c46d 100644
--- a/source/blender/python/api2_2x/vector.c
+++ b/source/blender/python/api2_2x/vector.c
@@ -28,652 +28,707 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#include <BKE_utildefines.h>
-#include "Mathutils.h"
-#include "gen_utils.h"
+#include "vector.h"
-//-------------------------DOC STRINGS ---------------------------
+//doc strings
char Vector_Zero_doc[] = "() - set all values in the vector to 0";
char Vector_Normalize_doc[] = "() - normalize the vector";
char Vector_Negate_doc[] = "() - changes vector to it's additive inverse";
char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]";
char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";
-//-----------------------METHOD DEFINITIONS ----------------------
+
+//method table
struct PyMethodDef Vector_methods[] = {
- {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc},
- {"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},
+ {"zero", ( PyCFunction ) Vector_Zero, METH_NOARGS,
+ Vector_Zero_doc},
+ {"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},
{NULL, NULL, 0, NULL}
};
-//-----------------------------METHODS----------------------------
-//----------------------------Vector.zero() ----------------------
-//set the vector data to 0,0,0
-PyObject *Vector_Zero(VectorObject * self)
+
+/******prototypes*************/
+PyObject *Vector_add( PyObject * v1, PyObject * v2 );
+PyObject *Vector_sub( PyObject * v1, PyObject * v2 );
+PyObject *Vector_mul( PyObject * v1, PyObject * v2 );
+PyObject *Vector_div( PyObject * v1, PyObject * v2 );
+int Vector_coerce( PyObject ** v1, PyObject ** v2 );
+
+
+/*****************************/
+// Vector Python Object
+/*****************************/
+
+//object methods
+PyObject *Vector_Zero( VectorObject * self )
{
int x;
- for(x = 0; x < self->size; x++) {
+ for( x = 0; x < self->size; x++ ) {
self->vec[x] = 0.0f;
}
- return (PyObject*)self;
+
+ return EXPP_incr_ret( Py_None );
}
-//----------------------------Vector.normalize() -----------------
-//normalize the vector data to a unit vector
-PyObject *Vector_Normalize(VectorObject * self)
+
+PyObject *Vector_Normalize( VectorObject * self )
{
+ float norm;
int x;
- float norm = 0.0f;
- for(x = 0; x < self->size; x++) {
+ norm = 0.0f;
+ for( x = 0; x < self->size; x++ ) {
norm += self->vec[x] * self->vec[x];
}
- norm = (float) sqrt(norm);
- for(x = 0; x < self->size; x++) {
+ norm = ( float ) sqrt( norm );
+ for( x = 0; x < self->size; x++ ) {
self->vec[x] /= norm;
}
- return (PyObject*)self;
+
+ return EXPP_incr_ret( Py_None );
}
-//----------------------------Vector.negate() --------------------
-//set the vector to it's negative -x, -y, -z
-PyObject *Vector_Negate(VectorObject * self)
+
+PyObject *Vector_Negate( VectorObject * self )
{
int x;
- for(x = 0; x < self->size; x++) {
- self->vec[x] = -(self->vec[x]);
- }
- return (PyObject*)self;
-}
-//----------------------------Vector.resize2D() ------------------
-//resize the vector to x,y
-PyObject *Vector_Resize2D(VectorObject * self)
-{
- if(self->data.blend_data){
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "vector.resize2d(): cannot resize wrapped data - only python vectors\n");
+ for( x = 0; x < self->size; x++ ) {
+ self->vec[x] = -( self->vec[x] );
}
- self->data.py_data =
- PyMem_Realloc(self->data.py_data, (sizeof(float) * 2));
- if(self->data.py_data == NULL) {
- return EXPP_ReturnPyObjError(PyExc_MemoryError,
- "vector.resize2d(): problem allocating pointer space\n\n");
- }
- self->vec = self->data.py_data; //force
- self->size = 2;
- return (PyObject*)self;
+ return EXPP_incr_ret( Py_None );
}
-//----------------------------Vector.resize3D() ------------------
-//resize the vector to x,y,z
-PyObject *Vector_Resize3D(VectorObject * self)
+
+PyObject *Vector_Resize2D( VectorObject * self )
{
- if(self->data.blend_data){
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "vector.resize3d(): cannot resize wrapped data - only python vectors\n");
- }
+ float x, y;
- self->data.py_data =
- PyMem_Realloc(self->data.py_data, (sizeof(float) * 3));
- if(self->data.py_data == NULL) {
- return EXPP_ReturnPyObjError(PyExc_MemoryError,
- "vector.resize3d(): problem allocating pointer space\n\n");
+ if( self->size == 4 || self->size == 3 ) {
+ x = self->vec[0];
+ y = self->vec[1];
+ PyMem_Free( self->vec );
+ self->vec = PyMem_Malloc( 2 * sizeof( float ) );
+ self->vec[0] = x;
+ self->vec[1] = y;
+ self->size = 2;
}
- self->vec = self->data.py_data; //force
- if(self->size == 2){
- self->data.py_data[2] = 0.0f;
- }
- self->size = 3;
- return (PyObject*)self;
+
+ return EXPP_incr_ret( Py_None );
}
-//----------------------------Vector.resize4D() ------------------
-//resize the vector to x,y,z,w
-PyObject *Vector_Resize4D(VectorObject * self)
-{
- if(self->data.blend_data){
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "vector.resize4d(): cannot resize wrapped data - only python vectors\n");
- }
- self->data.py_data =
- PyMem_Realloc(self->data.py_data, (sizeof(float) * 4));
- if(self->data.py_data == NULL) {
- return EXPP_ReturnPyObjError(PyExc_MemoryError,
- "vector.resize4d(): problem allocating pointer space\n\n");
- }
- self->vec = self->data.py_data; //force
- if(self->size == 2){
- self->data.py_data[2] = 0.0f;
- self->data.py_data[3] = 0.0f;
- }else if(self->size == 3){
- self->data.py_data[3] = 0.0f;
- }
- self->size = 4;
- return (PyObject*)self;
+PyObject *Vector_Resize3D( VectorObject * self )
+{
+ float x, y, z;
+
+ if( self->size == 2 ) {
+ x = self->vec[0];
+ y = self->vec[1];
+ PyMem_Free( self->vec );
+ self->vec = PyMem_Malloc( 3 * sizeof( float ) );
+ self->vec[0] = x;
+ self->vec[1] = y;
+ self->vec[2] = 0.0f;
+ self->size = 3;
+ } else if( self->size == 4 ) {
+ x = self->vec[0];
+ y = self->vec[1];
+ z = self->vec[2];
+ PyMem_Free( self->vec );
+ self->vec = PyMem_Malloc( 3 * sizeof( float ) );
+ self->vec[0] = x;
+ self->vec[1] = y;
+ self->vec[2] = z;
+ self->size = 3;
+ }
+
+ return EXPP_incr_ret( Py_None );
}
-//----------------------------dealloc()(internal) ----------------
-//free the py_object
-static void Vector_dealloc(VectorObject * self)
+
+PyObject *Vector_Resize4D( VectorObject * self )
{
- //only free py_data
- if(self->data.py_data){
- PyMem_Free(self->data.py_data);
- }
- PyObject_DEL(self);
+ float x, y, z;
+
+ if( self->size == 2 ) {
+ x = self->vec[0];
+ y = self->vec[1];
+ PyMem_Free( self->vec );
+ self->vec = PyMem_Malloc( 4 * sizeof( float ) );
+ self->vec[0] = x;
+ self->vec[1] = y;
+ self->vec[2] = 0.0f;
+ self->vec[3] = 1.0f;
+ self->size = 4;
+ } else if( self->size == 3 ) {
+ x = self->vec[0];
+ y = self->vec[1];
+ z = self->vec[2];
+ PyMem_Free( self->vec );
+ self->vec = PyMem_Malloc( 4 * sizeof( float ) );
+ self->vec[0] = x;
+ self->vec[1] = y;
+ self->vec[2] = z;
+ self->vec[3] = 1.0f;
+ self->size = 4;
+ }
+
+ return EXPP_incr_ret( Py_None );
}
-//----------------------------getattr()(internal) ----------------
-//object.attribute access (get)
-static PyObject *Vector_getattr(VectorObject * self, char *name)
+
+static void Vector_dealloc( VectorObject * self )
{
- int x;
- double dot = 0.0f;
-
- if(STREQ(name,"x")){
- return PyFloat_FromDouble(self->vec[0]);
- }else if(STREQ(name, "y")){
- return PyFloat_FromDouble(self->vec[1]);
- }else if(STREQ(name, "z")){
- if(self->size > 2){
- return PyFloat_FromDouble(self->vec[2]);
- }else{
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "vector.z: illegal attribute access\n");
- }
- }else if(STREQ(name, "w")){
- if(self->size > 3){
- return PyFloat_FromDouble(self->vec[3]);
- }else{
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "vector.w: illegal attribute access\n");
- }
- }else if(STREQ2(name, "length", "magnitude")) {
- for(x = 0; x < self->size; x++){
- dot += (self->vec[x] * self->vec[x]);
- }
- return PyFloat_FromDouble(sqrt(dot));
- }
+ /* if we own this memory we must delete it */
+ if( self->delete_pymem )
+ PyMem_Free( self->vec );
- return Py_FindMethod(Vector_methods, (PyObject *) self, name);
+ PyObject_DEL( self );
}
-//----------------------------setattr()(internal) ----------------
-//object.attribute access (set)
-static int Vector_setattr(VectorObject * self, char *name, PyObject * v)
-{
- PyObject *f = NULL;
- f = PyNumber_Float(v);
- if(f == NULL) { // parsed item not a number
- return EXPP_ReturnIntError(PyExc_TypeError,
- "vector.attribute = x: argument not a number\n");
- }
+static PyObject *Vector_getattr( VectorObject * self, char *name )
+{
+ if( self->size == 4 && ELEM4( name[0], 'x', 'y', 'z', 'w' )
+ && name[1] == 0 ) {
+ if( ( name[0] ) == ( 'w' ) ) {
+ return PyFloat_FromDouble( self->vec[3] );
+ } else {
+ return PyFloat_FromDouble( self->vec[name[0] - 'x'] );
+ }
+ } else if( self->size == 3 && ELEM3( name[0], 'x', 'y', 'z' )
+ && name[1] == 0 )
+ return PyFloat_FromDouble( self->vec[name[0] - 'x'] );
+ else if( self->size == 2 && ELEM( name[0], 'x', 'y' ) && name[1] == 0 )
+ return PyFloat_FromDouble( self->vec[name[0] - 'x'] );
+
+ if( ( strcmp( name, "length" ) == 0 ) ) {
+ if( self->size == 4 ) {
+ return PyFloat_FromDouble( sqrt
+ ( self->vec[0] *
+ self->vec[0] +
+ self->vec[1] *
+ self->vec[1] +
+ self->vec[2] *
+ self->vec[2] +
+ self->vec[3] *
+ self->vec[3] ) );
+ } else if( self->size == 3 ) {
+ return PyFloat_FromDouble( sqrt
+ ( self->vec[0] *
+ self->vec[0] +
+ self->vec[1] *
+ self->vec[1] +
+ self->vec[2] *
+ self->vec[2] ) );
+ } else if( self->size == 2 ) {
+ return PyFloat_FromDouble( sqrt
+ ( self->vec[0] *
+ self->vec[0] +
+ self->vec[1] *
+ self->vec[1] ) );
+ } else
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "can only return the length of a 2D ,3D or 4D vector\n" );
+ }
+
+ return Py_FindMethod( Vector_methods, ( PyObject * ) self, name );
+}
- if(STREQ(name,"x")){
- self->vec[0] = PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "y")){
- self->vec[1] = PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "z")){
- if(self->size > 2){
- self->vec[2] = PyFloat_AS_DOUBLE(f);
- }else{
- Py_DECREF(f);
- return EXPP_ReturnIntError(PyExc_AttributeError,
- "vector.z = x: illegal attribute access\n");
+static int Vector_setattr( VectorObject * self, char *name, PyObject * v )
+{
+ float val;
+ int valTemp;
+
+ if( !PyFloat_Check( v ) ) {
+ if( !PyInt_Check( v ) ) {
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "int or float expected\n" );
+ } else {
+ if( !PyArg_Parse( v, "i", &valTemp ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "unable to parse int argument\n" );
+ val = ( float ) valTemp;
}
- }else if(STREQ(name, "w")){
- if(self->size > 3){
- self->vec[3] = PyFloat_AS_DOUBLE(f);
- }else{
- Py_DECREF(f);
- return EXPP_ReturnIntError(PyExc_AttributeError,
- "vector.w = x: illegal attribute access\n");
+ } else {
+ if( !PyArg_Parse( v, "f", &val ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "unable to parse float argument\n" );
+ }
+ if( self->size == 4 && ELEM4( name[0], 'x', 'y', 'z', 'w' )
+ && name[1] == 0 ) {
+ if( ( name[0] ) == ( 'w' ) ) {
+ self->vec[3] = val;
+ } else {
+ self->vec[name[0] - 'x'] = val;
}
- }else{
- Py_DECREF(f);
- return EXPP_ReturnIntError(PyExc_AttributeError,
- "vector.attribute = x: unknown attribute\n");
- }
+ } else if( self->size == 3 && ELEM3( name[0], 'x', 'y', 'z' )
+ && name[1] == 0 )
+ self->vec[name[0] - 'x'] = val;
+ else if( self->size == 2 && ELEM( name[0], 'x', 'y' ) && name[1] == 0 )
+ self->vec[name[0] - 'x'] = val;
+ else
+ return -1;
- Py_DECREF(f);
return 0;
}
-//----------------------------print object (internal)-------------
-//print the object to screen
-static PyObject *Vector_repr(VectorObject * self)
-{
- int i;
- char buffer[48], str[1024];
-
- BLI_strncpy(str,"[",1024);
- for(i = 0; i < self->size; i++){
- if(i < (self->size - 1)){
- sprintf(buffer, "%.6f, ", self->vec[i]);
- strcat(str,buffer);
- }else{
- sprintf(buffer, "%.6f", self->vec[i]);
- strcat(str,buffer);
- }
- }
- strcat(str, "](vector)");
- return EXPP_incr_ret(PyString_FromString(str));
-}
-//---------------------SEQUENCE PROTOCOLS------------------------
-//----------------------------len(object)------------------------
-//sequence length
-static int Vector_len(VectorObject * self)
+/* Vectors Sequence methods */
+static int Vector_len( VectorObject * self )
{
return self->size;
}
-//----------------------------object[]---------------------------
-//sequence accessor (get)
-static PyObject *Vector_item(VectorObject * self, int i)
-{
- if(i < 0 || i >= self->size)
- return EXPP_ReturnPyObjError(PyExc_IndexError,
- "vector[attribute]: array index out of range\n");
-
- return Py_BuildValue("f", self->vec[i]);
-}
-//----------------------------object[]-------------------------
-//sequence accessor (set)
-static int Vector_ass_item(VectorObject * self, int i, PyObject * ob)
+static PyObject *Vector_item( VectorObject * self, int i )
{
- PyObject *f = NULL;
+ if( i < 0 || i >= self->size )
+ return EXPP_ReturnPyObjError( PyExc_IndexError,
+ "array index out of range\n" );
- f = PyNumber_Float(ob);
- if(f == NULL) { // parsed item not a number
- return EXPP_ReturnIntError(PyExc_TypeError,
- "vector[attribute] = x: argument not a number\n");
- }
+ return Py_BuildValue( "f", self->vec[i] );
- if(i < 0 || i >= self->size){
- Py_DECREF(f);
- return EXPP_ReturnIntError(PyExc_IndexError,
- "vector[attribute] = x: array assignment index out of range\n");
- }
- self->vec[i] = PyFloat_AS_DOUBLE(f);
- Py_DECREF(f);
- return 0;
}
-//----------------------------object[z:y]------------------------
-//sequence slice (get)
-static PyObject *Vector_slice(VectorObject * self, int begin, int end)
+
+static PyObject *Vector_slice( VectorObject * self, int begin, int end )
{
- PyObject *list = NULL;
+ PyObject *list;
int count;
- CLAMP(begin, 0, self->size);
- CLAMP(end, 0, self->size);
- begin = MIN2(begin,end);
+ if( begin < 0 )
+ begin = 0;
+ if( end > self->size )
+ end = self->size;
+ if( begin > end )
+ begin = end;
+
+ list = PyList_New( end - begin );
- list = PyList_New(end - begin);
- for(count = begin; count < end; count++) {
- PyList_SetItem(list, count - begin,
- PyFloat_FromDouble(self->vec[count]));
+ for( count = begin; count < end; count++ ) {
+ PyList_SetItem( list, count - begin,
+ PyFloat_FromDouble( self->vec[count] ) );
}
return list;
}
-//----------------------------object[z:y]------------------------
-//sequence slice (set)
-static int Vector_ass_slice(VectorObject * self, int begin, int end,
- PyObject * seq)
-{
- int i, y, size = 0;
- float vec[4];
-
- CLAMP(begin, 0, self->size);
- CLAMP(end, 0, self->size);
- begin = MIN2(begin,end);
- size = PySequence_Length(seq);
- if(size != (end - begin)){
- return EXPP_ReturnIntError(PyExc_TypeError,
- "vector[begin:end] = []: size mismatch in slice assignment\n");
- }
+static int Vector_ass_item( VectorObject * self, int i, PyObject * ob )
+{
+ if( i < 0 || i >= self->size )
+ return EXPP_ReturnIntError( PyExc_IndexError,
+ "array assignment index out of range\n" );
+ if( !PyInt_Check( ob ) && !PyFloat_Check( ob ) )
+ return EXPP_ReturnIntError( PyExc_IndexError,
+ "vector member must be a number\n" );
- for (i = 0; i < size; i++) {
- PyObject *v, *f;
+ self->vec[i] = ( float ) PyFloat_AsDouble( ob );
- v = PySequence_GetItem(seq, i);
- if (v == NULL) { // Failed to read sequence
- return EXPP_ReturnIntError(PyExc_RuntimeError,
- "vector[begin:end] = []: unable to read sequence\n");
- }
- f = PyNumber_Float(v);
- if(f == NULL) { // parsed item not a number
- Py_DECREF(v);
- return EXPP_ReturnIntError(PyExc_TypeError,
- "vector[begin:end] = []: sequence argument not a number\n");
- }
- vec[i] = PyFloat_AS_DOUBLE(f);
- EXPP_decr2(f,v);
- }
- //parsed well - now set in vector
- for(y = 0; y < size; y++){
- self->vec[begin + y] = vec[y];
- }
return 0;
}
-//------------------------NUMERIC PROTOCOLS----------------------
-//------------------------obj + obj------------------------------
-//addition
-static PyObject *Vector_add(PyObject * v1, PyObject * v2)
-{
- int x, size;
- float vec[4];
- VectorObject *vec1 = NULL, *vec2 = NULL;
-
- EXPP_incr2(v1, v2);
- vec1 = (VectorObject*)v1;
- vec2 = (VectorObject*)v2;
- if(vec1->coerced_object || vec2->coerced_object){
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector addition: arguments not valid for this operation....\n");
- }
- if(vec1->size != vec2->size){
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector addition: vectors must have the same dimensions for this operation\n");
- }
-
- size = vec1->size;
- for(x = 0; x < size; x++) {
- vec[x] = vec1->vec[x] + vec2->vec[x];
+static int Vector_ass_slice( VectorObject * self, int begin, int end,
+ PyObject * seq )
+{
+ int count, z;
+
+ if( begin < 0 )
+ begin = 0;
+ if( end > self->size )
+ end = self->size;
+ if( begin > end )
+ begin = end;
+
+ if( !PySequence_Check( seq ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "illegal argument type for built-in operation\n" );
+ if( PySequence_Length( seq ) != ( end - begin ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "size mismatch in slice assignment\n" );
+
+ z = 0;
+ for( count = begin; count < end; count++ ) {
+ PyObject *ob = PySequence_GetItem( seq, z );
+ z++;
+ if( !PyInt_Check( ob ) && !PyFloat_Check( ob ) )
+ return EXPP_ReturnIntError( PyExc_IndexError,
+ "list member must be a number\n" );
+
+ if( !PyArg_Parse( ob, "f", &self->vec[count] ) ) {
+ Py_DECREF( ob );
+ return -1;
+ }
}
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return (PyObject *) newVectorObject(vec, size, Py_NEW);
+ return 0;
}
-//------------------------obj - obj------------------------------
-//subtraction
-static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
-{
- int x, size;
- float vec[4];
- VectorObject *vec1 = NULL, *vec2 = NULL;
-
- EXPP_incr2(v1, v2);
- vec1 = (VectorObject*)v1;
- vec2 = (VectorObject*)v2;
- if(vec1->coerced_object || vec2->coerced_object){
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector subtraction: arguments not valid for this operation....\n");
- }
- if(vec1->size != vec2->size){
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector subtraction: vectors must have the same dimensions for this operation\n");
- }
+static PyObject *Vector_repr( VectorObject * self )
+{
+ int i, maxindex = self->size - 1;
+ char ftoa[24];
+ PyObject *str1, *str2;
+
+ str1 = PyString_FromString( "[" );
+
+ for( i = 0; i < maxindex; i++ ) {
+ sprintf( ftoa, "%.4f, ", self->vec[i] );
+ str2 = PyString_FromString( ftoa );
+ if( !str1 || !str2 )
+ goto error;
+ PyString_ConcatAndDel( &str1, str2 );
+ }
+
+ sprintf( ftoa, "%.4f]", self->vec[maxindex] );
+ str2 = PyString_FromString( ftoa );
+ if( !str1 || !str2 )
+ goto error;
+ PyString_ConcatAndDel( &str1, str2 );
+
+ if( str1 )
+ return str1;
+
+ error:
+ Py_XDECREF( str1 );
+ Py_XDECREF( str2 );
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "couldn't create PyString!\n" );
+}
- size = vec1->size;
- for(x = 0; x < size; x++) {
- vec[x] = vec1->vec[x] - vec2->vec[x];
- }
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return (PyObject *) newVectorObject(vec, size, Py_NEW);
-}
-//------------------------obj * obj------------------------------
-//mulplication
-static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
+PyObject *Vector_add( PyObject * v1, PyObject * v2 )
{
- int x, size;
- float vec[4], scalar, newVec[3];
- double dot = 0.0f;
- VectorObject *vec1 = NULL, *vec2 = NULL;
- PyObject *f = NULL, *retObj = NULL;
- MatrixObject *mat = NULL;
- QuaternionObject *quat = NULL;
-
- EXPP_incr2(v1, v2);
- vec1 = (VectorObject*)v1;
- vec2 = (VectorObject*)v2;
-
- if(vec1->coerced_object){
- if (PyFloat_Check(vec1->coerced_object) ||
- PyInt_Check(vec1->coerced_object)){ // FLOAT/INT * VECTOR
- f = PyNumber_Float(vec1->coerced_object);
- if(f == NULL) { // parsed item not a number
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "Vector multiplication: arguments not acceptable for this operation\n");
- }
- scalar = PyFloat_AS_DOUBLE(f);
- size = vec2->size;
- for(x = 0; x < size; x++) {
- vec[x] = vec2->vec[x] * scalar;
- }
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return (PyObject *) newVectorObject(vec, size, Py_NEW);
- }
- }else{
- if(vec2->coerced_object){
- if(MatrixObject_Check(vec2->coerced_object)){ //VECTOR * MATRIX
- mat = (MatrixObject*)EXPP_incr_ret(vec2->coerced_object);
- retObj = row_vector_multiplication(vec1, mat);
- EXPP_decr3((PyObject*)vec1, (PyObject*)vec2, (PyObject*)mat);
- return retObj;
- }else if (PyFloat_Check(vec2->coerced_object) ||
- PyInt_Check(vec2->coerced_object)){ // VECTOR * FLOAT/INT
- f = PyNumber_Float(vec2->coerced_object);
- if(f == NULL) { // parsed item not a number
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "Vector multiplication: arguments not acceptable for this operation\n");
- }
- scalar = PyFloat_AS_DOUBLE(f);
- size = vec1->size;
- for(x = 0; x < size; x++) {
- vec[x] = vec1->vec[x] * scalar;
- }
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return (PyObject *) newVectorObject(vec, size, Py_NEW);
- }else if(QuaternionObject_Check(vec2->coerced_object)){ //QUAT * VEC
- quat = (QuaternionObject*)EXPP_incr_ret(vec2->coerced_object);
- if(vec1->size != 3){
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
- }
- newVec[0] = quat->quat[0]*quat->quat[0]*vec1->vec[0] +
- 2*quat->quat[2]*quat->quat[0]*vec1->vec[2] -
- 2*quat->quat[3]*quat->quat[0]*vec1->vec[1] +
- quat->quat[1]*quat->quat[1]*vec1->vec[0] +
- 2*quat->quat[2]*quat->quat[1]*vec1->vec[1] +
- 2*quat->quat[3]*quat->quat[1]*vec1->vec[2] -
- quat->quat[3]*quat->quat[3]*vec1->vec[0] -
- quat->quat[2]*quat->quat[2]*vec1->vec[0];
- newVec[1] = 2*quat->quat[1]*quat->quat[2]*vec1->vec[0] +
- quat->quat[2]*quat->quat[2]*vec1->vec[1] +
- 2*quat->quat[3]*quat->quat[2]*vec1->vec[2] +
- 2*quat->quat[0]*quat->quat[3]*vec1->vec[0] -
- quat->quat[3]*quat->quat[3]*vec1->vec[1] +
- quat->quat[0]*quat->quat[0]*vec1->vec[1] -
- 2*quat->quat[1]*quat->quat[0]*vec1->vec[2] -
- quat->quat[1]*quat->quat[1]*vec1->vec[1];
- newVec[2] = 2*quat->quat[1]*quat->quat[3]*vec1->vec[0] +
- 2*quat->quat[2]*quat->quat[3]*vec1->vec[1] +
- quat->quat[3]*quat->quat[3]*vec1->vec[2] -
- 2*quat->quat[0]*quat->quat[2]*vec1->vec[0] -
- quat->quat[2]*quat->quat[2]*vec1->vec[2] +
- 2*quat->quat[0]*quat->quat[1]*vec1->vec[1] -
- quat->quat[1]*quat->quat[1]*vec1->vec[2] +
- quat->quat[0]*quat->quat[0]*vec1->vec[2];
- EXPP_decr3((PyObject*)vec1, (PyObject*)vec2, (PyObject*)quat);
- return newVectorObject(newVec,3,Py_NEW);
- }
- }else{ //VECTOR * VECTOR
- if(vec1->size != vec2->size){
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector multiplication: vectors must have the same dimensions for this operation\n");
- }
- size = vec1->size;
- //dot product
- for(x = 0; x < size; x++) {
- dot += vec1->vec[x] * vec2->vec[x];
- }
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return PyFloat_FromDouble(dot);
- }
- }
-
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "Vector multiplication: arguments not acceptable for this operation\n");
+ float *vec;
+ int x;
+ PyObject *retval;
+
+ if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "unsupported type for this operation\n" );
+ if( ( ( VectorObject * ) v1 )->flag != 0
+ || ( ( VectorObject * ) v2 )->flag != 0 )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "cannot add a scalar to a vector\n" );
+ if( ( ( VectorObject * ) v1 )->size !=
+ ( ( VectorObject * ) v2 )->size )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "vectors must have the same dimensions for this operation\n" );
+
+ vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
+ sizeof( float ) );
+
+ for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
+ vec[x] = ( ( VectorObject * ) v1 )->vec[x] +
+ ( ( VectorObject * ) v2 )->vec[x];
+ }
+
+ retval = ( PyObject * ) newVectorObject( vec,
+ ( ( ( VectorObject * ) v1 )->
+ size ) );
+ PyMem_Free( vec );
+ return retval;
}
-//------------------------obj / obj------------------------------
-//division
-static PyObject *Vector_div(PyObject * v1, PyObject * v2)
-{
- int x, size;
- float vec[4];
- VectorObject *vec1 = NULL, *vec2 = NULL;
- EXPP_incr2(v1, v2);
- vec1 = (VectorObject*)v1;
- vec2 = (VectorObject*)v2;
-
- if(vec1->coerced_object || vec2->coerced_object){
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector division: arguments not valid for this operation....\n");
- }
- if(vec1->size != vec2->size){
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Vector division: vectors must have the same dimensions for this operation\n");
- }
+PyObject *Vector_sub( PyObject * v1, PyObject * v2 )
+{
+ float *vec;
+ int x;
+ PyObject *retval;
+
+ if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "unsupported type for this operation\n" );
+ if( ( ( VectorObject * ) v1 )->flag != 0
+ || ( ( VectorObject * ) v2 )->flag != 0 )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "cannot subtract a scalar from a vector\n" );
+ if( ( ( VectorObject * ) v1 )->size !=
+ ( ( VectorObject * ) v2 )->size )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "vectors must have the same dimensions for this operation\n" );
+
+ vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
+ sizeof( float ) );
+
+ for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
+ vec[x] = ( ( VectorObject * ) v1 )->vec[x] -
+ ( ( VectorObject * ) v2 )->vec[x];
+ }
+
+ retval = ( PyObject * ) newVectorObject( vec,
+ ( ( ( VectorObject * ) v1 )->
+ size ) );
+ PyMem_Free( vec );
+ return retval;
+}
- size = vec1->size;
- for(x = 0; x < size; x++) {
- vec[x] = vec1->vec[x] / vec2->vec[x];
- }
+PyObject *Vector_mul( PyObject * v1, PyObject * v2 )
+{
+ float *vec;
+ int x;
+ PyObject *retval;
+
+ if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "unsupported type for this operation\n" );
+ if( ( ( VectorObject * ) v1 )->flag == 0
+ && ( ( VectorObject * ) v2 )->flag == 0 )
+ return EXPP_ReturnPyObjError( PyExc_ArithmeticError,
+ "please use the dot product or the cross product to multiply vectors\n" );
+ if( ( ( VectorObject * ) v1 )->size !=
+ ( ( VectorObject * ) v2 )->size )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "vector dimension error during Vector_mul\n" );
+
+ vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
+ sizeof( float ) );
+
+ for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
+ vec[x] = ( ( VectorObject * ) v1 )->vec[x] *
+ ( ( VectorObject * ) v2 )->vec[x];
+ }
+
+ retval = ( PyObject * ) newVectorObject( vec,
+ ( ( ( VectorObject * ) v1 )->
+ size ) );
+ PyMem_Free( vec );
+ return retval;
+}
- EXPP_decr2((PyObject*)vec1, (PyObject*)vec2);
- return (PyObject *) newVectorObject(vec, size, Py_NEW);
+PyObject *Vector_div( PyObject * v1, PyObject * v2 )
+{
+ float *vec;
+ int x;
+ PyObject *retval;
+
+ if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "unsupported type for this operation\n" );
+ if( ( ( VectorObject * ) v1 )->flag == 0
+ && ( ( VectorObject * ) v2 )->flag == 0 )
+ return EXPP_ReturnPyObjError( PyExc_ArithmeticError,
+ "cannot divide two vectors\n" );
+ if( ( ( VectorObject * ) v1 )->flag != 0
+ && ( ( VectorObject * ) v2 )->flag == 0 )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "cannot divide a scalar by a vector\n" );
+ if( ( ( VectorObject * ) v1 )->size !=
+ ( ( VectorObject * ) v2 )->size )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "vector dimension error during Vector_mul\n" );
+
+ vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
+ sizeof( float ) );
+
+ for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
+ vec[x] = ( ( VectorObject * ) v1 )->vec[x] /
+ ( ( VectorObject * ) v2 )->vec[x];
+ }
+
+ retval = ( PyObject * ) newVectorObject( vec,
+ ( ( ( VectorObject * ) v1 )->
+ size ) );
+ PyMem_Free( vec );
+ return retval;
}
-//------------------------coerce(obj, obj)-----------------------
+
//coercion of unknown types to type VectorObject for numeric protocols
-/*Coercion() is called whenever a math operation has 2 operands that
- it doesn't understand how to evaluate. 2+Matrix for example. We want to
- evaluate some of these operations like: (vector * 2), however, for math
- to proceed, the unknown operand must be cast to a type that python math will
- understand. (e.g. in the case above case, 2 must be cast to a vector and
- then call vector.multiply(vector, scalar_cast_as_vector)*/
-static int Vector_coerce(PyObject ** v1, PyObject ** v2)
+int Vector_coerce( PyObject ** v1, PyObject ** v2 )
{
+ long *tempI;
+ double *tempF;
+ float *vec;
int x;
- float vec[4];
- PyObject *coerced = NULL;
-
- if(!VectorObject_Check(*v2)) {
- if(MatrixObject_Check(*v2) || PyFloat_Check(*v2) || PyInt_Check(*v2) || QuaternionObject_Check(*v2)) {
- coerced = EXPP_incr_ret(*v2);
- *v2 = newVectorObject(NULL,3,Py_NEW);
- ((VectorObject*)*v2)->coerced_object = coerced;
- }else{
- return EXPP_ReturnIntError(PyExc_TypeError,
- "vector.coerce(): unknown operand - can't coerce for numeric protocols\n");
+
+ if( VectorObject_Check( *v1 ) ) {
+ if( VectorObject_Check( *v2 ) ) { //two vectors
+ Py_INCREF( *v1 ); /* fixme: wahy are we bumping the ref count? */
+ Py_INCREF( *v2 );
+ return 0;
+ } else {
+ if( Matrix_CheckPyObject( *v2 ) ) {
+ printf( "vector/matrix numeric protocols unsupported...\n" );
+ Py_INCREF( *v1 );
+ return 0; //operation will type check
+ } else if( PyNumber_Check( *v2 ) ) {
+ if( PyInt_Check( *v2 ) ) { //cast scalar to vector
+ tempI = PyMem_Malloc( 1 *
+ sizeof( long ) );
+ *tempI = PyInt_AsLong( *v2 );
+ vec = PyMem_Malloc( ( ( ( VectorObject
+ * ) *
+ v1 )->size ) *
+ sizeof( float ) );
+ for( x = 0;
+ x < ( ( ( VectorObject * ) * v1 )->size );
+ x++ ) {
+ vec[x] = ( float ) *tempI;
+ }
+ PyMem_Free( tempI );
+ *v2 = newVectorObject( vec,
+ ( ( ( VectorObject * ) * v1 )->size ) );
+ ( ( VectorObject * ) * v2 )->flag = 1; //int coercion
+ Py_INCREF( *v1 );
+ return 0;
+ } else if( PyFloat_Check( *v2 ) ) { //cast scalar to vector
+ tempF = PyMem_Malloc( 1 *
+ sizeof
+ ( double ) );
+ *tempF = PyFloat_AsDouble( *v2 );
+ vec = PyMem_Malloc( ( ( ( VectorObject
+ * ) *
+ v1 )->size ) *
+ sizeof( float ) );
+ for( x = 0;
+ x <
+ ( ( ( VectorObject * ) *
+ v1 )->size ); x++ ) {
+ vec[x] = ( float ) *tempF;
+ }
+ PyMem_Free( tempF );
+ *v2 = newVectorObject( vec,
+ ( ( ( VectorObject * ) * v1 )->size ) );
+ ( ( VectorObject * ) * v2 )->flag = 2; //float coercion
+ Py_INCREF( *v1 );
+ return 0;
+ }
+ }
+ //unknown type or numeric cast failure
+ printf( "attempting vector operation with unsupported type...\n" );
+ Py_INCREF( *v1 );
+ return 0; //operation will type check
}
+ } else {
+ printf( "numeric protocol failure...\n" );
+ return -1; //this should not occur - fail
}
- EXPP_incr2(*v1, *v2);
- return 0;
+ return -1;
}
-//-----------------PROTCOL DECLARATIONS--------------------------
+
+
static PySequenceMethods Vector_SeqMethods = {
- (inquiry) Vector_len, /* sq_length */
- (binaryfunc) 0, /* sq_concat */
- (intargfunc) 0, /* sq_repeat */
- (intargfunc) Vector_item, /* sq_item */
- (intintargfunc) Vector_slice, /* sq_slice */
- (intobjargproc) Vector_ass_item, /* sq_ass_item */
- (intintobjargproc) Vector_ass_slice, /* sq_ass_slice */
+ ( inquiry ) Vector_len, /* sq_length */
+ ( binaryfunc ) 0, /* sq_concat */
+ ( intargfunc ) 0, /* sq_repeat */
+ ( intargfunc ) Vector_item, /* sq_item */
+ ( intintargfunc ) Vector_slice, /* sq_slice */
+ ( intobjargproc ) Vector_ass_item, /* sq_ass_item */
+ ( intintobjargproc ) Vector_ass_slice, /* sq_ass_slice */
};
+
static PyNumberMethods Vector_NumMethods = {
- (binaryfunc) Vector_add, /* __add__ */
- (binaryfunc) Vector_sub, /* __sub__ */
- (binaryfunc) Vector_mul, /* __mul__ */
- (binaryfunc) Vector_div, /* __div__ */
- (binaryfunc) 0, /* __mod__ */
- (binaryfunc) 0, /* __divmod__ */
- (ternaryfunc) 0, /* __pow__ */
- (unaryfunc) 0, /* __neg__ */
- (unaryfunc) 0, /* __pos__ */
- (unaryfunc) 0, /* __abs__ */
- (inquiry) 0, /* __nonzero__ */
- (unaryfunc) 0, /* __invert__ */
- (binaryfunc) 0, /* __lshift__ */
- (binaryfunc) 0, /* __rshift__ */
- (binaryfunc) 0, /* __and__ */
- (binaryfunc) 0, /* __xor__ */
- (binaryfunc) 0, /* __or__ */
- (coercion) Vector_coerce, /* __coerce__ */
- (unaryfunc) 0, /* __int__ */
- (unaryfunc) 0, /* __long__ */
- (unaryfunc) 0, /* __float__ */
- (unaryfunc) 0, /* __oct__ */
- (unaryfunc) 0, /* __hex__ */
+ ( binaryfunc ) Vector_add, /* __add__ */
+ ( binaryfunc ) Vector_sub, /* __sub__ */
+ ( binaryfunc ) Vector_mul, /* __mul__ */
+ ( binaryfunc ) Vector_div, /* __div__ */
+ ( binaryfunc ) 0, /* __mod__ */
+ ( binaryfunc ) 0, /* __divmod__ */
+ ( ternaryfunc ) 0, /* __pow__ */
+ ( unaryfunc ) 0, /* __neg__ */
+ ( unaryfunc ) 0, /* __pos__ */
+ ( unaryfunc ) 0, /* __abs__ */
+ ( inquiry ) 0, /* __nonzero__ */
+ ( unaryfunc ) 0, /* __invert__ */
+ ( binaryfunc ) 0, /* __lshift__ */
+ ( binaryfunc ) 0, /* __rshift__ */
+ ( binaryfunc ) 0, /* __and__ */
+ ( binaryfunc ) 0, /* __xor__ */
+ ( binaryfunc ) 0, /* __or__ */
+ ( coercion ) Vector_coerce, /* __coerce__ */
+ ( unaryfunc ) 0, /* __int__ */
+ ( unaryfunc ) 0, /* __long__ */
+ ( unaryfunc ) 0, /* __float__ */
+ ( unaryfunc ) 0, /* __oct__ */
+ ( unaryfunc ) 0, /* __hex__ */
};
-//------------------PY_OBECT DEFINITION--------------------------
+
PyTypeObject vector_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size */
- "vector", /*tp_name */
- sizeof(VectorObject), /*tp_basicsize */
- 0, /*tp_itemsize */
- (destructor) Vector_dealloc, /*tp_dealloc */
- (printfunc) 0, /*tp_print */
- (getattrfunc) Vector_getattr, /*tp_getattr */
- (setattrfunc) Vector_setattr, /*tp_setattr */
- 0, /*tp_compare */
- (reprfunc) Vector_repr, /*tp_repr */
- &Vector_NumMethods, /*tp_as_number */
- &Vector_SeqMethods, /*tp_as_sequence */
+ PyObject_HEAD_INIT( NULL ) 0, /*ob_size */
+ "vector", /*tp_name */
+ sizeof( VectorObject ), /*tp_basicsize */
+ 0, /*tp_itemsize */
+ ( destructor ) Vector_dealloc, /*tp_dealloc */
+ ( printfunc ) 0, /*tp_print */
+ ( getattrfunc ) Vector_getattr, /*tp_getattr */
+ ( setattrfunc ) Vector_setattr, /*tp_setattr */
+ 0, /*tp_compare */
+ ( reprfunc ) Vector_repr, /*tp_repr */
+ &Vector_NumMethods, /*tp_as_number */
+ &Vector_SeqMethods, /*tp_as_sequence */
};
-//------------------------newVectorObject (internal)-------------
-//creates a new vector object
-/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- (i.e. it was allocated elsewhere by MEM_mallocN())
- pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *newVectorObject(float *vec, int size, int type)
+
+
+/*
+ * create a Vector Object( vec, size )
+ *
+ * Note: Vector now uses copy semantics like STL containers.
+ * Memory for vec member is allocated on python stack.
+ * We own this memory and will free it later.
+ *
+ * size arg is number of floats to alloc.
+ *
+ * if vec arg is NULL
+ * fill our vec with zeros
+ * initialize 4d vectors to zero in homogenous coords.
+ * else
+ * vec param is copied into our local memory and always freed.
+ */
+
+PyObject *newVectorObject( float *vec, int size )
{
VectorObject *self;
int x;
vector_Type.ob_type = &PyType_Type;
- self = PyObject_NEW(VectorObject, &vector_Type);
- self->data.blend_data = NULL;
- self->data.py_data = NULL;
- self->size = size;
- self->coerced_object = NULL;
-
- if(type == Py_WRAP){
- self->data.blend_data = vec;
- self->vec = self->data.blend_data;
- }else if (type == Py_NEW){
- self->data.py_data = PyMem_Malloc(size * sizeof(float));
- self->vec = self->data.py_data;
- if(!vec) { //new empty
- for(x = 0; x < size; x++){
- self->vec[x] = 0.0f;
- }
- if(size == 4) /* do the homogenous thing */
- self->vec[3] = 1.0f;
- }else{
- for(x = 0; x < size; x++){
- self->vec[x] = vec[x];
- }
+
+ self = PyObject_NEW( VectorObject, &vector_Type );
+
+ self->vec = PyMem_Malloc( size * sizeof( float ) );
+ self->delete_pymem = 1; /* must free this alloc later */
+
+ if( !vec ) {
+ for( x = 0; x < size; x++ ) {
+ self->vec[x] = 0.0f;
+ }
+ if( size == 4 ) /* do the homogenous thing */
+ self->vec[3] = 1.0f;
+ } else {
+ for( x = 0; x < size; x++ ){
+ self->vec[x] = vec[x];
}
- }else{ //bad type
- return NULL;
}
- return (PyObject *) EXPP_incr_ret((PyObject *)self);
+
+ self->size = size;
+ self->flag = 0;
+
+ return ( PyObject * ) self;
}
+
+/*
+ create a Vector that is a proxy for blender data.
+ we do not own this data, we NEVER free it.
+ Note: users must deal with bad pointer issue
+*/
+
+PyObject *newVectorProxy( float *vec, int size)
+{
+ VectorObject *proxy;
+
+ proxy = PyObject_NEW( VectorObject, &vector_Type );
+
+ proxy->delete_pymem = 0; /* must NOT free this alloc later */
+
+ if( !vec || size < 1 ) {
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "cannot creat zero length vector proxy" );
+ }
+
+ proxy->vec = vec;
+ proxy->size = size;
+ proxy->flag = 0;
+
+ return ( PyObject * ) proxy;
+}
+