23#ifndef MATH_STANDALONE
32#define MAX_DIMENSIONS 4
39#define SWIZZLE_BITS_PER_AXIS 3
40#define SWIZZLE_VALID_AXIS 0x4
41#define SWIZZLE_AXIS 0x3
67 if (mat->
row_num == 4 && vec_num == 3) {
71 PyErr_SetString(PyExc_ValueError,
72 "vector * matrix: matrix column size "
73 "and the vector size must be the same");
82 memcpy(vec_cpy, vec->vec, vec_num *
sizeof(
float));
88 for (row = 0; row < mat->
row_num; row++) {
115 ret = PyTuple_New(
self->vec_num);
118 for (
i = 0;
i <
self->vec_num;
i++) {
123 for (
i = 0;
i <
self->vec_num;
i++) {
124 PyTuple_SET_ITEM(
ret,
i, PyFloat_FromDouble(
self->vec[
i]));
142 PyObject *
const *args,
146 if (
UNLIKELY(kwnames && PyTuple_GET_SIZE(kwnames))) {
147 PyErr_SetString(PyExc_TypeError,
149 "takes no keyword args");
153 float *vec =
nullptr;
156 const size_t nargs = PyVectorcall_NARGS(nargsf);
159 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
161 if (vec ==
nullptr) {
162 PyErr_SetString(PyExc_MemoryError,
164 "problem allocating pointer space");
178 PyErr_Format(PyExc_TypeError,
179 "mathutils.Vector(): "
180 "takes at most 1 argument (%zd given)",
188static PyObject *
Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
190 if (
UNLIKELY(kwds && PyDict_GET_SIZE(kwds))) {
191 PyErr_SetString(PyExc_TypeError,
193 "takes no keyword args");
196 PyObject *
const *args_array = &PyTuple_GET_ITEM(args, 0);
197 const size_t args_array_num = PyTuple_GET_SIZE(args);
199 reinterpret_cast<PyObject *
>(type), args_array, args_array_num,
nullptr);
211 ".. classmethod:: Fill(size, fill=0.0, /)\n"
213 " Create a vector of length size with all values set to fill.\n"
215 " :arg size: The length of the vector to be created.\n"
217 " :arg fill: The value used to fill the vector.\n"
218 " :type fill: float\n");
225 if (!PyArg_ParseTuple(args,
"i|f:Vector.Fill", &vec_num, &fill)) {
230 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
234 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
236 if (vec ==
nullptr) {
237 PyErr_SetString(PyExc_MemoryError,
239 "problem allocating pointer space");
251 ".. classmethod:: Range(start, stop, step=1, /)\n"
253 " Create a filled with a range of values.\n"
255 " This method can also be called with a single argument, "
256 "in which case the argument is interpreted as ``stop`` and ``start`` defaults to 0.\n"
258 " :arg start: The start of the range used to fill the vector.\n"
259 " :type start: int\n"
260 " :arg stop: The end of the range used to fill the vector.\n"
262 " :arg step: The step between successive values in the vector.\n"
263 " :type step: int\n");
271 if (!PyArg_ParseTuple(args,
"i|ii:Vector.Range", &start, &stop, &
step)) {
275 switch (PyTuple_GET_SIZE(args)) {
283 PyErr_SetString(PyExc_RuntimeError,
284 "Start value is larger "
285 "than the stop value");
289 vec_num = stop - start;
294 PyErr_SetString(PyExc_RuntimeError,
295 "Start value is larger "
296 "than the stop value");
300 vec_num = (stop - start);
302 if ((vec_num %
step) != 0) {
313 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
317 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
319 if (vec ==
nullptr) {
320 PyErr_SetString(PyExc_MemoryError,
322 "problem allocating pointer space");
333 C_Vector_Linspace_doc,
334 ".. classmethod:: Linspace(start, stop, size, /)\n"
336 " Create a vector of the specified size which is filled with linearly spaced "
337 "values between start and stop values.\n"
339 " :arg start: The start of the range used to fill the vector.\n"
340 " :type start: int\n"
341 " :arg stop: The end of the range used to fill the vector.\n"
343 " :arg size: The size of the vector to be created.\n"
344 " :type size: int\n");
349 float start, end,
step;
351 if (!PyArg_ParseTuple(args,
"ffi:Vector.Linspace", &start, &end, &vec_num)) {
356 PyErr_SetString(PyExc_RuntimeError,
"Vector.Linspace(): invalid size");
360 step = (end - start) /
float(vec_num - 1);
362 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
364 if (vec ==
nullptr) {
365 PyErr_SetString(PyExc_MemoryError,
366 "Vector.Linspace(): "
367 "problem allocating pointer space");
379 ".. classmethod:: Repeat(vector, size, /)\n"
381 " Create a vector by repeating the values in vector until the required size is reached.\n"
383 " :arg vector: The vector to draw values from.\n"
384 " :type vector: :class:`mathutils.Vector`\n"
385 " :arg size: The size of the vector to be created.\n"
386 " :type size: int\n");
390 float *iter_vec =
nullptr;
391 int i, vec_num, value_num;
394 if (!PyArg_ParseTuple(args,
"Oi:Vector.Repeat", &value, &vec_num)) {
399 PyErr_SetString(PyExc_RuntimeError,
"Vector.Repeat(): invalid vec_num");
404 &iter_vec, 2, value,
"Vector.Repeat(vector, vec_num), invalid 'vector' arg")) == -1)
409 if (iter_vec ==
nullptr) {
410 PyErr_SetString(PyExc_MemoryError,
412 "problem allocating pointer space");
416 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
418 if (vec ==
nullptr) {
419 PyMem_Free(iter_vec);
420 PyErr_SetString(PyExc_MemoryError,
422 "problem allocating pointer space");
427 while (
i < vec_num) {
428 vec[
i] = iter_vec[
i % value_num];
432 PyMem_Free(iter_vec);
446 ".. method:: zero()\n"
448 " Set all values to zero.\n");
472 Vector_normalize_doc,
473 ".. method:: normalize()\n"
475 " Normalize the vector, making the length of the vector always 1.0.\n"
477 " .. warning:: Normalizing a vector where all values are zero has no effect.\n"
479 " .. note:: Normalize works for vectors of all sizes,\n"
480 " however 4D Vectors w axis is left untouched.\n");
483 const int vec_num = (
self->vec_num == 4 ? 3 :
self->vec_num);
495 Vector_normalized_doc,
496 ".. method:: normalized()\n"
498 " Return a new, normalized vector.\n"
500 " :return: a normalized copy of the vector\n"
501 " :rtype: :class:`Vector`\n");
516 ".. method:: resize(size, /)\n"
518 " Resize the vector to have size number of elements.\n");
529 if ((vec_num = PyC_Long_AsI32(value)) == -1) {
530 PyErr_SetString(PyExc_TypeError,
531 "Vector.resize(size): "
532 "expected size argument to be an integer");
537 PyErr_SetString(PyExc_RuntimeError,
"Vector.resize(): invalid size");
541 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec, (vec_num *
sizeof(
float))));
542 if (
self->vec ==
nullptr) {
543 PyErr_SetString(PyExc_MemoryError,
545 "problem allocating pointer space");
550 if (vec_num >
self->vec_num) {
554 self->vec_num = vec_num;
561 ".. method:: resized(size, /)\n"
563 " Return a resized copy of the vector with size number of elements.\n"
565 " :return: a new vector\n"
566 " :rtype: :class:`Vector`\n");
572 if ((vec_num = PyLong_AsLong(value)) == -1) {
577 PyErr_SetString(PyExc_RuntimeError,
"Vector.resized(): invalid size");
581 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
583 if (vec ==
nullptr) {
584 PyErr_SetString(PyExc_MemoryError,
586 "problem allocating pointer space");
591 memcpy(vec,
self->vec,
self->vec_num *
sizeof(
float));
598 Vector_resize_2d_doc,
599 ".. method:: resize_2d()\n"
601 " Resize the vector to 2D (x, y).\n");
609 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[2])));
610 if (
self->vec ==
nullptr) {
611 PyErr_SetString(PyExc_MemoryError,
612 "Vector.resize_2d(): "
613 "problem allocating pointer space");
623 Vector_resize_3d_doc,
624 ".. method:: resize_3d()\n"
626 " Resize the vector to 3D (x, y, z).\n");
634 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[3])));
635 if (
self->vec ==
nullptr) {
636 PyErr_SetString(PyExc_MemoryError,
637 "Vector.resize_3d(): "
638 "problem allocating pointer space");
642 if (
self->vec_num == 2) {
652 Vector_resize_4d_doc,
653 ".. method:: resize_4d()\n"
655 " Resize the vector to 4D (x, y, z, w).\n");
663 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[4])));
664 if (
self->vec ==
nullptr) {
665 PyErr_SetString(PyExc_MemoryError,
666 "Vector.resize_4d(): "
667 "problem allocating pointer space");
671 if (
self->vec_num == 2) {
675 else if (
self->vec_num == 3) {
691 ".. method:: to_2d()\n"
693 " Return a 2d copy of the vector.\n"
695 " :return: a new vector\n"
696 " :rtype: :class:`Vector`\n");
708 ".. method:: to_3d()\n"
710 " Return a 3d copy of the vector.\n"
712 " :return: a new vector\n"
713 " :rtype: :class:`Vector`\n");
716 float tvec[3] = {0.0f};
722 memcpy(tvec,
self->vec,
sizeof(
float) * std::min(
self->vec_num, 3));
728 ".. method:: to_4d()\n"
730 " Return a 4d copy of the vector.\n"
732 " :return: a new vector\n"
733 " :rtype: :class:`Vector`\n");
736 float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f};
742 memcpy(tvec,
self->vec,
sizeof(
float) * std::min(
self->vec_num, 4));
755 ".. method:: to_tuple(precision=-1, /)\n"
757 " Return this vector as a tuple with a given precision.\n"
759 " :arg precision: The number to round the value to in [-1, 21].\n"
760 " :type precision: int\n"
761 " :return: the values of the vector rounded by *precision*\n"
762 " :rtype: tuple[float, ...]\n");
767 if (!PyArg_ParseTuple(args,
"|i:to_tuple", &ndigits)) {
771 if (ndigits > 22 || ndigits < -1) {
772 PyErr_SetString(PyExc_ValueError,
773 "Vector.to_tuple(precision): "
774 "precision must be between -1 and 21");
793 Vector_to_track_quat_doc,
794 ".. method:: to_track_quat(track='Z', up='Y', /)\n"
796 " Return a quaternion rotation from the vector and the track and up axis.\n"
798 " :arg track: Track axis string.\n"
799 " :type track: Literal['-', 'X', 'Y', 'Z', '-X', '-Y', '-Z']\n"
800 " :arg up: Up axis string.\n"
801 " :type up: Literal['X', 'Y', 'Z']\n"
802 " :return: rotation from the vector and the track and up axis.\n"
803 " :rtype: :class:`Quaternion`\n");
806 float vec[3], quat[4];
807 const char *strack =
nullptr;
808 const char *sup =
nullptr;
809 short track = 2, up = 1;
811 if (!PyArg_ParseTuple(args,
"|ss:to_track_quat", &strack, &sup)) {
815 if (
self->vec_num != 3) {
816 PyErr_SetString(PyExc_TypeError,
817 "Vector.to_track_quat(): "
818 "only for 3D vectors");
827 const char *axis_err_msg =
"only X, -X, Y, -Y, Z or -Z for track axis";
829 if (strlen(strack) == 2) {
830 if (strack[0] ==
'-') {
845 PyErr_SetString(PyExc_ValueError, axis_err_msg);
851 PyErr_SetString(PyExc_ValueError, axis_err_msg);
855 else if (strlen(strack) == 1) {
871 PyErr_SetString(PyExc_ValueError, axis_err_msg);
877 PyErr_SetString(PyExc_ValueError, axis_err_msg);
883 const char *axis_err_msg =
"only X, Y or Z for up axis";
884 if (strlen(sup) == 1) {
899 PyErr_SetString(PyExc_ValueError, axis_err_msg);
905 PyErr_SetString(PyExc_ValueError, axis_err_msg);
911 PyErr_SetString(PyExc_ValueError,
"Can't have the same axis for track and up");
932 Vector_orthogonal_doc,
933 ".. method:: orthogonal()\n"
935 " Return a perpendicular vector.\n"
937 " :return: a new vector 90 degrees from this vector.\n"
938 " :rtype: :class:`Vector`\n"
940 " .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n");
945 if (
self->vec_num > 3) {
946 PyErr_SetString(PyExc_TypeError,
947 "Vector.orthogonal(): "
948 "Vector must be 3D or 2D");
956 if (
self->vec_num == 3) {
978 ".. method:: reflect(mirror, /)\n"
980 " Return the reflection vector from the *mirror* argument.\n"
982 " :arg mirror: This vector could be a normal from the reflecting surface.\n"
983 " :type mirror: :class:`Vector`\n"
984 " :return: The reflected vector matching the size of this vector.\n"
985 " :rtype: :class:`Vector`\n");
989 float mirror[3], vec[3];
998 tvec, 2, 4, value,
"Vector.reflect(other), invalid 'other' arg")) == -1)
1003 if (
self->vec_num < 2 ||
self->vec_num > 4) {
1004 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D, 3D or 4D");
1008 mirror[0] = tvec[0];
1009 mirror[1] = tvec[1];
1010 mirror[2] = (value_num > 2) ? tvec[2] : 0.0f;
1012 vec[0] =
self->vec[0];
1013 vec[1] =
self->vec[1];
1014 vec[2] = (value_num > 2) ?
self->vec[2] : 0.0f;
1031 ".. method:: cross(other, /)\n"
1033 " Return the cross product of this vector and another.\n"
1035 " :arg other: The other vector to perform the cross product with.\n"
1036 " :type other: :class:`Vector`\n"
1037 " :return: The cross product as a vector or a float when 2D vectors are used.\n"
1038 " :rtype: :class:`Vector` | float\n"
1040 " .. note:: both vectors must be 2D or 3D\n");
1050 if (
self->vec_num > 3) {
1051 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D or 3D");
1056 tvec,
self->vec_num,
self->vec_num, value,
"Vector.cross(other), invalid 'other' arg") ==
1062 if (
self->vec_num == 3) {
1082 ".. method:: dot(other, /)\n"
1084 " Return the dot product of this vector and another.\n"
1086 " :arg other: The other vector to perform the dot product with.\n"
1087 " :type other: :class:`Vector`\n"
1088 " :return: The dot product.\n"
1089 " :rtype: float\n");
1100 &tvec,
self->vec_num, value,
"Vector.dot(other), invalid 'other' arg") == -1)
1119 ".. function:: angle(other, fallback=None, /)\n"
1121 " Return the angle between two vectors.\n"
1123 " :arg other: another vector to compare the angle with\n"
1124 " :type other: :class:`Vector`\n"
1125 " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1126 " (instead of raising a :exc:`ValueError`).\n"
1127 " :type fallback: Any\n"
1128 " :return: angle in radians or fallback when given\n"
1129 " :rtype: float | Any\n");
1132 const int vec_num = std::min(
self->vec_num, 3);
1135 double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
1137 PyObject *fallback =
nullptr;
1139 if (!PyArg_ParseTuple(args,
"O|O:angle", &value, &fallback)) {
1150 tvec,
self->vec_num,
self->vec_num, value,
"Vector.angle(other), invalid 'other' arg") ==
1156 if (
self->vec_num > 4) {
1157 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D, 3D or 4D");
1161 for (
x = 0;
x < vec_num;
x++) {
1162 dot_self += double(
self->vec[
x]) * double(
self->vec[
x]);
1163 dot_other += double(tvec[
x]) * double(tvec[
x]);
1164 dot += double(
self->vec[
x]) * double(tvec[
x]);
1167 if (!dot_self || !dot_other) {
1170 Py_INCREF(fallback);
1174 PyErr_SetString(PyExc_ValueError,
1175 "Vector.angle(other): "
1176 "zero length vectors have no valid angle");
1191 Vector_angle_signed_doc,
1192 ".. function:: angle_signed(other, fallback=None, /)\n"
1194 " Return the signed angle between two 2D vectors (clockwise is positive).\n"
1196 " :arg other: another vector to compare the angle with\n"
1197 " :type other: :class:`Vector`\n"
1198 " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1199 " (instead of raising a :exc:`ValueError`).\n"
1200 " :type fallback: Any\n"
1201 " :return: angle in radians or fallback when given\n"
1202 " :rtype: float | Any\n");
1208 PyObject *fallback =
nullptr;
1210 if (!PyArg_ParseTuple(args,
"O|O:angle_signed", &value, &fallback)) {
1219 tvec, 2, 2, value,
"Vector.angle_signed(other), invalid 'other' arg") == -1)
1224 if (
self->vec_num != 2) {
1225 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D");
1232 Py_INCREF(fallback);
1236 PyErr_SetString(PyExc_ValueError,
1237 "Vector.angle_signed(other): "
1238 "zero length vectors have no valid angle");
1253 Vector_rotation_difference_doc,
1254 ".. function:: rotation_difference(other, /)\n"
1256 " Returns a quaternion representing the rotational difference between this\n"
1257 " vector and another.\n"
1259 " :arg other: second vector.\n"
1260 " :type other: :class:`Vector`\n"
1261 " :return: the rotational difference between the two vectors.\n"
1262 " :rtype: :class:`Quaternion`\n"
1264 " .. note:: 2D vectors raise an :exc:`AttributeError`.\n");
1267 float quat[4], vec_a[3], vec_b[3];
1269 if (
self->vec_num < 3 ||
self->vec_num > 4) {
1270 PyErr_SetString(PyExc_ValueError,
1271 "vec.difference(value): "
1272 "expects both vectors to be size 3 or 4");
1281 vec_b, 3,
MAX_DIMENSIONS, value,
"Vector.difference(other), invalid 'other' arg") == -1)
1303 ".. function:: project(other, /)\n"
1305 " Return the projection of this vector onto the *other*.\n"
1307 " :arg other: second vector.\n"
1308 " :type other: :class:`Vector`\n"
1309 " :return: the parallel projection vector\n"
1310 " :rtype: :class:`Vector`\n");
1313 const int vec_num =
self->vec_num;
1315 double dot = 0.0f, dot2 = 0.0f;
1323 &tvec, vec_num, value,
"Vector.project(other), invalid 'other' arg") == -1)
1329 for (
x = 0;
x < vec_num;
x++) {
1331 dot2 += double(tvec[
x] * tvec[
x]);
1335 for (
x = 0;
x < vec_num;
x++) {
1350 ".. function:: lerp(other, factor, /)\n"
1352 " Returns the interpolation of two vectors.\n"
1354 " :arg other: value to interpolate with.\n"
1355 " :type other: :class:`Vector`\n"
1356 " :arg factor: The interpolation value in [0.0, 1.0].\n"
1357 " :type factor: float\n"
1358 " :return: The interpolated vector.\n"
1359 " :rtype: :class:`Vector`\n");
1362 const int vec_num =
self->vec_num;
1363 PyObject *value =
nullptr;
1367 if (!PyArg_ParseTuple(args,
"Of:lerp", &value, &fac)) {
1376 &tvec, vec_num, value,
"Vector.lerp(other), invalid 'other' arg") == -1)
1395 ".. function:: slerp(other, factor, fallback=None, /)\n"
1397 " Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
1399 " :arg other: value to interpolate with.\n"
1400 " :type other: :class:`Vector`\n"
1401 " :arg factor: The interpolation value typically in [0.0, 1.0].\n"
1402 " :type factor: float\n"
1403 " :arg fallback: return this when the vector can't be calculated (zero length "
1404 "vector or direct opposites),\n"
1405 " (instead of raising a :exc:`ValueError`).\n"
1406 " :type fallback: Any\n"
1407 " :return: The interpolated vector.\n"
1408 " :rtype: :class:`Vector`\n");
1411 const int vec_num =
self->vec_num;
1412 PyObject *value =
nullptr;
1413 float fac, cosom,
w[2];
1414 float self_vec[3], other_vec[3], ret_vec[3];
1415 float self_len_sq, other_len_sq;
1417 PyObject *fallback =
nullptr;
1419 if (!PyArg_ParseTuple(args,
"Of|O:slerp", &value, &fac, &fallback)) {
1427 if (
self->vec_num > 3) {
1428 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D or 3D");
1433 other_vec, vec_num, vec_num, value,
"Vector.slerp(other), invalid 'other' arg") == -1)
1442 if (
UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) {
1445 Py_INCREF(fallback);
1449 PyErr_SetString(PyExc_ValueError,
1451 "zero length vectors unsupported");
1459 if (
UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
1462 Py_INCREF(fallback);
1466 PyErr_SetString(PyExc_ValueError,
1468 "opposite vectors unsupported");
1474 for (
x = 0;
x < vec_num;
x++) {
1475 ret_vec[
x] = (
w[0] * self_vec[
x]) + (
w[1] * other_vec[
x]);
1490 ".. function:: rotate(other, /)\n"
1492 " Rotate the vector by a rotation value.\n"
1494 " .. note:: 2D vectors are a special case that can only be rotated by a 2x2 matrix.\n"
1496 " :arg other: rotation component of mathutils value\n"
1497 " :type other: :class:`Euler` | :class:`Quaternion` | :class:`Matrix`\n");
1504 if (
self->vec_num == 2) {
1506 float other_rmat[2][2];
1516 float other_rmat[3][3];
1538 ".. method:: negate()\n"
1540 " Set all values to their negative.\n");
1562 ".. function:: copy()\n"
1564 " Returns a copy of this vector.\n"
1566 " :return: A copy of the vector.\n"
1567 " :rtype: :class:`Vector`\n"
1569 " .. note:: use this to get a copy of a wrapped vector with\n"
1570 " no reference to the original data.\n");
1595 PyObject *
ret, *tuple;
1602 ret = PyUnicode_FromFormat(
"Vector(%R)", tuple);
1607#ifndef MATH_STANDALONE
1622 for (
i = 0;
i <
self->vec_num;
i++) {
1652 view->len = Py_ssize_t(
self->vec_num *
sizeof(
float));
1655 if ((flags & PyBUF_WRITABLE) == 0) {
1658 if (flags & PyBUF_FORMAT) {
1659 view->format = (
char *)
"f";
1673 if (
view->readonly == 0) {
1691static PyObject *
Vector_richcmpr(PyObject *objectA, PyObject *objectB,
int comparison_type)
1695 const double epsilon = 0.000001f;
1699 if (comparison_type == Py_NE) {
1712 if (vecA->
vec_num != vecB->vec_num) {
1713 if (comparison_type == Py_NE) {
1720 switch (comparison_type) {
1736 result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1763 result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1768 printf(
"The result of the comparison could not be evaluated");
1807 return self->vec_num;
1818 PyErr_Format(PyExc_AttributeError,
1819 "Vector.%c: unavailable on %dd vector",
1820 *(((
const char *)
"xyzw") +
i),
1824 PyErr_SetString(PyExc_IndexError,
"vector[index]: out of range");
1833 return PyFloat_FromDouble(
self->vec[
i]);
1850 if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
1852 PyErr_SetString(PyExc_TypeError,
1853 "vector[index] = x: "
1854 "assigned value not a number");
1864 PyErr_Format(PyExc_AttributeError,
1865 "Vector.%c = x: unavailable on %dd vector",
1866 *(((
const char *)
"xyzw") +
i),
1870 PyErr_SetString(PyExc_IndexError,
1871 "vector[index] = x: "
1872 "assignment index out of range");
1876 self->vec[
i] = scalar;
1902 end =
self->vec_num + end + 1;
1907 tuple = PyTuple_New(end -
begin);
1919 float *vec =
nullptr;
1929 vec_num = (end -
begin);
1934 if (vec ==
nullptr) {
1935 PyErr_SetString(PyExc_MemoryError,
1937 "problem allocating pointer space");
1942 memcpy(
self->vec +
begin, vec, vec_num *
sizeof(
float));
1956 if (PyIndex_Check(item)) {
1958 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1959 if (
i == -1 && PyErr_Occurred()) {
1967 if (PySlice_Check(item)) {
1968 Py_ssize_t start, stop,
step, slicelength;
1970 if (PySlice_GetIndicesEx(item,
self->vec_num, &start, &stop, &
step, &slicelength) < 0) {
1974 if (slicelength <= 0) {
1975 return PyTuple_New(0);
1981 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
1986 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1993 if (PyIndex_Check(item)) {
1994 Py_ssize_t
i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1995 if (
i == -1 && PyErr_Occurred()) {
2003 if (PySlice_Check(item)) {
2004 Py_ssize_t start, stop,
step, slicelength;
2006 if (PySlice_GetIndicesEx(item,
self->vec_num, &start, &stop, &
step, &slicelength) < 0) {
2014 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
2019 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
2033 float *vec =
nullptr;
2036 PyErr_Format(PyExc_AttributeError,
2037 "Vector addition: (%s + %s) "
2038 "invalid type for this operation",
2039 Py_TYPE(v1)->tp_name,
2040 Py_TYPE(
v2)->tp_name);
2051 if (vec1->
vec_num != vec2->vec_num) {
2052 PyErr_SetString(PyExc_AttributeError,
2054 "vectors must have the same dimensions for this operation");
2058 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2059 if (vec ==
nullptr) {
2060 PyErr_SetString(PyExc_MemoryError,
2062 "problem allocating pointer space");
2077 PyErr_Format(PyExc_AttributeError,
2078 "Vector addition: (%s += %s) "
2079 "invalid type for this operation",
2080 Py_TYPE(v1)->tp_name,
2081 Py_TYPE(
v2)->tp_name);
2087 if (vec1->
vec_num != vec2->vec_num) {
2088 PyErr_SetString(PyExc_AttributeError,
2090 "vectors must have the same dimensions for this operation");
2112 PyErr_Format(PyExc_AttributeError,
2113 "Vector subtraction: (%s - %s) "
2114 "invalid type for this operation",
2115 Py_TYPE(v1)->tp_name,
2116 Py_TYPE(
v2)->tp_name);
2126 if (vec1->
vec_num != vec2->vec_num) {
2127 PyErr_SetString(PyExc_AttributeError,
2128 "Vector subtraction: "
2129 "vectors must have the same dimensions for this operation");
2133 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2134 if (vec ==
nullptr) {
2135 PyErr_SetString(PyExc_MemoryError,
2137 "problem allocating pointer space");
2152 PyErr_Format(PyExc_AttributeError,
2153 "Vector subtraction: (%s -= %s) "
2154 "invalid type for this operation",
2155 Py_TYPE(v1)->tp_name,
2156 Py_TYPE(
v2)->tp_name);
2162 if (vec1->
vec_num != vec2->vec_num) {
2163 PyErr_SetString(PyExc_AttributeError,
2164 "Vector subtraction: "
2165 "vectors must have the same dimensions for this operation");
2185 int row,
col,
z = 0;
2192 PyErr_SetString(PyExc_ValueError,
2194 "len(matrix.col) and len(vector) must be the same, "
2195 "except for 4x4 matrix * 3D vector.");
2200 memcpy(vec_cpy, vec->vec, vec->
vec_num *
sizeof(
float));
2204 for (row = 0; row < mat->
row_num; row++) {
2217 float *tvec =
static_cast<float *
>(PyMem_Malloc(vec->
vec_num *
sizeof(
float)));
2218 if (tvec ==
nullptr) {
2219 PyErr_SetString(PyExc_MemoryError,
2221 "problem allocating pointer space");
2231 float *tvec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2232 if (tvec ==
nullptr) {
2233 PyErr_SetString(PyExc_MemoryError,
2235 "problem allocating pointer space");
2266 if (vec1->
vec_num != vec2->vec_num) {
2267 PyErr_SetString(PyExc_ValueError,
2268 "Vector multiplication: "
2269 "vectors must have the same dimensions for this operation");
2277 if (((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) == 0) {
2282 if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) {
2287 PyErr_Format(PyExc_TypeError,
2288 "Element-wise multiplication: "
2289 "not supported between '%.200s' and '%.200s' types",
2290 Py_TYPE(v1)->tp_name,
2291 Py_TYPE(
v2)->tp_name);
2321 if (vec1->
vec_num != vec2->vec_num) {
2322 PyErr_SetString(PyExc_ValueError,
2323 "Vector multiplication: "
2324 "vectors must have the same dimensions for this operation");
2331 else if (vec1 && (((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) == 0)) {
2336 PyErr_Format(PyExc_TypeError,
2337 "In place element-wise multiplication: "
2338 "not supported between '%.200s' and '%.200s' types",
2339 Py_TYPE(v1)->tp_name,
2340 Py_TYPE(
v2)->tp_name);
2372 if (vec1->
vec_num != vec2->vec_num) {
2373 PyErr_SetString(PyExc_ValueError,
2374 "Vector multiplication: "
2375 "vectors must have the same dimensions for this operation");
2405 PyErr_Format(PyExc_TypeError,
2406 "Vector multiplication: "
2407 "not supported between '%.200s' and '%.200s' types",
2408 Py_TYPE(v1)->tp_name,
2409 Py_TYPE(
v2)->tp_name);
2416 PyErr_Format(PyExc_TypeError,
2417 "In place vector multiplication: "
2418 "not supported between '%.200s' and '%.200s' types",
2419 Py_TYPE(v1)->tp_name,
2420 Py_TYPE(
v2)->tp_name);
2427 float *vec =
nullptr, scalar;
2431 PyErr_SetString(PyExc_TypeError,
2433 "Vector must be divided by a float");
2442 if ((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) {
2444 PyErr_SetString(PyExc_TypeError,
2446 "Vector must be divided by a float");
2450 if (scalar == 0.0f) {
2451 PyErr_SetString(PyExc_ZeroDivisionError,
2453 "divide by zero error");
2457 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2459 if (vec ==
nullptr) {
2460 PyErr_SetString(PyExc_MemoryError,
2462 "problem allocating pointer space");
2481 if ((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) {
2483 PyErr_SetString(PyExc_TypeError,
2485 "Vector must be divided by a float");
2489 if (scalar == 0.0f) {
2490 PyErr_SetString(PyExc_ZeroDivisionError,
2492 "divide by zero error");
2513 tvec =
static_cast<float *
>(PyMem_Malloc(
self->vec_num *
sizeof(
float)));
2605 "Vector Z axis (3D Vectors only).\n"
2611 "Vector W axis (4D Vectors only).\n"
2644 double dot = 0.0f, param;
2650 if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
2651 PyErr_SetString(PyExc_TypeError,
"length must be set to a number");
2656 PyErr_SetString(PyExc_ValueError,
"cannot set a vectors length to a negative value");
2689 Vector_length_squared_doc,
2690 "Vector length squared (v.dot(v)).\n"
2706 ":type: :class:`Vector`");
2798 uint swizzleClosure;
2809 if (axis_from >=
self->vec_num) {
2810 PyErr_SetString(PyExc_AttributeError,
2812 "specified axis not present");
2816 vec[axis_to] =
self->vec[axis_from];
2843 uint swizzleClosure;
2859 if (axis_to >=
self->vec_num) {
2860 PyErr_SetString(PyExc_AttributeError,
2862 "specified axis not present");
2869 if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) {
2873 vec_assign[
i] = scalarVal;
2876 size_from = axis_from;
2878 else if (PyErr_Clear(),
2880 vec_assign, 2, 4, value,
"Vector.**** = swizzle assignment"))) ==
size_t(-1))
2885 if (axis_from != size_from) {
2886 PyErr_SetString(PyExc_AttributeError,
"Vector swizzle: size does not match swizzle");
2897 memcpy(tvec,
self->vec,
self->vec_num *
sizeof(
float));
2901 tvec[axis_to] = vec_assign[axis_from];
2908 memcpy(
self->vec, tvec,
self->vec_num *
sizeof(
float));
2918#define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
2919#define _SWIZZLE2(a, b) (_SWIZZLE1(a) | (((b) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS)))
2920#define _SWIZZLE3(a, b, c) \
2921 (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
2922#define _SWIZZLE4(a, b, c, d) \
2923 (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
2925#define SWIZZLE2(a, b) POINTER_FROM_INT(_SWIZZLE2(a, b))
2926#define SWIZZLE3(a, b, c) POINTER_FROM_INT(_SWIZZLE3(a, b, c))
2927#define SWIZZLE4(a, b, c, d) POINTER_FROM_INT(_SWIZZLE4(a, b, c, d))
2929#define VECTOR_SWIZZLE2_RW_DEF(attr, a, b) \
2932 (getter)Vector_swizzle_get, \
2933 (setter)Vector_swizzle_set, \
2934 Vector_swizzle_doc, \
2937#define VECTOR_SWIZZLE2_RO_DEF(attr, a, b) \
2940 (getter)Vector_swizzle_get, \
2942 Vector_swizzle_doc, \
2945#define VECTOR_SWIZZLE3_RW_DEF(attr, a, b, c) \
2948 (getter)Vector_swizzle_get, \
2949 (setter)Vector_swizzle_set, \
2950 Vector_swizzle_doc, \
2951 SWIZZLE3(a, b, c), \
2953#define VECTOR_SWIZZLE3_RO_DEF(attr, a, b, c) \
2956 (getter)Vector_swizzle_get, \
2958 Vector_swizzle_doc, \
2959 SWIZZLE3(a, b, c), \
2961#define VECTOR_SWIZZLE4_RW_DEF(attr, a, b, c, d) \
2964 (getter)Vector_swizzle_get, \
2965 (setter)Vector_swizzle_set, \
2966 Vector_swizzle_doc, \
2967 SWIZZLE4(a, b, c, d), \
2969#define VECTOR_SWIZZLE4_RO_DEF(attr, a, b, c, d) \
2970 {attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE4(a, b, c, d)}
2980# pragma clang diagnostic push
2981# pragma clang diagnostic ignored "-Wcast-function-type"
2983# pragma GCC diagnostic push
2984# pragma GCC diagnostic ignored "-Wcast-function-type"
3013 Vector_length_squared_doc,
3379#undef AXIS_FROM_CHAR
3389#undef VECTOR_SWIZZLE2_RW_DEF
3390#undef VECTOR_SWIZZLE2_RO_DEF
3391#undef VECTOR_SWIZZLE3_RW_DEF
3392#undef VECTOR_SWIZZLE3_RO_DEF
3393#undef VECTOR_SWIZZLE4_RW_DEF
3394#undef VECTOR_SWIZZLE4_RO_DEF
3396 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
3401# pragma clang diagnostic pop
3403# pragma GCC diagnostic pop
3415# pragma clang diagnostic push
3416# pragma clang diagnostic ignored "-Wcast-function-type"
3418# pragma GCC diagnostic push
3419# pragma GCC diagnostic ignored "-Wcast-function-type"
3425 {
"Fill", (PyCFunction)
C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
3426 {
"Range", (PyCFunction)
C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
3427 {
"Linspace", (PyCFunction)
C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
3428 {
"Repeat", (PyCFunction)
C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
3431 {
"zero", (PyCFunction)
Vector_zero, METH_NOARGS, Vector_zero_doc},
3432 {
"negate", (PyCFunction)
Vector_negate, METH_NOARGS, Vector_negate_doc},
3435 {
"normalize", (PyCFunction)
Vector_normalize, METH_NOARGS, Vector_normalize_doc},
3436 {
"normalized", (PyCFunction)
Vector_normalized, METH_NOARGS, Vector_normalized_doc},
3438 {
"resize", (PyCFunction)
Vector_resize, METH_O, Vector_resize_doc},
3439 {
"resized", (PyCFunction)
Vector_resized, METH_O, Vector_resized_doc},
3440 {
"to_2d", (PyCFunction)
Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
3441 {
"resize_2d", (PyCFunction)
Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
3442 {
"to_3d", (PyCFunction)
Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
3443 {
"resize_3d", (PyCFunction)
Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc},
3444 {
"to_4d", (PyCFunction)
Vector_to_4d, METH_NOARGS, Vector_to_4d_doc},
3445 {
"resize_4d", (PyCFunction)
Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
3446 {
"to_tuple", (PyCFunction)
Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
3448 {
"orthogonal", (PyCFunction)
Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
3451 {
"reflect", (PyCFunction)
Vector_reflect, METH_O, Vector_reflect_doc},
3452 {
"cross", (PyCFunction)
Vector_cross, METH_O, Vector_cross_doc},
3453 {
"dot", (PyCFunction)
Vector_dot, METH_O, Vector_dot_doc},
3454 {
"angle", (PyCFunction)
Vector_angle, METH_VARARGS, Vector_angle_doc},
3455 {
"angle_signed", (PyCFunction)
Vector_angle_signed, METH_VARARGS, Vector_angle_signed_doc},
3456 {
"rotation_difference",
3459 Vector_rotation_difference_doc},
3460 {
"project", (PyCFunction)
Vector_project, METH_O, Vector_project_doc},
3461 {
"lerp", (PyCFunction)
Vector_lerp, METH_VARARGS, Vector_lerp_doc},
3462 {
"slerp", (PyCFunction)
Vector_slerp, METH_VARARGS, Vector_slerp_doc},
3463 {
"rotate", (PyCFunction)
Vector_rotate, METH_O, Vector_rotate_doc},
3468 {
"copy", (PyCFunction)
Vector_copy, METH_NOARGS, Vector_copy_doc},
3469 {
"__copy__", (PyCFunction)
Vector_copy, METH_NOARGS,
nullptr},
3470 {
"__deepcopy__", (PyCFunction)
Vector_deepcopy, METH_VARARGS,
nullptr},
3471 {
nullptr,
nullptr, 0,
nullptr},
3476# pragma clang diagnostic pop
3478# pragma GCC diagnostic pop
3492#ifdef MATH_STANDALONE
3493# define Vector_str nullptr
3499 ".. class:: Vector(seq=(0.0, 0.0, 0.0), /)\n"
3501 " This object gives access to Vectors in Blender.\n"
3503 " :arg seq: Components of the vector, must be a sequence of at least two.\n"
3504 " :type seq: Sequence[float]\n");
3506 PyVarObject_HEAD_INIT(
nullptr, 0)
3525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3557#ifdef MATH_STANDALONE
3558# undef Vector_str nullptr
3573 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
3577 vec_alloc =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
3578 if (
UNLIKELY(vec_alloc ==
nullptr)) {
3579 PyErr_SetString(PyExc_MemoryError,
3581 "problem allocating data");
3587 self->vec = vec_alloc;
3588 self->vec_num = vec_num;
3591 self->cb_user =
nullptr;
3592 self->cb_type =
self->cb_subtype = 0;
3595 memcpy(
self->vec, vec, vec_num *
sizeof(
float));
3600 self->vec[3] = 1.0f;
3606 PyMem_Free(vec_alloc);
3609 return (PyObject *)
self;
3617 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
3623 self->vec_num = vec_num;
3626 self->cb_user =
nullptr;
3627 self->cb_type =
self->cb_subtype = 0;
3632 return (PyObject *)
self;
3640 self->cb_user = cb_user;
3641 self->cb_type = cb_type;
3642 self->cb_subtype = cb_subtype;
3644 PyObject_GC_Track(
self);
3647 return (PyObject *)
self;
3658 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
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
double double_round(double x, int ndigits)
MINLINE float safe_acosf(float a)
void mul_m3_v3(const float M[3][3], float r[3])
void normalize_m2_m2(float R[2][2], const float M[2][2]) ATTR_NONNULL()
void mul_m2_v2(const float mat[2][2], float vec[2])
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void vec_to_quat(float q[4], const float vec[3], short axis, short upflag)
void interp_dot_slerp(float t, float cosom, float r_w[2])
void add_vn_vn(float *array_tar, const float *array_src, int size)
double len_squared_vn(const float *array, int size) ATTR_WARN_UNUSED_RESULT
void mul_vn_fl(float *array_tar, int size, float f)
float normalize_vn(float *array_tar, int size)
void negate_vn(float *array_tar, int size)
void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
void range_vn_fl(float *array_tar, int size, float start, float step)
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
MINLINE void negate_v3_v3(float r[3], const float a[3])
void copy_vn_fl(float *array_tar, int size, float val)
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
float normalize_vn_vn(float *array_tar, const float *array_src, int size)
void ortho_v3_v3(float out[3], const float v[3])
double dot_vn_vn(const float *array_src_a, const float *array_src_b, int size) ATTR_WARN_UNUSED_RESULT
float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_v3(float r[3], const float a[3])
void mul_vn_vn(float *array_tar, const float *array_src, int size)
void ortho_v2_v2(float out[2], const float v[2])
void negate_vn_vn(float *array_tar, const float *array_src, int size)
void mul_vn_vn_fl(float *array_tar, const float *array_src, int size, float f)
void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
void interp_vn_vn(float *array_tar, const float *array_src, float t, int size)
MINLINE float normalize_v3(float n[3])
void sub_vn_vn(float *array_tar, const float *array_src, int size)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
VecBase< T, D > reflect(VecOp< T, D >, VecOp< T, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
int mathutils_array_parse_alloc(float **array, int array_num_min, PyObject *value, const char *error_prefix)
int BaseMathObject_is_gc(BaseMathObject *self)
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[]
char BaseMathObject_is_wrapped_doc[]
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *)
char BaseMathObject_is_frozen_doc[]
PyObject * mathutils_dynstr_to_py(DynStr *ds)
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *)
PyObject * BaseMathObject_freeze(BaseMathObject *self)
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *)
char BaseMathObject_owner_doc[]
char BaseMathObject_freeze_doc[]
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *)
int BaseMathObject_clear(BaseMathObject *self)
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
#define BaseMathObject_Prepare_ForResize(_self, error_prefix)
#define BaseMath_ReadCallback_ForWrite(_self)
#define BaseMath_Prepare_ForBufferAccess(_self, _view, _flags)
#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)
@ BASE_MATH_FLAG_HAS_BUFFER_VIEW
#define BaseMath_ReadCallback(_self)
#define BaseMath_WriteIndexCallback(_self, _index)
int Matrix_Parse2x2(PyObject *o, void *p)
#define MatrixObject_Check(v)
#define MATRIX_ITEM(_mat, _row, _col)
PyObject * Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
static PyObject * Vector_repr(VectorObject *self)
static PySequenceMethods Vector_SeqMethods
static PyObject * Vector_add(PyObject *v1, PyObject *v2)
static PyObject * Vector_neg(VectorObject *self)
static PyObject * Vector_normalize(VectorObject *self)
static PyObject * Vector_length_get(VectorObject *self, void *)
static PyObject * Vector_swizzle_get(VectorObject *self, void *closure)
static PyObject * vector_mul_float(VectorObject *vec, const float scalar)
static PyObject * C_Vector_Repeat(PyObject *cls, PyObject *args)
static PyObject * C_Vector_Linspace(PyObject *cls, PyObject *args)
static PyObject * vector_item_internal(VectorObject *self, int i, const bool is_attr)
static PyObject * Vector_length_squared_get(VectorObject *self, void *)
static PyObject * Vector_rotation_difference(VectorObject *self, PyObject *value)
static PyObject * Vector_to_track_quat(VectorObject *self, PyObject *args)
#define VECTOR_SWIZZLE2_RO_DEF(attr, a, b)
static PyObject * Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure)
static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const bool is_attr)
#define VECTOR_SWIZZLE3_RW_DEF(attr, a, b, c)
static PyObject * Vector_resize_2d(VectorObject *self)
static PyObject * C_Vector_Range(PyObject *cls, PyObject *args)
static Py_ssize_t Vector_len(VectorObject *self)
static PyObject * Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static int Vector_getbuffer(PyObject *obj, Py_buffer *view, int flags)
static PyObject * Vector_to_2d(VectorObject *self)
static PyObject * Vector_mul(PyObject *v1, PyObject *v2)
#define SWIZZLE_VALID_AXIS
static PyObject * Vector_iadd(PyObject *v1, PyObject *v2)
static int Vector_ass_item(VectorObject *self, Py_ssize_t i, PyObject *value)
static PyObject * Vector_zero(VectorObject *self)
static PyObject * vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), VectorObject *self)
static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *value)
static PyObject * Vector_str(VectorObject *self)
PyObject * Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
static PyObject * Vector_dot(VectorObject *self, PyObject *value)
static Py_hash_t Vector_hash(VectorObject *self)
static PyObject * Vector_project(VectorObject *self, PyObject *value)
static PyObject * Vector_to_3d(VectorObject *self)
static PyObject * Vector_imatmul(PyObject *v1, PyObject *v2)
static PyObject * Vector_to_4d(VectorObject *self)
static PyObject * Vector_axis_get(VectorObject *self, void *type)
static PyObject * Vector_to_tuple(VectorObject *self, PyObject *args)
PyObject * Vector_CreatePyObject_alloc(float *vec, const int vec_num, PyTypeObject *base_type)
static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
static void Vector_releasebuffer(PyObject *, Py_buffer *view)
static PyObject * Vector_reflect(VectorObject *self, PyObject *value)
static PyObject * Vector_slice(VectorObject *self, int begin, int end)
static PyObject * Vector_resize_3d(VectorObject *self)
static PyObject * Vector_imul(PyObject *v1, PyObject *v2)
static PyObject * Vector_resize(VectorObject *self, PyObject *value)
static PyObject * Vector_angle_signed(VectorObject *self, PyObject *args)
static PyNumberMethods Vector_NumMethods
static PyObject * Vector_isub(PyObject *v1, PyObject *v2)
static PyObject * Vector_normalized(VectorObject *self)
static PyMethodDef Vector_methods[]
static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
static PyObject * Vector_rotate(VectorObject *self, PyObject *value)
static PyObject * Vector_copy(VectorObject *self)
static PyObject * Vector_lerp(VectorObject *self, PyObject *args)
static PyObject * Vector_item(VectorObject *self, Py_ssize_t i)
static PyObject * Vector_angle(VectorObject *self, PyObject *args)
static PyObject * Vector_vectorcall(PyObject *type, PyObject *const *args, const size_t nargsf, PyObject *kwnames)
static int Vector_length_set(VectorObject *self, PyObject *value)
static PyObject * Vector_deepcopy(VectorObject *self, PyObject *args)
static PyObject * C_Vector_Fill(PyObject *cls, PyObject *args)
#define VECTOR_SWIZZLE2_RW_DEF(attr, a, b)
static PyObject * Vector_sub(PyObject *v1, PyObject *v2)
static PyObject * Vector_resize_4d(VectorObject *self)
static PyObject * Vector_cross(VectorObject *self, PyObject *value)
#define SWIZZLE_BITS_PER_AXIS
static PyBufferProcs Vector_as_buffer
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
PyDoc_STRVAR(C_Vector_Fill_doc, ".. classmethod:: Fill(size, fill=0.0, /)\n" "\n" " Create a vector of length size with all values set to fill.\n" "\n" " :arg size: The length of the vector to be created.\n" " :type size: int\n" " :arg fill: The value used to fill the vector.\n" " :type fill: float\n")
static PyObject * Vector_idiv(PyObject *v1, PyObject *v2)
#define VECTOR_SWIZZLE4_RO_DEF(attr, a, b, c, d)
#define VECTOR_SWIZZLE3_RO_DEF(attr, a, b, c)
static PyGetSetDef Vector_getseters[]
static int Vector_axis_set(VectorObject *self, PyObject *value, void *type)
static PyObject * Vector_resized(VectorObject *self, PyObject *value)
static PyObject * Vector_to_tuple_ex(VectorObject *self, int ndigits)
static PyObject * vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
static PyObject * Vector_div(PyObject *v1, PyObject *v2)
static PyObject * Vector_matmul(PyObject *v1, PyObject *v2)
static PyMappingMethods Vector_AsMapping
static PyObject * Vector_subscript(VectorObject *self, PyObject *item)
static PyObject * Vector_orthogonal(VectorObject *self)
PyObject * Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type)
#define VECTOR_SWIZZLE4_RW_DEF(attr, a, b, c, d)
int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
static PyObject * Vector_slerp(VectorObject *self, PyObject *args)
static PyObject * Vector_negate(VectorObject *self)
#define VectorObject_Check(v)
int PyC_CheckArgs_DeepCopy(PyObject *args)