ObColor wasnt converted into an RNA string.
Updated Mathutils.Vector/Euler/Quaternion/Matrix so these are types rather then module methods, each type now has a tp_new function, matching python builtins float/int/str. Also cleaned up float conversion and arg passing. Changed buttons_objects.py... if ob in groups.objects: # no longer works if ob.name in groups.objects: # is the new syntax ...its more dict like and a lot faster (avoids python iterating over each item and comparing each, use a single rna lookup instead).
This commit is contained in:
@@ -35,7 +35,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel):
|
||||
# layout.itemO("OBJECT_OT_add_group");
|
||||
|
||||
for group in bpy.data.groups:
|
||||
if ob in group.objects:
|
||||
if ob.name in group.objects:
|
||||
col = layout.column(align=True)
|
||||
|
||||
row = col.box().row()
|
||||
|
||||
@@ -235,17 +235,15 @@ static char *ob_adrcodes_to_paths (int adrcode, int *array_index)
|
||||
*array_index= 1; return "delta_scale";
|
||||
case OB_DSIZE_Z:
|
||||
*array_index= 2; return "delta_scale";
|
||||
|
||||
#if 0
|
||||
case OB_COL_R:
|
||||
poin= &(ob->col[0]); break;
|
||||
*array_index= 0; return "color";
|
||||
case OB_COL_G:
|
||||
poin= &(ob->col[1]); break;
|
||||
*array_index= 1; return "color";
|
||||
case OB_COL_B:
|
||||
poin= &(ob->col[2]); break;
|
||||
*array_index= 2; return "color";
|
||||
case OB_COL_A:
|
||||
poin= &(ob->col[3]); break;
|
||||
|
||||
*array_index= 3; return "color";
|
||||
#if 0
|
||||
case OB_PD_FSTR:
|
||||
if (ob->pd) poin= &(ob->pd->f_strength);
|
||||
break;
|
||||
|
||||
@@ -36,10 +36,6 @@
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
static char M_Mathutils_doc[] = "The Blender Mathutils module\n\n";
|
||||
static char M_Mathutils_Vector_doc[] = "() - create a new vector object from a list of floats";
|
||||
static char M_Mathutils_Matrix_doc[] = "() - create a new matrix object from a list of floats";
|
||||
static char M_Mathutils_Quaternion_doc[] = "() - create a quaternion from a list or an axis of rotation and an angle";
|
||||
static char M_Mathutils_Euler_doc[] = "() - create and return a new euler object";
|
||||
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";
|
||||
@@ -57,22 +53,36 @@ static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the norma
|
||||
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},
|
||||
{"Vector", (PyCFunction) M_Mathutils_Vector, METH_VARARGS, M_Mathutils_Vector_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},
|
||||
{"Matrix", (PyCFunction) M_Mathutils_Matrix, METH_VARARGS, M_Mathutils_Matrix_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},
|
||||
{"Quaternion", (PyCFunction) M_Mathutils_Quaternion, METH_VARARGS, M_Mathutils_Quaternion_doc},
|
||||
{"DifferenceQuats", (PyCFunction) M_Mathutils_DifferenceQuats, METH_VARARGS,M_Mathutils_DifferenceQuats_doc},
|
||||
{"Slerp", (PyCFunction) M_Mathutils_Slerp, METH_VARARGS, M_Mathutils_Slerp_doc},
|
||||
{"Euler", (PyCFunction) M_Mathutils_Euler, METH_VARARGS, M_Mathutils_Euler_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},
|
||||
@@ -80,6 +90,7 @@ struct PyMethodDef M_Mathutils_methods[] = {
|
||||
{"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 */
|
||||
|
||||
@@ -120,6 +131,12 @@ PyObject *Mathutils_Init(const char *from)
|
||||
submodule = Py_InitModule3(from, M_Mathutils_methods, M_Mathutils_doc);
|
||||
#endif
|
||||
|
||||
/* 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 );
|
||||
|
||||
return (submodule);
|
||||
}
|
||||
|
||||
@@ -250,7 +267,7 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
|
||||
|
||||
//----------------------------------Mathutils.Rand() --------------------
|
||||
//returns a random number between a high and low value
|
||||
PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
|
||||
{
|
||||
float high, low, range;
|
||||
double drand;
|
||||
@@ -278,65 +295,9 @@ PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
|
||||
return PyFloat_FromDouble(drand);
|
||||
}
|
||||
//----------------------------------VECTOR FUNCTIONS---------------------
|
||||
//----------------------------------Mathutils.Vector() ------------------
|
||||
// Supports 2D, 3D, and 4D vector objects both int and float values
|
||||
// accepted. Mixed float and int values accepted. Ints are parsed to float
|
||||
PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float vec[4], f;
|
||||
PyObject *v;
|
||||
|
||||
size = PySequence_Length(args);
|
||||
if (size == 1) {
|
||||
listObject = PySequence_GetItem(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
} else { // Single argument was not a sequence
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (size == 0) {
|
||||
//returns a new empty 3d vector
|
||||
return newVectorObject(NULL, 3, Py_NEW);
|
||||
} else {
|
||||
Py_INCREF(args);
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size<2 || size>4) { // Invalid vector size
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
v=PySequence_GetItem(listObject, i);
|
||||
if (v==NULL) { // Failed to read sequence
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f= PyFloat_AsDouble(v);
|
||||
if(f==-1 && PyErr_Occurred()) { // parsed item not a number
|
||||
Py_DECREF(v);
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vec[i]= f;
|
||||
Py_DECREF(v);
|
||||
}
|
||||
Py_DECREF(listObject);
|
||||
return newVectorObject(vec, size, Py_NEW);
|
||||
}
|
||||
//----------------------------------Mathutils.AngleBetweenVecs() ---------
|
||||
//calculates the angle between 2 vectors
|
||||
PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
|
||||
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;
|
||||
@@ -378,7 +339,7 @@ AttributeError2:
|
||||
}
|
||||
//----------------------------------Mathutils.MidpointVecs() -------------
|
||||
//calculates the midpoint between 2 vectors
|
||||
PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
float vec[4];
|
||||
@@ -400,7 +361,7 @@ PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.ProjectVecs() -------------
|
||||
//projects vector 1 onto vector 2
|
||||
PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
float vec[4];
|
||||
@@ -432,94 +393,10 @@ PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
|
||||
return newVectorObject(vec, size, Py_NEW);
|
||||
}
|
||||
//----------------------------------MATRIX FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.Matrix() -----------------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//create a new matrix type
|
||||
PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *listObject = NULL;
|
||||
PyObject *argObject, *m, *s, *f;
|
||||
MatrixObject *mat;
|
||||
int argSize, seqSize = 0, i, j;
|
||||
float matrix[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};
|
||||
|
||||
argSize = PySequence_Length(args);
|
||||
if(argSize > 4){ //bad arg nums
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
} else if (argSize == 0) { //return empty 4D matrix
|
||||
return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW);
|
||||
}else if (argSize == 1){
|
||||
//copy constructor for matrix objects
|
||||
argObject = PySequence_GetItem(args, 0);
|
||||
if(MatrixObject_Check(argObject)){
|
||||
mat = (MatrixObject*)argObject;
|
||||
|
||||
argSize = mat->rowSize; //rows
|
||||
seqSize = mat->colSize; //col
|
||||
for(i = 0; i < (seqSize * argSize); i++){
|
||||
matrix[i] = mat->contigPtr[i];
|
||||
}
|
||||
}
|
||||
Py_DECREF(argObject);
|
||||
}else{ //2-4 arguments (all seqs? all same size?)
|
||||
for(i =0; i < argSize; i++){
|
||||
argObject = PySequence_GetItem(args, i);
|
||||
if (PySequence_Check(argObject)) { //seq?
|
||||
if(seqSize){ //0 at first
|
||||
if(PySequence_Length(argObject) != seqSize){ //seq size not same
|
||||
Py_DECREF(argObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
seqSize = PySequence_Length(argObject);
|
||||
}else{ //arg not a sequence
|
||||
Py_XDECREF(argObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(argObject);
|
||||
}
|
||||
//all is well... let's continue parsing
|
||||
listObject = args;
|
||||
for (i = 0; i < argSize; i++){
|
||||
m = PySequence_GetItem(listObject, i);
|
||||
if (m == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < seqSize; j++) {
|
||||
s = PySequence_GetItem(m, j);
|
||||
if (s == NULL) { // Failed to read sequence
|
||||
Py_DECREF(m);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = PyNumber_Float(s);
|
||||
if(f == NULL) { // parsed item is not a number
|
||||
Py_DECREF(m);
|
||||
Py_DECREF(s);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
matrix[(seqSize*i)+j]=(float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(s);
|
||||
}
|
||||
Py_DECREF(m);
|
||||
}
|
||||
}
|
||||
return newMatrixObject(matrix, argSize, seqSize, Py_NEW);
|
||||
}
|
||||
//----------------------------------Mathutils.RotationMatrix() ----------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//creates a rotation matrix
|
||||
PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec = NULL;
|
||||
char *axis = NULL;
|
||||
@@ -648,7 +525,7 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.TranslationMatrix() -------
|
||||
//creates a translation matrix
|
||||
PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
|
||||
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,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
@@ -672,7 +549,7 @@ PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
|
||||
//----------------------------------Mathutils.ScaleMatrix() -------------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//creates a scaling matrix
|
||||
PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec = NULL;
|
||||
float norm = 0.0f, factor;
|
||||
@@ -746,7 +623,7 @@ 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
|
||||
PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec = NULL;
|
||||
char *plane;
|
||||
@@ -844,7 +721,7 @@ PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.ShearMatrix() -------------
|
||||
//creates a shear matrix
|
||||
PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
int matSize;
|
||||
char *plane;
|
||||
@@ -910,135 +787,10 @@ PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
|
||||
return newMatrixObject(mat, matSize, matSize, Py_NEW);
|
||||
}
|
||||
//----------------------------------QUATERNION FUNCTIONS-----------------
|
||||
//----------------------------------Mathutils.Quaternion() --------------
|
||||
PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *listObject = NULL, *n, *q, *f;
|
||||
int size, i;
|
||||
float quat[4];
|
||||
double norm = 0.0f, angle = 0.0f;
|
||||
|
||||
size = PySequence_Length(args);
|
||||
if (size == 1 || size == 2) { //seq?
|
||||
listObject = PySequence_GetItem(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
if ((size == 4 && PySequence_Length(args) !=1) ||
|
||||
(size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) {
|
||||
// invalid args/size
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
if(size == 3){ //get angle in axis/angle
|
||||
n = PySequence_GetItem(args, 1);
|
||||
if(n == NULL) { // parsed item not a number or getItem fail
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
angle = PyFloat_AsDouble(n);
|
||||
Py_DECREF(n);
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Py_DECREF(listObject); /* assume the list is teh second arg */
|
||||
listObject = PySequence_GetItem(args, 1);
|
||||
if (size>1 && PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
if (size != 3) {
|
||||
// invalid args/size
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
n = PySequence_GetItem(args, 0);
|
||||
if(n == NULL) { // parsed item not a number or getItem fail
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
angle = PyFloat_AsDouble(n);
|
||||
Py_DECREF(n);
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
} else { // argument was not a sequence
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (size == 0) { //returns a new empty quat
|
||||
return newQuaternionObject(NULL, Py_NEW);
|
||||
} else {
|
||||
Py_INCREF(args);
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size == 3) { // invalid quat size
|
||||
if(PySequence_Length(args) != 2){
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}else{
|
||||
if(size != 4){
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) { //parse
|
||||
q = PySequence_GetItem(listObject, i);
|
||||
if (q == NULL) { // Failed to read sequence
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = PyNumber_Float(q);
|
||||
if(f == NULL) { // parsed item not a number
|
||||
Py_DECREF(q);
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quat[i] = (float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(q);
|
||||
}
|
||||
if(size == 3){ //calculate the quat based on axis/angle
|
||||
norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
|
||||
quat[0] /= (float)norm;
|
||||
quat[1] /= (float)norm;
|
||||
quat[2] /= (float)norm;
|
||||
|
||||
angle = angle * (Py_PI / 180);
|
||||
quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
|
||||
quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
|
||||
quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
|
||||
quat[0] =(float) (cos(angle/ 2.0f));
|
||||
}
|
||||
|
||||
Py_DECREF(listObject);
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
|
||||
//----------------------------------Mathutils.DifferenceQuats() ---------
|
||||
//returns the difference between 2 quaternions
|
||||
PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
|
||||
{
|
||||
QuaternionObject *quatU = NULL, *quatV = NULL;
|
||||
float quat[4], tempQuat[4];
|
||||
@@ -1065,7 +817,7 @@ PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.Slerp() ------------------
|
||||
//attemps to interpolate 2 quaternions and return the result
|
||||
PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
|
||||
{
|
||||
QuaternionObject *quatU = NULL, *quatV = NULL;
|
||||
float quat[4], quat_u[4], quat_v[4], param;
|
||||
@@ -1121,67 +873,9 @@ PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
//----------------------------------EULER FUNCTIONS----------------------
|
||||
//----------------------------------Mathutils.Euler() -------------------
|
||||
//makes a new euler for you to play with
|
||||
PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args)
|
||||
{
|
||||
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float eul[3];
|
||||
PyObject *e, *f;
|
||||
|
||||
size = PySequence_Length(args);
|
||||
if (size == 1) {
|
||||
listObject = PySequence_GetItem(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
} else { // Single argument was not a sequence
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (size == 0) {
|
||||
//returns a new empty 3d euler
|
||||
return newEulerObject(NULL, Py_NEW);
|
||||
} else {
|
||||
Py_INCREF(args);
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size != 3) { // Invalid euler size
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
e = PySequence_GetItem(listObject, i);
|
||||
if (e == NULL) { // Failed to read sequence
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = PyNumber_Float(e);
|
||||
if(f == NULL) { // parsed item not a number
|
||||
Py_DECREF(e);
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eul[i]=(float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(e);
|
||||
}
|
||||
Py_DECREF(listObject);
|
||||
return newEulerObject(eul, Py_NEW);
|
||||
}
|
||||
|
||||
//---------------------------------INTERSECTION FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.Intersect() -------------------
|
||||
PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
|
||||
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];
|
||||
@@ -1251,7 +945,7 @@ PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
|
||||
}
|
||||
//----------------------------------Mathutils.LineIntersect() -------------------
|
||||
/* Line-Line intersection using algorithm from mathworld.wolfram.com */
|
||||
PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject * tuple;
|
||||
VectorObject *vec1, *vec2, *vec3, *vec4;
|
||||
@@ -1315,7 +1009,7 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
|
||||
//---------------------------------NORMALS FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.QuadNormal() -------------------
|
||||
PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
|
||||
{
|
||||
VectorObject *vec1;
|
||||
VectorObject *vec2;
|
||||
@@ -1362,7 +1056,7 @@ PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
|
||||
}
|
||||
|
||||
//----------------------------Mathutils.TriangleNormal() -------------------
|
||||
PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
|
||||
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];
|
||||
@@ -1396,7 +1090,7 @@ PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
|
||||
|
||||
//--------------------------------- AREA FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.TriangleArea() -------------------
|
||||
PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
|
||||
{
|
||||
VectorObject *vec1, *vec2, *vec3;
|
||||
float v1[3], v2[3], v3[3];
|
||||
|
||||
@@ -44,27 +44,6 @@ PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat);
|
||||
PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec);
|
||||
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
|
||||
|
||||
PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value);
|
||||
PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args );
|
||||
|
||||
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
|
||||
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
|
||||
|
||||
|
||||
@@ -34,15 +34,24 @@
|
||||
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
char Euler_Zero_doc[] = "() - set all values in the euler to 0";
|
||||
char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock";
|
||||
char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation";
|
||||
char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation";
|
||||
char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation";
|
||||
char Euler_copy_doc[] = "() - returns a copy of the euler.";
|
||||
char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping).";
|
||||
static char Euler_Zero_doc[] = "() - set all values in the euler to 0";
|
||||
static char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock";
|
||||
static char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation";
|
||||
static char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation";
|
||||
static char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation";
|
||||
static char Euler_copy_doc[] = "() - returns a copy of the euler.";
|
||||
static char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping).";
|
||||
|
||||
static PyObject *Euler_Zero( EulerObject * self );
|
||||
static PyObject *Euler_Unique( EulerObject * self );
|
||||
static PyObject *Euler_ToMatrix( EulerObject * self );
|
||||
static PyObject *Euler_ToQuat( EulerObject * self );
|
||||
static PyObject *Euler_Rotate( EulerObject * self, PyObject *args );
|
||||
static PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value );
|
||||
static PyObject *Euler_copy( EulerObject * self, PyObject *args );
|
||||
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
struct PyMethodDef Euler_methods[] = {
|
||||
static struct PyMethodDef Euler_methods[] = {
|
||||
{"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc},
|
||||
{"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc},
|
||||
{"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc},
|
||||
@@ -53,10 +62,63 @@ struct PyMethodDef Euler_methods[] = {
|
||||
{"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Euler() -------------------
|
||||
//makes a new euler for you to play with
|
||||
static PyObject *Euler_new(PyObject * self, PyObject * args)
|
||||
{
|
||||
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float eul[3], scalar;
|
||||
PyObject *e;
|
||||
|
||||
size = PyTuple_GET_SIZE(args);
|
||||
if (size == 1) {
|
||||
listObject = PyTuple_GET_ITEM(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
} else { // Single argument was not a sequence
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (size == 0) {
|
||||
//returns a new empty 3d euler
|
||||
return newEulerObject(NULL, Py_NEW);
|
||||
} else {
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size != 3) { // Invalid euler size
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
e = PySequence_GetItem(listObject, i);
|
||||
if (e == NULL) { // Failed to read sequence
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar= (float)PyFloat_AsDouble(e);
|
||||
Py_DECREF(e);
|
||||
|
||||
if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eul[i]= scalar;
|
||||
}
|
||||
return newEulerObject(eul, Py_NEW);
|
||||
}
|
||||
|
||||
//-----------------------------METHODS----------------------------
|
||||
//----------------------------Euler.toQuat()----------------------
|
||||
//return a quaternion representation of the euler
|
||||
PyObject *Euler_ToQuat(EulerObject * self)
|
||||
static PyObject *Euler_ToQuat(EulerObject * self)
|
||||
{
|
||||
float eul[3], quat[4];
|
||||
int x;
|
||||
@@ -69,7 +131,7 @@ PyObject *Euler_ToQuat(EulerObject * self)
|
||||
}
|
||||
//----------------------------Euler.toMatrix()---------------------
|
||||
//return a matrix representation of the euler
|
||||
PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
static PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
{
|
||||
float eul[3];
|
||||
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
@@ -83,7 +145,7 @@ PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
}
|
||||
//----------------------------Euler.unique()-----------------------
|
||||
//sets the x,y,z values to a unique euler rotation
|
||||
PyObject *Euler_Unique(EulerObject * self)
|
||||
static PyObject *Euler_Unique(EulerObject * self)
|
||||
{
|
||||
double heading, pitch, bank;
|
||||
double pi2 = Py_PI * 2.0f;
|
||||
@@ -134,7 +196,7 @@ PyObject *Euler_Unique(EulerObject * self)
|
||||
}
|
||||
//----------------------------Euler.zero()-------------------------
|
||||
//sets the euler to 0,0,0
|
||||
PyObject *Euler_Zero(EulerObject * self)
|
||||
static PyObject *Euler_Zero(EulerObject * self)
|
||||
{
|
||||
self->eul[0] = 0.0;
|
||||
self->eul[1] = 0.0;
|
||||
@@ -146,7 +208,7 @@ PyObject *Euler_Zero(EulerObject * self)
|
||||
//----------------------------Euler.rotate()-----------------------
|
||||
//rotates a euler a certain amount and returns the result
|
||||
//should return a unique euler rotation (i.e. no 720 degree pitches :)
|
||||
PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
||||
static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
||||
{
|
||||
float angle = 0.0f;
|
||||
char *axis;
|
||||
@@ -176,7 +238,7 @@ PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
{
|
||||
float eul_from_rad[3];
|
||||
int x;
|
||||
@@ -203,7 +265,7 @@ PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
|
||||
//----------------------------Euler.rotate()-----------------------
|
||||
// return a copy of the euler
|
||||
PyObject *Euler_copy(EulerObject * self, PyObject *args)
|
||||
static PyObject *Euler_copy(EulerObject * self, PyObject *args)
|
||||
{
|
||||
return newEulerObject(self->eul, Py_NEW);
|
||||
}
|
||||
@@ -509,7 +571,7 @@ PyTypeObject euler_Type = {
|
||||
0, //tp_dictoffset
|
||||
0, //tp_init
|
||||
0, //tp_alloc
|
||||
0, //tp_new
|
||||
Euler_new, //tp_new
|
||||
0, //tp_free
|
||||
0, //tp_is_gc
|
||||
0, //tp_bases
|
||||
|
||||
@@ -54,13 +54,6 @@ be stored in py_data) or be a wrapper for data allocated through
|
||||
blender (stored in blend_data). This is an either/or struct not both*/
|
||||
|
||||
//prototypes
|
||||
PyObject *Euler_Zero( EulerObject * self );
|
||||
PyObject *Euler_Unique( EulerObject * self );
|
||||
PyObject *Euler_ToMatrix( EulerObject * self );
|
||||
PyObject *Euler_ToQuat( EulerObject * self );
|
||||
PyObject *Euler_Rotate( EulerObject * self, PyObject *args );
|
||||
PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value );
|
||||
PyObject *Euler_copy( EulerObject * self, PyObject *args );
|
||||
PyObject *newEulerObject( float *eul, int type );
|
||||
|
||||
#endif /* EXPP_euler_h */
|
||||
|
||||
@@ -32,20 +32,34 @@
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
/*-------------------------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_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_scalePart_doc[] = "() - convert matrix to a 3D vector";
|
||||
char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix";
|
||||
char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with.";
|
||||
char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation";
|
||||
char Matrix_copy_doc[] = "() - return a copy of the matrix";
|
||||
static char Matrix_Zero_doc[] = "() - set all values in the matrix to 0";
|
||||
static char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix";
|
||||
static char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose";
|
||||
static char Matrix_Determinant_doc[] = "() - return the determinant of the matrix";
|
||||
static char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible";
|
||||
static char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix";
|
||||
static char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix";
|
||||
static char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector";
|
||||
static char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix";
|
||||
static char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with.";
|
||||
static char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation";
|
||||
static char Matrix_copy_doc[] = "() - return a copy of the matrix";
|
||||
|
||||
static PyObject *Matrix_Zero( MatrixObject * self );
|
||||
static PyObject *Matrix_Identity( MatrixObject * self );
|
||||
static PyObject *Matrix_Transpose( MatrixObject * self );
|
||||
static PyObject *Matrix_Determinant( MatrixObject * self );
|
||||
static PyObject *Matrix_Invert( MatrixObject * self );
|
||||
static PyObject *Matrix_TranslationPart( MatrixObject * self );
|
||||
static PyObject *Matrix_RotationPart( MatrixObject * self );
|
||||
static PyObject *Matrix_scalePart( MatrixObject * self );
|
||||
static PyObject *Matrix_Resize4x4( MatrixObject * self );
|
||||
static PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args );
|
||||
static PyObject *Matrix_toQuat( MatrixObject * self );
|
||||
static PyObject *Matrix_copy( MatrixObject * self );
|
||||
|
||||
/*-----------------------METHOD DEFINITIONS ----------------------*/
|
||||
struct PyMethodDef Matrix_methods[] = {
|
||||
static 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},
|
||||
@@ -61,9 +75,86 @@ struct PyMethodDef Matrix_methods[] = {
|
||||
{"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Matrix() -----------------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//create a new matrix type
|
||||
static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *argObject, *m, *s;
|
||||
MatrixObject *mat;
|
||||
int argSize, seqSize = 0, i, j;
|
||||
float matrix[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};
|
||||
float scalar;
|
||||
|
||||
argSize = PyTuple_GET_SIZE(args);
|
||||
if(argSize > 4){ //bad arg nums
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
} else if (argSize == 0) { //return empty 4D matrix
|
||||
return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW);
|
||||
}else if (argSize == 1){
|
||||
//copy constructor for matrix objects
|
||||
argObject = PyTuple_GET_ITEM(args, 0);
|
||||
if(MatrixObject_Check(argObject)){
|
||||
mat = (MatrixObject*)argObject;
|
||||
|
||||
argSize = mat->rowSize; //rows
|
||||
seqSize = mat->colSize; //col
|
||||
for(i = 0; i < (seqSize * argSize); i++){
|
||||
matrix[i] = mat->contigPtr[i];
|
||||
}
|
||||
}
|
||||
}else{ //2-4 arguments (all seqs? all same size?)
|
||||
for(i =0; i < argSize; i++){
|
||||
argObject = PyTuple_GET_ITEM(args, i);
|
||||
if (PySequence_Check(argObject)) { //seq?
|
||||
if(seqSize){ //0 at first
|
||||
if(PySequence_Length(argObject) != seqSize){ //seq size not same
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
seqSize = PySequence_Length(argObject);
|
||||
}else{ //arg not a sequence
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
//all is well... let's continue parsing
|
||||
for (i = 0; i < argSize; i++){
|
||||
m = PyTuple_GET_ITEM(args, i);
|
||||
if (m == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < seqSize; j++) {
|
||||
s = PySequence_GetItem(m, j);
|
||||
if (s == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar= (float)PyFloat_AsDouble(s);
|
||||
Py_DECREF(s);
|
||||
|
||||
if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
matrix[(seqSize*i)+j]= scalar;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newMatrixObject(matrix, argSize, seqSize, Py_NEW);
|
||||
}
|
||||
|
||||
/*-----------------------------METHODS----------------------------*/
|
||||
/*---------------------------Matrix.toQuat() ---------------------*/
|
||||
PyObject *Matrix_toQuat(MatrixObject * self)
|
||||
static PyObject *Matrix_toQuat(MatrixObject * self)
|
||||
{
|
||||
float quat[4];
|
||||
|
||||
@@ -872,7 +963,7 @@ PyTypeObject matrix_Type = {
|
||||
0, /*tp_dictoffset*/
|
||||
0, /*tp_init*/
|
||||
0, /*tp_alloc*/
|
||||
0, /*tp_new*/
|
||||
Matrix_new, /*tp_new*/
|
||||
0, /*tp_free*/
|
||||
0, /*tp_is_gc*/
|
||||
0, /*tp_bases*/
|
||||
|
||||
@@ -56,18 +56,6 @@ be stored in py_data) or be a wrapper for data allocated through
|
||||
blender (stored in blend_data). This is an either/or struct not both*/
|
||||
|
||||
/*prototypes*/
|
||||
PyObject *Matrix_Zero( MatrixObject * self );
|
||||
PyObject *Matrix_Identity( MatrixObject * self );
|
||||
PyObject *Matrix_Transpose( MatrixObject * self );
|
||||
PyObject *Matrix_Determinant( MatrixObject * self );
|
||||
PyObject *Matrix_Invert( MatrixObject * self );
|
||||
PyObject *Matrix_TranslationPart( MatrixObject * self );
|
||||
PyObject *Matrix_RotationPart( MatrixObject * self );
|
||||
PyObject *Matrix_scalePart( MatrixObject * self );
|
||||
PyObject *Matrix_Resize4x4( MatrixObject * self );
|
||||
PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args );
|
||||
PyObject *Matrix_toQuat( MatrixObject * self );
|
||||
PyObject *Matrix_copy( MatrixObject * self );
|
||||
PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type);
|
||||
|
||||
#endif /* EXPP_matrix_H */
|
||||
|
||||
@@ -34,18 +34,30 @@
|
||||
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)";
|
||||
char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative";
|
||||
char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate";
|
||||
char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse";
|
||||
char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion";
|
||||
char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with.";
|
||||
char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion";
|
||||
char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another";
|
||||
char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another";
|
||||
char Quaternion_copy_doc[] = "() - return a copy of the quat";
|
||||
static char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)";
|
||||
static char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative";
|
||||
static char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate";
|
||||
static char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse";
|
||||
static char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion";
|
||||
static char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with.";
|
||||
static char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion";
|
||||
static char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another";
|
||||
static char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another";
|
||||
static char Quaternion_copy_doc[] = "() - return a copy of the quat";
|
||||
|
||||
static PyObject *Quaternion_Identity( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Negate( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Conjugate( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Inverse( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Normalize( QuaternionObject * self );
|
||||
static PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args );
|
||||
static PyObject *Quaternion_ToMatrix( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value );
|
||||
static PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value );
|
||||
static PyObject *Quaternion_copy( QuaternionObject * self );
|
||||
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
struct PyMethodDef Quaternion_methods[] = {
|
||||
static struct PyMethodDef Quaternion_methods[] = {
|
||||
{"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, Quaternion_Identity_doc},
|
||||
{"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, Quaternion_Negate_doc},
|
||||
{"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc},
|
||||
@@ -59,10 +71,117 @@ struct PyMethodDef Quaternion_methods[] = {
|
||||
{"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Quaternion() --------------
|
||||
static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *listObject = NULL, *n, *q, *f;
|
||||
int size, i;
|
||||
float quat[4], scalar;
|
||||
double norm = 0.0f, angle = 0.0f;
|
||||
|
||||
size = PyTuple_GET_SIZE(args);
|
||||
if (size == 1 || size == 2) { //seq?
|
||||
listObject = PyTuple_GET_ITEM(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
if ((size == 4 && PySequence_Length(args) !=1) ||
|
||||
(size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) {
|
||||
// invalid args/size
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
if(size == 3){ //get angle in axis/angle
|
||||
n = PySequence_GetItem(args, 1);
|
||||
if(n == NULL) { // parsed item not a number or getItem fail
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
angle = PyFloat_AsDouble(n);
|
||||
Py_DECREF(n);
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
listObject = PyTuple_GET_ITEM(args, 1);
|
||||
if (size>1 && PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
if (size != 3) {
|
||||
// invalid args/size
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
angle = PyFloat_AsDouble(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
} else { // argument was not a sequence
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (size == 0) { //returns a new empty quat
|
||||
return newQuaternionObject(NULL, Py_NEW);
|
||||
} else {
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size == 3) { // invalid quat size
|
||||
if(PySequence_Length(args) != 2){
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}else{
|
||||
if(size != 4){
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) { //parse
|
||||
q = PySequence_GetItem(listObject, i);
|
||||
if (q == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar = PyFloat_AsDouble(q);
|
||||
if (scalar==-1 && PyErr_Occurred()) {
|
||||
Py_DECREF(q);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quat[i] = scalar;
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(q);
|
||||
}
|
||||
if(size == 3){ //calculate the quat based on axis/angle
|
||||
norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
|
||||
quat[0] /= (float)norm;
|
||||
quat[1] /= (float)norm;
|
||||
quat[2] /= (float)norm;
|
||||
|
||||
angle = angle * (Py_PI / 180);
|
||||
quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
|
||||
quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
|
||||
quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
|
||||
quat[0] =(float) (cos(angle/ 2.0f));
|
||||
}
|
||||
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
|
||||
//-----------------------------METHODS------------------------------
|
||||
//----------------------------Quaternion.toEuler()------------------
|
||||
//return the quat as a euler
|
||||
PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
{
|
||||
float eul[3];
|
||||
EulerObject *eul_compat = NULL;
|
||||
@@ -93,7 +212,7 @@ PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
}
|
||||
//----------------------------Quaternion.toMatrix()------------------
|
||||
//return the quat as a matrix
|
||||
PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
{
|
||||
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
QuatToMat3(self->quat, (float (*)[3]) mat);
|
||||
@@ -103,7 +222,7 @@ PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
|
||||
//----------------------------Quaternion.cross(other)------------------
|
||||
//return the cross quat
|
||||
PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
|
||||
static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
|
||||
{
|
||||
float quat[4];
|
||||
|
||||
@@ -118,7 +237,7 @@ PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
|
||||
|
||||
//----------------------------Quaternion.dot(other)------------------
|
||||
//return the dot quat
|
||||
PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
{
|
||||
int x;
|
||||
double dot = 0.0;
|
||||
@@ -136,7 +255,7 @@ PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
|
||||
//----------------------------Quaternion.normalize()----------------
|
||||
//normalize the axis of rotation of [theta,vector]
|
||||
PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
{
|
||||
NormalQuat(self->quat);
|
||||
Py_INCREF(self);
|
||||
@@ -144,7 +263,7 @@ PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.inverse()------------------
|
||||
//invert the quat
|
||||
PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
{
|
||||
double mag = 0.0f;
|
||||
int x;
|
||||
@@ -165,7 +284,7 @@ PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.identity()-----------------
|
||||
//generate the identity quaternion
|
||||
PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
{
|
||||
self->quat[0] = 1.0;
|
||||
self->quat[1] = 0.0;
|
||||
@@ -177,7 +296,7 @@ PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.negate()-------------------
|
||||
//negate the quat
|
||||
PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
{
|
||||
int x;
|
||||
for(x = 0; x < 4; x++) {
|
||||
@@ -188,7 +307,7 @@ PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.conjugate()----------------
|
||||
//negate the vector part
|
||||
PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
{
|
||||
int x;
|
||||
for(x = 1; x < 4; x++) {
|
||||
@@ -199,7 +318,7 @@ PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.copy()----------------
|
||||
//return a copy of the quat
|
||||
PyObject *Quaternion_copy(QuaternionObject * self)
|
||||
static PyObject *Quaternion_copy(QuaternionObject * self)
|
||||
{
|
||||
return newQuaternionObject(self->quat, Py_NEW);
|
||||
}
|
||||
@@ -680,7 +799,7 @@ PyTypeObject quaternion_Type = {
|
||||
0, //tp_dictoffset
|
||||
0, //tp_init
|
||||
0, //tp_alloc
|
||||
0, //tp_new
|
||||
Quaternion_new, //tp_new
|
||||
0, //tp_free
|
||||
0, //tp_is_gc
|
||||
0, //tp_bases
|
||||
|
||||
@@ -54,16 +54,6 @@ be stored in py_data) or be a wrapper for data allocated through
|
||||
blender (stored in blend_data). This is an either/or struct not both*/
|
||||
|
||||
//prototypes
|
||||
PyObject *Quaternion_Identity( QuaternionObject * self );
|
||||
PyObject *Quaternion_Negate( QuaternionObject * self );
|
||||
PyObject *Quaternion_Conjugate( QuaternionObject * self );
|
||||
PyObject *Quaternion_Inverse( QuaternionObject * self );
|
||||
PyObject *Quaternion_Normalize( QuaternionObject * self );
|
||||
PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args );
|
||||
PyObject *Quaternion_ToMatrix( QuaternionObject * self );
|
||||
PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value );
|
||||
PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value );
|
||||
PyObject *Quaternion_copy( QuaternionObject * self );
|
||||
PyObject *newQuaternionObject( float *quat, int type );
|
||||
|
||||
#endif /* EXPP_quat_h */
|
||||
|
||||
@@ -40,20 +40,32 @@
|
||||
#define SWIZZLE_AXIS 0x3
|
||||
|
||||
/*-------------------------DOC STRINGS ---------------------------*/
|
||||
char Vector_Zero_doc[] = "() - set all values in the vector to 0";
|
||||
char Vector_Normalize_doc[] = "() - normalize the vector";
|
||||
char Vector_Negate_doc[] = "() - changes vector to it's additive inverse";
|
||||
char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]";
|
||||
char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
|
||||
char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";
|
||||
char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis";
|
||||
char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal";
|
||||
char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another";
|
||||
char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another";
|
||||
char Vector_copy_doc[] = "() - return a copy of the vector";
|
||||
char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order";
|
||||
static char Vector_Zero_doc[] = "() - set all values in the vector to 0";
|
||||
static char Vector_Normalize_doc[] = "() - normalize the vector";
|
||||
static char Vector_Negate_doc[] = "() - changes vector to it's additive inverse";
|
||||
static char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]";
|
||||
static char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
|
||||
static char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";
|
||||
static char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis";
|
||||
static char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal";
|
||||
static char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another";
|
||||
static char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another";
|
||||
static char Vector_copy_doc[] = "() - return a copy of the vector";
|
||||
static char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order";
|
||||
/*-----------------------METHOD DEFINITIONS ----------------------*/
|
||||
struct PyMethodDef Vector_methods[] = {
|
||||
static PyObject *Vector_Zero( VectorObject * self );
|
||||
static PyObject *Vector_Normalize( VectorObject * self );
|
||||
static PyObject *Vector_Negate( VectorObject * self );
|
||||
static PyObject *Vector_Resize2D( VectorObject * self );
|
||||
static PyObject *Vector_Resize3D( VectorObject * self );
|
||||
static PyObject *Vector_Resize4D( VectorObject * self );
|
||||
static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
|
||||
static PyObject *Vector_Reflect( VectorObject * self, PyObject * value );
|
||||
static PyObject *Vector_Cross( VectorObject * self, VectorObject * value );
|
||||
static PyObject *Vector_Dot( VectorObject * self, VectorObject * value );
|
||||
static PyObject *Vector_copy( VectorObject * self );
|
||||
|
||||
static struct PyMethodDef Vector_methods[] = {
|
||||
{"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc},
|
||||
{"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc},
|
||||
{"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc},
|
||||
@@ -69,10 +81,61 @@ struct PyMethodDef Vector_methods[] = {
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Vector() ------------------
|
||||
// Supports 2D, 3D, and 4D vector objects both int and float values
|
||||
// accepted. Mixed float and int values accepted. Ints are parsed to float
|
||||
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float vec[4], f;
|
||||
PyObject *v;
|
||||
|
||||
size = PyTuple_GET_SIZE(args); /* we know its a tuple because its an arg */
|
||||
if (size == 1) {
|
||||
listObject = PyTuple_GET_ITEM(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
} else { // Single argument was not a sequence
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (size == 0) {
|
||||
//returns a new empty 3d vector
|
||||
return newVectorObject(NULL, 3, Py_NEW);
|
||||
} else {
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size<2 || size>4) { // Invalid vector size
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
v=PySequence_GetItem(listObject, i);
|
||||
if (v==NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f= PyFloat_AsDouble(v);
|
||||
if(f==-1 && PyErr_Occurred()) { // parsed item not a number
|
||||
Py_DECREF(v);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vec[i]= f;
|
||||
Py_DECREF(v);
|
||||
}
|
||||
return newVectorObject(vec, size, Py_NEW);
|
||||
}
|
||||
|
||||
/*-----------------------------METHODS---------------------------- */
|
||||
/*----------------------------Vector.zero() ----------------------
|
||||
set the vector data to 0,0,0 */
|
||||
PyObject *Vector_Zero(VectorObject * self)
|
||||
static PyObject *Vector_Zero(VectorObject * self)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < self->size; i++) {
|
||||
@@ -83,7 +146,7 @@ PyObject *Vector_Zero(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.normalize() -----------------
|
||||
normalize the vector data to a unit vector */
|
||||
PyObject *Vector_Normalize(VectorObject * self)
|
||||
static PyObject *Vector_Normalize(VectorObject * self)
|
||||
{
|
||||
int i;
|
||||
float norm = 0.0f;
|
||||
@@ -102,7 +165,7 @@ PyObject *Vector_Normalize(VectorObject * self)
|
||||
|
||||
/*----------------------------Vector.resize2D() ------------------
|
||||
resize the vector to x,y */
|
||||
PyObject *Vector_Resize2D(VectorObject * self)
|
||||
static PyObject *Vector_Resize2D(VectorObject * self)
|
||||
{
|
||||
if(self->wrapped==Py_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n");
|
||||
@@ -120,7 +183,7 @@ PyObject *Vector_Resize2D(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.resize3D() ------------------
|
||||
resize the vector to x,y,z */
|
||||
PyObject *Vector_Resize3D(VectorObject * self)
|
||||
static PyObject *Vector_Resize3D(VectorObject * self)
|
||||
{
|
||||
if (self->wrapped==Py_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n");
|
||||
@@ -141,7 +204,7 @@ PyObject *Vector_Resize3D(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.resize4D() ------------------
|
||||
resize the vector to x,y,z,w */
|
||||
PyObject *Vector_Resize4D(VectorObject * self)
|
||||
static PyObject *Vector_Resize4D(VectorObject * self)
|
||||
{
|
||||
if(self->wrapped==Py_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors");
|
||||
@@ -164,7 +227,7 @@ PyObject *Vector_Resize4D(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.toTrackQuat(track, up) ----------------------
|
||||
extract a quaternion from the vector and the track and up axis */
|
||||
PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
{
|
||||
float vec[3], quat[4];
|
||||
char *strack, *sup;
|
||||
@@ -279,7 +342,7 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
return a reflected vector on the mirror normal
|
||||
((2 * DotVecs(vec, mirror)) * mirror) - vec
|
||||
using arithb.c would be nice here */
|
||||
PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
|
||||
static PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
|
||||
{
|
||||
VectorObject *mirrvec;
|
||||
float mirror[3];
|
||||
@@ -326,7 +389,7 @@ PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
|
||||
return newVectorObject(reflect, self->size, Py_NEW);
|
||||
}
|
||||
|
||||
PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
|
||||
static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
|
||||
{
|
||||
VectorObject *vecCross = NULL;
|
||||
|
||||
@@ -345,7 +408,7 @@ PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
|
||||
return (PyObject *)vecCross;
|
||||
}
|
||||
|
||||
PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
|
||||
static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
|
||||
{
|
||||
double dot = 0.0;
|
||||
int x;
|
||||
@@ -368,7 +431,7 @@ PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
|
||||
|
||||
/*----------------------------Vector.copy() --------------------------------------
|
||||
return a copy of the vector */
|
||||
PyObject *Vector_copy(VectorObject * self)
|
||||
static PyObject *Vector_copy(VectorObject * self)
|
||||
{
|
||||
return newVectorObject(self->vec, self->size, Py_NEW);
|
||||
}
|
||||
@@ -839,7 +902,7 @@ static double vec_magnitude_nosqrt(float *data, int size)
|
||||
|
||||
/*------------------------tp_richcmpr
|
||||
returns -1 execption, 0 false, 1 true */
|
||||
PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
{
|
||||
VectorObject *vecA = NULL, *vecB = NULL;
|
||||
int result = 0;
|
||||
@@ -1727,7 +1790,7 @@ PyTypeObject vector_Type = {
|
||||
0, /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
Vector_new, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
@@ -1785,7 +1848,7 @@ PyObject *newVectorObject(float *vec, int size, int type)
|
||||
#######################################################################
|
||||
----------------------------Vector.negate() --------------------
|
||||
set the vector to it's negative -x, -y, -z */
|
||||
PyObject *Vector_Negate(VectorObject * self)
|
||||
static PyObject *Vector_Negate(VectorObject * self)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < self->size; i++) {
|
||||
|
||||
@@ -45,17 +45,6 @@ typedef struct {
|
||||
} VectorObject;
|
||||
|
||||
/*prototypes*/
|
||||
PyObject *Vector_Zero( VectorObject * self );
|
||||
PyObject *Vector_Normalize( VectorObject * self );
|
||||
PyObject *Vector_Negate( VectorObject * self );
|
||||
PyObject *Vector_Resize2D( VectorObject * self );
|
||||
PyObject *Vector_Resize3D( VectorObject * self );
|
||||
PyObject *Vector_Resize4D( VectorObject * self );
|
||||
PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
|
||||
PyObject *Vector_Reflect( VectorObject * self, PyObject * value );
|
||||
PyObject *Vector_Cross( VectorObject * self, VectorObject * value );
|
||||
PyObject *Vector_Dot( VectorObject * self, VectorObject * value );
|
||||
PyObject *Vector_copy( VectorObject * self );
|
||||
PyObject *newVectorObject(float *vec, int size, int type);
|
||||
|
||||
#endif /* EXPP_vector_h */
|
||||
|
||||
@@ -771,12 +771,12 @@ static int pyrna_prop_contains(BPy_PropertyRNA * self, PyObject *value)
|
||||
char *keyname = _PyUnicode_AsString(value);
|
||||
|
||||
if(keyname==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "PropertyRNA - key in prop, key must be a string type");
|
||||
PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, key must be a string type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (RNA_property_type(self->prop) != PROP_COLLECTION) {
|
||||
PyErr_SetString(PyExc_SystemError, "PropertyRNA - key in prop, is only valid for collection types");
|
||||
PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, is only valid for collection types");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user