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:
authorJoseph Gilbert <ascotan@gmail.com>2005-05-20 23:28:04 +0400
committerJoseph Gilbert <ascotan@gmail.com>2005-05-20 23:28:04 +0400
commit7586eb28a14c1283fdac8d485edf46cabd6219ad (patch)
tree774a811c3dcb7a49113e062d91cf0eb047b2a7fb /source/blender/python/api2_2x/matrix.c
parentd99f64b82346da82f4f1a179c6f3b647f90d44ed (diff)
-rewrite and bugfixes
---------------------------------- Here's my changelog: -fixed Rand() so that it doesn't seed everytime and should generate better random numbers - changed a few error return types to something more appropriate - clean up of uninitialized variables & removal of unneccessary objects - NMesh returns wrapped vectors now - World returns wrapped matrices now - Object.getEuler() and Object.getBoundingBox() return Wrapped data when data is present - Object.getMatrix() returns wrapped data if it's worldspace, 'localspace' returns a new matrix - Vector, Euler, Mat, Quat, call all now internally wrap object without destroying internal datablocks - Removed memory allocation (unneeded) from all methods - Vector's resize methods are only applicable to new vectors not wrapped data. - Matrix(), Quat(), Euler(), Vector() now accepts ANY sequence list, including tuples, list, or a self object to copy - matrices accept multiple sequences - Fixed Slerp() so that it now works correctly values are clamped between 0 and 1 - Euler.rotate does internal rotation now - Slice assignment now works better for all types - Vector * Vector and Quat * Quat are defined and return the DOT product - Mat * Vec and Vec * Mat are defined now - Moved #includes to .c file from headers. Also fixed prototypes in mathutils - Added new helper functions for incref'ing to genutils - Major cleanup of header files includes - include Mathutils.h for access to math types - matrix.toQuat() and .toEuler() now fixed take appropriate matrix sizes - Matrix() with no parameters now returns an identity matrix by default not a zero matrix - printf() now prints with 6 digits instead of 4 - printf() now prints output with object descriptor - Matrices now support [x][y] assignment (e.g. matrix[x][y] = 5.4) - Matrix[index] = value now expectes a sequence not an integer. This will now set a ROW of the matrix through a sequence. index cannot go above the row size of the matrix. - slice operations on matrices work with sequences now (rows of the matrix) example: mymatrix[0:2] returns a list of 2 wrapped vectors with access to the matrix data. - slice assignment will no longer modify the data if the assignment operation fails - fixed error in matrix * scalar multiplication - euler.toMatrix(), toQuat() no longer causes "creep" from repeated use - Wrapped data will generate wrapped objects when toEuler(), toQuat(), toMatrix() is used - Quats can be created with angle/axis, axis/angle - 4x4 matrices can be multiplied by 3D vectors (by popular demand :)) - vec *quat / quat * vec is now defined - vec.magnitude alias for vec.length - all self, internal methods return a pointer to self now so you can do print vector.internalmethod() or vector.internalmethod().nextmethod() (no more print matrix.inverse() returning 'none') - these methods have been deprecated (still functioning but suggested to use the corrected functionality): * CopyVec() - replaced by Vector() functionality * CopyMat() - replaced by Matrix() functionality * CopyQuat() - replace by Quaternion() functionality * CopyEuler() - replaced by Euler() functionality * RotateEuler() - replaced by Euler.rotate() funtionality * MatMultVec() - replaced by matrix * vector * VecMultMat() - replaced by vector * matrix - New struct containers references to python object data or internally allocated blender data for wrapping * Explaination here: math structs now function as a 'simple wrapper' or a 'py_object' - data that is created on the fly will now be a 'py_object' with its memory managed by python * otherwise if the data is returned by blender's G.main then the math object is a 'simple wrapper' and data can be accessed directly from the struct just like other python objects.
Diffstat (limited to 'source/blender/python/api2_2x/matrix.c')
-rw-r--r--source/blender/python/api2_2x/matrix.c1473
1 files changed, 635 insertions, 838 deletions
diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c
index 82391c0c9e5..ff00c6da2b3 100644
--- a/source/blender/python/api2_2x/matrix.c
+++ b/source/blender/python/api2_2x/matrix.c
@@ -28,1007 +28,804 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#include "matrix.h"
+#include <BKE_utildefines.h>
+#include <BLI_arithb.h>
+#include "Mathutils.h"
+#include "gen_utils.h"
-//doc strings
+//-------------------------DOC STRINGS ---------------------------
char Matrix_Zero_doc[] = "() - set all values in the matrix to 0";
-char Matrix_Identity_doc[] =
- "() - set the square matrix to it's identity matrix";
+char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix";
char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose";
char Matrix_Determinant_doc[] = "() - return the determinant of the matrix";
-char Matrix_Invert_doc[] =
- "() - set the matrix to it's inverse if an inverse is possible";
-char Matrix_TranslationPart_doc[] =
- "() - return a vector encompassing the translation of the matrix";
-char Matrix_RotationPart_doc[] =
- "() - return a vector encompassing the rotation of the matrix";
+char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible";
+char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix";
+char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix";
char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix";
char Matrix_toEuler_doc[] = "() - convert matrix to a euler angle rotation";
char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation";
-
-//methods table
+//-----------------------METHOD DEFINITIONS ----------------------
struct PyMethodDef Matrix_methods[] = {
- {"zero", ( PyCFunction ) Matrix_Zero, METH_NOARGS,
- Matrix_Zero_doc},
- {"identity", ( PyCFunction ) Matrix_Identity, METH_NOARGS,
- Matrix_Identity_doc},
- {"transpose", ( PyCFunction ) Matrix_Transpose, METH_NOARGS,
- Matrix_Transpose_doc},
- {"determinant", ( PyCFunction ) Matrix_Determinant, METH_NOARGS,
- Matrix_Determinant_doc},
- {"invert", ( PyCFunction ) Matrix_Invert, METH_NOARGS,
- Matrix_Invert_doc},
- {"translationPart", ( PyCFunction ) Matrix_TranslationPart,
- METH_NOARGS,
- Matrix_TranslationPart_doc},
- {"rotationPart", ( PyCFunction ) Matrix_RotationPart, METH_NOARGS,
- Matrix_RotationPart_doc},
- {"resize4x4", ( PyCFunction ) Matrix_Resize4x4, METH_NOARGS,
- Matrix_Resize4x4_doc},
- {"toEuler", ( PyCFunction ) Matrix_toEuler, METH_NOARGS,
- Matrix_toEuler_doc},
- {"toQuat", ( PyCFunction ) Matrix_toQuat, METH_NOARGS,
- Matrix_toQuat_doc},
+ {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, Matrix_Zero_doc},
+ {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, Matrix_Identity_doc},
+ {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, Matrix_Transpose_doc},
+ {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, Matrix_Determinant_doc},
+ {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, Matrix_Invert_doc},
+ {"translationPart", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, Matrix_TranslationPart_doc},
+ {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc},
+ {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc},
+ {"toEuler", (PyCFunction) Matrix_toEuler, METH_NOARGS, Matrix_toEuler_doc},
+ {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc},
{NULL, NULL, 0, NULL}
};
-
-/*****************************/
-// Matrix Python Object
-/*****************************/
-
-PyObject *Matrix_toQuat( MatrixObject * self )
+//-----------------------------METHODS----------------------------
+//---------------------------Matrix.toQuat() ---------------------
+PyObject *Matrix_toQuat(MatrixObject * self)
{
- float *quat, *mat;
-
- if( self->colSize < 3 ) {
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
- } else if( self->colSize > 2 ) { //3 or 4 col
- if( self->rowSize < 3 ) //3 or 4 row
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
-
- mat = PyMem_Malloc( 3 * 3 * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating matrix\n\n" ) );
- }
- mat[0] = self->matrix[0][0];
- mat[1] = self->matrix[0][1];
- mat[2] = self->matrix[0][2];
- mat[3] = self->matrix[1][0];
- mat[4] = self->matrix[1][1];
- mat[5] = self->matrix[1][2];
- mat[6] = self->matrix[2][0];
- mat[7] = self->matrix[2][1];
- mat[8] = self->matrix[2][2];
+ float quat[4];
+
+ //must be 3-4 cols, 3-4 rows, square matrix
+ if(self->colSize < 3 || self->rowSize < 3 || (self->colSize != self->rowSize)) {
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.toQuat(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
+ }
+ if(self->colSize == 3){
+ Mat3ToQuat((float (*)[3])*self->matrix, quat);
+ }else{
+ Mat4ToQuat((float (*)[4])*self->matrix, quat);
}
- quat = PyMem_Malloc( 4 * sizeof( float ) );
- if( quat == NULL ) {
- PyMem_Free( mat );
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating quat\n\n" ) );
- }
- Mat3ToQuat( ( float ( * )[3] ) mat, quat );
-
- return ( PyObject * ) newQuaternionObject( quat );
+
+ if(self->data.blend_data)
+ return (PyObject *) newQuaternionObject(quat, Py_WRAP);
+ else
+ return (PyObject *) newQuaternionObject(quat, Py_NEW);
}
-
-
-PyObject *Matrix_toEuler( MatrixObject * self )
+//---------------------------Matrix.toEuler() --------------------
+PyObject *Matrix_toEuler(MatrixObject * self)
{
- float *eul, *mat;
+ float eul[3];
int x;
- if( self->colSize < 3 ) {
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
- } else if( self->colSize > 2 ) { //3 or 4 col
- if( self->rowSize < 3 ) //3 or 4 row
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
-
- mat = PyMem_Malloc( 3 * 3 * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- mat[0] = self->matrix[0][0];
- mat[1] = self->matrix[0][1];
- mat[2] = self->matrix[0][2];
- mat[3] = self->matrix[1][0];
- mat[4] = self->matrix[1][1];
- mat[5] = self->matrix[1][2];
- mat[6] = self->matrix[2][0];
- mat[7] = self->matrix[2][1];
- mat[8] = self->matrix[2][2];
- }
- eul = PyMem_Malloc( 3 * sizeof( float ) );
- if( eul == NULL ) {
- PyMem_Free( mat );
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating eul\n\n" ) );
- }
- Mat3ToEul( ( float ( * )[3] ) mat, eul );
-
- for( x = 0; x < 3; x++ ) {
- eul[x] *= ( float ) ( 180 / Py_PI );
- }
-
- return ( PyObject * ) newEulerObject( eul );
+ //must be 3-4 cols, 3-4 rows, square matrix
+ if(self->colSize !=3 || self->rowSize != 3) {
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.toQuat(): inappropriate matrix size - expects 3x3 matrix\n");
+ }
+ Mat3ToEul((float (*)[3])*self->matrix, eul);
+ //have to convert to degrees
+ for(x = 0; x < 3; x++) {
+ eul[x] *= (float) (180 / Py_PI);
+ }
+ if(self->data.blend_data)
+ return (PyObject *) newEulerObject(eul, Py_WRAP);
+ else
+ return (PyObject *) newEulerObject(eul, Py_NEW);
}
-
-PyObject *Matrix_Resize4x4( MatrixObject * self )
+//---------------------------Matrix.resize4x4() ------------------
+PyObject *Matrix_Resize4x4(MatrixObject * self)
{
- float *mat;
- int x, row, col;
-
- if( self->colSize == 4 && self->rowSize == 4 )
- return EXPP_incr_ret( Py_None );
+ int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows;
- mat = PyMem_Malloc( 4 * 4 * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- for( x = 0; x < 16; x++ ) {
- mat[x] = 0.0f;
+ if(self->data.blend_data){
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "cannot resize wrapped data - only python matrices\n");
}
- if( self->colSize == 2 ) { //2x2, 2x3, 2x4
- mat[0] = self->matrix[0][0];
- mat[1] = self->matrix[0][1];
- mat[4] = self->matrix[1][0];
- mat[5] = self->matrix[1][1];
- if( self->rowSize > 2 ) {
- mat[8] = self->matrix[2][0];
- mat[9] = self->matrix[2][1];
- }
- if( self->rowSize > 3 ) {
- mat[12] = self->matrix[3][0];
- mat[13] = self->matrix[3][1];
- }
- mat[10] = 1.0f;
- mat[15] = 1.0f;
- } else if( self->colSize == 3 ) { //3x2, 3x3, 3x4
- mat[0] = self->matrix[0][0];
- mat[1] = self->matrix[0][1];
- mat[2] = self->matrix[0][2];
- mat[4] = self->matrix[1][0];
- mat[5] = self->matrix[1][1];
- mat[6] = self->matrix[1][2];
- if( self->rowSize > 2 ) {
- mat[8] = self->matrix[2][0];
- mat[9] = self->matrix[2][1];
- mat[10] = self->matrix[2][2];
- }
- if( self->rowSize > 3 ) {
- mat[12] = self->matrix[3][0];
- mat[13] = self->matrix[3][1];
- mat[14] = self->matrix[3][2];
- }
- if( self->rowSize == 2 )
- mat[10] = 1.0f;
- mat[15] = 1.0f;
- } else if( self->colSize == 4 ) { //2x4, 3x4
- mat[0] = self->matrix[0][0];
- mat[1] = self->matrix[0][1];
- mat[2] = self->matrix[0][2];
- mat[3] = self->matrix[0][3];
- mat[4] = self->matrix[1][0];
- mat[5] = self->matrix[1][1];
- mat[6] = self->matrix[1][2];
- mat[7] = self->matrix[1][3];
- if( self->rowSize > 2 ) {
- mat[8] = self->matrix[2][0];
- mat[9] = self->matrix[2][1];
- mat[10] = self->matrix[2][2];
- mat[11] = self->matrix[2][3];
- }
- if( self->rowSize == 2 )
- mat[10] = 1.0f;
- mat[15] = 1.0f;
+ self->data.py_data = PyMem_Realloc(self->data.py_data, (sizeof(float) * 16));
+ if(self->data.py_data == NULL) {
+ return EXPP_ReturnPyObjError(PyExc_MemoryError,
+ "matrix.resize4x4(): problem allocating pointer space\n\n");
}
-
- PyMem_Free( self->matrix );
- PyMem_Free( self->contigPtr );
- self->contigPtr = PyMem_Malloc( 4 * 4 * sizeof( float ) );
- if( self->contigPtr == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating array space\n\n" ) );
+ self->contigPtr = self->data.py_data; //force
+ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * 4));
+ if(self->matrix == NULL) {
+ return EXPP_ReturnPyObjError(PyExc_MemoryError,
+ "matrix.resize4x4(): problem allocating pointer space\n\n");
}
- self->matrix = PyMem_Malloc( 4 * sizeof( float * ) );
- if( self->matrix == NULL ) {
- PyMem_Free( self->contigPtr );
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating pointer space\n\n" ) );
+ //set row pointers
+ for(x = 0; x < 4; x++) {
+ self->matrix[x] = self->contigPtr + (x * 4);
}
- for( x = 0; x < 4; x++ ) {
- self->matrix[x] = self->contigPtr + ( x * 4 );
+ //move data to new spot in array + clean
+ for(blank_rows = (4 - self->rowSize); blank_rows > 0; blank_rows--){
+ for(x = 0; x < 4; x++){
+ self->contigPtr[(4 * (self->rowSize + (blank_rows - 1))) + x] = 0.0f;
+ }
}
-
- for( row = 0; row < 4; row++ ) {
- for( col = 0; col < 4; col++ ) {
- self->matrix[row][col] = mat[( row * 4 ) + col];
+ for(x = 1; x <= self->rowSize; x++){
+ first_row_elem = (self->colSize * (self->rowSize - x));
+ curr_pos = (first_row_elem + (self->colSize -1));
+ new_pos = (4 * (self->rowSize - x )) + (curr_pos - first_row_elem);
+ for(blank_columns = (4 - self->colSize); blank_columns > 0; blank_columns--){
+ self->contigPtr[new_pos + blank_columns] = 0.0f;
+ }
+ for(curr_pos; curr_pos >= first_row_elem; curr_pos--){
+ self->contigPtr[new_pos] = self->contigPtr[curr_pos];
+ new_pos--;
}
}
- PyMem_Free( mat );
-
- self->colSize = 4;
self->rowSize = 4;
-
- return EXPP_incr_ret( Py_None );
+ self->colSize = 4;
+ return (PyObject*)self;
}
-
-PyObject *Matrix_TranslationPart( MatrixObject * self )
+//---------------------------Matrix.translationPart() ------------
+PyObject *Matrix_TranslationPart(MatrixObject * self)
{
- float *vec = NULL;
- PyObject *retval;
+ float vec[4];
- if( self->colSize < 3 ) {
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
- } else if( self->colSize > 2 ) { //3 or 4 columns
- if( self->rowSize < 4 ) //all 4 rows
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
-
- vec = PyMem_Malloc( 3 * sizeof( float ) );
- if( vec == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating vec\n\n" ) );
- }
- vec[0] = self->matrix[3][0];
- vec[1] = self->matrix[3][1];
- vec[2] = self->matrix[3][2];
+ if(self->colSize < 3 && self->rowSize < 4){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.translationPart: inappropriate matrix size\n");
}
- retval = ( PyObject * ) newVectorObject( vec, 3 );
- PyMem_Free( vec );
- return retval;
-}
+ vec[0] = self->matrix[3][0];
+ vec[1] = self->matrix[3][1];
+ vec[2] = self->matrix[3][2];
-PyObject *Matrix_RotationPart( MatrixObject * self )
+ return newVectorObject(vec, 3, Py_NEW);
+}
+//---------------------------Matrix.rotationPart() ---------------
+PyObject *Matrix_RotationPart(MatrixObject * self)
{
- float *mat;
-
- if( self->colSize < 3 ) {
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
- } else if( self->colSize > 2 ) { //3 or 4 col
- if( self->rowSize < 3 ) //3 or 4 row
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "inappropriate matrix size\n" );
+ float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
- mat = PyMem_Malloc( 3 * 3 * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- mat[0] = self->matrix[0][0];
- mat[1] = self->matrix[0][1];
- mat[2] = self->matrix[0][2];
- mat[3] = self->matrix[1][0];
- mat[4] = self->matrix[1][1];
- mat[5] = self->matrix[1][2];
- mat[6] = self->matrix[2][0];
- mat[7] = self->matrix[2][1];
- mat[8] = self->matrix[2][2];
+ if(self->colSize < 3 && self->rowSize < 3){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.rotationPart: inappropriate matrix size\n");
}
- return ( PyObject * ) newMatrixObject( mat, 3, 3 );
-}
+ mat[0] = self->matrix[0][0];
+ mat[1] = self->matrix[0][1];
+ mat[2] = self->matrix[0][2];
+ mat[3] = self->matrix[1][0];
+ mat[4] = self->matrix[1][1];
+ mat[5] = self->matrix[1][2];
+ mat[6] = self->matrix[2][0];
+ mat[7] = self->matrix[2][1];
+ mat[8] = self->matrix[2][2];
-PyObject *Matrix_Invert( MatrixObject * self )
+ return newMatrixObject(mat, 3, 3, Py_NEW);
+}
+//---------------------------Matrix.invert() ---------------------
+PyObject *Matrix_Invert(MatrixObject * self)
{
- float det;
- int x, y, z;
- float *mat = NULL;
- float t;
-
- if( self->rowSize != self->colSize )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "only square matrices are supported\n" );
+
+ int x, y, z = 0;
+ float det = 0.0f;
+ PyObject *f = NULL;
+ float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
- //calculate the determinant
- if( self->rowSize == 2 ) {
- det = Det2x2( self->matrix[0][0], self->matrix[0][1],
- self->matrix[1][0], self->matrix[1][1] );
- } else if( self->rowSize == 3 ) {
- det = Det3x3( self->matrix[0][0], self->matrix[0][1],
- self->matrix[0][2], self->matrix[1][0],
- self->matrix[1][1], self->matrix[1][2],
- self->matrix[2][0], self->matrix[2][1],
- self->matrix[2][2] );
- } else if( self->rowSize == 4 ) {
- det = Det4x4( (float ( * )[4]) *self->matrix );
- } else {
- return EXPP_ReturnPyObjError( PyExc_StandardError,
- "error calculating determinant for inverse()\n" );
+ if(self->rowSize != self->colSize){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.invert: only square matrices are supported\n");
}
- if( det != 0 ) {
+ //calculate the determinant
+ f = Matrix_Determinant(self);
+ det = PyFloat_AS_DOUBLE(f);
+ if(det != 0) {
//calculate the classical adjoint
- if( self->rowSize == 2 ) {
- mat = PyMem_Malloc( self->rowSize * self->colSize *
- sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError
- ( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
+ if(self->rowSize == 2) {
mat[0] = self->matrix[1][1];
mat[1] = -self->matrix[1][0];
mat[2] = -self->matrix[0][1];
mat[3] = self->matrix[0][0];
- } else if( self->rowSize == 3 ) {
- mat = PyMem_Malloc( self->rowSize * self->colSize *
- sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError
- ( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- Mat3Adj( ( float ( * )[3] ) mat,( float ( * )[3] ) *self->matrix );
- } else if( self->rowSize == 4 ) {
- mat = PyMem_Malloc( self->rowSize * self->colSize *
- sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError
- ( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- Mat4Adj( ( float ( * )[4] ) mat, ( float ( * )[4] ) *self->matrix );
+ } else if(self->rowSize == 3) {
+ Mat3Adj((float (*)[3]) mat,(float (*)[3]) *self->matrix);
+ } else if(self->rowSize == 4) {
+ Mat4Adj((float (*)[4]) mat, (float (*)[4]) *self->matrix);
}
//divide by determinate
- for( x = 0; x < ( self->rowSize * self->colSize ); x++ ) {
+ for(x = 0; x < (self->rowSize * self->colSize); x++) {
mat[x] /= det;
}
-
//set values
- z = 0;
- for( x = 0; x < self->rowSize; x++ ) {
- for( y = 0; y < self->colSize; y++ ) {
+ for(x = 0; x < self->rowSize; x++) {
+ for(y = 0; y < self->colSize; y++) {
self->matrix[x][y] = mat[z];
z++;
}
}
-
//transpose
- if( self->rowSize == 2 ) {
- t = self->matrix[1][0];
- self->matrix[1][0] = self->matrix[0][1];
- self->matrix[0][1] = t;
-
-/*
- Note: is the code below correct?
- transposing mat and not copying into self->matrix?
- s. swaney 11-oct-2004
-*/
- } else if( self->rowSize == 3 ) {
- Mat3Transp( ( float ( * )[3] ) mat );
- } else if( self->rowSize == 4 ) {
- Mat4Transp( ( float ( * )[4] ) mat );
- }
+ Matrix_Transpose(self);
} else {
- printf( "matrix does not have an inverse - none attempted\n" );
+ printf("Matrix.invert: matrix does not have an inverse\n");
}
- PyMem_Free( mat );
- return EXPP_incr_ret( Py_None );
+ return (PyObject*)self;
}
-
-
-PyObject *Matrix_Determinant( MatrixObject * self )
+//---------------------------Matrix.determinant() ----------------
+PyObject *Matrix_Determinant(MatrixObject * self)
{
- float det;
-
- if( self->rowSize != self->colSize )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "only square matrices are supported\n" );
-
- if( self->rowSize == 2 ) {
- det = Det2x2( self->matrix[0][0], self->matrix[0][1],
- self->matrix[1][0], self->matrix[1][1] );
- } else if( self->rowSize == 3 ) {
- det = Det3x3( self->matrix[0][0], self->matrix[0][1],
- self->matrix[0][2], self->matrix[1][0],
- self->matrix[1][1], self->matrix[1][2],
- self->matrix[2][0], self->matrix[2][1],
- self->matrix[2][2] );
- } else if( self->rowSize == 4 ) {
- det = Det4x4( (float ( * )[4]) *self->matrix );
+ float det = 0.0f;
+
+ if(self->rowSize != self->colSize){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.determinant: only square matrices are supported\n");
+ }
+
+ if(self->rowSize == 2) {
+ det = Det2x2(self->matrix[0][0], self->matrix[0][1],
+ self->matrix[1][0], self->matrix[1][1]);
+ } else if(self->rowSize == 3) {
+ det = Det3x3(self->matrix[0][0], self->matrix[0][1],
+ self->matrix[0][2], self->matrix[1][0],
+ self->matrix[1][1], self->matrix[1][2],
+ self->matrix[2][0], self->matrix[2][1],
+ self->matrix[2][2]);
} else {
- return EXPP_ReturnPyObjError( PyExc_StandardError,
- "error in determinant()\n" );
+ det = Det4x4((float (*)[4]) *self->matrix);
}
- return PyFloat_FromDouble( det );
-}
-PyObject *Matrix_Transpose( MatrixObject * self )
+ return (PyObject*)self;
+}
+//---------------------------Matrix.transpose() ------------------
+PyObject *Matrix_Transpose(MatrixObject * self)
{
- float t;
+ float t = 0.0f;
- if( self->rowSize != self->colSize )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "only square matrices are supported\n" );
+ if(self->rowSize != self->colSize){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.transpose: only square matrices are supported\n");
+ }
- if( self->rowSize == 2 ) {
+ if(self->rowSize == 2) {
t = self->matrix[1][0];
self->matrix[1][0] = self->matrix[0][1];
self->matrix[0][1] = t;
- } else if( self->rowSize == 3 ) {
- Mat3Transp( (float ( * )[3])*self->matrix );
- } else if( self->rowSize == 4 ) {
- Mat4Transp( (float ( * )[4])*self->matrix );
- } else
- return ( EXPP_ReturnPyObjError( PyExc_TypeError,
- "unable to transpose matrix\n" ) );
+ } else if(self->rowSize == 3) {
+ Mat3Transp((float (*)[3])*self->matrix);
+ } else {
+ Mat4Transp((float (*)[4])*self->matrix);
+ }
- return EXPP_incr_ret( Py_None );
+ return (PyObject*)self;
}
-
-PyObject *Matrix_Zero( MatrixObject * self )
+//---------------------------Matrix.zero() -----------------------
+PyObject *Matrix_Zero(MatrixObject * self)
{
int row, col;
- for( row = 0; row < self->rowSize; row++ ) {
- for( col = 0; col < self->colSize; col++ ) {
+ for(row = 0; row < self->rowSize; row++) {
+ for(col = 0; col < self->colSize; col++) {
self->matrix[row][col] = 0.0f;
}
}
- return EXPP_incr_ret( Py_None );
+ return (PyObject*)self;
}
-
-PyObject *Matrix_Identity( MatrixObject * self )
+//---------------------------Matrix.identity(() ------------------
+PyObject *Matrix_Identity(MatrixObject * self)
{
- if( self->rowSize != self->colSize )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "only square matrices supported\n" ) );
+ if(self->rowSize != self->colSize){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix.identity: only square matrices are supported\n");
+ }
- if( self->rowSize == 2 ) {
+ if(self->rowSize == 2) {
self->matrix[0][0] = 1.0f;
self->matrix[0][1] = 0.0f;
self->matrix[1][0] = 0.0f;
self->matrix[1][1] = 1.0f;
- } else if( self->rowSize == 3 ) {
- Mat3One( ( float ( * )[3] ) *self->matrix );
- } else if( self->rowSize == 4 ) {
- Mat4One( ( float ( * )[4] ) *self->matrix );
- } else
- return ( EXPP_ReturnPyObjError( PyExc_TypeError,
- "unable to create identity matrix\n" ) );
+ } else if(self->rowSize == 3) {
+ Mat3One((float (*)[3]) *self->matrix);
+ } else {
+ Mat4One((float (*)[4]) *self->matrix);
+ }
- return EXPP_incr_ret( Py_None );
+ return (PyObject*)self;
}
-
-static void Matrix_dealloc( MatrixObject * self )
+//----------------------------dealloc()(internal) ----------------
+//free the py_object
+static void Matrix_dealloc(MatrixObject * self)
{
- PyMem_Free( self->contigPtr );
- PyMem_Free( self->matrix );
-
- PyObject_DEL( self );
+ Py_XDECREF(self->coerced_object);
+ PyMem_Free(self->matrix);
+ //only free py_data
+ if(self->data.py_data){
+ PyMem_Free(self->data.py_data);
+ }
+ PyObject_DEL(self);
}
-
-static PyObject *Matrix_getattr( MatrixObject * self, char *name )
+//----------------------------getattr()(internal) ----------------
+//object.attribute access (get)
+static PyObject *Matrix_getattr(MatrixObject * self, char *name)
{
- if( strcmp( name, "rowSize" ) == 0 ) {
- return PyInt_FromLong( ( long ) self->rowSize );
- } else if( strcmp( name, "colSize" ) == 0 ) {
- return PyInt_FromLong( ( long ) self->colSize );
+ if(STREQ(name, "rowSize")) {
+ return PyInt_FromLong((long) self->rowSize);
+ } else if(STREQ(name, "colSize")) {
+ return PyInt_FromLong((long) self->colSize);
}
- return Py_FindMethod( Matrix_methods, ( PyObject * ) self, name );
+ return Py_FindMethod(Matrix_methods, (PyObject *) self, name);
}
-
-static int Matrix_setattr( MatrixObject * self, char *name, PyObject * v )
+//----------------------------setattr()(internal) ----------------
+//object.attribute access (set)
+static int Matrix_setattr(MatrixObject * self, char *name, PyObject * v)
{
/* This is not supported. */
- return ( -1 );
+ return (-1);
}
-
-static PyObject *Matrix_repr( MatrixObject * self )
+//----------------------------print object (internal)-------------
+//print the object to screen
+static PyObject *Matrix_repr(MatrixObject * self)
{
- PyObject *repr, *str;
int x, y;
- char ftoa[24];
-
- repr = PyString_FromString( "" );
- if( !repr )
- return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
- "Attribute error in PyMatrix (repr)\n" ) );
-
- for( x = 0; x < self->rowSize; x++ ) {
- str = PyString_FromString( "[" );
- PyString_ConcatAndDel( &repr, str );
-
- for( y = 0; y < ( self->colSize - 1 ); y++ ) {
- sprintf( ftoa, "%.4f, ", self->matrix[x][y] );
- str = PyString_FromString( ftoa );
- PyString_ConcatAndDel( &repr, str );
+ char buffer[48], str[1024];
+
+ BLI_strncpy(str,"",1024);
+ for(x = 0; x < self->rowSize; x++){
+ sprintf(buffer, "[", x);
+ strcat(str,buffer);
+ for(y = 0; y < (self->colSize - 1); y++) {
+ sprintf(buffer, "%.6f, ", self->matrix[x][y]);
+ strcat(str,buffer);
+ }
+ if(x < (self->rowSize-1)){
+ sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[x][y], x);
+ strcat(str,buffer);
+ }else{
+ sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[x][y], x);
+ strcat(str,buffer);
}
- sprintf( ftoa, "%.4f]\n", self->matrix[x][y] );
- str = PyString_FromString( ftoa );
- PyString_ConcatAndDel( &repr, str );
}
- return repr;
+
+ return EXPP_incr_ret(PyString_FromString(str));
}
-//no support for matrix[x][y] so have to return by sequence index
-//will return a row from the matrix to support previous API
-//compatability
-static PyObject *Matrix_item( MatrixObject * self, int i )
+//---------------------SEQUENCE PROTOCOLS------------------------
+//----------------------------len(object)------------------------
+//sequence length
+static int Matrix_len(MatrixObject * self)
{
- float *vec = NULL;
- PyObject *retval;
- int x;
-
- if( i < 0 || i >= self->rowSize )
- return EXPP_ReturnPyObjError( PyExc_IndexError,
- "matrix row index out of range\n" );
-
- vec = PyMem_Malloc( self->colSize * sizeof( float ) );
- if( vec == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating vec\n\n" ) );
- }
- for( x = 0; x < self->colSize; x++ ) {
- vec[x] = self->matrix[i][x];
- }
-
- retval =( PyObject * ) newVectorObject( vec, self->colSize );
- PyMem_Free( vec );
- return retval;
+ return (self->colSize * self->rowSize);
}
-
-static PyObject *Matrix_slice( MatrixObject * self, int begin, int end )
+//----------------------------object[]---------------------------
+//sequence accessor (get)
+//the wrapped vector gives direct access to the matrix data
+static PyObject *Matrix_item(MatrixObject * self, int i)
{
- PyObject *list;
- int count, maxsize, x, y;
-
- maxsize = self->colSize * self->rowSize;
- if( begin < 0 )
- begin = 0;
- if( end > maxsize )
- end = maxsize;
- if( begin > end )
- begin = end;
+ if(i < 0 || i >= self->rowSize)
+ return EXPP_ReturnPyObjError(PyExc_IndexError,
+ "matrix[attribute]: array index out of range\n");
- list = PyList_New( end - begin );
-
- for( count = begin; count < end; count++ ) {
- x = ( int ) floor( ( double ) ( count / self->colSize ) );
- y = count % self->colSize;
- PyList_SetItem( list, count - begin,
- PyFloat_FromDouble( self->matrix[x][y] ) );
- }
-
- return list;
+ return newVectorObject(self->matrix[i], self->colSize, Py_WRAP);
}
-
-static int Matrix_ass_item( MatrixObject * self, int i, PyObject * ob )
+//----------------------------object[]-------------------------
+//sequence accessor (set)
+static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
{
- int maxsize, x, y;
+ int y, x, size = 0;
+ float vec[4];
- maxsize = self->colSize * self->rowSize;
- if( i < 0 || i >= maxsize )
- return EXPP_ReturnIntError( PyExc_IndexError,
- "array assignment index out of range\n" );
- if( !PyInt_Check( ob ) && !PyFloat_Check( ob ) )
- return EXPP_ReturnIntError( PyExc_IndexError,
- "matrix member must be a number\n" );
+ if(i > self->rowSize || i < 0){
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[attribute] = x: bad row\n");
+ }
- x = ( int ) floor( ( double ) ( i / self->colSize ) );
- y = i % self->colSize;
- self->matrix[x][y] = ( float ) PyFloat_AsDouble( ob );
+ if(PySequence_Check(ob)){
+ size = PySequence_Length(ob);
+ if(size != self->colSize){
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[attribute] = x: bad sequence size\n");
+ }
+ for (x = 0; x < size; x++) {
+ PyObject *m, *f;
- return 0;
+ m = PySequence_GetItem(ob, x);
+ if (m == NULL) { // Failed to read sequence
+ return EXPP_ReturnIntError(PyExc_RuntimeError,
+ "matrix[attribute] = x: unable to read sequence\n");
+ }
+ f = PyNumber_Float(m);
+ if(f == NULL) { // parsed item not a number
+ Py_DECREF(m);
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[attribute] = x: sequence argument not a number\n");
+ }
+ vec[x] = PyFloat_AS_DOUBLE(f);
+ EXPP_decr2(m, f);
+ }
+ //parsed well - now set in matrix
+ for(y = 0; y < size; y++){
+ self->matrix[i][y] = vec[y];
+ }
+ return 0;
+ }else{
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[attribute] = x: expects a sequence of column size\n");
+ }
}
-
-static int Matrix_ass_slice( MatrixObject * self, int begin, int end,
- PyObject * seq )
+//----------------------------object[z:y]------------------------
+//sequence slice (get)
+static PyObject *Matrix_slice(MatrixObject * self, int begin, int end)
{
- int count, maxsize, x, y, z;
-
- maxsize = self->colSize * self->rowSize;
- if( begin < 0 )
- begin = 0;
- if( end > maxsize )
- end = maxsize;
- 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" );
+ PyObject *list = NULL;
+ int count;
- 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" );
+ CLAMP(begin, 0, self->rowSize);
+ CLAMP(end, 0, self->rowSize);
+ begin = MIN2(begin,end);
- x = ( int ) floor( ( double ) ( count / self->colSize ) );
- y = count % self->colSize;
- if( !PyArg_Parse( ob, "f", &self->matrix[x][y] ) ) {
- Py_DECREF( ob );
- return -1;
- }
+ list = PyList_New(end - begin);
+ for(count = begin; count < end; count++) {
+ PyList_SetItem(list, count - begin,
+ newVectorObject(self->matrix[count], self->colSize, Py_WRAP));
}
- return 0;
-}
-static int Matrix_len( MatrixObject * self )
+ return EXPP_incr_ret(list);
+}
+//----------------------------object[z:y]------------------------
+//sequence slice (set)
+static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
+ PyObject * seq)
{
- return ( self->colSize * self->rowSize );
+ int i, x, y, size, sub_size;
+ float mat[16];
+
+ CLAMP(begin, 0, self->rowSize);
+ CLAMP(end, 0, self->rowSize);
+ begin = MIN2(begin,end);
+
+ if(PySequence_Check(seq)){
+ size = PySequence_Length(seq);
+ if(size != (end - begin)){
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[begin:end] = []: size mismatch in slice assignment\n");
+ }
+ //parse sub items
+ for (i = 0; i < size; i++) {
+ //parse each sub sequence
+ PyObject *subseq;
+ subseq = PySequence_GetItem(seq, i);
+ if (subseq == NULL) { // Failed to read sequence
+ return EXPP_ReturnIntError(PyExc_RuntimeError,
+ "matrix[begin:end] = []: unable to read sequence\n");
+ }
+ if(PySequence_Check(subseq)){
+ //subsequence is also a sequence
+ sub_size = PySequence_Length(subseq);
+ if(sub_size != self->colSize){
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[begin:end] = []: size mismatch in slice assignment\n");
+ }
+ for (y = 0; y < sub_size; y++) {
+ PyObject *m, *f;
+ m = PySequence_GetItem(subseq, y);
+ if (m == NULL) { // Failed to read sequence
+ return EXPP_ReturnIntError(PyExc_RuntimeError,
+ "matrix[begin:end] = []: unable to read sequence\n");
+ }
+ f = PyNumber_Float(m);
+ if(f == NULL) { // parsed item not a number
+ Py_DECREF(m);
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[begin:end] = []: sequence argument not a number\n");
+ }
+ mat[(i * self->colSize) + y] = PyFloat_AS_DOUBLE(f);
+ EXPP_decr2(f, m);
+ }
+ }else{
+ Py_DECREF(subseq);
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[begin:end] = []: illegal argument type for built-in operation\n");
+ }
+ }
+ //parsed well - now set in matrix
+ for(x = 0; x < (size * sub_size); x++){
+ self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x];
+ }
+ return 0;
+ }else{
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix[begin:end] = []: illegal argument type for built-in operation\n");
+ }
}
-
-static PyObject *Matrix_add( PyObject * m1, PyObject * m2 )
+//------------------------NUMERIC PROTOCOLS----------------------
+//------------------------obj + obj------------------------------
+static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
{
- float *mat;
- int matSize, rowSize, colSize, x, y;
-
- if( ( !Matrix_CheckPyObject( m1 ) )
- || ( !Matrix_CheckPyObject( m2 ) ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "unsupported type for this operation\n" );
-
- if( ( ( MatrixObject * ) m1 )->flag > 0
- || ( ( MatrixObject * ) m2 )->flag > 0 )
- return EXPP_ReturnPyObjError( PyExc_ArithmeticError,
- "cannot add scalar to a matrix\n" );
-
- if( ( ( MatrixObject * ) m1 )->rowSize !=
- ( ( MatrixObject * ) m2 )->rowSize
- || ( ( MatrixObject * ) m1 )->colSize !=
- ( ( MatrixObject * ) m2 )->colSize )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "matrices must be the same same for this operation\n" );
+ int x, y;
+ float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
- rowSize = ( ( ( MatrixObject * ) m1 )->rowSize );
- colSize = ( ( ( MatrixObject * ) m1 )->colSize );
- matSize = rowSize * colSize;
+ EXPP_incr2(m1, m2);
+ mat1 = (MatrixObject*)m1;
+ mat2 = (MatrixObject*)m2;
- mat = PyMem_Malloc( matSize * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
+ if(mat1->coerced_object || mat2->coerced_object){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix addition: arguments not valid for this operation....\n");
+ }
+ if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix addition: matrices must have the same dimensions for this operation\n");
}
- for( x = 0; x < rowSize; x++ ) {
- for( y = 0; y < colSize; y++ ) {
- mat[( ( x * rowSize ) + y )] =
- ( ( MatrixObject * ) m1 )->matrix[x][y] +
- ( ( MatrixObject * ) m2 )->matrix[x][y];
+
+ for(x = 0; x < mat1->rowSize; x++) {
+ for(y = 0; y < mat1->colSize; y++) {
+ mat[((x * mat1->colSize) + y)] = mat1->matrix[x][y] + mat2->matrix[x][y];
}
}
- return newMatrixObject( mat, rowSize, colSize );
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW);
}
-
-static PyObject *Matrix_sub( PyObject * m1, PyObject * m2 )
+//------------------------obj - obj------------------------------
+//subtraction
+static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
{
- float *mat;
- int matSize, rowSize, colSize, x, y;
-
- if( ( !Matrix_CheckPyObject( m1 ) )
- || ( !Matrix_CheckPyObject( m2 ) ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "unsupported type for this operation\n" );
-
- if( ( ( MatrixObject * ) m1 )->flag > 0
- || ( ( MatrixObject * ) m2 )->flag > 0 )
- return EXPP_ReturnPyObjError( PyExc_ArithmeticError,
- "cannot subtract a scalar from a matrix\n" );
-
- if( ( ( MatrixObject * ) m1 )->rowSize !=
- ( ( MatrixObject * ) m2 )->rowSize
- || ( ( MatrixObject * ) m1 )->colSize !=
- ( ( MatrixObject * ) m2 )->colSize )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "matrices must be the same same for this operation\n" );
+ int x, y;
+ float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
- rowSize = ( ( ( MatrixObject * ) m1 )->rowSize );
- colSize = ( ( ( MatrixObject * ) m1 )->colSize );
- matSize = rowSize * colSize;
+ EXPP_incr2(m1, m2);
+ mat1 = (MatrixObject*)m1;
+ mat2 = (MatrixObject*)m2;
- mat = PyMem_Malloc( matSize * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
+ if(mat1->coerced_object || mat2->coerced_object){
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix addition: arguments not valid for this operation....\n");
+ }
+ if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix addition: matrices must have the same dimensions for this operation\n");
}
- for( x = 0; x < rowSize; x++ ) {
- for( y = 0; y < colSize; y++ ) {
- mat[( ( x * rowSize ) + y )] =
- ( ( MatrixObject * ) m1 )->matrix[x][y] -
- ( ( MatrixObject * ) m2 )->matrix[x][y];
+
+ for(x = 0; x < mat1->rowSize; x++) {
+ for(y = 0; y < mat1->colSize; y++) {
+ mat[((x * mat1->colSize) + y)] = mat1->matrix[x][y] - mat2->matrix[x][y];
}
}
- return newMatrixObject( mat, rowSize, colSize );
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW);
}
-
-static PyObject *Matrix_mul( PyObject * m1, PyObject * m2 )
+//------------------------obj * obj------------------------------
+//mulplication
+static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
{
- PyObject *retval;
- int matSizeV, rowSizeV, colSizeV, rowSizeW, colSizeW, matSizeW, x, y,z;
- MatrixObject *matV;
- MatrixObject *matW;
- float *mat = NULL;
- float dot = 0;
-
-
- if( ( !Matrix_CheckPyObject( m1 ) )
- || ( !Matrix_CheckPyObject( m2 ) ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "unsupported type for this operation\n" );
-
- //get some vars
- rowSizeV = ( ( ( MatrixObject * ) m1 )->rowSize );
- colSizeV = ( ( ( MatrixObject * ) m1 )->colSize );
- matSizeV = rowSizeV * colSizeV;
- rowSizeW = ( ( ( MatrixObject * ) m2 )->rowSize );
- colSizeW = ( ( ( MatrixObject * ) m2 )->colSize );
- matSizeW = rowSizeW * colSizeW;
- matV = ( ( MatrixObject * ) m1 );
- matW = ( ( MatrixObject * ) m2 );
-
- //coerced int or float for scalar multiplication
- if( matW->flag > 1 || matW->flag > 2 ) {
-
- if( rowSizeV != rowSizeW && colSizeV != colSizeW )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "Matrix dimension error during scalar multiplication\n" );
-
- mat = PyMem_Malloc( matSizeV * sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- for( x = 0; x < rowSizeV; x++ ) {
- for( y = 0; y < colSizeV; y++ ) {
- mat[( ( x * rowSizeV ) + y )] =
- matV->matrix[x][y] *
- matW->matrix[x][y];
+ int x, y, z;
+ float scalar;
+ float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+ double dot = 0.0f;
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
+ PyObject *f = NULL, *retObj = NULL;
+ VectorObject *vec = NULL;
+
+ EXPP_incr2(m1, m2);
+ mat1 = (MatrixObject*)m1;
+ mat2 = (MatrixObject*)m2;
+
+ if(mat1->coerced_object){
+ if (PyFloat_Check(mat1->coerced_object) ||
+ PyInt_Check(mat1->coerced_object)){ // FLOAT/INT * MATRIX
+ f = PyNumber_Float(mat1->coerced_object);
+ if(f == NULL) { // parsed item not a number
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "Matrix multiplication: arguments not acceptable for this operation\n");
}
- }
- retval = ( PyObject* ) newMatrixObject( mat, rowSizeV, colSizeV );
- PyMem_Free( mat );
- return retval;
- } else if( matW->flag == 0 && matV->flag == 0 ) { //true matrix multiplication
- if( colSizeV != rowSizeW ) {
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "Matrix multiplication undefined...\n" );
- }
-
- mat = PyMem_Malloc( ( rowSizeV * colSizeW ) *
- sizeof( float ) );
- if( mat == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- for( x = 0; x < rowSizeV; x++ ) {
- for( y = 0; y < colSizeW; y++ ) {
- for( z = 0; z < colSizeV; z++ ) {
- dot += ( matV->matrix[x][z] *
- matW->matrix[z][y] );
+ scalar = PyFloat_AS_DOUBLE(f);
+ for(x = 0; x < mat2->rowSize; x++) {
+ for(y = 0; y < mat2->colSize; y++) {
+ mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y];
}
- mat[( ( x * rowSizeV ) + y )] = dot;
- dot = 0;
}
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW);
}
- retval = ( PyObject* ) newMatrixObject( mat, rowSizeV, colSizeW );
- PyMem_Free( mat );
- return retval;
- } else
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "Error in matrix_mul...\n" );
-}
-
-//coercion of unknown types to type MatrixObject for numeric protocols
-static int Matrix_coerce( PyObject ** m1, PyObject ** m2 )
-{
- long *tempI;
- double *tempF;
- float *mat;
- int x, matSize;
-
- matSize =
- ( ( ( MatrixObject * ) * m1 )->rowSize ) *
- ( ( ( MatrixObject * ) * m1 )->rowSize );
- if( Matrix_CheckPyObject( *m1 ) ) {
- if( Matrix_CheckPyObject( *m2 ) ) { //matrix & matrix
- Py_INCREF( *m1 );
- Py_INCREF( *m2 );
- return 0;
- } else {
- if( VectorObject_Check( *m2 ) ) { //matrix & vector?
- printf( "use MatMultVec() for column vector multiplication\n" );
- Py_INCREF( *m1 );
- return 0;
- } else if( PyNumber_Check( *m2 ) ) { //& scalar?
- if( PyInt_Check( *m2 ) ) { //it's a int
- tempI = PyMem_Malloc( 1 *
- sizeof( long ) );
- if( tempI == NULL ) {
- return ( EXPP_ReturnIntError
- ( PyExc_MemoryError,
- "problem allocating tempI\n\n" ) );
- }
- *tempI = PyInt_AsLong( *m2 );
- mat = PyMem_Malloc( matSize *
- sizeof( float ) );
- if( mat == NULL ) {
- PyMem_Free( tempI );
- return ( EXPP_ReturnIntError
- ( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
- }
- for( x = 0; x < matSize; x++ ) {
- mat[x] = ( float ) *tempI;
- }
- PyMem_Free( tempI );
- *m2 = newMatrixObject( mat,
- ( ( ( MatrixObject * ) * m1 )->rowSize ), ( ( ( MatrixObject * ) * m1 )->colSize ) );
- ( ( MatrixObject * ) * m2 )->flag = 1; //int coercion
- PyMem_Free( mat );
- Py_INCREF( *m1 );
- return 0;
- } else if( PyFloat_Check( *m2 ) ) { //it's a float
- tempF = PyMem_Malloc( 1 *
- sizeof
- ( double ) );
- if( tempF == NULL ) {
- return ( EXPP_ReturnIntError
- ( PyExc_MemoryError,
- "problem allocating tempF\n\n" ) );
- }
- *tempF = PyFloat_AsDouble( *m2 );
- mat = PyMem_Malloc( matSize *
- sizeof( float ) );
- if( mat == NULL ) {
- PyMem_Free( tempF );
- return ( EXPP_ReturnIntError
- ( PyExc_MemoryError,
- "problem allocating mat\n\n" ) );
+ }else{
+ if(mat2->coerced_object){
+ if(VectorObject_Check(mat2->coerced_object)){ //MATRIX * VECTOR
+ vec = (VectorObject*)EXPP_incr_ret(mat2->coerced_object);
+ retObj = column_vector_multiplication(mat1, vec);
+ EXPP_decr3((PyObject*)mat1, (PyObject*)mat2, (PyObject*)vec);
+ return retObj;
+ }else if (PyFloat_Check(mat2->coerced_object) ||
+ PyInt_Check(mat2->coerced_object)){ // MATRIX * FLOAT/INT
+ f = PyNumber_Float(mat2->coerced_object);
+ if(f == NULL) { // parsed item not a number
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "Matrix multiplication: arguments not acceptable for this operation\n");
+ }
+ scalar = PyFloat_AS_DOUBLE(f);
+ for(x = 0; x < mat1->rowSize; x++) {
+ for(y = 0; y < mat1->colSize; y++) {
+ mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y];
}
- for( x = 0; x < matSize; x++ ) {
- mat[x] = ( float ) *tempF;
+ }
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW);
+ }
+ }else{ //MATRIX * MATRIX
+ if(mat1->colSize != mat2->rowSize){
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return EXPP_ReturnPyObjError(PyExc_AttributeError,
+ "Matrix multiplication: matrix A rowsize must equal matrix B colsize\n");
+ }
+ for(x = 0; x < mat1->rowSize; x++) {
+ for(y = 0; y < mat2->colSize; y++) {
+ for(z = 0; z < mat1->colSize; z++) {
+ dot += (mat1->matrix[x][z] * mat2->matrix[z][y]);
}
- PyMem_Free( tempF );
- *m2 = newMatrixObject( mat,
- ( ( ( MatrixObject * ) * m1 )->rowSize ), ( ( ( MatrixObject * ) * m1 )->colSize ) );
- ( ( MatrixObject * ) * m2 )->flag = 2; //float coercion
- PyMem_Free( mat );
- Py_INCREF( *m1 );
- return 0;
+ mat[((x * mat1->rowSize) + y)] = dot;
+ dot = 0.0f;
}
}
- //unknom2n type or numeric cast failure
- printf( "attempting matrix operation m2ith unsupported type...\n" );
- Py_INCREF( *m1 );
- return 0; //operation m2ill type check
+ return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW);
}
- } else {
- //1st not Matrix
- printf( "numeric protocol failure...\n" );
- return -1; //this should not occur - fail
}
- return -1;
-}
-//******************************************************************
-// Matrix definition
-//******************************************************************
+ EXPP_decr2((PyObject*)mat1, (PyObject*)mat2);
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "Matrix multiplication: arguments not acceptable for this operation\n");
+}
+//------------------------coerce(obj, obj)-----------------------
+//coercion of unknown types to type MatrixObject 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 Matrix_coerce(PyObject ** m1, PyObject ** m2)
+{
+ int x;
+ float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+ PyObject *coerced = NULL;
+
+ if(!MatrixObject_Check(*m2)) {
+ if(VectorObject_Check(*m2) || PyFloat_Check(*m2) || PyInt_Check(*m2)) {
+ coerced = EXPP_incr_ret(*m2);
+ *m2 = newMatrixObject(NULL,3,3,Py_NEW);
+ ((MatrixObject*)*m2)->coerced_object = coerced;
+ }else{
+ return EXPP_ReturnIntError(PyExc_TypeError,
+ "matrix.coerce(): unknown operand - can't coerce for numeric protocols\n");
+ }
+ }
+ Py_INCREF(*m2);
+ Py_INCREF(*m1);
+ return 0;
+}
+//-----------------PROTCOL DECLARATIONS--------------------------
static PySequenceMethods Matrix_SeqMethods = {
- ( inquiry ) Matrix_len, /* sq_length */
- ( binaryfunc ) 0, /* sq_concat */
- ( intargfunc ) 0, /* sq_repeat */
- ( intargfunc ) Matrix_item, /* sq_item */
- ( intintargfunc ) Matrix_slice, /* sq_slice */
- ( intobjargproc ) Matrix_ass_item, /* sq_ass_item */
- ( intintobjargproc ) Matrix_ass_slice, /* sq_ass_slice */
+ (inquiry) Matrix_len, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (intargfunc) 0, /* sq_repeat */
+ (intargfunc) Matrix_item, /* sq_item */
+ (intintargfunc) Matrix_slice, /* sq_slice */
+ (intobjargproc) Matrix_ass_item, /* sq_ass_item */
+ (intintobjargproc) Matrix_ass_slice, /* sq_ass_slice */
};
-
static PyNumberMethods Matrix_NumMethods = {
- ( binaryfunc ) Matrix_add, /* __add__ */
- ( binaryfunc ) Matrix_sub, /* __sub__ */
- ( binaryfunc ) Matrix_mul, /* __mul__ */
- ( binaryfunc ) 0, /* __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 ) Matrix_coerce, /* __coerce__ */
- ( unaryfunc ) 0, /* __int__ */
- ( unaryfunc ) 0, /* __long__ */
- ( unaryfunc ) 0, /* __float__ */
- ( unaryfunc ) 0, /* __oct__ */
- ( unaryfunc ) 0, /* __hex__ */
+ (binaryfunc) Matrix_add, /* __add__ */
+ (binaryfunc) Matrix_sub, /* __sub__ */
+ (binaryfunc) Matrix_mul, /* __mul__ */
+ (binaryfunc) 0, /* __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) Matrix_coerce, /* __coerce__ */
+ (unaryfunc) 0, /* __int__ */
+ (unaryfunc) 0, /* __long__ */
+ (unaryfunc) 0, /* __float__ */
+ (unaryfunc) 0, /* __oct__ */
+ (unaryfunc) 0, /* __hex__ */
};
-
+//------------------PY_OBECT DEFINITION--------------------------
PyTypeObject matrix_Type = {
- PyObject_HEAD_INIT( NULL ) /* required python macro */
- 0, /*ob_size */
- "Matrix", /*tp_name */
- sizeof( MatrixObject ), /*tp_basicsize */
- 0, /*tp_itemsize */
- ( destructor ) Matrix_dealloc, /*tp_dealloc */
- ( printfunc ) 0, /*tp_print */
- ( getattrfunc ) Matrix_getattr, /*tp_getattr */
- ( setattrfunc ) Matrix_setattr, /*tp_setattr */
- 0, /*tp_compare */
- ( reprfunc ) Matrix_repr, /*tp_repr */
- &Matrix_NumMethods, /*tp_as_number */
- &Matrix_SeqMethods, /*tp_as_sequence */
+ PyObject_HEAD_INIT(NULL) /* required python macro */
+ 0, /*ob_size */
+ "Matrix", /*tp_name */
+ sizeof(MatrixObject), /*tp_basicsize */
+ 0, /*tp_itemsize */
+ (destructor) Matrix_dealloc, /*tp_dealloc */
+ (printfunc) 0, /*tp_print */
+ (getattrfunc) Matrix_getattr, /*tp_getattr */
+ (setattrfunc) Matrix_setattr, /*tp_setattr */
+ 0, /*tp_compare */
+ (reprfunc) Matrix_repr, /*tp_repr */
+ &Matrix_NumMethods, /*tp_as_number */
+ &Matrix_SeqMethods, /*tp_as_sequence */
};
-
-//******************************************************************
-//Function: newMatrixObject
-//******************************************************************
-PyObject *newMatrixObject( float *mat, int rowSize, int colSize )
+//------------------------newMatrixObject (internal)-------------
+//creates a new matrix object
+//self->matrix self->contiguous_ptr (reference to data.xxx)
+// [0]------------->[0]
+// [1]
+// [2]
+// [1]------------->[3]
+// [4]
+// [5]
+// ....
+//self->matrix[1][1] = self->contiguous_ptr[4] = self->data.xxx_data[4]
+/*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 *newMatrixObject(float *mat, int rowSize, int colSize, int type)
{
MatrixObject *self;
- int row, col, x;
-
- if( rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4 )
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "row and column sizes must be between 2 and 4\n" ) );
-
- self = PyObject_NEW( MatrixObject, &matrix_Type );
+ int x, row, col;
- //generate contigous memory space
- self->contigPtr = PyMem_Malloc( rowSize * colSize * sizeof( float ) );
- if( self->contigPtr == NULL ) {
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating array space\n\n" ) );
- }
- //create pointer array
- self->matrix = PyMem_Malloc( rowSize * sizeof( float * ) );
- if( self->matrix == NULL ) {
- PyMem_Free( self->contigPtr );
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "problem allocating pointer space\n\n" ) );
- }
- //pointer array points to contigous memory
- for( x = 0; x < rowSize; x++ ) {
- self->matrix[x] = self->contigPtr + ( x * colSize );
+ //matrix objects can be any 2-4row x 2-4col matrix
+ if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4){
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError,
+ "matrix(): row and column sizes must be between 2 and 4\n");
}
- if( mat ) { //if a float array passed
- for( row = 0; row < rowSize; row++ ) {
- for( col = 0; col < colSize; col++ ) {
- self->matrix[row][col] =
- mat[( row * colSize ) + col];
- }
+ matrix_Type.ob_type = &PyType_Type;
+ self = PyObject_NEW(MatrixObject, &matrix_Type);
+ self->data.blend_data = NULL;
+ self->data.py_data = NULL;
+ self->rowSize = rowSize;
+ self->colSize = colSize;
+ self->coerced_object = NULL;
+
+ if(type == Py_WRAP){
+ self->data.blend_data = mat;
+ self->contigPtr = self->data.blend_data;
+ //create pointer array
+ self->matrix = PyMem_Malloc(rowSize * sizeof(float *));
+ if(self->matrix == NULL) { //allocation failure
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "matrix(): problem allocating pointer space\n");
+ }
+ //pointer array points to contigous memory
+ for(x = 0; x < rowSize; x++) {
+ self->matrix[x] = self->contigPtr + (x * colSize);
+ }
+ }else if (type == Py_NEW){
+ self->data.py_data = PyMem_Malloc(rowSize * colSize * sizeof(float));
+ if(self->data.py_data == NULL) { //allocation failure
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "matrix(): problem allocating pointer space\n");
}
- } else { //or if NULL passed
- for( row = 0; row < rowSize; row++ ) {
- for( col = 0; col < colSize; col++ ) {
- self->matrix[row][col] = 0.0f;
+ self->contigPtr = self->data.py_data;
+ //create pointer array
+ self->matrix = PyMem_Malloc(rowSize * sizeof(float *));
+ if(self->matrix == NULL) { //allocation failure
+ PyMem_Free(self->data.py_data);
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "matrix(): problem allocating pointer space\n");
+ }
+ //pointer array points to contigous memory
+ for(x = 0; x < rowSize; x++) {
+ self->matrix[x] = self->contigPtr + (x * colSize);
+ }
+ //parse
+ if(mat) { //if a float array passed
+ for(row = 0; row < rowSize; row++) {
+ for(col = 0; col < colSize; col++) {
+ self->matrix[row][col] = mat[(row * colSize) + col];
+ }
}
+ } else { //or if no arguments are passed return identity matrix
+ Matrix_Identity(self);
}
+ }else{ //bad type
+ return NULL;
}
-
- //set size vars of matrix
- self->rowSize = rowSize;
- self->colSize = colSize;
-
- //set coercion flag
- self->flag = 0;
-
- return ( ( PyObject * ) self );
+ return (PyObject *) EXPP_incr_ret((PyObject *)self);
}