forked from bartvdbraak/blender
Mathutils API: Euler support for rotation order.
Examples. euler = Euler(1, 2, 3) euler.order = 'ZXY' euler = matrix.to_euler('XZY') Still missing rna support. this still wont give the right order, defaulting to XYZ. eul = object.rotation_euler
This commit is contained in:
parent
65a4dafcff
commit
02e7871149
@ -2876,7 +2876,7 @@ Takes: {''')
|
|||||||
context_bone_anim_vecs = []
|
context_bone_anim_vecs = []
|
||||||
prev_eul = None
|
prev_eul = None
|
||||||
for mtx in context_bone_anim_mats:
|
for mtx in context_bone_anim_mats:
|
||||||
if prev_eul: prev_eul = mtx[1].to_euler(prev_eul)
|
if prev_eul: prev_eul = mtx[1].to_euler('XYZ', prev_eul)
|
||||||
else: prev_eul = mtx[1].to_euler()
|
else: prev_eul = mtx[1].to_euler()
|
||||||
context_bone_anim_vecs.append(eulerRadToDeg(prev_eul))
|
context_bone_anim_vecs.append(eulerRadToDeg(prev_eul))
|
||||||
# context_bone_anim_vecs.append(prev_eul)
|
# context_bone_anim_vecs.append(prev_eul)
|
||||||
|
@ -1052,7 +1052,7 @@ static RotOrderInfo rotOrders[]= {
|
|||||||
{{1, 0, 2}, 1}, // YXZ
|
{{1, 0, 2}, 1}, // YXZ
|
||||||
{{1, 2, 0}, 0}, // YZX
|
{{1, 2, 0}, 0}, // YZX
|
||||||
{{2, 0, 1}, 0}, // ZXY
|
{{2, 0, 1}, 0}, // ZXY
|
||||||
{{2, 1, 0}, 1} // ZYZ
|
{{2, 1, 0}, 1} // ZYX
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get relevant pointer to rotation order set from the array
|
/* Get relevant pointer to rotation order set from the array
|
||||||
|
@ -170,18 +170,10 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
/* Clamp to -360:360 */
|
|
||||||
while (angle<-360.0f)
|
|
||||||
angle+=360.0;
|
|
||||||
while (angle>360.0f)
|
|
||||||
angle-=360.0;
|
|
||||||
#else
|
|
||||||
while (angle<-(Py_PI*2))
|
while (angle<-(Py_PI*2))
|
||||||
angle+=(Py_PI*2);
|
angle+=(Py_PI*2);
|
||||||
while (angle>(Py_PI*2))
|
while (angle>(Py_PI*2))
|
||||||
angle-=(Py_PI*2);
|
angle-=(Py_PI*2);
|
||||||
#endif
|
|
||||||
|
|
||||||
if(matSize != 2 && matSize != 3 && matSize != 4) {
|
if(matSize != 2 && matSize != 3 && matSize != 4) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
|
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
|
||||||
@ -205,10 +197,6 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
//convert to radians
|
|
||||||
angle = angle * (float) (Py_PI / 180);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* check for valid vector/axis above */
|
/* check for valid vector/axis above */
|
||||||
if(vec) {
|
if(vec) {
|
||||||
|
@ -37,8 +37,6 @@
|
|||||||
#include "quat.h"
|
#include "quat.h"
|
||||||
#include "euler.h"
|
#include "euler.h"
|
||||||
|
|
||||||
/* #define USE_MATHUTILS_DEG - for backwards compat */
|
|
||||||
|
|
||||||
/* Can cast different mathutils types to this, use for generic funcs */
|
/* Can cast different mathutils types to this, use for generic funcs */
|
||||||
|
|
||||||
extern char BaseMathObject_Wrapped_doc[];
|
extern char BaseMathObject_Wrapped_doc[];
|
||||||
|
@ -41,6 +41,7 @@ static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwar
|
|||||||
int size, i;
|
int size, i;
|
||||||
float eul[3];
|
float eul[3];
|
||||||
PyObject *e;
|
PyObject *e;
|
||||||
|
short order= 0; // TODO, add order option
|
||||||
|
|
||||||
size = PyTuple_GET_SIZE(args);
|
size = PyTuple_GET_SIZE(args);
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
@ -53,7 +54,7 @@ static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwar
|
|||||||
}
|
}
|
||||||
} else if (size == 0) {
|
} else if (size == 0) {
|
||||||
//returns a new empty 3d euler
|
//returns a new empty 3d euler
|
||||||
return newEulerObject(NULL, Py_NEW, NULL);
|
return newEulerObject(NULL, order, Py_NEW, NULL);
|
||||||
} else {
|
} else {
|
||||||
listObject = args;
|
listObject = args;
|
||||||
}
|
}
|
||||||
@ -79,7 +80,24 @@ static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwar
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newEulerObject(eul, Py_NEW, NULL);
|
return newEulerObject(eul, order, Py_NEW, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
short euler_order_from_string(const char *str, const char *error_prefix)
|
||||||
|
{
|
||||||
|
if((str[0] && str[1] && str[2] && str[3]=='\0')) {
|
||||||
|
switch(*((int32_t *)str)) {
|
||||||
|
case 'X'|'Y'<<8|'Z'<<16: return 0;
|
||||||
|
case 'X'|'Z'<<8|'Y'<<16: return 1;
|
||||||
|
case 'Y'|'X'<<8|'Z'<<16: return 2;
|
||||||
|
case 'Y'|'Z'<<8|'X'<<16: return 3;
|
||||||
|
case 'Z'|'X'<<8|'Y'<<16: return 4;
|
||||||
|
case 'Z'|'Y'<<8|'X'<<16: return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_Format(PyExc_TypeError, "%s: invalid euler order '%s'", error_prefix, str);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------METHODS----------------------------
|
//-----------------------------METHODS----------------------------
|
||||||
@ -97,22 +115,12 @@ static char Euler_ToQuat_doc[] =
|
|||||||
static PyObject *Euler_ToQuat(EulerObject * self)
|
static PyObject *Euler_ToQuat(EulerObject * self)
|
||||||
{
|
{
|
||||||
float quat[4];
|
float quat[4];
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
float eul[3];
|
|
||||||
int x;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
if(self->order==0) eul_to_quat(quat, self->eul);
|
||||||
for(x = 0; x < 3; x++) {
|
else eulO_to_quat(quat, self->eul, self->order);
|
||||||
eul[x] = self->eul[x] * ((float)Py_PI / 180);
|
|
||||||
}
|
|
||||||
eul_to_quat( quat,eul);
|
|
||||||
#else
|
|
||||||
eul_to_quat( quat,self->eul);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return newQuaternionObject(quat, Py_NEW, NULL);
|
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
@ -133,24 +141,14 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
|
|||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
if(self->order==0) eul_to_mat3((float (*)[3])mat, self->eul);
|
||||||
{
|
else eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
|
||||||
float eul[3];
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
eul[x] = self->eul[x] * ((float)Py_PI / 180);
|
|
||||||
}
|
|
||||||
eul_to_mat3( (float (*)[3]) mat,eul);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
eul_to_mat3( (float (*)[3]) mat,self->eul);
|
|
||||||
#endif
|
|
||||||
return newMatrixObject(mat, 3, 3 , Py_NEW, NULL);
|
return newMatrixObject(mat, 3, 3 , Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
//----------------------------Euler.unique()-----------------------
|
//----------------------------Euler.unique()-----------------------
|
||||||
//sets the x,y,z values to a unique euler rotation
|
//sets the x,y,z values to a unique euler rotation
|
||||||
|
// TODO, check if this works with rotation order!!!
|
||||||
static char Euler_Unique_doc[] =
|
static char Euler_Unique_doc[] =
|
||||||
".. method:: unique()\n"
|
".. method:: unique()\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -170,16 +168,9 @@ static PyObject *Euler_Unique(EulerObject * self)
|
|||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
//radians
|
|
||||||
heading = self->eul[0] * (float)Py_PI / 180;
|
|
||||||
pitch = self->eul[1] * (float)Py_PI / 180;
|
|
||||||
bank = self->eul[2] * (float)Py_PI / 180;
|
|
||||||
#else
|
|
||||||
heading = self->eul[0];
|
heading = self->eul[0];
|
||||||
pitch = self->eul[1];
|
pitch = self->eul[1];
|
||||||
bank = self->eul[2];
|
bank = self->eul[2];
|
||||||
#endif
|
|
||||||
|
|
||||||
//wrap heading in +180 / -180
|
//wrap heading in +180 / -180
|
||||||
pitch += Py_PI;
|
pitch += Py_PI;
|
||||||
@ -210,13 +201,6 @@ static PyObject *Euler_Unique(EulerObject * self)
|
|||||||
heading -= (floor(heading * PI_INV)) * PI_2;
|
heading -= (floor(heading * PI_INV)) * PI_2;
|
||||||
heading -= Py_PI;
|
heading -= Py_PI;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
//back to degrees
|
|
||||||
self->eul[0] = (float)(heading * 180 / (float)Py_PI);
|
|
||||||
self->eul[1] = (float)(pitch * 180 / (float)Py_PI);
|
|
||||||
self->eul[2] = (float)(bank * 180 / (float)Py_PI);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BaseMath_WriteCallback(self);
|
BaseMath_WriteCallback(self);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
@ -261,28 +245,8 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
|||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
if(self->order == 0) rotate_eul(self->eul, *axis, angle);
|
||||||
{
|
else rotate_eulO(self->eul, self->order, *axis, angle);
|
||||||
int x;
|
|
||||||
|
|
||||||
//covert to radians
|
|
||||||
angle *= ((float)Py_PI / 180);
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
self->eul[x] *= ((float)Py_PI / 180);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rotate_eul(self->eul, *axis, angle);
|
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
//convert back from radians
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
self->eul[x] *= (180 / (float)Py_PI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BaseMath_WriteCallback(self);
|
BaseMath_WriteCallback(self);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
@ -297,40 +261,27 @@ static char Euler_MakeCompatible_doc[] =
|
|||||||
" :arg other: make compatible with this rotation.\n"
|
" :arg other: make compatible with this rotation.\n"
|
||||||
" :type other: :class:`Euler`\n"
|
" :type other: :class:`Euler`\n"
|
||||||
" :return: an instance of itself.\n"
|
" :return: an instance of itself.\n"
|
||||||
" :rtype: :class:`Euler`\n";
|
" :rtype: :class:`Euler`\n"
|
||||||
|
"\n"
|
||||||
|
" .. note:: the order of eulers must match or an exception is raised.\n";
|
||||||
|
|
||||||
static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||||
{
|
{
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
float eul_from_rad[3];
|
|
||||||
int x;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!EulerObject_Check(value)) {
|
if(!EulerObject_Check(value)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "euler.makeCompatible(euler):expected a single euler argument.");
|
PyErr_SetString(PyExc_TypeError, "euler.make_compatible(euler): expected a single euler argument.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
if(self->order != value->order) {
|
||||||
//covert to radians
|
PyErr_SetString(PyExc_ValueError, "euler.make_compatible(euler): rotation orders don't match\n");
|
||||||
for(x = 0; x < 3; x++) {
|
return NULL;
|
||||||
self->eul[x] = self->eul[x] * ((float)Py_PI / 180);
|
|
||||||
eul_from_rad[x] = value->eul[x] * ((float)Py_PI / 180);
|
|
||||||
}
|
}
|
||||||
compatible_eul(self->eul, eul_from_rad);
|
|
||||||
#else
|
|
||||||
compatible_eul(self->eul, value->eul);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
compatible_eul(self->eul, value->eul);
|
||||||
//convert back from radians
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
self->eul[x] *= (180 / (float)Py_PI);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
BaseMath_WriteCallback(self);
|
BaseMath_WriteCallback(self);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
@ -354,7 +305,7 @@ static PyObject *Euler_copy(EulerObject * self, PyObject *args)
|
|||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return newEulerObject(self->eul, Py_NEW, Py_TYPE(self));
|
return newEulerObject(self->eul, self->order, Py_NEW, Py_TYPE(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------print object (internal)--------------
|
//----------------------------print object (internal)--------------
|
||||||
@ -402,12 +353,7 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar
|
|||||||
result = EXPP_VectorsAreEqual(eulA->eul, eulB->eul, 3, 1);
|
result = EXPP_VectorsAreEqual(eulA->eul, eulB->eul, 3, 1);
|
||||||
break;
|
break;
|
||||||
case Py_NE:
|
case Py_NE:
|
||||||
result = EXPP_VectorsAreEqual(eulA->eul, eulB->eul, 3, 1);
|
result = !EXPP_VectorsAreEqual(eulA->eul, eulB->eul, 3, 1);
|
||||||
if (result == 0){
|
|
||||||
result = 1;
|
|
||||||
}else{
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("The result of the comparison could not be evaluated");
|
printf("The result of the comparison could not be evaluated");
|
||||||
@ -563,6 +509,30 @@ static int Euler_setAxis( EulerObject * self, PyObject * value, void * type )
|
|||||||
return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value);
|
return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rotation order */
|
||||||
|
static PyObject *Euler_getOrder(EulerObject *self, void *type)
|
||||||
|
{
|
||||||
|
static char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"};
|
||||||
|
return PyUnicode_FromString(order[self->order]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Euler_setOrder( EulerObject * self, PyObject * value, void * type )
|
||||||
|
{
|
||||||
|
char *order_str= _PyUnicode_AsString(value);
|
||||||
|
short order= euler_order_from_string(order_str, "euler.order");
|
||||||
|
|
||||||
|
if(order < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(self->cb_user) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "euler.order: assignment is not allowed on eulers with an owner");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->order= order;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Python attributes get/set structure: */
|
/* Python attributes get/set structure: */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -570,6 +540,7 @@ static PyGetSetDef Euler_getseters[] = {
|
|||||||
{"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis in radians. **type** float", (void *)0},
|
{"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis in radians. **type** float", (void *)0},
|
||||||
{"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis in radians. **type** float", (void *)1},
|
{"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis in radians. **type** float", (void *)1},
|
||||||
{"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis in radians. **type** float", (void *)2},
|
{"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis in radians. **type** float", (void *)2},
|
||||||
|
{"order", (getter)Euler_getOrder, (setter)Euler_setOrder, "Euler rotation order. **type** string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']", (void *)NULL},
|
||||||
|
|
||||||
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
|
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
|
||||||
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
|
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
|
||||||
@ -650,7 +621,7 @@ PyTypeObject euler_Type = {
|
|||||||
(i.e. it was allocated elsewhere by MEM_mallocN())
|
(i.e. it was allocated elsewhere by MEM_mallocN())
|
||||||
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
|
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
|
||||||
(i.e. it must be created here with PyMEM_malloc())*/
|
(i.e. it must be created here with PyMEM_malloc())*/
|
||||||
PyObject *newEulerObject(float *eul, int type, PyTypeObject *base_type)
|
PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_type)
|
||||||
{
|
{
|
||||||
EulerObject *self;
|
EulerObject *self;
|
||||||
int x;
|
int x;
|
||||||
@ -678,12 +649,14 @@ PyObject *newEulerObject(float *eul, int type, PyTypeObject *base_type)
|
|||||||
}else{ //bad type
|
}else{ //bad type
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->order= order;
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
|
PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype)
|
||||||
{
|
{
|
||||||
EulerObject *self= (EulerObject *)newEulerObject(NULL, Py_NEW, NULL);
|
EulerObject *self= (EulerObject *)newEulerObject(NULL, order, Py_NEW, NULL);
|
||||||
if(self) {
|
if(self) {
|
||||||
Py_INCREF(cb_user);
|
Py_INCREF(cb_user);
|
||||||
self->cb_user= cb_user;
|
self->cb_user= cb_user;
|
||||||
|
@ -45,6 +45,8 @@ typedef struct {
|
|||||||
unsigned char wrapped; /* wrapped data type? */
|
unsigned char wrapped; /* wrapped data type? */
|
||||||
/* end BaseMathObject */
|
/* end BaseMathObject */
|
||||||
|
|
||||||
|
unsigned char order; /* rotation order */
|
||||||
|
|
||||||
} EulerObject;
|
} EulerObject;
|
||||||
|
|
||||||
/*struct data contains a pointer to the actual data that the
|
/*struct data contains a pointer to the actual data that the
|
||||||
@ -53,7 +55,10 @@ 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*/
|
blender (stored in blend_data). This is an either/or struct not both*/
|
||||||
|
|
||||||
//prototypes
|
//prototypes
|
||||||
PyObject *newEulerObject( float *eul, int type, PyTypeObject *base_type);
|
PyObject *newEulerObject( float *eul, short order, int type, PyTypeObject *base_type);
|
||||||
PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
|
PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype);
|
||||||
|
|
||||||
|
short euler_order_from_string(const char *str, const char *error_prefix);
|
||||||
|
|
||||||
|
|
||||||
#endif /* EXPP_euler_h */
|
#endif /* EXPP_euler_h */
|
||||||
|
@ -217,7 +217,7 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
|
|||||||
|
|
||||||
/*must be 3-4 cols, 3-4 rows, square matrix*/
|
/*must be 3-4 cols, 3-4 rows, square matrix*/
|
||||||
if(self->colSize < 3 || self->rowSize < 3 || (self->colSize != self->rowSize)) {
|
if(self->colSize < 3 || self->rowSize < 3 || (self->colSize != self->rowSize)) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Matrix.toQuat(): inappropriate matrix size - expects 3x3 or 4x4 matrix");
|
PyErr_SetString(PyExc_AttributeError, "Matrix.to_quat(): inappropriate matrix size - expects 3x3 or 4x4 matrix");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(self->colSize == 3){
|
if(self->colSize == 3){
|
||||||
@ -228,12 +228,15 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
|
|||||||
|
|
||||||
return newQuaternionObject(quat, Py_NEW, NULL);
|
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------Matrix.toEuler() --------------------*/
|
/*---------------------------Matrix.toEuler() --------------------*/
|
||||||
static char Matrix_toEuler_doc[] =
|
static char Matrix_toEuler_doc[] =
|
||||||
".. method:: to_euler(euler_compat)\n"
|
".. method:: to_euler(order, euler_compat)\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Return an Euler representation of the rotation matrix (3x3 or 4x4 matrix only).\n"
|
" Return an Euler representation of the rotation matrix (3x3 or 4x4 matrix only).\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" :arg order: Optional rotation order argument in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
|
||||||
|
" :type order: string\n"
|
||||||
" :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
|
" :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
|
||||||
" :type euler_compat: :class:`Euler`\n"
|
" :type euler_compat: :class:`Euler`\n"
|
||||||
" :return: Euler representation of the matrix.\n"
|
" :return: Euler representation of the matrix.\n"
|
||||||
@ -241,53 +244,55 @@ static char Matrix_toEuler_doc[] =
|
|||||||
|
|
||||||
PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
|
PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
char *order_str= NULL;
|
||||||
|
short order= 0;
|
||||||
float eul[3], eul_compatf[3];
|
float eul[3], eul_compatf[3];
|
||||||
EulerObject *eul_compat = NULL;
|
EulerObject *eul_compat = NULL;
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
int x;
|
float tmat[3][3];
|
||||||
#endif
|
float (*mat)[3];
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
|
if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(eul_compat) {
|
if(eul_compat) {
|
||||||
if(!BaseMath_ReadCallback(eul_compat))
|
if(!BaseMath_ReadCallback(eul_compat))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
VECCOPY(eul_compatf, eul_compat->eul);
|
VECCOPY(eul_compatf, eul_compat->eul);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*must be 3-4 cols, 3-4 rows, square matrix*/
|
/*must be 3-4 cols, 3-4 rows, square matrix*/
|
||||||
if(self->colSize ==3 && self->rowSize ==3) {
|
if(self->colSize ==3 && self->rowSize ==3) {
|
||||||
if(eul_compat) mat3_to_compatible_eul( eul, eul_compatf,(float (*)[3])*self->matrix);
|
mat= (float (*)[3])self->matrix;
|
||||||
else mat3_to_eul( eul,(float (*)[3])*self->matrix);
|
|
||||||
}else if (self->colSize ==4 && self->rowSize ==4) {
|
}else if (self->colSize ==4 && self->rowSize ==4) {
|
||||||
float tempmat3[3][3];
|
copy_m3_m4(tmat, (float (*)[4])*self->matrix);
|
||||||
copy_m3_m4(tempmat3, (float (*)[4])*self->matrix);
|
mat= tmat;
|
||||||
mat3_to_eul( eul,tempmat3);
|
|
||||||
if(eul_compat) mat3_to_compatible_eul( eul, eul_compatf,tempmat3);
|
|
||||||
else mat3_to_eul( eul,tempmat3);
|
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
|
PyErr_SetString(PyExc_AttributeError, "Matrix.to_euler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
/*have to convert to degrees*/
|
if(order_str) {
|
||||||
for(x = 0; x < 3; x++) {
|
order= euler_order_from_string(order_str, "Matrix.to_euler()");
|
||||||
eul[x] *= (float) (180 / Py_PI);
|
|
||||||
|
if(order < 0)
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return newEulerObject(eul, Py_NEW, NULL);
|
if(eul_compat) {
|
||||||
|
if(order == 0) mat3_to_compatible_eul( eul, eul_compatf, mat);
|
||||||
|
else mat3_to_compatible_eulO(eul, eul_compatf, order, mat);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(order == 0) mat3_to_eul(eul, mat);
|
||||||
|
else mat3_to_eulO(eul, order, mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newEulerObject(eul, order, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
/*---------------------------Matrix.resize4x4() ------------------*/
|
/*---------------------------Matrix.resize4x4() ------------------*/
|
||||||
static char Matrix_Resize4x4_doc[] =
|
static char Matrix_Resize4x4_doc[] =
|
||||||
@ -367,21 +372,15 @@ static char Matrix_TranslationPart_doc[] =
|
|||||||
|
|
||||||
PyObject *Matrix_TranslationPart(MatrixObject * self)
|
PyObject *Matrix_TranslationPart(MatrixObject * self)
|
||||||
{
|
{
|
||||||
float vec[4];
|
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(self->colSize < 3 || self->rowSize < 4){
|
if(self->colSize < 3 || self->rowSize < 4){
|
||||||
PyErr_SetString(PyExc_AttributeError, "Matrix.translationPart: inappropriate matrix size");
|
PyErr_SetString(PyExc_AttributeError, "Matrix.translation_part(): inappropriate matrix size");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec[0] = self->matrix[3][0];
|
return newVectorObject(self->matrix[3], 3, Py_NEW, NULL);
|
||||||
vec[1] = self->matrix[3][1];
|
|
||||||
vec[2] = self->matrix[3][2];
|
|
||||||
|
|
||||||
return newVectorObject(vec, 3, Py_NEW, NULL);
|
|
||||||
}
|
}
|
||||||
/*---------------------------Matrix.rotationPart() ---------------*/
|
/*---------------------------Matrix.rotationPart() ---------------*/
|
||||||
static char Matrix_RotationPart_doc[] =
|
static char Matrix_RotationPart_doc[] =
|
||||||
@ -403,7 +402,7 @@ PyObject *Matrix_RotationPart(MatrixObject * self)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(self->colSize < 3 || self->rowSize < 3){
|
if(self->colSize < 3 || self->rowSize < 3){
|
||||||
PyErr_SetString(PyExc_AttributeError, "Matrix.rotationPart: inappropriate matrix size\n");
|
PyErr_SetString(PyExc_AttributeError, "Matrix.rotation_part(): inappropriate matrix size\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +443,7 @@ PyObject *Matrix_scalePart(MatrixObject * self)
|
|||||||
else if(self->colSize == 3 && self->rowSize == 3)
|
else if(self->colSize == 3 && self->rowSize == 3)
|
||||||
copy_m3_m3(mat, (float (*)[3])*self->matrix);
|
copy_m3_m3(mat, (float (*)[3])*self->matrix);
|
||||||
else {
|
else {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Matrix.scalePart(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
|
PyErr_SetString(PyExc_AttributeError, "Matrix.scale_part(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* functionality copied from editobject.c apply_obmat */
|
/* functionality copied from editobject.c apply_obmat */
|
||||||
|
@ -34,10 +34,12 @@
|
|||||||
|
|
||||||
//-----------------------------METHODS------------------------------
|
//-----------------------------METHODS------------------------------
|
||||||
static char Quaternion_ToEuler_doc[] =
|
static char Quaternion_ToEuler_doc[] =
|
||||||
".. method:: to_euler(euler_compat)\n"
|
".. method:: to_euler(order, euler_compat)\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Return Euler representation of the quaternion.\n"
|
" Return Euler representation of the quaternion.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" :arg order: Optional rotation order argument in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
|
||||||
|
" :type order: string\n"
|
||||||
" :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
|
" :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
|
||||||
" :type euler_compat: :class:`Euler`\n"
|
" :type euler_compat: :class:`Euler`\n"
|
||||||
" :return: Euler representation of the quaternion.\n"
|
" :return: Euler representation of the quaternion.\n"
|
||||||
@ -46,50 +48,40 @@ static char Quaternion_ToEuler_doc[] =
|
|||||||
static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||||
{
|
{
|
||||||
float eul[3];
|
float eul[3];
|
||||||
|
char *order_str= NULL;
|
||||||
|
short order= 0;
|
||||||
EulerObject *eul_compat = NULL;
|
EulerObject *eul_compat = NULL;
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
|
if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if(order_str) {
|
||||||
|
order= euler_order_from_string(order_str, "Matrix.to_euler()");
|
||||||
|
|
||||||
|
if(order < 0)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(eul_compat) {
|
if(eul_compat) {
|
||||||
float mat[3][3];
|
float mat[3][3];
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(eul_compat))
|
if(!BaseMath_ReadCallback(eul_compat))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
quat_to_mat3( mat,self->quat);
|
quat_to_mat3(mat, self->quat);
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
if(order == 0) mat3_to_compatible_eul(eul, eul_compat->eul, mat);
|
||||||
{
|
else mat3_to_compatible_eulO(eul, order, eul_compat->eul, mat);
|
||||||
float eul_compatf[3];
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
|
|
||||||
}
|
|
||||||
mat3_to_compatible_eul( eul, eul_compatf,mat);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
mat3_to_compatible_eul( eul, eul_compat->eul,mat);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
quat_to_eul( eul,self->quat);
|
if(order == 0) quat_to_eul(eul, self->quat);
|
||||||
|
else quat_to_eulO(eul, order, self->quat);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
return newEulerObject(eul, order, Py_NEW, NULL);
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
for(x = 0; x < 3; x++) {
|
|
||||||
eul[x] *= (180 / (float)Py_PI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return newEulerObject(eul, Py_NEW, NULL);
|
|
||||||
}
|
}
|
||||||
//----------------------------Quaternion.toMatrix()------------------
|
//----------------------------Quaternion.toMatrix()------------------
|
||||||
static char Quaternion_ToMatrix_doc[] =
|
static char Quaternion_ToMatrix_doc[] =
|
||||||
@ -218,8 +210,8 @@ static PyObject *Quaternion_Slerp(QuaternionObject *self, PyObject *args)
|
|||||||
QuaternionObject *value;
|
QuaternionObject *value;
|
||||||
float quat[4], fac;
|
float quat[4], fac;
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args, "O!f", &quaternion_Type, &value, &fac)) {
|
if(!PyArg_ParseTuple(args, "O!f:slerp", &quaternion_Type, &value, &fac)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
|
PyErr_SetString(PyExc_TypeError, "quat.slerp(): expected Quaternion types and float");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +219,7 @@ static PyObject *Quaternion_Slerp(QuaternionObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(fac > 1.0f || fac < 0.0f) {
|
if(fac > 1.0f || fac < 0.0f) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
|
PyErr_SetString(PyExc_AttributeError, "quat.slerp(): interpolation factor must be between 0.0 and 1.0");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,12 +690,7 @@ static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type )
|
|||||||
|
|
||||||
static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type )
|
static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type )
|
||||||
{
|
{
|
||||||
double ang = self->quat[0];
|
return PyFloat_FromDouble(2.0 * (saacos(self->quat[0])));
|
||||||
ang = 2 * (saacos(ang));
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
ang *= (180 / Py_PI);
|
|
||||||
#endif
|
|
||||||
return PyFloat_FromDouble(ang);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type )
|
static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type )
|
||||||
@ -815,11 +802,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(size == 3) //calculate the quat based on axis/angle
|
if(size == 3) //calculate the quat based on axis/angle
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
axis_angle_to_quat(quat, quat, angle * (Py_PI / 180));
|
|
||||||
#else
|
|
||||||
axis_angle_to_quat(quat, quat, angle);
|
axis_angle_to_quat(quat, quat, angle);
|
||||||
#endif
|
|
||||||
|
|
||||||
return newQuaternionObject(quat, Py_NEW, NULL);
|
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
@ -159,17 +159,17 @@ static char Vector_Resize2D_doc[] =
|
|||||||
static PyObject *Vector_Resize2D(VectorObject * self)
|
static PyObject *Vector_Resize2D(VectorObject * self)
|
||||||
{
|
{
|
||||||
if(self->wrapped==Py_WRAP) {
|
if(self->wrapped==Py_WRAP) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n");
|
PyErr_SetString(PyExc_TypeError, "vector.resize2D(): cannot resize wrapped data - only python vectors\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(self->cb_user) {
|
if(self->cb_user) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize a vector that has an owner");
|
PyErr_SetString(PyExc_TypeError, "vector.resize2D(): cannot resize a vector that has an owner");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2));
|
self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2));
|
||||||
if(self->vec == NULL) {
|
if(self->vec == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "vector.resize2d(): problem allocating pointer space\n\n");
|
PyErr_SetString(PyExc_MemoryError, "vector.resize2D(): problem allocating pointer space\n\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,17 +189,17 @@ static char Vector_Resize3D_doc[] =
|
|||||||
static PyObject *Vector_Resize3D(VectorObject * self)
|
static PyObject *Vector_Resize3D(VectorObject * self)
|
||||||
{
|
{
|
||||||
if (self->wrapped==Py_WRAP) {
|
if (self->wrapped==Py_WRAP) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n");
|
PyErr_SetString(PyExc_TypeError, "vector.resize3D(): cannot resize wrapped data - only python vectors\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(self->cb_user) {
|
if(self->cb_user) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize a vector that has an owner");
|
PyErr_SetString(PyExc_TypeError, "vector.resize3D(): cannot resize a vector that has an owner");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3));
|
self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3));
|
||||||
if(self->vec == NULL) {
|
if(self->vec == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "vector.resize3d(): problem allocating pointer space\n\n");
|
PyErr_SetString(PyExc_MemoryError, "vector.resize3D(): problem allocating pointer space\n\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,17 +222,17 @@ static char Vector_Resize4D_doc[] =
|
|||||||
static PyObject *Vector_Resize4D(VectorObject * self)
|
static PyObject *Vector_Resize4D(VectorObject * self)
|
||||||
{
|
{
|
||||||
if(self->wrapped==Py_WRAP) {
|
if(self->wrapped==Py_WRAP) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors");
|
PyErr_SetString(PyExc_TypeError, "vector.resize4D(): cannot resize wrapped data - only python vectors");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(self->cb_user) {
|
if(self->cb_user) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner");
|
PyErr_SetString(PyExc_TypeError, "vector.resize4D(): cannot resize a vector that has an owner");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4));
|
self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4));
|
||||||
if(self->vec == NULL) {
|
if(self->vec == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "vector.resize4d(): problem allocating pointer space\n\n");
|
PyErr_SetString(PyExc_MemoryError, "vector.resize4D(): problem allocating pointer space\n\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(self->size == 2){
|
if(self->size == 2){
|
||||||
@ -265,7 +265,7 @@ static PyObject *Vector_ToTuple(VectorObject * self, PyObject *value)
|
|||||||
PyObject *ret;
|
PyObject *ret;
|
||||||
|
|
||||||
if(ndigits > 22 || ndigits < 0) { /* accounts for non ints */
|
if(ndigits > 22 || ndigits < 0) { /* accounts for non ints */
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.key(ndigits): ndigits must be between 0 and 21");
|
PyErr_SetString(PyExc_TypeError, "vector.to_tuple(ndigits): ndigits must be between 0 and 21");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
|||||||
char *strack, *sup;
|
char *strack, *sup;
|
||||||
short track = 2, up = 1;
|
short track = 2, up = 1;
|
||||||
|
|
||||||
if( !PyArg_ParseTuple ( args, "|ss", &strack, &sup ) ) {
|
if(!PyArg_ParseTuple( args, "|ss:to_track_quat", &strack, &sup)) {
|
||||||
PyErr_SetString( PyExc_TypeError, "expected optional two strings\n" );
|
PyErr_SetString( PyExc_TypeError, "expected optional two strings\n" );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -558,11 +558,7 @@ static PyObject *Vector_Angle(VectorObject * self, VectorObject * value)
|
|||||||
|
|
||||||
angleRads = (double)saacos(dot);
|
angleRads = (double)saacos(dot);
|
||||||
|
|
||||||
#ifdef USE_MATHUTILS_DEG
|
|
||||||
return PyFloat_FromDouble(angleRads * (180/ Py_PI));
|
|
||||||
#else
|
|
||||||
return PyFloat_FromDouble(angleRads);
|
return PyFloat_FromDouble(angleRads);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char Vector_Difference_doc[] =
|
static char Vector_Difference_doc[] =
|
||||||
@ -666,12 +662,12 @@ static PyObject *Vector_Lerp(VectorObject * self, PyObject * args)
|
|||||||
float fac, ifac, vec[4];
|
float fac, ifac, vec[4];
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args, "O!f", &vector_Type, &vec2, &fac)) {
|
if(!PyArg_ParseTuple(args, "O!f:lerp", &vector_Type, &vec2, &fac)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "vector.lerp(): expects a vector of the same size and float");
|
PyErr_SetString(PyExc_TypeError, "vector.lerp(): expects a vector of the same size and float");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(self->size != vec2->size) {
|
if(self->size != vec2->size) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size");
|
PyErr_SetString(PyExc_AttributeError, "vector.lerp(): expects (2) vector objects of the same size");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,11 @@ static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self );
|
|||||||
/* bpyrna vector/euler/quat callbacks */
|
/* bpyrna vector/euler/quat callbacks */
|
||||||
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
|
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
|
||||||
|
|
||||||
|
/* not used yet but may want to use the subtype below */
|
||||||
|
#define MATHUTILS_CB_SUBTYPE_EUL 0
|
||||||
|
#define MATHUTILS_CB_SUBTYPE_VEC 1
|
||||||
|
#define MATHUTILS_CB_SUBTYPE_QUAT 2
|
||||||
|
|
||||||
static int mathutils_rna_generic_check(BPy_PropertyRNA *self)
|
static int mathutils_rna_generic_check(BPy_PropertyRNA *self)
|
||||||
{
|
{
|
||||||
return self->prop?1:0;
|
return self->prop?1:0;
|
||||||
@ -181,7 +186,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
|||||||
RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
|
RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
|
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC);
|
||||||
Py_DECREF(ret); /* the vector owns now */
|
Py_DECREF(ret); /* the vector owns now */
|
||||||
ret= vec_cb; /* return the vector instead */
|
ret= vec_cb; /* return the vector instead */
|
||||||
}
|
}
|
||||||
@ -215,11 +220,11 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
|||||||
case PROP_QUATERNION:
|
case PROP_QUATERNION:
|
||||||
if(len==3) { /* euler */
|
if(len==3) { /* euler */
|
||||||
if(is_thick) {
|
if(is_thick) {
|
||||||
ret= newEulerObject(NULL, Py_NEW, NULL);
|
ret= newEulerObject(NULL, 0, Py_NEW, NULL); // TODO, get order from RNA
|
||||||
RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
|
RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
|
PyObject *eul_cb= newEulerObject_cb(ret, 0, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
|
||||||
Py_DECREF(ret); /* the matrix owns now */
|
Py_DECREF(ret); /* the matrix owns now */
|
||||||
ret= eul_cb; /* return the matrix instead */
|
ret= eul_cb; /* return the matrix instead */
|
||||||
}
|
}
|
||||||
@ -230,7 +235,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
|||||||
RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
|
RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
|
PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT);
|
||||||
Py_DECREF(ret); /* the matrix owns now */
|
Py_DECREF(ret); /* the matrix owns now */
|
||||||
ret= quat_cb; /* return the matrix instead */
|
ret= quat_cb; /* return the matrix instead */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user