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:
authorCampbell Barton <ideasman42@gmail.com>2010-01-25 12:44:04 +0300
committerCampbell Barton <ideasman42@gmail.com>2010-01-25 12:44:04 +0300
commit0a0f4c9d81cfa2a4b4a9999e1dc976bc417d7d54 (patch)
tree367f259b695955a514530d125ab495344724eafb /source/blender/python/generic/Mathutils.c
parenteed13d859b67185996569178ede9241a5695f215 (diff)
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac) - Mathutils.AngleBetweenVecs --> vector.angle(other) - Mathutils.ProjectVecs --> vector.project(other) - Mathutils.DifferenceQuats --> quat.difference(other) - Mathutils.Slerp --> quat.slerp(other, fac) - Mathutils.Rand: removed, use pythons random module - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args - Matrix.scalePart --> Matrix.scale_part - Matrix.translationPart --> Matrix.translation_part - Matrix.rotationPart --> Matrix.rotation_part - toMatrix --> to_matrix - toEuler --> to_euler - toQuat --> to_quat - Vector.toTrackQuat --> Vector.to_track_quat
Diffstat (limited to 'source/blender/python/generic/Mathutils.c')
-rw-r--r--source/blender/python/generic/Mathutils.c842
1 files changed, 174 insertions, 668 deletions
diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c
index b44d6450145..2e4b6dbb490 100644
--- a/source/blender/python/generic/Mathutils.c
+++ b/source/blender/python/generic/Mathutils.c
@@ -27,114 +27,34 @@
* ***** END GPL LICENSE BLOCK *****
*/
+/* Note: Changes to Mathutils since 2.4x
+ * use radians rather then degrees
+ * - Mathutils.MidpointVecs --> vector.lerp(other, fac)
+ * - Mathutils.AngleBetweenVecs --> vector.angle(other)
+ * - Mathutils.ProjectVecs --> vector.project(other)
+ * - Mathutils.DifferenceQuats --> quat.difference(other)
+ * - Mathutils.Slerp --> quat.slerp(other, fac)
+ * - Mathutils.Rand: removed, use pythons random module
+ * - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args
+ * - Matrix.scalePart --> Matrix.scale_part
+ * - Matrix.translationPart --> Matrix.translation_part
+ * - Matrix.rotationPart --> Matrix.rotation_part
+ * - toMatrix --> to_matrix
+ * - toEuler --> to_euler
+ * - toQuat --> to_quat
+ * - Vector.toTrackQuat --> Vector.to_track_quat
+ *
+ * Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
+ */
+
#include "Mathutils.h"
#include "BLI_math.h"
#include "PIL_time.h"
-#include "BLI_rand.h"
#include "BKE_utildefines.h"
//-------------------------DOC STRINGS ---------------------------
-static char M_Mathutils_doc[] = "The Blender Mathutils module\n\n";
-static char M_Mathutils_Rand_doc[] = "() - return a random number";
-static char M_Mathutils_AngleBetweenVecs_doc[] = "() - returns the angle between two vectors in degrees";
-static char M_Mathutils_MidpointVecs_doc[] = "() - return the vector to the midpoint between two vectors";
-static char M_Mathutils_ProjectVecs_doc[] = "() - returns the projection vector from the projection of vecA onto vecB";
-static char M_Mathutils_RotationMatrix_doc[] = "() - construct a rotation matrix from an angle and axis of rotation";
-static char M_Mathutils_ScaleMatrix_doc[] = "() - construct a scaling matrix from a scaling factor";
-static char M_Mathutils_OrthoProjectionMatrix_doc[] = "() - construct a orthographic projection matrix from a selected plane";
-static char M_Mathutils_ShearMatrix_doc[] = "() - construct a shearing matrix from a plane of shear and a shear factor";
-static char M_Mathutils_TranslationMatrix_doc[] = "(vec) - create a translation matrix from a vector";
-static char M_Mathutils_Slerp_doc[] = "() - returns the interpolation between two quaternions";
-static char M_Mathutils_DifferenceQuats_doc[] = "() - return the angular displacment difference between two quats";
-static char M_Mathutils_Intersect_doc[] = "(v1, v2, v3, ray, orig, clip=1) - returns the intersection between a ray and a triangle, if possible, returns None otherwise";
-static char M_Mathutils_TriangleArea_doc[] = "(v1, v2, v3) - returns the area size of the 2D or 3D triangle defined";
-static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined";
-static char M_Mathutils_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined";
-static char M_Mathutils_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other";
-//-----------------------METHOD DEFINITIONS ----------------------
-
-static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value);
-static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args);
-static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args );
-static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args );
-static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args );
-static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args );
-static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args );
-
-struct PyMethodDef M_Mathutils_methods[] = {
- {"Rand", (PyCFunction) M_Mathutils_Rand, METH_VARARGS, M_Mathutils_Rand_doc},
- {"AngleBetweenVecs", (PyCFunction) M_Mathutils_AngleBetweenVecs, METH_VARARGS, M_Mathutils_AngleBetweenVecs_doc},
- {"MidpointVecs", (PyCFunction) M_Mathutils_MidpointVecs, METH_VARARGS, M_Mathutils_MidpointVecs_doc},
- {"ProjectVecs", (PyCFunction) M_Mathutils_ProjectVecs, METH_VARARGS, M_Mathutils_ProjectVecs_doc},
- {"RotationMatrix", (PyCFunction) M_Mathutils_RotationMatrix, METH_VARARGS, M_Mathutils_RotationMatrix_doc},
- {"ScaleMatrix", (PyCFunction) M_Mathutils_ScaleMatrix, METH_VARARGS, M_Mathutils_ScaleMatrix_doc},
- {"ShearMatrix", (PyCFunction) M_Mathutils_ShearMatrix, METH_VARARGS, M_Mathutils_ShearMatrix_doc},
- {"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_O, M_Mathutils_TranslationMatrix_doc},
- {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix, METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
- {"DifferenceQuats", (PyCFunction) M_Mathutils_DifferenceQuats, METH_VARARGS,M_Mathutils_DifferenceQuats_doc},
- {"Slerp", (PyCFunction) M_Mathutils_Slerp, METH_VARARGS, M_Mathutils_Slerp_doc},
- {"Intersect", ( PyCFunction ) M_Mathutils_Intersect, METH_VARARGS, M_Mathutils_Intersect_doc},
- {"TriangleArea", ( PyCFunction ) M_Mathutils_TriangleArea, METH_VARARGS, M_Mathutils_TriangleArea_doc},
- {"TriangleNormal", ( PyCFunction ) M_Mathutils_TriangleNormal, METH_VARARGS, M_Mathutils_TriangleNormal_doc},
- {"QuadNormal", ( PyCFunction ) M_Mathutils_QuadNormal, METH_VARARGS, M_Mathutils_QuadNormal_doc},
- {"LineIntersect", ( PyCFunction ) M_Mathutils_LineIntersect, METH_VARARGS, M_Mathutils_LineIntersect_doc},
- {NULL, NULL, 0, NULL}
-};
-
-/*----------------------------MODULE INIT-------------------------*/
-/* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */
-
-static struct PyModuleDef M_Mathutils_module_def = {
- PyModuleDef_HEAD_INIT,
- "Mathutils", /* m_name */
- M_Mathutils_doc, /* m_doc */
- 0, /* m_size */
- M_Mathutils_methods, /* m_methods */
- 0, /* m_reload */
- 0, /* m_traverse */
- 0, /* m_clear */
- 0, /* m_free */
-};
-
-PyObject *Mathutils_Init(void)
-{
- PyObject *submodule;
-
- //seed the generator for the rand function
- BLI_srand((unsigned int) (PIL_check_seconds_timer() * 0x7FFFFFFF));
-
- if( PyType_Ready( &vector_Type ) < 0 )
- return NULL;
- if( PyType_Ready( &matrix_Type ) < 0 )
- return NULL;
- if( PyType_Ready( &euler_Type ) < 0 )
- return NULL;
- if( PyType_Ready( &quaternion_Type ) < 0 )
- return NULL;
-
- submodule = PyModule_Create(&M_Mathutils_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), M_Mathutils_module_def.m_name, submodule);
-
- /* each type has its own new() function */
- PyModule_AddObject( submodule, "Vector", (PyObject *)&vector_Type );
- PyModule_AddObject( submodule, "Matrix", (PyObject *)&matrix_Type );
- PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type );
- PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type );
-
- mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb);
-
- return (submodule);
-}
+static char M_Mathutils_doc[] = "This module provides access to matrices, eulers, quaternions and vectors.";
//-----------------------------METHODS----------------------------
//-----------------quat_rotation (internal)-----------
@@ -204,164 +124,49 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
}
-//----------------------------------Mathutils.Rand() --------------------
-//returns a random number between a high and low value
-static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
-{
- float high, low, range;
- double drand;
- //initializers
- high = 1.0;
- low = 0.0;
-
- if(!PyArg_ParseTuple(args, "|ff", &low, &high)) {
- PyErr_SetString(PyExc_TypeError, "Mathutils.Rand(): expected nothing or optional (float, float)\n");
- return NULL;
- }
-
- if((high < low) || (high < 0 && low > 0)) {
- PyErr_SetString(PyExc_ValueError, "Mathutils.Rand(): high value should be larger than low value\n");
- return NULL;
- }
- //get the random number 0 - 1
- drand = BLI_drand();
-
- //set it to range
- range = high - low;
- drand = drand * range;
- drand = drand + low;
-
- return PyFloat_FromDouble(drand);
-}
-//----------------------------------VECTOR FUNCTIONS---------------------
-//----------------------------------Mathutils.AngleBetweenVecs() ---------
-//calculates the angle between 2 vectors
-static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
-{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- double dot = 0.0f, angleRads, test_v1 = 0.0f, test_v2 = 0.0f;
- int x, size;
-
- if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2))
- goto AttributeError1; //not vectors
- if(vec1->size != vec2->size)
- goto AttributeError1; //bad sizes
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
- return NULL;
-
- //since size is the same....
- size = vec1->size;
-
- for(x = 0; x < size; x++) {
- test_v1 += vec1->vec[x] * vec1->vec[x];
- test_v2 += vec2->vec[x] * vec2->vec[x];
- }
- if (!test_v1 || !test_v2){
- goto AttributeError2; //zero-length vector
- }
-
- //dot product
- for(x = 0; x < size; x++) {
- dot += vec1->vec[x] * vec2->vec[x];
- }
- dot /= (sqrt(test_v1) * sqrt(test_v2));
-
- angleRads = (double)saacos(dot);
-
-#ifdef USE_MATHUTILS_DEG
- return PyFloat_FromDouble(angleRads * (180/ Py_PI));
-#else
- return PyFloat_FromDouble(angleRads);
-#endif
-AttributeError1:
- PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n");
- return NULL;
-
-AttributeError2:
- PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): zero length vectors are not acceptable arguments\n");
- return NULL;
-}
-//----------------------------------Mathutils.MidpointVecs() -------------
-//calculates the midpoint between 2 vectors
-static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
-{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- float vec[4];
- int x;
-
- if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) {
- PyErr_SetString(PyExc_TypeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n");
- return NULL;
- }
- if(vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n");
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
- return NULL;
-
- for(x = 0; x < vec1->size; x++) {
- vec[x] = 0.5f * (vec1->vec[x] + vec2->vec[x]);
- }
- return newVectorObject(vec, vec1->size, Py_NEW, NULL);
-}
-//----------------------------------Mathutils.ProjectVecs() -------------
-//projects vector 1 onto vector 2
-static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
-{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- float vec[4];
- double dot = 0.0f, dot2 = 0.0f;
- int x, size;
-
- if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) {
- PyErr_SetString(PyExc_TypeError, "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n");
- return NULL;
- }
- if(vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n");
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
- return NULL;
-
-
- //since they are the same size...
- size = vec1->size;
-
- //get dot products
- for(x = 0; x < size; x++) {
- dot += vec1->vec[x] * vec2->vec[x];
- dot2 += vec2->vec[x] * vec2->vec[x];
- }
- //projection
- dot /= dot2;
- for(x = 0; x < size; x++) {
- vec[x] = (float)(dot * vec2->vec[x]);
- }
- return newVectorObject(vec, size, Py_NEW, NULL);
-}
//----------------------------------MATRIX FUNCTIONS--------------------
//----------------------------------Mathutils.RotationMatrix() ----------
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-//creates a rotation matrix
+static char M_Mathutils_RotationMatrix_doc[] =
+".. function:: RotationMatrix(angle, size, axis)\n"
+"\n"
+" Create a matrix representing a rotation.\n"
+"\n"
+" :arg angle: The angle of rotation desired.\n"
+" :type angle: float\n"
+" :arg size: The size of the rotation matrix to construct [2, 4].\n"
+" :type size: int\n"
+" :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object (optional when size is 2).\n"
+" :type axis: string or vector\n"
+" :return: A new rotation matrix.\n"
+" :rtype: Matrix\n";
+
static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
{
- VectorObject *vec = NULL;
- char *axis = NULL;
+ VectorObject *vec= NULL;
+ char *axis= NULL;
int matSize;
float angle = 0.0f;
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};
- if(!PyArg_ParseTuple(args, "fi|sO!", &angle, &matSize, &axis, &vector_Type, &vec)) {
- PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n");
+ if(!PyArg_ParseTuple(args, "fi|O", &angle, &matSize, &vec)) {
+ PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(angle, size, axis): expected float int and a string or vector\n");
return NULL;
}
+ if(vec && !VectorObject_Check(vec)) {
+ axis= _PyUnicode_AsString((PyObject *)vec);
+ if(axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') {
+ PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): 3rd argument axis value must be a 3D vector or a string in 'X', 'Y', 'Z'\n");
+ return NULL;
+ }
+ else {
+ /* use the string */
+ vec= NULL;
+ }
+ }
+
#ifdef USE_MATHUTILS_DEG
/* Clamp to -360:360 */
while (angle<-360.0f)
@@ -379,23 +184,17 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
return NULL;
}
- if(matSize == 2 && (axis != NULL || vec != NULL)) {
+ if(matSize == 2 && (vec != NULL)) {
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis\n");
return NULL;
}
- if((matSize == 3 || matSize == 4) && axis == NULL) {
+ if((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): please choose an axis of rotation for 3d and 4d matrices\n");
return NULL;
}
- if(axis) {
- if(((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) && vec == NULL) {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): please define the arbitrary axis of rotation\n");
- return NULL;
- }
- }
if(vec) {
if(vec->size != 3) {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n");
+ PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the vector axis must be a 3D vector\n");
return NULL;
}
@@ -414,35 +213,32 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
mat[1] = (float) sin (angle);
mat[2] = -((float) sin(angle));
mat[3] = (float) cos(angle);
- } else if((strcmp(axis, "x") == 0) || (strcmp(axis, "X") == 0)) {
+ } else if(strcmp(axis, "X") == 0) {
//rotation around X
mat[0] = 1.0f;
mat[4] = (float) cos(angle);
mat[5] = (float) sin(angle);
mat[7] = -((float) sin(angle));
mat[8] = (float) cos(angle);
- } else if((strcmp(axis, "y") == 0) || (strcmp(axis, "Y") == 0)) {
+ } else if(strcmp(axis, "Y") == 0) {
//rotation around Y
mat[0] = (float) cos(angle);
mat[2] = -((float) sin(angle));
mat[4] = 1.0f;
mat[6] = (float) sin(angle);
mat[8] = (float) cos(angle);
- } else if((strcmp(axis, "z") == 0) || (strcmp(axis, "Z") == 0)) {
+ } else if(strcmp(axis, "Z") == 0) {
//rotation around Z
mat[0] = (float) cos(angle);
mat[1] = (float) sin(angle);
mat[3] = -((float) sin(angle));
mat[4] = (float) cos(angle);
mat[8] = 1.0f;
- } else if((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) {
- //arbitrary rotation
- axis_angle_to_mat3( (float (*)[3])mat,vec->vec, angle);
-
} else {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n");
- return NULL;
+ /* check for valid vector/axis above */
+ axis_angle_to_mat3( (float (*)[3])mat,vec->vec, angle);
}
+
if(matSize == 4) {
//resize matrix
mat[10] = mat[8];
@@ -457,8 +253,17 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
//pass to matrix creation
return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
}
-//----------------------------------Mathutils.TranslationMatrix() -------
-//creates a translation matrix
+
+static char M_Mathutils_TranslationMatrix_doc[] =
+".. function:: TranslationMatrix(vector)\n"
+"\n"
+" Create a matrix representing a translation.\n"
+"\n"
+" :arg vector: The translation vector.\n"
+" :type vector: Vector\n"
+" :return: An identity matrix with a translation.\n"
+" :rtype: Matrix\n";
+
static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
{
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
@@ -486,7 +291,20 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v
}
//----------------------------------Mathutils.ScaleMatrix() -------------
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-//creates a scaling matrix
+static char M_Mathutils_ScaleMatrix_doc[] =
+".. function:: ScaleMatrix(factor, size, axis)\n"
+"\n"
+" Create a matrix representing a scaling.\n"
+"\n"
+" :arg factor: The factor of scaling to apply.\n"
+" :type factor: float\n"
+" :arg size: The size of the scale matrix to construct [2, 4].\n"
+" :type size: int\n"
+" :arg axis: Direction to influence scale. (optional).\n"
+" :type axis: Vector\n"
+" :return: A new scale matrix.\n"
+" :rtype: Matrix\n";
+
static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
{
VectorObject *vec = NULL;
@@ -564,7 +382,19 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
}
//----------------------------------Mathutils.OrthoProjectionMatrix() ---
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-//creates an ortho projection matrix
+static char M_Mathutils_OrthoProjectionMatrix_doc[] =
+".. function:: OrthoProjectionMatrix(plane, size, axis)\n"
+"\n"
+" Create a matrix to represent an orthographic projection.\n"
+"\n"
+" :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ', 'R'], where a single axis is for a 2D matrix and 'R' requires axis is given.\n"
+" :type plane: string\n"
+" :arg size: The size of the projection matrix to construct [2, 4].\n"
+" :type size: int\n"
+" :arg axis: Arbitrary perpendicular plane vector.\n"
+" :type axis: vector (optional)\n"
+" :return: A new projection matrix.\n"
+" :rtype: Matrix\n";
static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
{
VectorObject *vec = NULL;
@@ -593,30 +423,21 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
}
if(vec == NULL) { //ortho projection onto cardinal plane
- if(((strcmp(plane, "x") == 0)
- || (strcmp(plane, "X") == 0)) && matSize == 2) {
+ if((strcmp(plane, "X") == 0) && matSize == 2) {
mat[0] = 1.0f;
- } else if(((strcmp(plane, "y") == 0)
- || (strcmp(plane, "Y") == 0))
- && matSize == 2) {
+ } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
mat[3] = 1.0f;
- } else if(((strcmp(plane, "xy") == 0)
- || (strcmp(plane, "XY") == 0))
- && matSize > 2) {
+ } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
mat[0] = 1.0f;
mat[4] = 1.0f;
- } else if(((strcmp(plane, "xz") == 0)
- || (strcmp(plane, "XZ") == 0))
- && matSize > 2) {
+ } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
mat[0] = 1.0f;
mat[8] = 1.0f;
- } else if(((strcmp(plane, "yz") == 0)
- || (strcmp(plane, "YZ") == 0))
- && matSize > 2) {
+ } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
mat[4] = 1.0f;
mat[8] = 1.0f;
} else {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: x, y, xy, xz, yz\n");
+ PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: X, Y, XY, XZ, YZ\n");
return NULL;
}
} else { //arbitrary plane
@@ -628,15 +449,12 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
for(x = 0; x < vec->size; x++) {
vec->vec[x] /= norm;
}
- if(((strcmp(plane, "r") == 0)
- || (strcmp(plane, "R") == 0)) && matSize == 2) {
+ if((strcmp(plane, "R") == 0) && matSize == 2) {
mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
mat[1] = -(vec->vec[0] * vec->vec[1]);
mat[2] = -(vec->vec[0] * vec->vec[1]);
mat[3] = 1 - (vec->vec[1] * vec->vec[1]);
- } else if(((strcmp(plane, "r") == 0)
- || (strcmp(plane, "R") == 0))
- && matSize > 2) {
+ } else if((strcmp(plane, "R") == 0) && matSize > 2) {
mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
mat[1] = -(vec->vec[0] * vec->vec[1]);
mat[2] = -(vec->vec[0] * vec->vec[2]);
@@ -665,8 +483,21 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
//pass to matrix creation
return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
}
-//----------------------------------Mathutils.ShearMatrix() -------------
-//creates a shear matrix
+
+static char M_Mathutils_ShearMatrix_doc[] =
+".. function:: ShearMatrix(plane, factor, size)\n"
+"\n"
+" Create a matrix to represent an shear transformation.\n"
+"\n"
+" :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], where a single axis is for a 2D matrix.\n"
+" :type plane: string\n"
+" :arg factor: The factor of shear to apply.\n"
+" :type factor: float\n"
+" :arg size: The size of the shear matrix to construct [2, 4].\n"
+" :type size: int\n"
+" :return: A new shear matrix.\n"
+" :rtype: Matrix\n";
+
static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
{
int matSize;
@@ -684,31 +515,27 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
return NULL;
}
- if(((strcmp(plane, "x") == 0) || (strcmp(plane, "X") == 0))
+ if((strcmp(plane, "X") == 0)
&& matSize == 2) {
mat[0] = 1.0f;
mat[2] = factor;
mat[3] = 1.0f;
- } else if(((strcmp(plane, "y") == 0)
- || (strcmp(plane, "Y") == 0)) && matSize == 2) {
+ } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
mat[0] = 1.0f;
mat[1] = factor;
mat[3] = 1.0f;
- } else if(((strcmp(plane, "xy") == 0)
- || (strcmp(plane, "XY") == 0)) && matSize > 2) {
+ } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
mat[0] = 1.0f;
mat[4] = 1.0f;
mat[6] = factor;
mat[7] = factor;
- } else if(((strcmp(plane, "xz") == 0)
- || (strcmp(plane, "XZ") == 0)) && matSize > 2) {
+ } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
mat[0] = 1.0f;
mat[3] = factor;
mat[4] = 1.0f;
mat[5] = factor;
mat[8] = 1.0f;
- } else if(((strcmp(plane, "yz") == 0)
- || (strcmp(plane, "YZ") == 0)) && matSize > 2) {
+ } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
mat[0] = 1.0f;
mat[1] = factor;
mat[2] = factor;
@@ -732,375 +559,6 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
//pass to matrix creation
return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
}
-//----------------------------------QUATERNION FUNCTIONS-----------------
-
-//----------------------------------Mathutils.DifferenceQuats() ---------
-//returns the difference between 2 quaternions
-static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
-{
- QuaternionObject *quatU = NULL, *quatV = NULL;
- float quat[4], tempQuat[4];
- double dot = 0.0f;
- int x;
-
- if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) {
- PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types");
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
- return NULL;
-
- tempQuat[0] = quatU->quat[0];
- tempQuat[1] = -quatU->quat[1];
- tempQuat[2] = -quatU->quat[2];
- tempQuat[3] = -quatU->quat[3];
-
- dot = sqrt(tempQuat[0] * tempQuat[0] + tempQuat[1] * tempQuat[1] +
- tempQuat[2] * tempQuat[2] + tempQuat[3] * tempQuat[3]);
-
- for(x = 0; x < 4; x++) {
- tempQuat[x] /= (float)(dot * dot);
- }
- mul_qt_qtqt(quat, tempQuat, quatV->quat);
- return newQuaternionObject(quat, Py_NEW, NULL);
-}
-//----------------------------------Mathutils.Slerp() ------------------
-//attemps to interpolate 2 quaternions and return the result
-static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
-{
- QuaternionObject *quatU = NULL, *quatV = NULL;
- float quat[4], quat_u[4], quat_v[4], param;
- double x, y, dot, sinT, angle, IsinT;
- int z;
-
- if(!PyArg_ParseTuple(args, "O!O!f", &quaternion_Type, &quatU, &quaternion_Type, &quatV, &param)) {
- PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
- return NULL;
-
- if(param > 1.0f || param < 0.0f) {
- PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
- return NULL;
- }
-
- //copy quats
- for(z = 0; z < 4; z++){
- quat_u[z] = quatU->quat[z];
- quat_v[z] = quatV->quat[z];
- }
-
- //dot product
- dot = quat_u[0] * quat_v[0] + quat_u[1] * quat_v[1] +
- quat_u[2] * quat_v[2] + quat_u[3] * quat_v[3];
-
- //if negative negate a quat (shortest arc)
- if(dot < 0.0f) {
- quat_v[0] = -quat_v[0];
- quat_v[1] = -quat_v[1];
- quat_v[2] = -quat_v[2];
- quat_v[3] = -quat_v[3];
- dot = -dot;
- }
- if(dot > .99999f) { //very close
- x = 1.0f - param;
- y = param;
- } else {
- //calculate sin of angle
- sinT = sqrt(1.0f - (dot * dot));
- //calculate angle
- angle = atan2(sinT, dot);
- //caluculate inverse of sin(theta)
- IsinT = 1.0f / sinT;
- x = sin((1.0f - param) * angle) * IsinT;
- y = sin(param * angle) * IsinT;
- }
- //interpolate
- quat[0] = (float)(quat_u[0] * x + quat_v[0] * y);
- quat[1] = (float)(quat_u[1] * x + quat_v[1] * y);
- quat[2] = (float)(quat_u[2] * x + quat_v[2] * y);
- quat[3] = (float)(quat_u[3] * x + quat_v[3] * y);
-
- return newQuaternionObject(quat, Py_NEW, NULL);
-}
-//----------------------------------EULER FUNCTIONS----------------------
-//---------------------------------INTERSECTION FUNCTIONS--------------------
-//----------------------------------Mathutils.Intersect() -------------------
-static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
-{
- VectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
- float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
- float det, inv_det, u, v, t;
- int clip = 1;
-
- if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) {
- PyErr_SetString( PyExc_TypeError, "expected 5 vector types\n" );
- return NULL;
- }
- if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
- PyErr_SetString( PyExc_TypeError, "only 3D vectors for all parameters\n");
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
- return NULL;
-
- VECCOPY(v1, vec1->vec);
- VECCOPY(v2, vec2->vec);
- VECCOPY(v3, vec3->vec);
-
- VECCOPY(dir, ray->vec);
- normalize_v3(dir);
-
- VECCOPY(orig, ray_off->vec);
-
- /* find vectors for two edges sharing v1 */
- sub_v3_v3v3(e1, v2, v1);
- sub_v3_v3v3(e2, v3, v1);
-
- /* begin calculating determinant - also used to calculated U parameter */
- cross_v3_v3v3(pvec, dir, e2);
-
- /* if determinant is near zero, ray lies in plane of triangle */
- det = dot_v3v3(e1, pvec);
-
- if (det > -0.000001 && det < 0.000001) {
- Py_RETURN_NONE;
- }
-
- inv_det = 1.0f / det;
-
- /* calculate distance from v1 to ray origin */
- sub_v3_v3v3(tvec, orig, v1);
-
- /* calculate U parameter and test bounds */
- u = dot_v3v3(tvec, pvec) * inv_det;
- if (clip && (u < 0.0f || u > 1.0f)) {
- Py_RETURN_NONE;
- }
-
- /* prepare to test the V parameter */
- cross_v3_v3v3(qvec, tvec, e1);
-
- /* calculate V parameter and test bounds */
- v = dot_v3v3(dir, qvec) * inv_det;
-
- if (clip && (v < 0.0f || u + v > 1.0f)) {
- Py_RETURN_NONE;
- }
-
- /* calculate t, ray intersects triangle */
- t = dot_v3v3(e2, qvec) * inv_det;
-
- mul_v3_fl(dir, t);
- add_v3_v3v3(pvec, orig, dir);
-
- return newVectorObject(pvec, 3, Py_NEW, NULL);
-}
-//----------------------------------Mathutils.LineIntersect() -------------------
-/* Line-Line intersection using algorithm from mathworld.wolfram.com */
-static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
-{
- PyObject * tuple;
- VectorObject *vec1, *vec2, *vec3, *vec4;
- float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
-
- if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) {
- PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
- return NULL;
- }
- if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
- PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
- return NULL;
-
- if( vec1->size == 3 || vec1->size == 2) {
- int result;
-
- if (vec1->size == 3) {
- VECCOPY(v1, vec1->vec);
- VECCOPY(v2, vec2->vec);
- VECCOPY(v3, vec3->vec);
- VECCOPY(v4, vec4->vec);
- }
- else {
- v1[0] = vec1->vec[0];
- v1[1] = vec1->vec[1];
- v1[2] = 0.0f;
-
- v2[0] = vec2->vec[0];
- v2[1] = vec2->vec[1];
- v2[2] = 0.0f;
-
- v3[0] = vec3->vec[0];
- v3[1] = vec3->vec[1];
- v3[2] = 0.0f;
-
- v4[0] = vec4->vec[0];
- v4[1] = vec4->vec[1];
- v4[2] = 0.0f;
- }
-
- result = isect_line_line_v3(v1, v2, v3, v4, i1, i2);
-
- if (result == 0) {
- /* colinear */
- Py_RETURN_NONE;
- }
- else {
- tuple = PyTuple_New( 2 );
- PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL) );
- PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL) );
- return tuple;
- }
- }
- else {
- PyErr_SetString( PyExc_TypeError, "2D/3D vectors only\n" );
- return NULL;
- }
-}
-
-
-
-//---------------------------------NORMALS FUNCTIONS--------------------
-//----------------------------------Mathutils.QuadNormal() -------------------
-static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
-{
- VectorObject *vec1;
- VectorObject *vec2;
- VectorObject *vec3;
- VectorObject *vec4;
- float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3], n1[3], n2[3];
-
- if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) {
- PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
- return NULL;
- }
- if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
- PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
- return NULL;
- }
- if( vec1->size != 3 ) {
- PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" );
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
- return NULL;
-
- VECCOPY(v1, vec1->vec);
- VECCOPY(v2, vec2->vec);
- VECCOPY(v3, vec3->vec);
- VECCOPY(v4, vec4->vec);
-
- /* find vectors for two edges sharing v2 */
- sub_v3_v3v3(e1, v1, v2);
- sub_v3_v3v3(e2, v3, v2);
-
- cross_v3_v3v3(n1, e2, e1);
- normalize_v3(n1);
-
- /* find vectors for two edges sharing v4 */
- sub_v3_v3v3(e1, v3, v4);
- sub_v3_v3v3(e2, v1, v4);
-
- cross_v3_v3v3(n2, e2, e1);
- normalize_v3(n2);
-
- /* adding and averaging the normals of both triangles */
- add_v3_v3v3(n1, n2, n1);
- normalize_v3(n1);
-
- return newVectorObject(n1, 3, Py_NEW, NULL);
-}
-
-//----------------------------Mathutils.TriangleNormal() -------------------
-static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
-{
- VectorObject *vec1, *vec2, *vec3;
- float v1[3], v2[3], v3[3], e1[3], e2[3], n[3];
-
- if( !PyArg_ParseTuple( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3 ) ) {
- PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" );
- return NULL;
- }
- if( vec1->size != vec2->size || vec1->size != vec3->size ) {
- PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" );
- return NULL;
- }
- if( vec1->size != 3 ) {
- PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" );
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
- return NULL;
-
- VECCOPY(v1, vec1->vec);
- VECCOPY(v2, vec2->vec);
- VECCOPY(v3, vec3->vec);
-
- /* find vectors for two edges sharing v2 */
- sub_v3_v3v3(e1, v1, v2);
- sub_v3_v3v3(e2, v3, v2);
-
- cross_v3_v3v3(n, e2, e1);
- normalize_v3(n);
-
- return newVectorObject(n, 3, Py_NEW, NULL);
-}
-
-//--------------------------------- AREA FUNCTIONS--------------------
-//----------------------------------Mathutils.TriangleArea() -------------------
-static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
-{
- VectorObject *vec1, *vec2, *vec3;
- float v1[3], v2[3], v3[3];
-
- if( !PyArg_ParseTuple
- ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2
- , &vector_Type, &vec3 ) ) {
- PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n");
- return NULL;
- }
- if( vec1->size != vec2->size || vec1->size != vec3->size ) {
- PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" );
- return NULL;
- }
-
- if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
- return NULL;
-
- if (vec1->size == 3) {
- VECCOPY(v1, vec1->vec);
- VECCOPY(v2, vec2->vec);
- VECCOPY(v3, vec3->vec);
-
- return PyFloat_FromDouble( area_tri_v3(v1, v2, v3) );
- }
- else if (vec1->size == 2) {
- v1[0] = vec1->vec[0];
- v1[1] = vec1->vec[1];
-
- v2[0] = vec2->vec[0];
- v2[1] = vec2->vec[1];
-
- v3[0] = vec3->vec[0];
- v3[1] = vec3->vec[1];
-
- return PyFloat_FromDouble( area_tri_v2(v1, v2, v3) );
- }
- else {
- PyErr_SetString( PyExc_TypeError, "only 2D,3D vectors are supported\n" );
- return NULL;
- }
-}
/* Utility functions */
@@ -1219,3 +677,51 @@ void BaseMathObject_dealloc(BaseMathObject * self)
Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
}
+/*----------------------------MODULE INIT-------------------------*/
+struct PyMethodDef M_Mathutils_methods[] = {
+ {"RotationMatrix", (PyCFunction) M_Mathutils_RotationMatrix, METH_VARARGS, M_Mathutils_RotationMatrix_doc},
+ {"ScaleMatrix", (PyCFunction) M_Mathutils_ScaleMatrix, METH_VARARGS, M_Mathutils_ScaleMatrix_doc},
+ {"ShearMatrix", (PyCFunction) M_Mathutils_ShearMatrix, METH_VARARGS, M_Mathutils_ShearMatrix_doc},
+ {"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_O, M_Mathutils_TranslationMatrix_doc},
+ {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix, METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef M_Mathutils_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "Mathutils", /* m_name */
+ M_Mathutils_doc, /* m_doc */
+ 0, /* m_size */
+ M_Mathutils_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+
+PyObject *Mathutils_Init(void)
+{
+ PyObject *submodule;
+
+ if( PyType_Ready( &vector_Type ) < 0 )
+ return NULL;
+ if( PyType_Ready( &matrix_Type ) < 0 )
+ return NULL;
+ if( PyType_Ready( &euler_Type ) < 0 )
+ return NULL;
+ if( PyType_Ready( &quaternion_Type ) < 0 )
+ return NULL;
+
+ submodule = PyModule_Create(&M_Mathutils_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), M_Mathutils_module_def.m_name, submodule);
+
+ /* each type has its own new() function */
+ PyModule_AddObject( submodule, "Vector", (PyObject *)&vector_Type );
+ PyModule_AddObject( submodule, "Matrix", (PyObject *)&matrix_Type );
+ PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type );
+ PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type );
+
+ mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb);
+
+ return (submodule);
+}