| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  |  * ***** 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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  |  * Contributor(s): Willian P. Germano & Joseph Gilbert | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL/BL DUAL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "vector.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | //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} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | /*****************************/ | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | //    Vector Python Object   
 | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | /*****************************/ | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //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); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void Vector_dealloc(VectorObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  |   PyObject_DEL (self); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Vector_getattr(VectorObject *self, char *name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int Vector_setattr(VectorObject *self, char *name, PyObject *v) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	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; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Vectors Sequence methods */ | 
					
						
							|  |  |  | static int Vector_len(VectorObject *self)  | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	return self->size; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Vector_item(VectorObject *self, int i) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	if (i < 0 || i >= self->size) | 
					
						
							|  |  |  | 	  return EXPP_ReturnPyObjError (PyExc_IndexError, "array index out of range\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Py_BuildValue("f", self->vec[i]); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Vector_slice(VectorObject *self, int begin, int end) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	PyObject *list; | 
					
						
							|  |  |  | 	int count; | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	if (begin < 0) begin= 0; | 
					
						
							|  |  |  | 	if (end > self->size) end= self->size; | 
					
						
							|  |  |  | 	if (begin > end) begin= end; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	list= PyList_New(end-begin); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	for (count = begin; count < end; count++){ | 
					
						
							|  |  |  | 		PyList_SetItem(list, count-begin, PyFloat_FromDouble(self->vec[count])); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	return list; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int Vector_ass_item(VectorObject *self, int i, PyObject *ob) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	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"); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	self->vec[i]= (float)PyFloat_AsDouble(ob); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	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; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Vector_repr (VectorObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	int i, maxindex = self->size - 1; | 
					
						
							|  |  |  | 	char ftoa[24]; | 
					
						
							|  |  |  | 	PyObject *str1, *str2; | 
					
						
							| 
									
										
										
										
											2003-07-06 20:34:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	str1 = PyString_FromString ("["); | 
					
						
							| 
									
										
										
										
											2003-07-06 20:34:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	sprintf(ftoa, "%.4f]\n", self->vec[maxindex]); | 
					
						
							|  |  |  | 	str2 = PyString_FromString (ftoa); | 
					
						
							|  |  |  | 	if (!str1 || !str2) goto error;  | 
					
						
							|  |  |  | 	PyString_ConcatAndDel (&str1, str2); | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	if (str1) return str1; | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | error: | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	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)); | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | //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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | static PySequenceMethods Vector_SeqMethods = | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 	(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__ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-28 04:36:18 +00:00
										 |  |  | PyTypeObject vector_Type = | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  |   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*/ | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  |   &Vector_NumMethods,           /*tp_as_number*/ | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  |   &Vector_SeqMethods,           /*tp_as_sequence*/ | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *newVectorObject(float *vec, int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  |   VectorObject *self; | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  |   int x; | 
					
						
							| 
									
										
										
										
											2003-06-02 20:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-12 04:51:50 +00:00
										 |  |  |   vector_Type.ob_type = &PyType_Type; | 
					
						
							| 
									
										
										
										
											2003-06-02 20:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  |   self = PyObject_NEW(VectorObject, &vector_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  |   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; | 
					
						
							|  |  |  |   }else{ | 
					
						
							|  |  |  | 	self->vec = vec; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  |   self->size = size; | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  |   self->flag = 0; | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2003-07-05 01:18:41 +00:00
										 |  |  |   return (PyObject*) self; | 
					
						
							| 
									
										
										
										
											2003-05-17 04:29:49 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-02-29 13:20:34 +00:00
										 |  |  | 
 |