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:
2009-06-20 02:44:57 +00:00
parent d0e8acaf29
commit 7785ead4eb
13 changed files with 464 additions and 498 deletions

View File

@@ -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()

View File

@@ -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;

View File

@@ -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];

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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*/

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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++) {

View File

@@ -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 */

View File

@@ -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;
}