|
Blender
V2.59
|
00001 /* 00002 * $Id: mathutils_Euler.c 38409 2011-07-15 04:01:47Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Joseph Gilbert 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <Python.h> 00035 00036 #include "mathutils.h" 00037 00038 #include "BLI_math.h" 00039 #include "BLI_utildefines.h" 00040 00041 #define EULER_SIZE 3 00042 00043 //----------------------------------mathutils.Euler() ------------------- 00044 //makes a new euler for you to play with 00045 static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 00046 { 00047 PyObject *seq= NULL; 00048 const char *order_str= NULL; 00049 00050 float eul[EULER_SIZE]= {0.0f, 0.0f, 0.0f}; 00051 short order= EULER_ORDER_XYZ; 00052 00053 if(kwds && PyDict_Size(kwds)) { 00054 PyErr_SetString(PyExc_TypeError, 00055 "mathutils.Euler(): " 00056 "takes no keyword args"); 00057 return NULL; 00058 } 00059 00060 if(!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str)) 00061 return NULL; 00062 00063 switch(PyTuple_GET_SIZE(args)) { 00064 case 0: 00065 break; 00066 case 2: 00067 if((order=euler_order_from_string(order_str, "mathutils.Euler()")) == -1) 00068 return NULL; 00069 /* intentionally pass through */ 00070 case 1: 00071 if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1) 00072 return NULL; 00073 break; 00074 } 00075 return newEulerObject(eul, order, Py_NEW, type); 00076 } 00077 00078 /* internal use, assuem read callback is done */ 00079 static const char *euler_order_str(EulerObject *self) 00080 { 00081 static const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"}; 00082 return order[self->order-EULER_ORDER_XYZ]; 00083 } 00084 00085 short euler_order_from_string(const char *str, const char *error_prefix) 00086 { 00087 if((str[0] && str[1] && str[2] && str[3]=='\0')) { 00088 switch(*((PY_INT32_T *)str)) { 00089 case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ; 00090 case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY; 00091 case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ; 00092 case 'Y'|'Z'<<8|'X'<<16: return EULER_ORDER_YZX; 00093 case 'Z'|'X'<<8|'Y'<<16: return EULER_ORDER_ZXY; 00094 case 'Z'|'Y'<<8|'X'<<16: return EULER_ORDER_ZYX; 00095 } 00096 } 00097 00098 PyErr_Format(PyExc_ValueError, 00099 "%s: invalid euler order '%s'", 00100 error_prefix, str); 00101 return -1; 00102 } 00103 00104 /* note: BaseMath_ReadCallback must be called beforehand */ 00105 static PyObject *Euler_ToTupleExt(EulerObject *self, int ndigits) 00106 { 00107 PyObject *ret; 00108 int i; 00109 00110 ret= PyTuple_New(EULER_SIZE); 00111 00112 if(ndigits >= 0) { 00113 for(i= 0; i < EULER_SIZE; i++) { 00114 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits))); 00115 } 00116 } 00117 else { 00118 for(i= 0; i < EULER_SIZE; i++) { 00119 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->eul[i])); 00120 } 00121 } 00122 00123 return ret; 00124 } 00125 00126 //-----------------------------METHODS---------------------------- 00127 //return a quaternion representation of the euler 00128 00129 PyDoc_STRVAR(Euler_to_quaternion_doc, 00130 ".. method:: to_quaternion()\n" 00131 "\n" 00132 " Return a quaternion representation of the euler.\n" 00133 "\n" 00134 " :return: Quaternion representation of the euler.\n" 00135 " :rtype: :class:`Quaternion`\n" 00136 ); 00137 static PyObject *Euler_to_quaternion(EulerObject * self) 00138 { 00139 float quat[4]; 00140 00141 if(BaseMath_ReadCallback(self) == -1) 00142 return NULL; 00143 00144 eulO_to_quat(quat, self->eul, self->order); 00145 00146 return newQuaternionObject(quat, Py_NEW, NULL); 00147 } 00148 00149 //return a matrix representation of the euler 00150 PyDoc_STRVAR(Euler_to_matrix_doc, 00151 ".. method:: to_matrix()\n" 00152 "\n" 00153 " Return a matrix representation of the euler.\n" 00154 "\n" 00155 " :return: A 3x3 roation matrix representation of the euler.\n" 00156 " :rtype: :class:`Matrix`\n" 00157 ); 00158 static PyObject *Euler_to_matrix(EulerObject * self) 00159 { 00160 float mat[9]; 00161 00162 if(BaseMath_ReadCallback(self) == -1) 00163 return NULL; 00164 00165 eulO_to_mat3((float (*)[3])mat, self->eul, self->order); 00166 00167 return newMatrixObject(mat, 3, 3 , Py_NEW, NULL); 00168 } 00169 00170 PyDoc_STRVAR(Euler_zero_doc, 00171 ".. method:: zero()\n" 00172 "\n" 00173 " Set all values to zero.\n" 00174 ); 00175 static PyObject *Euler_zero(EulerObject * self) 00176 { 00177 zero_v3(self->eul); 00178 00179 if(BaseMath_WriteCallback(self) == -1) 00180 return NULL; 00181 00182 Py_RETURN_NONE; 00183 } 00184 00185 PyDoc_STRVAR(Euler_rotate_axis_doc, 00186 ".. method:: rotate_axis(axis, angle)\n" 00187 "\n" 00188 " Rotates the euler a certain amount and returning a unique euler rotation\n" 00189 " (no 720 degree pitches).\n" 00190 "\n" 00191 " :arg axis: single character in ['X, 'Y', 'Z'].\n" 00192 " :type axis: string\n" 00193 " :arg angle: angle in radians.\n" 00194 " :type angle: float\n" 00195 ); 00196 static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args) 00197 { 00198 float angle = 0.0f; 00199 const char *axis; 00200 00201 if(!PyArg_ParseTuple(args, "sf:rotate", &axis, &angle)){ 00202 PyErr_SetString(PyExc_TypeError, 00203 "euler.rotate(): " 00204 "expected angle (float) and axis (x, y, z)"); 00205 return NULL; 00206 } 00207 if(!(ELEM3(*axis, 'X', 'Y', 'Z') && axis[1]=='\0')){ 00208 PyErr_SetString(PyExc_ValueError, "euler.rotate(): " 00209 "expected axis to be 'X', 'Y' or 'Z'"); 00210 return NULL; 00211 } 00212 00213 if(BaseMath_ReadCallback(self) == -1) 00214 return NULL; 00215 00216 00217 rotate_eulO(self->eul, self->order, *axis, angle); 00218 00219 (void)BaseMath_WriteCallback(self); 00220 00221 Py_RETURN_NONE; 00222 } 00223 00224 PyDoc_STRVAR(Euler_rotate_doc, 00225 ".. method:: rotate(other)\n" 00226 "\n" 00227 " Rotates the euler a by another mathutils value.\n" 00228 "\n" 00229 " :arg other: rotation component of mathutils value\n" 00230 " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" 00231 ); 00232 static PyObject *Euler_rotate(EulerObject * self, PyObject *value) 00233 { 00234 float self_rmat[3][3], other_rmat[3][3], rmat[3][3]; 00235 00236 if(BaseMath_ReadCallback(self) == -1) 00237 return NULL; 00238 00239 if(mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1) 00240 return NULL; 00241 00242 eulO_to_mat3(self_rmat, self->eul, self->order); 00243 mul_m3_m3m3(rmat, self_rmat, other_rmat); 00244 00245 mat3_to_compatible_eulO(self->eul, self->eul, self->order, rmat); 00246 00247 (void)BaseMath_WriteCallback(self); 00248 Py_RETURN_NONE; 00249 } 00250 00251 PyDoc_STRVAR(Euler_make_compatible_doc, 00252 ".. method:: make_compatible(other)\n" 00253 "\n" 00254 " Make this euler compatible with another,\n" 00255 " so interpolating between them works as intended.\n" 00256 "\n" 00257 " .. note:: the rotation order is not taken into account for this function.\n" 00258 ); 00259 static PyObject *Euler_make_compatible(EulerObject * self, PyObject *value) 00260 { 00261 float teul[EULER_SIZE]; 00262 00263 if(BaseMath_ReadCallback(self) == -1) 00264 return NULL; 00265 00266 if(mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value, "euler.make_compatible(other), invalid 'other' arg") == -1) 00267 return NULL; 00268 00269 compatible_eul(self->eul, teul); 00270 00271 (void)BaseMath_WriteCallback(self); 00272 00273 Py_RETURN_NONE; 00274 } 00275 00276 //----------------------------Euler.rotate()----------------------- 00277 // return a copy of the euler 00278 00279 PyDoc_STRVAR(Euler_copy_doc, 00280 ".. function:: copy()\n" 00281 "\n" 00282 " Returns a copy of this euler.\n" 00283 "\n" 00284 " :return: A copy of the euler.\n" 00285 " :rtype: :class:`Euler`\n" 00286 "\n" 00287 " .. note:: use this to get a copy of a wrapped euler with\n" 00288 " no reference to the original data.\n" 00289 ); 00290 static PyObject *Euler_copy(EulerObject *self) 00291 { 00292 if(BaseMath_ReadCallback(self) == -1) 00293 return NULL; 00294 00295 return newEulerObject(self->eul, self->order, Py_NEW, Py_TYPE(self)); 00296 } 00297 00298 //----------------------------print object (internal)-------------- 00299 //print the object to screen 00300 00301 static PyObject *Euler_repr(EulerObject * self) 00302 { 00303 PyObject *ret, *tuple; 00304 00305 if(BaseMath_ReadCallback(self) == -1) 00306 return NULL; 00307 00308 tuple= Euler_ToTupleExt(self, -1); 00309 00310 ret= PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self)); 00311 00312 Py_DECREF(tuple); 00313 return ret; 00314 } 00315 00316 static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op) 00317 { 00318 PyObject *res; 00319 int ok= -1; /* zero is true */ 00320 00321 if (EulerObject_Check(a) && EulerObject_Check(b)) { 00322 EulerObject *eulA= (EulerObject*)a; 00323 EulerObject *eulB= (EulerObject*)b; 00324 00325 if(BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1) 00326 return NULL; 00327 00328 ok= ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1; 00329 } 00330 00331 switch (op) { 00332 case Py_NE: 00333 ok = !ok; /* pass through */ 00334 case Py_EQ: 00335 res = ok ? Py_False : Py_True; 00336 break; 00337 00338 case Py_LT: 00339 case Py_LE: 00340 case Py_GT: 00341 case Py_GE: 00342 res = Py_NotImplemented; 00343 break; 00344 default: 00345 PyErr_BadArgument(); 00346 return NULL; 00347 } 00348 00349 return Py_INCREF(res), res; 00350 } 00351 00352 //---------------------SEQUENCE PROTOCOLS------------------------ 00353 //----------------------------len(object)------------------------ 00354 //sequence length 00355 static int Euler_len(EulerObject *UNUSED(self)) 00356 { 00357 return EULER_SIZE; 00358 } 00359 //----------------------------object[]--------------------------- 00360 //sequence accessor (get) 00361 static PyObject *Euler_item(EulerObject * self, int i) 00362 { 00363 if(i<0) i= EULER_SIZE-i; 00364 00365 if(i < 0 || i >= EULER_SIZE) { 00366 PyErr_SetString(PyExc_IndexError, 00367 "euler[attribute]: " 00368 "array index out of range"); 00369 return NULL; 00370 } 00371 00372 if(BaseMath_ReadIndexCallback(self, i) == -1) 00373 return NULL; 00374 00375 return PyFloat_FromDouble(self->eul[i]); 00376 00377 } 00378 //----------------------------object[]------------------------- 00379 //sequence accessor (set) 00380 static int Euler_ass_item(EulerObject * self, int i, PyObject *value) 00381 { 00382 float f = PyFloat_AsDouble(value); 00383 00384 if(f == -1 && PyErr_Occurred()) { // parsed item not a number 00385 PyErr_SetString(PyExc_TypeError, 00386 "euler[attribute] = x: " 00387 "argument not a number"); 00388 return -1; 00389 } 00390 00391 if(i<0) i= EULER_SIZE-i; 00392 00393 if(i < 0 || i >= EULER_SIZE){ 00394 PyErr_SetString(PyExc_IndexError, 00395 "euler[attribute] = x: " 00396 "array assignment index out of range"); 00397 return -1; 00398 } 00399 00400 self->eul[i] = f; 00401 00402 if(BaseMath_WriteIndexCallback(self, i) == -1) 00403 return -1; 00404 00405 return 0; 00406 } 00407 //----------------------------object[z:y]------------------------ 00408 //sequence slice (get) 00409 static PyObject *Euler_slice(EulerObject * self, int begin, int end) 00410 { 00411 PyObject *tuple; 00412 int count; 00413 00414 if(BaseMath_ReadCallback(self) == -1) 00415 return NULL; 00416 00417 CLAMP(begin, 0, EULER_SIZE); 00418 if (end<0) end= (EULER_SIZE + 1) + end; 00419 CLAMP(end, 0, EULER_SIZE); 00420 begin= MIN2(begin, end); 00421 00422 tuple= PyTuple_New(end - begin); 00423 for(count = begin; count < end; count++) { 00424 PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->eul[count])); 00425 } 00426 00427 return tuple; 00428 } 00429 //----------------------------object[z:y]------------------------ 00430 //sequence slice (set) 00431 static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq) 00432 { 00433 int i, size; 00434 float eul[EULER_SIZE]; 00435 00436 if(BaseMath_ReadCallback(self) == -1) 00437 return -1; 00438 00439 CLAMP(begin, 0, EULER_SIZE); 00440 if (end<0) end= (EULER_SIZE + 1) + end; 00441 CLAMP(end, 0, EULER_SIZE); 00442 begin = MIN2(begin, end); 00443 00444 if((size=mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1) 00445 return -1; 00446 00447 if(size != (end - begin)){ 00448 PyErr_SetString(PyExc_ValueError, 00449 "euler[begin:end] = []: " 00450 "size mismatch in slice assignment"); 00451 return -1; 00452 } 00453 00454 for(i= 0; i < EULER_SIZE; i++) 00455 self->eul[begin + i] = eul[i]; 00456 00457 (void)BaseMath_WriteCallback(self); 00458 return 0; 00459 } 00460 00461 static PyObject *Euler_subscript(EulerObject *self, PyObject *item) 00462 { 00463 if (PyIndex_Check(item)) { 00464 Py_ssize_t i; 00465 i = PyNumber_AsSsize_t(item, PyExc_IndexError); 00466 if (i == -1 && PyErr_Occurred()) 00467 return NULL; 00468 if (i < 0) 00469 i += EULER_SIZE; 00470 return Euler_item(self, i); 00471 } 00472 else if (PySlice_Check(item)) { 00473 Py_ssize_t start, stop, step, slicelength; 00474 00475 if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) 00476 return NULL; 00477 00478 if (slicelength <= 0) { 00479 return PyTuple_New(0); 00480 } 00481 else if (step == 1) { 00482 return Euler_slice(self, start, stop); 00483 } 00484 else { 00485 PyErr_SetString(PyExc_IndexError, 00486 "slice steps not supported with eulers"); 00487 return NULL; 00488 } 00489 } 00490 else { 00491 PyErr_Format(PyExc_TypeError, 00492 "euler indices must be integers, not %.200s", 00493 Py_TYPE(item)->tp_name); 00494 return NULL; 00495 } 00496 } 00497 00498 00499 static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value) 00500 { 00501 if (PyIndex_Check(item)) { 00502 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); 00503 if (i == -1 && PyErr_Occurred()) 00504 return -1; 00505 if (i < 0) 00506 i += EULER_SIZE; 00507 return Euler_ass_item(self, i, value); 00508 } 00509 else if (PySlice_Check(item)) { 00510 Py_ssize_t start, stop, step, slicelength; 00511 00512 if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) 00513 return -1; 00514 00515 if (step == 1) 00516 return Euler_ass_slice(self, start, stop, value); 00517 else { 00518 PyErr_SetString(PyExc_IndexError, 00519 "slice steps not supported with euler"); 00520 return -1; 00521 } 00522 } 00523 else { 00524 PyErr_Format(PyExc_TypeError, 00525 "euler indices must be integers, not %.200s", 00526 Py_TYPE(item)->tp_name); 00527 return -1; 00528 } 00529 } 00530 00531 //-----------------PROTCOL DECLARATIONS-------------------------- 00532 static PySequenceMethods Euler_SeqMethods = { 00533 (lenfunc) Euler_len, /* sq_length */ 00534 (binaryfunc) NULL, /* sq_concat */ 00535 (ssizeargfunc) NULL, /* sq_repeat */ 00536 (ssizeargfunc) Euler_item, /* sq_item */ 00537 (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ 00538 (ssizeobjargproc) Euler_ass_item, /* sq_ass_item */ 00539 (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */ 00540 (objobjproc) NULL, /* sq_contains */ 00541 (binaryfunc) NULL, /* sq_inplace_concat */ 00542 (ssizeargfunc) NULL, /* sq_inplace_repeat */ 00543 }; 00544 00545 static PyMappingMethods Euler_AsMapping = { 00546 (lenfunc)Euler_len, 00547 (binaryfunc)Euler_subscript, 00548 (objobjargproc)Euler_ass_subscript 00549 }; 00550 00551 /* 00552 * euler axis, euler.x/y/z 00553 */ 00554 static PyObject *Euler_getAxis(EulerObject *self, void *type) 00555 { 00556 return Euler_item(self, GET_INT_FROM_POINTER(type)); 00557 } 00558 00559 static int Euler_setAxis(EulerObject *self, PyObject *value, void *type) 00560 { 00561 return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value); 00562 } 00563 00564 /* rotation order */ 00565 static PyObject *Euler_getOrder(EulerObject *self, void *UNUSED(closure)) 00566 { 00567 if(BaseMath_ReadCallback(self) == -1) /* can read order too */ 00568 return NULL; 00569 00570 return PyUnicode_FromString(euler_order_str(self)); 00571 } 00572 00573 static int Euler_setOrder(EulerObject *self, PyObject *value, void *UNUSED(closure)) 00574 { 00575 const char *order_str= _PyUnicode_AsString(value); 00576 short order= euler_order_from_string(order_str, "euler.order"); 00577 00578 if(order == -1) 00579 return -1; 00580 00581 self->order= order; 00582 (void)BaseMath_WriteCallback(self); /* order can be written back */ 00583 return 0; 00584 } 00585 00586 /*****************************************************************************/ 00587 /* Python attributes get/set structure: */ 00588 /*****************************************************************************/ 00589 static PyGetSetDef Euler_getseters[] = { 00590 {(char *)"x", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler X axis in radians.\n\n:type: float", (void *)0}, 00591 {(char *)"y", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler Y axis in radians.\n\n:type: float", (void *)1}, 00592 {(char *)"z", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler Z axis in radians.\n\n:type: float", (void *)2}, 00593 {(char *)"order", (getter)Euler_getOrder, (setter)Euler_setOrder, (char *)"Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']", (void *)NULL}, 00594 00595 {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, 00596 {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, 00597 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ 00598 }; 00599 00600 00601 //-----------------------METHOD DEFINITIONS ---------------------- 00602 static struct PyMethodDef Euler_methods[] = { 00603 {"zero", (PyCFunction) Euler_zero, METH_NOARGS, Euler_zero_doc}, 00604 {"to_matrix", (PyCFunction) Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc}, 00605 {"to_quaternion", (PyCFunction) Euler_to_quaternion, METH_NOARGS, Euler_to_quaternion_doc}, 00606 {"rotate_axis", (PyCFunction) Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc}, 00607 {"rotate", (PyCFunction) Euler_rotate, METH_O, Euler_rotate_doc}, 00608 {"make_compatible", (PyCFunction) Euler_make_compatible, METH_O, Euler_make_compatible_doc}, 00609 {"__copy__", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc}, 00610 {"copy", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc}, 00611 {NULL, NULL, 0, NULL} 00612 }; 00613 00614 //------------------PY_OBECT DEFINITION-------------------------- 00615 PyDoc_STRVAR(euler_doc, 00616 "This object gives access to Eulers in Blender." 00617 ); 00618 PyTypeObject euler_Type = { 00619 PyVarObject_HEAD_INIT(NULL, 0) 00620 "mathutils.Euler", //tp_name 00621 sizeof(EulerObject), //tp_basicsize 00622 0, //tp_itemsize 00623 (destructor)BaseMathObject_dealloc, //tp_dealloc 00624 NULL, //tp_print 00625 NULL, //tp_getattr 00626 NULL, //tp_setattr 00627 NULL, //tp_compare 00628 (reprfunc) Euler_repr, //tp_repr 00629 NULL, //tp_as_number 00630 &Euler_SeqMethods, //tp_as_sequence 00631 &Euler_AsMapping, //tp_as_mapping 00632 NULL, //tp_hash 00633 NULL, //tp_call 00634 NULL, //tp_str 00635 NULL, //tp_getattro 00636 NULL, //tp_setattro 00637 NULL, //tp_as_buffer 00638 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags 00639 euler_doc, //tp_doc 00640 (traverseproc)BaseMathObject_traverse, //tp_traverse 00641 (inquiry)BaseMathObject_clear, //tp_clear 00642 (richcmpfunc)Euler_richcmpr, //tp_richcompare 00643 0, //tp_weaklistoffset 00644 NULL, //tp_iter 00645 NULL, //tp_iternext 00646 Euler_methods, //tp_methods 00647 NULL, //tp_members 00648 Euler_getseters, //tp_getset 00649 NULL, //tp_base 00650 NULL, //tp_dict 00651 NULL, //tp_descr_get 00652 NULL, //tp_descr_set 00653 0, //tp_dictoffset 00654 NULL, //tp_init 00655 NULL, //tp_alloc 00656 Euler_new, //tp_new 00657 NULL, //tp_free 00658 NULL, //tp_is_gc 00659 NULL, //tp_bases 00660 NULL, //tp_mro 00661 NULL, //tp_cache 00662 NULL, //tp_subclasses 00663 NULL, //tp_weaklist 00664 NULL //tp_del 00665 }; 00666 //------------------------newEulerObject (internal)------------- 00667 //creates a new euler object 00668 /*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER 00669 (i.e. it was allocated elsewhere by MEM_mallocN()) 00670 pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON 00671 (i.e. it must be created here with PyMEM_malloc())*/ 00672 PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_type) 00673 { 00674 EulerObject *self; 00675 00676 self= base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) : 00677 (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type); 00678 00679 if(self) { 00680 /* init callbacks as NULL */ 00681 self->cb_user= NULL; 00682 self->cb_type= self->cb_subtype= 0; 00683 00684 if(type == Py_WRAP) { 00685 self->eul = eul; 00686 self->wrapped = Py_WRAP; 00687 } 00688 else if (type == Py_NEW) { 00689 self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float)); 00690 if(eul) { 00691 copy_v3_v3(self->eul, eul); 00692 } 00693 else { 00694 zero_v3(self->eul); 00695 } 00696 00697 self->wrapped = Py_NEW; 00698 } 00699 else { 00700 Py_FatalError("Euler(): invalid type!"); 00701 } 00702 00703 self->order= order; 00704 } 00705 00706 return (PyObject *)self; 00707 } 00708 00709 PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype) 00710 { 00711 EulerObject *self= (EulerObject *)newEulerObject(NULL, order, Py_NEW, NULL); 00712 if(self) { 00713 Py_INCREF(cb_user); 00714 self->cb_user= cb_user; 00715 self->cb_type= (unsigned char)cb_type; 00716 self->cb_subtype= (unsigned char)cb_subtype; 00717 PyObject_GC_Track(self); 00718 } 00719 00720 return (PyObject *)self; 00721 }