25 #include "../generic/py_capi_utils.h"
26 #include "../generic/python_utildefines.h"
30 #ifndef MATH_STANDALONE
38 static PyObject *
Euler_new(PyTypeObject *
type, PyObject *args, PyObject *kwds)
41 const char *order_str =
NULL;
46 if (kwds && PyDict_Size(kwds)) {
47 PyErr_SetString(PyExc_TypeError,
49 "takes no keyword args");
53 if (!PyArg_ParseTuple(args,
"|Os:mathutils.Euler", &seq, &order_str)) {
57 switch (PyTuple_GET_SIZE(args)) {
77 static const char order[][4] = {
"XYZ",
"XZY",
"YXZ",
"YZX",
"ZXY",
"ZYX"};
85 #ifdef __LITTLE_ENDIAN__
86 # define MAKE_ID3(a, b, c) (((a)) | ((b) << 8) | ((c) << 16))
88 # define MAKE_ID3(a, b, c) (((a) << 24) | ((b) << 16) | ((c) << 8))
91 switch (*((PY_INT32_T *)
str)) {
109 PyErr_Format(PyExc_ValueError,
"%s: invalid euler order '%s'", error_prefix,
str);
128 PyTuple_SET_ITEM(
ret, i, PyFloat_FromDouble(
self->eul[i]));
139 ".. method:: to_quaternion()\n"
141 " Return a quaternion representation of the euler.\n"
143 " :return: Quaternion representation of the euler.\n"
144 " :rtype: :class:`Quaternion`\n");
160 ".. method:: to_matrix()\n"
162 " Return a matrix representation of the euler.\n"
164 " :return: A 3x3 rotation matrix representation of the euler.\n"
165 " :rtype: :class:`Matrix`\n");
180 ".. method:: zero()\n"
182 " Set all values to zero.\n");
199 ".. method:: rotate_axis(axis, angle)\n"
201 " Rotates the euler a certain amount and returning a unique euler rotation\n"
202 " (no 720 degree pitches).\n"
204 " :arg axis: single character in ['X, 'Y', 'Z'].\n"
205 " :type axis: string\n"
206 " :arg angle: angle in radians.\n"
207 " :type angle: float\n");
213 if (!PyArg_ParseTuple(args,
"Cf:rotate_axis", &axis, &
angle)) {
214 PyErr_SetString(PyExc_TypeError,
215 "Euler.rotate_axis(): "
216 "expected an axis 'X', 'Y', 'Z' and an angle (float)");
220 if (!(
ELEM(axis,
'X',
'Y',
'Z'))) {
221 PyErr_SetString(PyExc_ValueError,
222 "Euler.rotate_axis(): "
223 "expected axis to be 'X', 'Y' or 'Z'");
239 ".. method:: rotate(other)\n"
241 " Rotates the euler by another mathutils value.\n"
243 " :arg other: rotation component of mathutils value\n"
244 " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n");
247 float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
267 ".. method:: make_compatible(other)\n"
269 " Make this euler compatible with another,\n"
270 " so interpolating between them works as intended.\n"
272 " .. note:: the rotation order is not taken into account for this function.\n");
285 "euler.make_compatible(other), invalid 'other' arg") == -1) {
300 ".. function:: copy()\n"
302 " Returns a copy of this euler.\n"
304 " :return: A copy of the euler.\n"
305 " :rtype: :class:`Euler`\n"
307 " .. note:: use this to get a copy of a wrapped euler with\n"
308 " no reference to the original data.\n");
330 PyObject *
ret, *tuple;
344 #ifndef MATH_STANDALONE
356 "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>",
390 res = ok ? Py_False : Py_True;
397 res = Py_NotImplemented;
404 return Py_INCREF_RET(res);
436 PyErr_SetString(PyExc_IndexError,
438 "array index out of range");
446 return PyFloat_FromDouble(
self->eul[i]);
458 f = PyFloat_AsDouble(value);
459 if (f == -1 && PyErr_Occurred()) {
460 PyErr_SetString(PyExc_TypeError,
461 "euler[attribute] = x: "
462 "assigned value not a number");
471 PyErr_SetString(PyExc_IndexError,
472 "euler[attribute] = x: "
473 "array assignment index out of range");
501 begin =
MIN2(begin, end);
503 tuple = PyTuple_New(end - begin);
505 PyTuple_SET_ITEM(tuple,
count - begin, PyFloat_FromDouble(
self->eul[
count]));
526 begin =
MIN2(begin, end);
533 if (
size != (end - begin)) {
534 PyErr_SetString(PyExc_ValueError,
535 "euler[begin:end] = []: "
536 "size mismatch in slice assignment");
541 self->eul[begin + i] = eul[i];
550 if (PyIndex_Check(item)) {
552 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
553 if (i == -1 && PyErr_Occurred()) {
561 if (PySlice_Check(item)) {
562 Py_ssize_t start, stop, step, slicelength;
564 if (PySlice_GetIndicesEx(item,
EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
568 if (slicelength <= 0) {
569 return PyTuple_New(0);
575 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with eulers");
580 PyExc_TypeError,
"euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
586 if (PyIndex_Check(item)) {
587 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
588 if (i == -1 && PyErr_Occurred()) {
596 if (PySlice_Check(item)) {
597 Py_ssize_t start, stop, step, slicelength;
599 if (PySlice_GetIndicesEx(item,
EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
607 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with euler");
612 PyExc_TypeError,
"euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
622 (ssizessizeargfunc)
NULL,
624 (ssizessizeobjargproc)
NULL,
638 PyDoc_STRVAR(Euler_axis_doc,
"Euler axis angle in radians.\n\n:type: float");
653 "Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']");
666 const char *order_str;
673 if (((order_str = PyUnicode_AsUTF8(value)) ==
NULL) ||
708 {
"zero", (PyCFunction)
Euler_zero, METH_NOARGS, Euler_zero_doc},
709 {
"to_matrix", (PyCFunction)
Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc},
711 {
"rotate_axis", (PyCFunction)
Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc},
712 {
"rotate", (PyCFunction)
Euler_rotate, METH_O, Euler_rotate_doc},
714 {
"copy", (PyCFunction)
Euler_copy, METH_NOARGS, Euler_copy_doc},
715 {
"__copy__", (PyCFunction)
Euler_copy, METH_NOARGS, Euler_copy_doc},
716 {
"__deepcopy__", (PyCFunction)
Euler_deepcopy, METH_VARARGS, Euler_copy_doc},
726 ".. class:: Euler(angles, order='XYZ')\n"
728 " This object gives access to Eulers in Blender.\n"
730 " .. seealso:: `Euler angles <https://en.wikipedia.org/wiki/Euler_angles>`__ on Wikipedia.\n"
732 " :param angles: Three angles, in radians.\n"
733 " :type angles: 3d vector\n"
734 " :param order: Optional order of the angles, a permutation of ``XYZ``.\n"
735 " :type order: str\n");
737 PyVarObject_HEAD_INIT(
NULL, 0)
"Euler",
751 #ifndef MATH_STANDALONE
759 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
793 eul_alloc = PyMem_Malloc(
EULER_SIZE *
sizeof(
float));
795 PyErr_SetString(PyExc_MemoryError,
797 "problem allocating data");
803 self->eul = eul_alloc;
806 self->cb_user =
NULL;
807 self->cb_type =
self->cb_subtype = 0;
820 PyMem_Free(eul_alloc);
823 return (PyObject *)
self;
833 self->cb_user =
NULL;
834 self->cb_type =
self->cb_subtype = 0;
842 return (PyObject *)
self;
853 self->cb_user = cb_user;
854 self->cb_type = cb_type;
855 self->cb_subtype = cb_subtype;
856 PyObject_GC_Track(
self);
859 return (PyObject *)
self;
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
double double_round(double x, int ndigits)
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void eulO_to_quat(float quat[4], const float eul[3], const short order)
void rotate_eulO(float eul[3], const short order, char axis, float angle)
void eulO_to_mat3(float mat[3][3], const float eul[3], const short order)
void compatible_eul(float eul[3], const float old[3])
void mat3_to_compatible_eulO(float eul[3], const float old[3], const short order, const float mat[3][3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
#define POINTER_AS_INT(i)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
Group RGB to Bright Vector Camera CLAMP
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
PyObject * BaseMathObject_freeze(BaseMathObject *self)
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
PyObject * mathutils_dynstr_to_py(struct DynStr *ds)
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
void BaseMathObject_dealloc(BaseMathObject *self)
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
char BaseMathObject_is_wrapped_doc[]
char BaseMathObject_is_frozen_doc[]
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
char BaseMathObject_owner_doc[]
char BaseMathObject_freeze_doc[]
int BaseMathObject_clear(BaseMathObject *self)
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
#define BaseMath_ReadCallback_ForWrite(_self)
#define BaseMath_ReadIndexCallback(_self, _index)
#define BaseMath_WriteCallback(_self)
#define BASE_MATH_NEW(struct_name, root_type, base_type)
#define BaseMathObject_Prepare_ForHash(_self)
#define BASE_MATH_FLAG_DEFAULT
#define BaseMath_Prepare_ForWrite(_self)
#define BaseMath_ReadCallback(_self)
#define BaseMath_WriteIndexCallback(_self, _index)
static PySequenceMethods Euler_SeqMethods
PyObject * Euler_CreatePyObject_wrap(float eul[3], const short order, PyTypeObject *base_type)
static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq)
PyObject * Euler_CreatePyObject_cb(PyObject *cb_user, const short order, uchar cb_type, uchar cb_subtype)
short euler_order_from_string(const char *str, const char *error_prefix)
static PyObject * Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * Euler_repr(EulerObject *self)
static PyObject * Euler_axis_get(EulerObject *self, void *type)
static PyObject * Euler_zero(EulerObject *self)
static Py_hash_t Euler_hash(EulerObject *self)
static PyObject * Euler_ToTupleExt(EulerObject *self, int ndigits)
static const char * euler_order_str(EulerObject *self)
static int Euler_len(EulerObject *UNUSED(self))
static PyObject * Euler_rotate_axis(EulerObject *self, PyObject *args)
#define MAKE_ID3(a, b, c)
static PyObject * Euler_slice(EulerObject *self, int begin, int end)
static PyObject * Euler_subscript(EulerObject *self, PyObject *item)
static int Euler_axis_set(EulerObject *self, PyObject *value, void *type)
static PyObject * Euler_to_quaternion(EulerObject *self)
static int Euler_order_set(EulerObject *self, PyObject *value, void *UNUSED(closure))
static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value)
static PyObject * Euler_to_matrix(EulerObject *self)
static PyObject * Euler_item(EulerObject *self, int i)
PyDoc_STRVAR(Euler_to_quaternion_doc, ".. method:: to_quaternion()\n" "\n" " Return a quaternion representation of the euler.\n" "\n" " :return: Quaternion representation of the euler.\n" " :rtype: :class:`Quaternion`\n")
static PyObject * Euler_copy(EulerObject *self)
PyObject * Euler_CreatePyObject(const float eul[3], const short order, PyTypeObject *base_type)
static PyObject * Euler_rotate(EulerObject *self, PyObject *value)
static PyObject * Euler_str(EulerObject *self)
static int Euler_ass_item(EulerObject *self, int i, PyObject *value)
static PyGetSetDef Euler_getseters[]
static PyObject * Euler_richcmpr(PyObject *a, PyObject *b, int op)
static PyObject * Euler_make_compatible(EulerObject *self, PyObject *value)
static PyMappingMethods Euler_AsMapping
static struct PyMethodDef Euler_methods[]
static PyObject * Euler_order_get(EulerObject *self, void *UNUSED(closure))
static PyObject * Euler_deepcopy(EulerObject *self, PyObject *args)
#define EulerObject_Check(v)
PyObject * Matrix_CreatePyObject(const float *mat, const ushort num_col, const ushort num_row, PyTypeObject *base_type)
PyObject * Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
int PyC_CheckArgs_DeepCopy(PyObject *args)