Blender V2.61 - r43446
|
00001 /* 00002 * 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * 00023 * Contributor(s): Joseph Gilbert 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <Python.h> 00034 00035 #include "mathutils.h" 00036 00037 #include "BLI_math.h" 00038 #include "BLI_utildefines.h" 00039 #include "BLI_dynstr.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 Euler_CreatePyObject(eul, order, Py_NEW, type); 00076 } 00077 00078 /* internal use, assume 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 Quaternion_CreatePyObject(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 Matrix_CreatePyObject(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 int axis; /* actually a character */ 00200 00201 if (!PyArg_ParseTuple(args, "Cf:rotate_axis", &axis, &angle)) { 00202 PyErr_SetString(PyExc_TypeError, 00203 "Euler.rotate_axis(): " 00204 "expected an axis 'X', 'Y', 'Z' and an angle (float)"); 00205 return NULL; 00206 } 00207 00208 if (!(ELEM3(axis, 'X', 'Y', 'Z'))) { 00209 PyErr_SetString(PyExc_ValueError, 00210 "Euler.rotate_axis(): " 00211 "expected axis to be 'X', 'Y' or 'Z'"); 00212 return NULL; 00213 } 00214 00215 if (BaseMath_ReadCallback(self) == -1) 00216 return NULL; 00217 00218 00219 rotate_eulO(self->eul, self->order, (char)axis, angle); 00220 00221 (void)BaseMath_WriteCallback(self); 00222 00223 Py_RETURN_NONE; 00224 } 00225 00226 PyDoc_STRVAR(Euler_rotate_doc, 00227 ".. method:: rotate(other)\n" 00228 "\n" 00229 " Rotates the euler a by another mathutils value.\n" 00230 "\n" 00231 " :arg other: rotation component of mathutils value\n" 00232 " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" 00233 ); 00234 static PyObject *Euler_rotate(EulerObject *self, PyObject *value) 00235 { 00236 float self_rmat[3][3], other_rmat[3][3], rmat[3][3]; 00237 00238 if (BaseMath_ReadCallback(self) == -1) 00239 return NULL; 00240 00241 if (mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1) 00242 return NULL; 00243 00244 eulO_to_mat3(self_rmat, self->eul, self->order); 00245 mul_m3_m3m3(rmat, other_rmat, self_rmat); 00246 00247 mat3_to_compatible_eulO(self->eul, self->eul, self->order, rmat); 00248 00249 (void)BaseMath_WriteCallback(self); 00250 Py_RETURN_NONE; 00251 } 00252 00253 PyDoc_STRVAR(Euler_make_compatible_doc, 00254 ".. method:: make_compatible(other)\n" 00255 "\n" 00256 " Make this euler compatible with another,\n" 00257 " so interpolating between them works as intended.\n" 00258 "\n" 00259 " .. note:: the rotation order is not taken into account for this function.\n" 00260 ); 00261 static PyObject *Euler_make_compatible(EulerObject *self, PyObject *value) 00262 { 00263 float teul[EULER_SIZE]; 00264 00265 if (BaseMath_ReadCallback(self) == -1) 00266 return NULL; 00267 00268 if (mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value, 00269 "euler.make_compatible(other), invalid 'other' arg") == -1) 00270 { 00271 return NULL; 00272 } 00273 00274 compatible_eul(self->eul, teul); 00275 00276 (void)BaseMath_WriteCallback(self); 00277 00278 Py_RETURN_NONE; 00279 } 00280 00281 //----------------------------Euler.rotate()----------------------- 00282 // return a copy of the euler 00283 00284 PyDoc_STRVAR(Euler_copy_doc, 00285 ".. function:: copy()\n" 00286 "\n" 00287 " Returns a copy of this euler.\n" 00288 "\n" 00289 " :return: A copy of the euler.\n" 00290 " :rtype: :class:`Euler`\n" 00291 "\n" 00292 " .. note:: use this to get a copy of a wrapped euler with\n" 00293 " no reference to the original data.\n" 00294 ); 00295 static PyObject *Euler_copy(EulerObject *self) 00296 { 00297 if (BaseMath_ReadCallback(self) == -1) 00298 return NULL; 00299 00300 return Euler_CreatePyObject(self->eul, self->order, Py_NEW, Py_TYPE(self)); 00301 } 00302 00303 //----------------------------print object (internal)-------------- 00304 //print the object to screen 00305 00306 static PyObject *Euler_repr(EulerObject *self) 00307 { 00308 PyObject *ret, *tuple; 00309 00310 if (BaseMath_ReadCallback(self) == -1) 00311 return NULL; 00312 00313 tuple = Euler_ToTupleExt(self, -1); 00314 00315 ret = PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self)); 00316 00317 Py_DECREF(tuple); 00318 return ret; 00319 } 00320 00321 static PyObject *Euler_str(EulerObject *self) 00322 { 00323 DynStr *ds; 00324 00325 if (BaseMath_ReadCallback(self) == -1) 00326 return NULL; 00327 00328 ds = BLI_dynstr_new(); 00329 00330 BLI_dynstr_appendf(ds, "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>", 00331 self->eul[0], self->eul[1], self->eul[2], euler_order_str(self)); 00332 00333 return mathutils_dynstr_to_py(ds); /* frees ds */ 00334 } 00335 00336 static PyObject *Euler_richcmpr(PyObject *a, PyObject *b, int op) 00337 { 00338 PyObject *res; 00339 int ok = -1; /* zero is true */ 00340 00341 if (EulerObject_Check(a) && EulerObject_Check(b)) { 00342 EulerObject *eulA = (EulerObject *)a; 00343 EulerObject *eulB = (EulerObject *)b; 00344 00345 if (BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1) 00346 return NULL; 00347 00348 ok = ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1; 00349 } 00350 00351 switch (op) { 00352 case Py_NE: 00353 ok = !ok; /* pass through */ 00354 case Py_EQ: 00355 res = ok ? Py_False : Py_True; 00356 break; 00357 00358 case Py_LT: 00359 case Py_LE: 00360 case Py_GT: 00361 case Py_GE: 00362 res = Py_NotImplemented; 00363 break; 00364 default: 00365 PyErr_BadArgument(); 00366 return NULL; 00367 } 00368 00369 return Py_INCREF(res), res; 00370 } 00371 00372 //---------------------SEQUENCE PROTOCOLS------------------------ 00373 //----------------------------len(object)------------------------ 00374 //sequence length 00375 static int Euler_len(EulerObject *UNUSED(self)) 00376 { 00377 return EULER_SIZE; 00378 } 00379 //----------------------------object[]--------------------------- 00380 //sequence accessor (get) 00381 static PyObject *Euler_item(EulerObject *self, int i) 00382 { 00383 if (i < 0) i = EULER_SIZE - i; 00384 00385 if (i < 0 || i >= EULER_SIZE) { 00386 PyErr_SetString(PyExc_IndexError, 00387 "euler[attribute]: " 00388 "array index out of range"); 00389 return NULL; 00390 } 00391 00392 if (BaseMath_ReadIndexCallback(self, i) == -1) 00393 return NULL; 00394 00395 return PyFloat_FromDouble(self->eul[i]); 00396 00397 } 00398 //----------------------------object[]------------------------- 00399 //sequence accessor (set) 00400 static int Euler_ass_item(EulerObject *self, int i, PyObject *value) 00401 { 00402 float f = PyFloat_AsDouble(value); 00403 00404 if (f == -1 && PyErr_Occurred()) { // parsed item not a number 00405 PyErr_SetString(PyExc_TypeError, 00406 "euler[attribute] = x: " 00407 "argument not a number"); 00408 return -1; 00409 } 00410 00411 if (i < 0) i = EULER_SIZE - i; 00412 00413 if (i < 0 || i >= EULER_SIZE) { 00414 PyErr_SetString(PyExc_IndexError, 00415 "euler[attribute] = x: " 00416 "array assignment index out of range"); 00417 return -1; 00418 } 00419 00420 self->eul[i] = f; 00421 00422 if (BaseMath_WriteIndexCallback(self, i) == -1) 00423 return -1; 00424 00425 return 0; 00426 } 00427 //----------------------------object[z:y]------------------------ 00428 //sequence slice (get) 00429 static PyObject *Euler_slice(EulerObject *self, int begin, int end) 00430 { 00431 PyObject *tuple; 00432 int count; 00433 00434 if (BaseMath_ReadCallback(self) == -1) 00435 return NULL; 00436 00437 CLAMP(begin, 0, EULER_SIZE); 00438 if (end < 0) end = (EULER_SIZE + 1) + end; 00439 CLAMP(end, 0, EULER_SIZE); 00440 begin = MIN2(begin, end); 00441 00442 tuple = PyTuple_New(end - begin); 00443 for (count = begin; count < end; count++) { 00444 PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->eul[count])); 00445 } 00446 00447 return tuple; 00448 } 00449 //----------------------------object[z:y]------------------------ 00450 //sequence slice (set) 00451 static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq) 00452 { 00453 int i, size; 00454 float eul[EULER_SIZE]; 00455 00456 if (BaseMath_ReadCallback(self) == -1) 00457 return -1; 00458 00459 CLAMP(begin, 0, EULER_SIZE); 00460 if (end < 0) end = (EULER_SIZE + 1) + end; 00461 CLAMP(end, 0, EULER_SIZE); 00462 begin = MIN2(begin, end); 00463 00464 if ((size = mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1) 00465 return -1; 00466 00467 if (size != (end - begin)) { 00468 PyErr_SetString(PyExc_ValueError, 00469 "euler[begin:end] = []: " 00470 "size mismatch in slice assignment"); 00471 return -1; 00472 } 00473 00474 for (i = 0; i < EULER_SIZE; i++) 00475 self->eul[begin + i] = eul[i]; 00476 00477 (void)BaseMath_WriteCallback(self); 00478 return 0; 00479 } 00480 00481 static PyObject *Euler_subscript(EulerObject *self, PyObject *item) 00482 { 00483 if (PyIndex_Check(item)) { 00484 Py_ssize_t i; 00485 i = PyNumber_AsSsize_t(item, PyExc_IndexError); 00486 if (i == -1 && PyErr_Occurred()) 00487 return NULL; 00488 if (i < 0) 00489 i += EULER_SIZE; 00490 return Euler_item(self, i); 00491 } 00492 else if (PySlice_Check(item)) { 00493 Py_ssize_t start, stop, step, slicelength; 00494 00495 if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) 00496 return NULL; 00497 00498 if (slicelength <= 0) { 00499 return PyTuple_New(0); 00500 } 00501 else if (step == 1) { 00502 return Euler_slice(self, start, stop); 00503 } 00504 else { 00505 PyErr_SetString(PyExc_IndexError, 00506 "slice steps not supported with eulers"); 00507 return NULL; 00508 } 00509 } 00510 else { 00511 PyErr_Format(PyExc_TypeError, 00512 "euler indices must be integers, not %.200s", 00513 Py_TYPE(item)->tp_name); 00514 return NULL; 00515 } 00516 } 00517 00518 00519 static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value) 00520 { 00521 if (PyIndex_Check(item)) { 00522 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); 00523 if (i == -1 && PyErr_Occurred()) 00524 return -1; 00525 if (i < 0) 00526 i += EULER_SIZE; 00527 return Euler_ass_item(self, i, value); 00528 } 00529 else if (PySlice_Check(item)) { 00530 Py_ssize_t start, stop, step, slicelength; 00531 00532 if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) 00533 return -1; 00534 00535 if (step == 1) 00536 return Euler_ass_slice(self, start, stop, value); 00537 else { 00538 PyErr_SetString(PyExc_IndexError, 00539 "slice steps not supported with euler"); 00540 return -1; 00541 } 00542 } 00543 else { 00544 PyErr_Format(PyExc_TypeError, 00545 "euler indices must be integers, not %.200s", 00546 Py_TYPE(item)->tp_name); 00547 return -1; 00548 } 00549 } 00550 00551 //-----------------PROTCOL DECLARATIONS-------------------------- 00552 static PySequenceMethods Euler_SeqMethods = { 00553 (lenfunc) Euler_len, /* sq_length */ 00554 (binaryfunc) NULL, /* sq_concat */ 00555 (ssizeargfunc) NULL, /* sq_repeat */ 00556 (ssizeargfunc) Euler_item, /* sq_item */ 00557 (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ 00558 (ssizeobjargproc) Euler_ass_item, /* sq_ass_item */ 00559 (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */ 00560 (objobjproc) NULL, /* sq_contains */ 00561 (binaryfunc) NULL, /* sq_inplace_concat */ 00562 (ssizeargfunc) NULL, /* sq_inplace_repeat */ 00563 }; 00564 00565 static PyMappingMethods Euler_AsMapping = { 00566 (lenfunc)Euler_len, 00567 (binaryfunc)Euler_subscript, 00568 (objobjargproc)Euler_ass_subscript 00569 }; 00570 00571 /* euler axis, euler.x/y/z */ 00572 00573 PyDoc_STRVAR(Euler_axis_doc, 00574 "Euler axis angle in radians.\n\n:type: float" 00575 ); 00576 static PyObject *Euler_axis_get(EulerObject *self, void *type) 00577 { 00578 return Euler_item(self, GET_INT_FROM_POINTER(type)); 00579 } 00580 00581 static int Euler_axis_set(EulerObject *self, PyObject *value, void *type) 00582 { 00583 return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value); 00584 } 00585 00586 /* rotation order */ 00587 00588 PyDoc_STRVAR(Euler_order_doc, 00589 "Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']" 00590 ); 00591 static PyObject *Euler_order_get(EulerObject *self, void *UNUSED(closure)) 00592 { 00593 if (BaseMath_ReadCallback(self) == -1) /* can read order too */ 00594 return NULL; 00595 00596 return PyUnicode_FromString(euler_order_str(self)); 00597 } 00598 00599 static int Euler_order_set(EulerObject *self, PyObject *value, void *UNUSED(closure)) 00600 { 00601 const char *order_str = _PyUnicode_AsString(value); 00602 short order = euler_order_from_string(order_str, "euler.order"); 00603 00604 if (order == -1) 00605 return -1; 00606 00607 self->order = order; 00608 (void)BaseMath_WriteCallback(self); /* order can be written back */ 00609 return 0; 00610 } 00611 00612 /*****************************************************************************/ 00613 /* Python attributes get/set structure: */ 00614 /*****************************************************************************/ 00615 static PyGetSetDef Euler_getseters[] = { 00616 {(char *)"x", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)0}, 00617 {(char *)"y", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)1}, 00618 {(char *)"z", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)2}, 00619 {(char *)"order", (getter)Euler_order_get, (setter)Euler_order_set, Euler_order_doc, (void *)NULL}, 00620 00621 {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, 00622 {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, 00623 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ 00624 }; 00625 00626 00627 //-----------------------METHOD DEFINITIONS ---------------------- 00628 static struct PyMethodDef Euler_methods[] = { 00629 {"zero", (PyCFunction) Euler_zero, METH_NOARGS, Euler_zero_doc}, 00630 {"to_matrix", (PyCFunction) Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc}, 00631 {"to_quaternion", (PyCFunction) Euler_to_quaternion, METH_NOARGS, Euler_to_quaternion_doc}, 00632 {"rotate_axis", (PyCFunction) Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc}, 00633 {"rotate", (PyCFunction) Euler_rotate, METH_O, Euler_rotate_doc}, 00634 {"make_compatible", (PyCFunction) Euler_make_compatible, METH_O, Euler_make_compatible_doc}, 00635 {"__copy__", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc}, 00636 {"copy", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc}, 00637 {NULL, NULL, 0, NULL} 00638 }; 00639 00640 //------------------PY_OBECT DEFINITION-------------------------- 00641 PyDoc_STRVAR(euler_doc, 00642 "This object gives access to Eulers in Blender." 00643 ); 00644 PyTypeObject euler_Type = { 00645 PyVarObject_HEAD_INIT(NULL, 0) 00646 "mathutils.Euler", //tp_name 00647 sizeof(EulerObject), //tp_basicsize 00648 0, //tp_itemsize 00649 (destructor)BaseMathObject_dealloc, //tp_dealloc 00650 NULL, //tp_print 00651 NULL, //tp_getattr 00652 NULL, //tp_setattr 00653 NULL, //tp_compare 00654 (reprfunc) Euler_repr, //tp_repr 00655 NULL, //tp_as_number 00656 &Euler_SeqMethods, //tp_as_sequence 00657 &Euler_AsMapping, //tp_as_mapping 00658 NULL, //tp_hash 00659 NULL, //tp_call 00660 (reprfunc) Euler_str, //tp_str 00661 NULL, //tp_getattro 00662 NULL, //tp_setattro 00663 NULL, //tp_as_buffer 00664 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags 00665 euler_doc, //tp_doc 00666 (traverseproc)BaseMathObject_traverse, //tp_traverse 00667 (inquiry)BaseMathObject_clear, //tp_clear 00668 (richcmpfunc)Euler_richcmpr, //tp_richcompare 00669 0, //tp_weaklistoffset 00670 NULL, //tp_iter 00671 NULL, //tp_iternext 00672 Euler_methods, //tp_methods 00673 NULL, //tp_members 00674 Euler_getseters, //tp_getset 00675 NULL, //tp_base 00676 NULL, //tp_dict 00677 NULL, //tp_descr_get 00678 NULL, //tp_descr_set 00679 0, //tp_dictoffset 00680 NULL, //tp_init 00681 NULL, //tp_alloc 00682 Euler_new, //tp_new 00683 NULL, //tp_free 00684 NULL, //tp_is_gc 00685 NULL, //tp_bases 00686 NULL, //tp_mro 00687 NULL, //tp_cache 00688 NULL, //tp_subclasses 00689 NULL, //tp_weaklist 00690 NULL //tp_del 00691 }; 00692 //------------------------Euler_CreatePyObject (internal)------------- 00693 //creates a new euler object 00694 /*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER 00695 (i.e. it was allocated elsewhere by MEM_mallocN()) 00696 pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON 00697 (i.e. it must be created here with PyMEM_malloc())*/ 00698 PyObject *Euler_CreatePyObject(float *eul, short order, int type, PyTypeObject *base_type) 00699 { 00700 EulerObject *self; 00701 00702 self = base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) : 00703 (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type); 00704 00705 if (self) { 00706 /* init callbacks as NULL */ 00707 self->cb_user = NULL; 00708 self->cb_type = self->cb_subtype = 0; 00709 00710 if (type == Py_WRAP) { 00711 self->eul = eul; 00712 self->wrapped = Py_WRAP; 00713 } 00714 else if (type == Py_NEW) { 00715 self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float)); 00716 if (eul) { 00717 copy_v3_v3(self->eul, eul); 00718 } 00719 else { 00720 zero_v3(self->eul); 00721 } 00722 00723 self->wrapped = Py_NEW; 00724 } 00725 else { 00726 Py_FatalError("Euler(): invalid type!"); 00727 } 00728 00729 self->order = order; 00730 } 00731 00732 return (PyObject *)self; 00733 } 00734 00735 PyObject *Euler_CreatePyObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype) 00736 { 00737 EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, Py_NEW, NULL); 00738 if (self) { 00739 Py_INCREF(cb_user); 00740 self->cb_user = cb_user; 00741 self->cb_type = (unsigned char)cb_type; 00742 self->cb_subtype = (unsigned char)cb_subtype; 00743 PyObject_GC_Track(self); 00744 } 00745 00746 return (PyObject *)self; 00747 }