Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-04-26 03:33:09 +0400
committerCampbell Barton <ideasman42@gmail.com>2010-04-26 03:33:09 +0400
commit4fc4fb9bfb11a2a1cb416ef6044ecc61735f0bf6 (patch)
tree3f3d9f10bbaa9a279835ee3cd8c92db7a0d08306 /source/blender/python/generic/mathutils_euler.c
parent64359c9abce7cbccf27883fd9a39ac1b221cd617 (diff)
rna/python mathutils module
- return euler rotation values from rna now have correct rotation order. - mathutils.Euler stored rotation order off by 1. (didnt work at all) - Euler/Quat/Color sliceing working again.
Diffstat (limited to 'source/blender/python/generic/mathutils_euler.c')
-rw-r--r--source/blender/python/generic/mathutils_euler.c205
1 files changed, 131 insertions, 74 deletions
diff --git a/source/blender/python/generic/mathutils_euler.c b/source/blender/python/generic/mathutils_euler.c
index 2c8dbf41997..e3635012d91 100644
--- a/source/blender/python/generic/mathutils_euler.c
+++ b/source/blender/python/generic/mathutils_euler.c
@@ -35,6 +35,8 @@
#include "BLO_sys_types.h"
#endif
+#define EULER_SIZE 3
+
//----------------------------------mathutils.Euler() -------------------
//makes a new euler for you to play with
static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
@@ -42,8 +44,8 @@ static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwar
PyObject *seq= NULL;
char *order_str= NULL;
- float eul[3]= {0.0f, 0.0f, 0.0f};
- short order= 0;
+ float eul[EULER_SIZE]= {0.0f, 0.0f, 0.0f};
+ short order= EULER_ORDER_XYZ;
if(!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str))
return NULL;
@@ -56,7 +58,7 @@ static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwar
return NULL;
/* intentionally pass through */
case 1:
- if (mathutils_array_parse(eul, 3, 3, seq, "mathutils.Euler()") == -1)
+ if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1)
return NULL;
break;
}
@@ -67,12 +69,12 @@ 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;
+ case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ;
+ case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY;
+ case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ;
+ case 'Y'|'Z'<<8|'X'<<16: return EULER_ORDER_YZX;
+ case 'Z'|'X'<<8|'Y'<<16: return EULER_ORDER_ZXY;
+ case 'Z'|'Y'<<8|'X'<<16: return EULER_ORDER_ZYX;
}
}
@@ -86,15 +88,15 @@ static PyObject *Euler_ToTupleExt(EulerObject *self, int ndigits)
PyObject *ret;
int i;
- ret= PyTuple_New(3);
+ ret= PyTuple_New(EULER_SIZE);
if(ndigits >= 0) {
- for(i= 0; i < 3; i++) {
+ for(i= 0; i < EULER_SIZE; i++) {
PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits)));
}
}
else {
- for(i= 0; i < 3; i++) {
+ for(i= 0; i < EULER_SIZE; i++) {
PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->eul[i]));
}
}
@@ -120,8 +122,8 @@ static PyObject *Euler_ToQuat(EulerObject * self)
if(!BaseMath_ReadCallback(self))
return NULL;
- if(self->order==0) eul_to_quat(quat, self->eul);
- else eulO_to_quat(quat, self->eul, self->order);
+ if(self->order==EULER_ORDER_XYZ) eul_to_quat(quat, self->eul);
+ else eulO_to_quat(quat, self->eul, self->order);
return newQuaternionObject(quat, Py_NEW, NULL);
}
@@ -142,8 +144,8 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
if(!BaseMath_ReadCallback(self))
return NULL;
- if(self->order==0) eul_to_mat3((float (*)[3])mat, self->eul);
- else eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
+ if(self->order==EULER_ORDER_XYZ) eul_to_mat3((float (*)[3])mat, self->eul);
+ else eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
return newMatrixObject(mat, 3, 3 , Py_NEW, NULL);
}
@@ -256,8 +258,8 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
if(!BaseMath_ReadCallback(self))
return NULL;
- if(self->order == 0) rotate_eul(self->eul, *axis, angle);
- else rotate_eulO(self->eul, self->order, *axis, angle);
+ if(self->order == EULER_ORDER_XYZ) rotate_eul(self->eul, *axis, angle);
+ else rotate_eulO(self->eul, self->order, *axis, angle);
BaseMath_WriteCallback(self);
Py_INCREF(self);
@@ -367,10 +369,10 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar
switch (comparison_type){
case Py_EQ:
- result = EXPP_VectorsAreEqual(eulA->eul, eulB->eul, 3, 1);
+ result = EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1);
break;
case Py_NE:
- result = !EXPP_VectorsAreEqual(eulA->eul, eulB->eul, 3, 1);
+ result = !EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1);
break;
default:
printf("The result of the comparison could not be evaluated");
@@ -388,15 +390,15 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar
//sequence length
static int Euler_len(EulerObject * self)
{
- return 3;
+ return EULER_SIZE;
}
//----------------------------object[]---------------------------
//sequence accessor (get)
static PyObject *Euler_item(EulerObject * self, int i)
{
- if(i<0) i= 3-i;
+ if(i<0) i= EULER_SIZE-i;
- if(i < 0 || i >= 3) {
+ if(i < 0 || i >= EULER_SIZE) {
PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range");
return NULL;
}
@@ -418,9 +420,9 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
return -1;
}
- if(i<0) i= 3-i;
+ if(i<0) i= EULER_SIZE-i;
- if(i < 0 || i >= 3){
+ if(i < 0 || i >= EULER_SIZE){
PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n");
return -1;
}
@@ -442,9 +444,9 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
if(!BaseMath_ReadCallback(self))
return NULL;
- CLAMP(begin, 0, 3);
- if (end<0) end= 4+end;
- CLAMP(end, 0, 3);
+ CLAMP(begin, 0, EULER_SIZE);
+ if (end<0) end= (EULER_SIZE + 1) + end;
+ CLAMP(end, 0, EULER_SIZE);
begin = MIN2(begin,end);
list = PyList_New(end - begin);
@@ -457,61 +459,117 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
}
//----------------------------object[z:y]------------------------
//sequence slice (set)
-static int Euler_ass_slice(EulerObject * self, int begin, int end,
- PyObject * seq)
+static int Euler_ass_slice(EulerObject * self, int begin, int end, PyObject * seq)
{
- int i, y, size = 0;
- float eul[3];
- PyObject *e;
+ int i, size;
+ float eul[EULER_SIZE];
if(!BaseMath_ReadCallback(self))
return -1;
- CLAMP(begin, 0, 3);
- if (end<0) end= 4+end;
- CLAMP(end, 0, 3);
+ CLAMP(begin, 0, EULER_SIZE);
+ if (end<0) end= (EULER_SIZE + 1) + end;
+ CLAMP(end, 0, EULER_SIZE);
begin = MIN2(begin,end);
- size = PySequence_Length(seq);
+ if((size=mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1)
+ return -1;
+
if(size != (end - begin)){
PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: size mismatch in slice assignment");
return -1;
}
- for (i = 0; i < size; i++) {
- e = PySequence_GetItem(seq, i);
- if (e == NULL) { // Failed to read sequence
- PyErr_SetString(PyExc_RuntimeError, "euler[begin:end] = []: unable to read sequence");
- return -1;
+ for(i= 0; i < EULER_SIZE; i++)
+ self->eul[begin + i] = eul[i];
+
+ BaseMath_WriteCallback(self);
+ return 0;
+}
+
+static PyObject *Euler_subscript(EulerObject *self, PyObject *item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i;
+ i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += EULER_SIZE;
+ return Euler_item(self, i);
+ } else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0)
+ return NULL;
+
+ if (slicelength <= 0) {
+ return PyList_New(0);
+ }
+ else if (step == 1) {
+ return Euler_slice(self, start, stop);
}
+ else {
+ PyErr_SetString(PyExc_TypeError, "slice steps not supported with eulers");
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "euler indices must be integers, not %.200s",
+ item->ob_type->tp_name);
+ return NULL;
+ }
+}
+
+
+static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += EULER_SIZE;
+ return Euler_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
- eul[i] = (float)PyFloat_AsDouble(e);
- Py_DECREF(e);
+ if (PySlice_GetIndicesEx((PySliceObject*)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0)
+ return -1;
- if(eul[i]==-1 && PyErr_Occurred()) { // parsed item not a number
- PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number");
+ if (step == 1)
+ return Euler_ass_slice(self, start, stop, value);
+ else {
+ PyErr_SetString(PyExc_TypeError, "slice steps not supported with euler");
return -1;
}
}
- //parsed well - now set in vector
- for(y = 0; y < 3; y++){
- self->eul[begin + y] = eul[y];
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "euler indices must be integers, not %.200s",
+ item->ob_type->tp_name);
+ return -1;
}
-
- BaseMath_WriteCallback(self);
- return 0;
}
+
//-----------------PROTCOL DECLARATIONS--------------------------
static PySequenceMethods Euler_SeqMethods = {
- (lenfunc) Euler_len, /* sq_length */
- (binaryfunc) 0, /* sq_concat */
- (ssizeargfunc) 0, /* sq_repeat */
- (ssizeargfunc) Euler_item, /* sq_item */
- (ssizessizeargfunc) Euler_slice, /* sq_slice */
- (ssizeobjargproc) Euler_ass_item, /* sq_ass_item */
- (ssizessizeobjargproc) Euler_ass_slice, /* sq_ass_slice */
+ (lenfunc) Euler_len, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (ssizeargfunc) 0, /* sq_repeat */
+ (ssizeargfunc) Euler_item, /* sq_item */
+ (ssizessizeargfunc) NULL, /* sq_slice, deprecated */
+ (ssizeobjargproc) Euler_ass_item, /* sq_ass_item */
+ (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */
};
+static PyMappingMethods Euler_AsMapping = {
+ (lenfunc)Euler_len,
+ (binaryfunc)Euler_subscript,
+ (objobjargproc)Euler_ass_subscript
+};
/*
* euler axis, euler.x/y/z
@@ -530,7 +588,7 @@ static int Euler_setAxis( EulerObject * self, PyObject * value, void * type )
static PyObject *Euler_getOrder(EulerObject *self, void *type)
{
static char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"};
- return PyUnicode_FromString(order[self->order]);
+ return PyUnicode_FromString(order[self->order-EULER_ORDER_XYZ]);
}
static int Euler_setOrder( EulerObject * self, PyObject * value, void * type )
@@ -538,7 +596,7 @@ 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)
+ if(order == -1)
return -1;
if(self->cb_user) {
@@ -595,7 +653,7 @@ PyTypeObject euler_Type = {
(reprfunc) Euler_repr, //tp_repr
0, //tp_as_number
&Euler_SeqMethods, //tp_as_sequence
- 0, //tp_as_mapping
+ &Euler_AsMapping, //tp_as_mapping
0, //tp_hash
0, //tp_call
0, //tp_str
@@ -639,7 +697,6 @@ PyTypeObject euler_Type = {
PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_type)
{
EulerObject *self;
- int x;
if(base_type) self = (EulerObject *)base_type->tp_alloc(base_type, 0);
else self = PyObject_NEW(EulerObject, &euler_Type);
@@ -648,20 +705,20 @@ PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_t
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
- if(type == Py_WRAP){
+ if(type == Py_WRAP) {
self->eul = eul;
self->wrapped = Py_WRAP;
- }else if (type == Py_NEW){
- self->eul = PyMem_Malloc(3 * sizeof(float));
- if(!eul) { //new empty
- for(x = 0; x < 3; x++) {
- self->eul[x] = 0.0f;
- }
- }else{
- VECCOPY(self->eul, eul);
- }
+ }
+ else if (type == Py_NEW){
+ self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
+ if(eul)
+ copy_v3_v3(self->eul, eul);
+ else
+ zero_v3(self->eul);
+
self->wrapped = Py_NEW;
- }else{ //bad type
+ }
+ else{
return NULL;
}