11 #include "../generic/py_capi_utils.h"
12 #include "../generic/python_utildefines.h"
16 #ifndef MATH_STANDALONE
29 static const char order[][4] = {
"XYZ",
"XZY",
"YXZ",
"YZX",
"ZXY",
"ZYX"};
37 #ifdef __LITTLE_ENDIAN__
38 # define MAKE_ID3(a, b, c) (((a)) | ((b) << 8) | ((c) << 16))
40 # define MAKE_ID3(a, b, c) (((a) << 24) | ((b) << 16) | ((c) << 8))
43 switch (*((
const PY_INT32_T *)
str)) {
61 PyErr_Format(PyExc_ValueError,
"%s: invalid euler order '%s'", error_prefix,
str);
82 PyTuple_SET_ITEM(
ret, i, PyFloat_FromDouble(
self->eul[i]));
95 static PyObject *
Euler_new(PyTypeObject *
type, PyObject *args, PyObject *kwds)
98 const char *order_str =
NULL;
103 if (kwds && PyDict_Size(kwds)) {
104 PyErr_SetString(PyExc_TypeError,
105 "mathutils.Euler(): "
106 "takes no keyword args");
110 if (!PyArg_ParseTuple(args,
"|Os:mathutils.Euler", &seq, &order_str)) {
114 switch (PyTuple_GET_SIZE(args)) {
138 ".. method:: to_quaternion()\n"
140 " Return a quaternion representation of the euler.\n"
142 " :return: Quaternion representation of the euler.\n"
143 " :rtype: :class:`Quaternion`\n");
158 ".. method:: to_matrix()\n"
160 " Return a matrix representation of the euler.\n"
162 " :return: A 3x3 rotation matrix representation of the euler.\n"
163 " :rtype: :class:`Matrix`\n");
178 ".. method:: zero()\n"
180 " Set all values to zero.\n");
197 ".. method:: rotate_axis(axis, angle)\n"
199 " Rotates the euler a certain amount and returning a unique euler rotation\n"
200 " (no 720 degree pitches).\n"
202 " :arg axis: single character in ['X, 'Y', 'Z'].\n"
203 " :type axis: string\n"
204 " :arg angle: angle in radians.\n"
205 " :type angle: float\n");
211 if (!PyArg_ParseTuple(args,
"Cf:rotate_axis", &axis, &
angle)) {
212 PyErr_SetString(PyExc_TypeError,
213 "Euler.rotate_axis(): "
214 "expected an axis 'X', 'Y', 'Z' and an angle (float)");
218 if (!(
ELEM(axis,
'X',
'Y',
'Z'))) {
219 PyErr_SetString(PyExc_ValueError,
220 "Euler.rotate_axis(): "
221 "expected axis to be 'X', 'Y' or 'Z'");
237 ".. method:: rotate(other)\n"
239 " Rotates the euler by another mathutils value.\n"
241 " :arg other: rotation component of mathutils value\n"
242 " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n");
245 float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
265 ".. method:: make_compatible(other)\n"
267 " Make this euler compatible with another,\n"
268 " so interpolating between them works as intended.\n"
270 " .. note:: the rotation order is not taken into account for this function.\n");
283 "euler.make_compatible(other), invalid 'other' arg") == -1) {
295 ".. function:: copy()\n"
297 " Returns a copy of this euler.\n"
299 " :return: A copy of the euler.\n"
300 " :rtype: :class:`Euler`\n"
302 " .. note:: use this to get a copy of a wrapped euler with\n"
303 " no reference to the original data.\n");
328 PyObject *
ret, *tuple;
342 #ifndef MATH_STANDALONE
354 "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>",
394 res = ok ? Py_False : Py_True;
401 res = Py_NotImplemented;
408 return Py_INCREF_RET(res);
450 PyErr_SetString(PyExc_IndexError,
452 "array index out of range");
460 return PyFloat_FromDouble(
self->eul[i]);
472 f = PyFloat_AsDouble(value);
473 if (f == -1 && PyErr_Occurred()) {
474 PyErr_SetString(PyExc_TypeError,
475 "euler[attribute] = x: "
476 "assigned value not a number");
485 PyErr_SetString(PyExc_IndexError,
486 "euler[attribute] = x: "
487 "array assignment index out of range");
515 begin =
MIN2(begin, end);
517 tuple = PyTuple_New(end - begin);
519 PyTuple_SET_ITEM(tuple,
count - begin, PyFloat_FromDouble(
self->eul[
count]));
540 begin =
MIN2(begin, end);
547 if (
size != (end - begin)) {
548 PyErr_SetString(PyExc_ValueError,
549 "euler[begin:end] = []: "
550 "size mismatch in slice assignment");
555 self->eul[begin + i] = eul[i];
565 if (PyIndex_Check(item)) {
567 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
568 if (i == -1 && PyErr_Occurred()) {
576 if (PySlice_Check(item)) {
577 Py_ssize_t start, stop, step, slicelength;
579 if (PySlice_GetIndicesEx(item,
EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
583 if (slicelength <= 0) {
584 return PyTuple_New(0);
590 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with eulers");
595 PyExc_TypeError,
"euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
602 if (PyIndex_Check(item)) {
603 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
604 if (i == -1 && PyErr_Occurred()) {
612 if (PySlice_Check(item)) {
613 Py_ssize_t start, stop, step, slicelength;
615 if (PySlice_GetIndicesEx(item,
EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
623 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with euler");
628 PyExc_TypeError,
"euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
643 (ssizessizeargfunc)
NULL,
645 (ssizessizeobjargproc)
NULL,
665 PyDoc_STRVAR(Euler_axis_doc,
"Euler axis angle in radians.\n\n:type: float");
680 "Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']");
693 const char *order_str;
700 if (((order_str = PyUnicode_AsUTF8(value)) ==
NULL) ||
748 {
"zero", (PyCFunction)
Euler_zero, METH_NOARGS, Euler_zero_doc},
749 {
"to_matrix", (PyCFunction)
Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc},
751 {
"rotate_axis", (PyCFunction)
Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc},
752 {
"rotate", (PyCFunction)
Euler_rotate, METH_O, Euler_rotate_doc},
754 {
"copy", (PyCFunction)
Euler_copy, METH_NOARGS, Euler_copy_doc},
755 {
"__copy__", (PyCFunction)
Euler_copy, METH_NOARGS, Euler_copy_doc},
756 {
"__deepcopy__", (PyCFunction)
Euler_deepcopy, METH_VARARGS, Euler_copy_doc},
771 ".. class:: Euler(angles, order='XYZ')\n"
773 " This object gives access to Eulers in Blender.\n"
775 " .. seealso:: `Euler angles <https://en.wikipedia.org/wiki/Euler_angles>`__ on Wikipedia.\n"
777 " :param angles: Three angles, in radians.\n"
778 " :type angles: 3d vector\n"
779 " :param order: Optional order of the angles, a permutation of ``XYZ``.\n"
780 " :type order: str\n");
782 PyVarObject_HEAD_INIT(
NULL, 0)
"Euler",
796 #ifndef MATH_STANDALONE
804 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
844 eul_alloc = PyMem_Malloc(
EULER_SIZE *
sizeof(
float));
846 PyErr_SetString(PyExc_MemoryError,
848 "problem allocating data");
854 self->eul = eul_alloc;
857 self->cb_user =
NULL;
858 self->cb_type =
self->cb_subtype = 0;
871 PyMem_Free(eul_alloc);
874 return (PyObject *)
self;
884 self->cb_user =
NULL;
885 self->cb_type =
self->cb_subtype = 0;
893 return (PyObject *)
self;
904 self->cb_user = cb_user;
905 self->cb_type = cb_type;
906 self->cb_subtype = cb_subtype;
907 PyObject_GC_Track(
self);
910 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_mat3(float mat[3][3], const float eul[3], short order)
void mat3_to_compatible_eulO(float eul[3], const float old[3], short order, const float mat[3][3])
void rotate_eulO(float eul[3], short order, char axis, float angle)
void eulO_to_quat(float quat[4], const float eul[3], short order)
void compatible_eul(float eul[3], const float old[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 Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position 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.
SyclQueue void void size_t num_bytes void
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)
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
char BaseMathObject_is_valid_doc[]
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
char BaseMathObject_is_wrapped_doc[]
char BaseMathObject_is_frozen_doc[]
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *UNUSED(closure))
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 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 PyObject * Euler_to_tuple_ex(EulerObject *self, int ndigits)
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 col_num, const ushort row_num, PyTypeObject *base_type)
PyObject * Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
int PyC_CheckArgs_DeepCopy(PyObject *args)