
fix memory leak in vector module. Memory allocated by vector constructor was not being freed.
616 lines
17 KiB
C
616 lines
17 KiB
C
/*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* Contributor(s): Willian P. Germano & Joseph Gilbert
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include "vector.h"
|
|
|
|
//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 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},
|
|
{NULL, NULL, 0, NULL}
|
|
};
|
|
|
|
/*****************************/
|
|
// Vector Python Object
|
|
/*****************************/
|
|
|
|
//object methods
|
|
PyObject *Vector_Zero(VectorObject *self)
|
|
{
|
|
int x;
|
|
for(x = 0; x < self->size; x++){
|
|
self->vec[x] = 0.0f;
|
|
}
|
|
|
|
return EXPP_incr_ret(Py_None);
|
|
}
|
|
|
|
PyObject *Vector_Normalize(VectorObject *self)
|
|
{
|
|
float norm;
|
|
int 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++){
|
|
self->vec[x] /= norm;
|
|
}
|
|
|
|
return EXPP_incr_ret(Py_None);
|
|
}
|
|
|
|
PyObject *Vector_Negate(VectorObject *self)
|
|
{
|
|
int x;
|
|
for(x = 0; x < self->size; x++){
|
|
self->vec[x] = -(self->vec[x]);
|
|
}
|
|
|
|
return EXPP_incr_ret(Py_None);
|
|
}
|
|
|
|
PyObject *Vector_Resize2D(VectorObject *self)
|
|
{
|
|
float x, y;
|
|
|
|
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;
|
|
}
|
|
|
|
return EXPP_incr_ret(Py_None);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
PyObject *Vector_Resize4D(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(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);
|
|
}
|
|
|
|
static void Vector_dealloc(VectorObject *self)
|
|
{
|
|
/* if we own this memory we must delete it */
|
|
if( self->delete_pymem )
|
|
PyMem_Free( self->vec );
|
|
|
|
PyObject_DEL (self);
|
|
}
|
|
|
|
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 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);
|
|
}
|
|
|
|
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 (!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 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;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Vectors Sequence methods */
|
|
static int Vector_len(VectorObject *self)
|
|
{
|
|
return self->size;
|
|
}
|
|
|
|
static PyObject *Vector_item(VectorObject *self, int i)
|
|
{
|
|
if (i < 0 || i >= self->size)
|
|
return EXPP_ReturnPyObjError (PyExc_IndexError, "array index out of range\n");
|
|
|
|
return Py_BuildValue("f", self->vec[i]);
|
|
|
|
}
|
|
|
|
static PyObject *Vector_slice(VectorObject *self, int begin, int end)
|
|
{
|
|
PyObject *list;
|
|
int count;
|
|
|
|
if (begin < 0) begin= 0;
|
|
if (end > self->size) end= self->size;
|
|
if (begin > end) begin= end;
|
|
|
|
list= PyList_New(end-begin);
|
|
|
|
for (count = begin; count < end; count++){
|
|
PyList_SetItem(list, count-begin, PyFloat_FromDouble(self->vec[count]));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
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");
|
|
|
|
self->vec[i]= (float)PyFloat_AsDouble(ob);
|
|
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
|
|
PyObject * Vector_add(PyObject *v1, PyObject *v2)
|
|
{
|
|
float * vec;
|
|
int x;
|
|
|
|
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];
|
|
}
|
|
|
|
return (PyObject*)newVectorObject(vec, (((VectorObject*)v1)->size));
|
|
}
|
|
|
|
PyObject * Vector_sub(PyObject *v1, PyObject *v2)
|
|
{
|
|
float * vec;
|
|
int x;
|
|
|
|
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];
|
|
}
|
|
|
|
return (PyObject*)newVectorObject(vec, (((VectorObject*)v1)->size));
|
|
}
|
|
|
|
PyObject * Vector_mul(PyObject *v1, PyObject * v2)
|
|
{
|
|
float * vec;
|
|
int x;
|
|
|
|
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];
|
|
}
|
|
|
|
return (PyObject*)newVectorObject(vec, (((VectorObject*)v1)->size));
|
|
}
|
|
|
|
PyObject * Vector_div(PyObject *v1, PyObject * v2)
|
|
{
|
|
float * vec;
|
|
int x;
|
|
|
|
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];
|
|
}
|
|
|
|
return (PyObject*)newVectorObject(vec, (((VectorObject*)v1)->size));
|
|
}
|
|
|
|
//coercion of unknown types to type VectorObject for numeric protocols
|
|
int Vector_coerce(PyObject **v1, PyObject **v2)
|
|
{
|
|
long *tempI;
|
|
double *tempF;
|
|
float *vec;
|
|
int x;
|
|
|
|
if (VectorObject_Check(*v1)) {
|
|
if (VectorObject_Check(*v2)) { //two vectors
|
|
Py_INCREF(*v1);
|
|
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
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
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 */
|
|
};
|
|
|
|
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__ */
|
|
|
|
};
|
|
|
|
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*/
|
|
};
|
|
|
|
|
|
/*
|
|
* create a Vector Object
|
|
* if vec arg is NULL
|
|
* allocate memory on python stack.
|
|
* initialize to zero in homogenous coords.
|
|
* size arg is number of floats to alloc.
|
|
*/
|
|
|
|
PyObject *newVectorObject(float *vec, int size)
|
|
{
|
|
VectorObject *self;
|
|
int x;
|
|
|
|
vector_Type.ob_type = &PyType_Type;
|
|
|
|
self = PyObject_NEW(VectorObject, &vector_Type);
|
|
|
|
if(!vec){
|
|
self->vec = PyMem_Malloc (size *sizeof (float));
|
|
for(x = 0; x < size; x++){
|
|
self->vec[x] = 0.0f;
|
|
}
|
|
if(size == 4) self->vec[3] = 1.0f;
|
|
self->delete_pymem = 1; /* must free this alloc later */
|
|
}else{
|
|
self->vec = vec;
|
|
self->delete_pymem = 0;
|
|
}
|
|
|
|
self->size = size;
|
|
self->flag = 0;
|
|
|
|
return (PyObject*) self;
|
|
}
|
|
|