[Bf-python] Matrix object

Joseph Gilbert models at paposo.com
Thu Jan 1 17:22:17 CET 2004


Hello ya'all & :) New Year!

Anyway I was wondering...
In my attempt to create a math utils library for the python API I need to
make support for 3x3 and 4x4 matrices. So in my attempt to do this I have
recreated the Matrix object as a union:

typedef float (*Matrix4Ptr)[4];
typedef float (*Matrix3Ptr)[3];

typedef struct _Matrix {
	PyObject_VAR_HEAD
	union {
		PyObject *rows3[3];
		PyObject *rows4[4];
	}rows;

	union {
		Matrix3Ptr mat3;
		Matrix4Ptr mat4;
	}mat;

	union {
		Matrix3Ptr mem3;
		Matrix4Ptr mem4;
	}mem;

	int size;
} MatrixObject;

This format works well and is modular because you can add more
typedefs/structs to the union if needed - which supports 2x2 or 4x4 matrices
etc.

The size variable can identify which union types to use from the MatrixObect
struct. So you could ask the struct what size it is - if it says "3" than
you know that this struct was initialized as a 3x3 square matrix and to use
the union types associated with it.

It is designed for square matrices, but with an xsize, ysize and some more
typedefs you could easily make the Matrix Object to have any number of row
and column formats within one object type. I didn't add this though because
almost every math function will require a square matrix.

However, you must declare the size of the matrix when you initialize a new
MatrixObject. So, the new declaration for creating a matrix is:
PyObject * newMatrixObject (float * mat, int size)
where float * mat is a pointer to a matrix to initialize with, and size is
the size of the square matrix (either 3x3 or 4x4), and PyObject * is the
pointer to the new MatrixObject created.

Here's the function:
PyObject * newMatrixObject (float * mat, int size)
{
    MatrixObject    * self;

	if (size != 3 && size != 4)
		return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                "You may only attempt to create 3x3 or 4x4 sized matrices...
(newMatrixObject)"));

    self = PyObject_NEW (MatrixObject, &matrix_Type);

	if (size == 4){
		if (mat){
			self->mem.mem4 = NULL;
			self->mat.mat4 = mat;
		}
		else{
			self->mem.mem4 = PyMem_Malloc (4*4*sizeof (float));
			self->mat.mat4 = self->mem.mem4;
		}
		self->size = 4;
	}
	else if (size == 3){
		if (mat){
			self->mem.mem3 = NULL;
			self->mat.mat3 = mat;
		}
		else{
			self->mem.mem3 = PyMem_Malloc (3*3*sizeof (float));
			self->mat.mat3 = self->mem.mem3;
		}
		self->size = 3;
	}

	if (size == 4){
		self->rows.rows4[0] = newVectorObject ((float *)(self->mat.mat4[0]), 4);
		self->rows.rows4[1] = newVectorObject ((float *)(self->mat.mat4[1]), 4);
		self->rows.rows4[2] = newVectorObject ((float *)(self->mat.mat4[2]), 4);
		self->rows.rows4[3] = newVectorObject ((float *)(self->mat.mat4[3]), 4);
	}
	else if (size == 3){
		self->rows.rows3[0] = newVectorObject ((float *)(self->mat.mat3[0]), 3);
		self->rows.rows3[1] = newVectorObject ((float *)(self->mat.mat3[1]), 3);
		self->rows.rows3[2] = newVectorObject ((float *)(self->mat.mat3[2]), 3);
	}

	if (size == 4){
		if ((self->rows.rows4[0] == NULL) ||
			(self->rows.rows4[1] == NULL) ||
			(self->rows.rows4[2] == NULL) ||
			(self->rows.rows4[3] == NULL))
        return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                "Something wrong with creating a 4x4 matrix object
(newMatrixObject)"));
	}
	else if (size == 3){
		if ((self->rows.rows3[0] == NULL) ||
			(self->rows.rows3[1] == NULL) ||
			(self->rows.rows3[2] == NULL))
        return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
                "Something wrong with creating a 3x3 matrix object
(newMatrixObject)"));
    }

    return ((PyObject *)self);
}

If this is o.k. I'll continue working with this. :)




More information about the Bf-python mailing list