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++) {
101 Py_DECREF(ret_dummy);
102 return (PyObject *)
ret;
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]));
141static PyObject *
Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
143 float *vec =
nullptr;
146 if (kwds && PyDict_Size(kwds)) {
147 PyErr_SetString(PyExc_TypeError,
149 "takes no keyword args");
153 switch (PyTuple_GET_SIZE(args)) {
155 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
157 if (vec ==
nullptr) {
158 PyErr_SetString(PyExc_MemoryError,
160 "problem allocating pointer space");
168 &vec, 2, PyTuple_GET_ITEM(args, 0),
"mathutils.Vector()")) == -1)
174 PyErr_SetString(PyExc_TypeError,
175 "mathutils.Vector(): "
176 "more than a single arg given");
191 ".. classmethod:: Fill(size, fill=0.0)\n"
193 " Create a vector of length size with all values set to fill.\n"
195 " :arg size: The length of the vector to be created.\n"
197 " :arg fill: The value used to fill the vector.\n"
198 " :type fill: float\n");
205 if (!PyArg_ParseTuple(args,
"i|f:Vector.Fill", &vec_num, &fill)) {
210 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
214 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
216 if (vec ==
nullptr) {
217 PyErr_SetString(PyExc_MemoryError,
219 "problem allocating pointer space");
231 ".. classmethod:: Range(start, stop, step=1)\n"
233 " Create a filled with a range of values.\n"
235 " :arg start: The start of the range used to fill the vector.\n"
236 " :type start: int\n"
237 " :arg stop: The end of the range used to fill the vector.\n"
239 " :arg step: The step between successive values in the vector.\n"
240 " :type step: int\n");
248 if (!PyArg_ParseTuple(args,
"i|ii:Vector.Range", &start, &stop, &step)) {
252 switch (PyTuple_GET_SIZE(args)) {
259 PyErr_SetString(PyExc_RuntimeError,
260 "Start value is larger "
261 "than the stop value");
265 vec_num = stop - start;
269 PyErr_SetString(PyExc_RuntimeError,
270 "Start value is larger "
271 "than the stop value");
275 vec_num = (stop - start);
277 if ((vec_num % step) != 0) {
287 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
291 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
293 if (vec ==
nullptr) {
294 PyErr_SetString(PyExc_MemoryError,
296 "problem allocating pointer space");
300 range_vn_fl(vec, vec_num,
float(start),
float(step));
307 C_Vector_Linspace_doc,
308 ".. classmethod:: Linspace(start, stop, size)\n"
310 " Create a vector of the specified size which is filled with linearly spaced "
311 "values between start and stop values.\n"
313 " :arg start: The start of the range used to fill the vector.\n"
314 " :type start: int\n"
315 " :arg stop: The end of the range used to fill the vector.\n"
317 " :arg size: The size of the vector to be created.\n"
318 " :type size: int\n");
323 float start, end, step;
325 if (!PyArg_ParseTuple(args,
"ffi:Vector.Linspace", &start, &end, &vec_num)) {
330 PyErr_SetString(PyExc_RuntimeError,
"Vector.Linspace(): invalid size");
334 step = (end - start) /
float(vec_num - 1);
336 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
338 if (vec ==
nullptr) {
339 PyErr_SetString(PyExc_MemoryError,
340 "Vector.Linspace(): "
341 "problem allocating pointer space");
353 ".. classmethod:: Repeat(vector, size)\n"
355 " Create a vector by repeating the values in vector until the required size is reached.\n"
357 " :arg vector: The vector to draw values from.\n"
358 " :type vector: :class:`mathutils.Vector`\n"
359 " :arg size: The size of the vector to be created.\n"
360 " :type size: int\n");
364 float *iter_vec =
nullptr;
365 int i, vec_num, value_num;
368 if (!PyArg_ParseTuple(args,
"Oi:Vector.Repeat", &value, &vec_num)) {
373 PyErr_SetString(PyExc_RuntimeError,
"Vector.Repeat(): invalid vec_num");
378 &iter_vec, 2, value,
"Vector.Repeat(vector, vec_num), invalid 'vector' arg")) == -1)
383 if (iter_vec ==
nullptr) {
384 PyErr_SetString(PyExc_MemoryError,
386 "problem allocating pointer space");
390 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
392 if (vec ==
nullptr) {
393 PyMem_Free(iter_vec);
394 PyErr_SetString(PyExc_MemoryError,
396 "problem allocating pointer space");
401 while (i < vec_num) {
402 vec[i] = iter_vec[i % value_num];
406 PyMem_Free(iter_vec);
420 ".. method:: zero()\n"
422 " Set all values to zero.\n");
446 Vector_normalize_doc,
447 ".. method:: normalize()\n"
449 " Normalize the vector, making the length of the vector always 1.0.\n"
451 " .. warning:: Normalizing a vector where all values are zero has no effect.\n"
453 " .. note:: Normalize works for vectors of all sizes,\n"
454 " however 4D Vectors w axis is left untouched.\n");
457 const int vec_num = (
self->vec_num == 4 ? 3 :
self->vec_num);
469 Vector_normalized_doc,
470 ".. method:: normalized()\n"
472 " Return a new, normalized vector.\n"
474 " :return: a normalized copy of the vector\n"
475 " :rtype: :class:`Vector`\n");
490 ".. method:: resize(size=3)\n"
492 " Resize the vector to have size number of elements.\n");
498 PyErr_SetString(PyExc_TypeError,
500 "cannot resize wrapped data - only Python vectors");
504 PyErr_SetString(PyExc_TypeError,
506 "cannot resize a vector that has an owner");
510 if ((vec_num = PyC_Long_AsI32(value)) == -1) {
511 PyErr_SetString(PyExc_TypeError,
512 "Vector.resize(size): "
513 "expected size argument to be an integer");
518 PyErr_SetString(PyExc_RuntimeError,
"Vector.resize(): invalid size");
522 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec, (vec_num *
sizeof(
float))));
523 if (
self->vec ==
nullptr) {
524 PyErr_SetString(PyExc_MemoryError,
526 "problem allocating pointer space");
531 if (vec_num >
self->vec_num) {
535 self->vec_num = vec_num;
542 ".. method:: resized(size=3)\n"
544 " Return a resized copy of the vector with size number of elements.\n"
546 " :return: a new vector\n"
547 " :rtype: :class:`Vector`\n");
553 if ((vec_num = PyLong_AsLong(value)) == -1) {
558 PyErr_SetString(PyExc_RuntimeError,
"Vector.resized(): invalid size");
562 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
564 if (vec ==
nullptr) {
565 PyErr_SetString(PyExc_MemoryError,
567 "problem allocating pointer space");
572 memcpy(vec,
self->vec,
self->vec_num *
sizeof(
float));
579 Vector_resize_2d_doc,
580 ".. method:: resize_2d()\n"
582 " Resize the vector to 2D (x, y).\n");
586 PyErr_SetString(PyExc_TypeError,
587 "Vector.resize_2d(): "
588 "cannot resize wrapped data - only Python vectors");
592 PyErr_SetString(PyExc_TypeError,
593 "Vector.resize_2d(): "
594 "cannot resize a vector that has an owner");
598 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[2])));
599 if (
self->vec ==
nullptr) {
600 PyErr_SetString(PyExc_MemoryError,
601 "Vector.resize_2d(): "
602 "problem allocating pointer space");
612 Vector_resize_3d_doc,
613 ".. method:: resize_3d()\n"
615 " Resize the vector to 3D (x, y, z).\n");
619 PyErr_SetString(PyExc_TypeError,
620 "Vector.resize_3d(): "
621 "cannot resize wrapped data - only Python vectors");
625 PyErr_SetString(PyExc_TypeError,
626 "Vector.resize_3d(): "
627 "cannot resize a vector that has an owner");
631 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[3])));
632 if (
self->vec ==
nullptr) {
633 PyErr_SetString(PyExc_MemoryError,
634 "Vector.resize_3d(): "
635 "problem allocating pointer space");
639 if (
self->vec_num == 2) {
649 Vector_resize_4d_doc,
650 ".. method:: resize_4d()\n"
652 " Resize the vector to 4D (x, y, z, w).\n");
656 PyErr_SetString(PyExc_TypeError,
657 "Vector.resize_4d(): "
658 "cannot resize wrapped data - only Python vectors");
662 PyErr_SetString(PyExc_TypeError,
663 "Vector.resize_4d(): "
664 "cannot resize a vector that has an owner");
668 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[4])));
669 if (
self->vec ==
nullptr) {
670 PyErr_SetString(PyExc_MemoryError,
671 "Vector.resize_4d(): "
672 "problem allocating pointer space");
676 if (
self->vec_num == 2) {
680 else if (
self->vec_num == 3) {
696 ".. method:: to_2d()\n"
698 " Return a 2d copy of the vector.\n"
700 " :return: a new vector\n"
701 " :rtype: :class:`Vector`\n");
713 ".. method:: to_3d()\n"
715 " Return a 3d copy of the vector.\n"
717 " :return: a new vector\n"
718 " :rtype: :class:`Vector`\n");
721 float tvec[3] = {0.0f};
727 memcpy(tvec,
self->vec,
sizeof(
float) * std::min(
self->vec_num, 3));
733 ".. method:: to_4d()\n"
735 " Return a 4d copy of the vector.\n"
737 " :return: a new vector\n"
738 " :rtype: :class:`Vector`\n");
741 float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f};
747 memcpy(tvec,
self->vec,
sizeof(
float) * std::min(
self->vec_num, 4));
760 ".. method:: to_tuple(precision=-1)\n"
762 " Return this vector as a tuple with.\n"
764 " :arg precision: The number to round the value to in [-1, 21].\n"
765 " :type precision: int\n"
766 " :return: the values of the vector rounded by *precision*\n"
767 " :rtype: tuple[float]\n");
772 if (!PyArg_ParseTuple(args,
"|i:to_tuple", &ndigits)) {
776 if (ndigits > 22 || ndigits < 0) {
777 PyErr_SetString(PyExc_ValueError,
778 "Vector.to_tuple(ndigits): "
779 "ndigits must be between 0 and 21");
783 if (PyTuple_GET_SIZE(args) == 0) {
802 Vector_to_track_quat_doc,
803 ".. method:: to_track_quat(track, up)\n"
805 " Return a quaternion rotation from the vector and the track and up axis.\n"
807 " :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n"
808 " :type track: str\n"
809 " :arg up: Up axis in ['X', 'Y', 'Z'].\n"
811 " :return: rotation from the vector and the track and up axis.\n"
812 " :rtype: :class:`Quaternion`\n");
815 float vec[3], quat[4];
816 const char *strack =
nullptr;
817 const char *sup =
nullptr;
818 short track = 2, up = 1;
820 if (!PyArg_ParseTuple(args,
"|ss:to_track_quat", &strack, &sup)) {
824 if (
self->vec_num != 3) {
825 PyErr_SetString(PyExc_TypeError,
826 "Vector.to_track_quat(): "
827 "only for 3D vectors");
836 const char *axis_err_msg =
"only X, -X, Y, -Y, Z or -Z for track axis";
838 if (strlen(strack) == 2) {
839 if (strack[0] ==
'-') {
851 PyErr_SetString(PyExc_ValueError, axis_err_msg);
856 PyErr_SetString(PyExc_ValueError, axis_err_msg);
860 else if (strlen(strack) == 1) {
873 PyErr_SetString(PyExc_ValueError, axis_err_msg);
878 PyErr_SetString(PyExc_ValueError, axis_err_msg);
884 const char *axis_err_msg =
"only X, Y or Z for up axis";
885 if (strlen(sup) == 1) {
897 PyErr_SetString(PyExc_ValueError, axis_err_msg);
902 PyErr_SetString(PyExc_ValueError, axis_err_msg);
908 PyErr_SetString(PyExc_ValueError,
"Can't have the same axis for track and up");
929 Vector_orthogonal_doc,
930 ".. method:: orthogonal()\n"
932 " Return a perpendicular vector.\n"
934 " :return: a new vector 90 degrees from this vector.\n"
935 " :rtype: :class:`Vector`\n"
937 " .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n");
942 if (
self->vec_num > 3) {
943 PyErr_SetString(PyExc_TypeError,
944 "Vector.orthogonal(): "
945 "Vector must be 3D or 2D");
953 if (
self->vec_num == 3) {
975 ".. method:: reflect(mirror)\n"
977 " Return the reflection vector from the *mirror* argument.\n"
979 " :arg mirror: This vector could be a normal from the reflecting surface.\n"
980 " :type mirror: :class:`Vector`\n"
981 " :return: The reflected vector matching the size of this vector.\n"
982 " :rtype: :class:`Vector`\n");
986 float mirror[3], vec[3];
995 tvec, 2, 4, value,
"Vector.reflect(other), invalid 'other' arg")) == -1)
1000 if (
self->vec_num < 2 ||
self->vec_num > 4) {
1001 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D, 3D or 4D");
1005 mirror[0] = tvec[0];
1006 mirror[1] = tvec[1];
1007 mirror[2] = (value_num > 2) ? tvec[2] : 0.0f;
1009 vec[0] =
self->vec[0];
1010 vec[1] =
self->vec[1];
1011 vec[2] = (value_num > 2) ?
self->vec[2] : 0.0f;
1028 ".. method:: cross(other)\n"
1030 " Return the cross product of this vector and another.\n"
1032 " :arg other: The other vector to perform the cross product with.\n"
1033 " :type other: :class:`Vector`\n"
1034 " :return: The cross product as a vector or a float when 2D vectors are used.\n"
1035 " :rtype: :class:`Vector` | float\n"
1037 " .. note:: both vectors must be 2D or 3D\n");
1047 if (
self->vec_num > 3) {
1048 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D or 3D");
1053 tvec,
self->vec_num,
self->vec_num, value,
"Vector.cross(other), invalid 'other' arg") ==
1059 if (
self->vec_num == 3) {
1079 ".. method:: dot(other)\n"
1081 " Return the dot product of this vector and another.\n"
1083 " :arg other: The other vector to perform the dot product with.\n"
1084 " :type other: :class:`Vector`\n"
1085 " :return: The dot product.\n"
1086 " :rtype: float\n");
1097 &tvec,
self->vec_num, value,
"Vector.dot(other), invalid 'other' arg") == -1)
1116 ".. function:: angle(other, fallback=None)\n"
1118 " Return the angle between two vectors.\n"
1120 " :arg other: another vector to compare the angle with\n"
1121 " :type other: :class:`Vector`\n"
1122 " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1123 " (instead of raising a :exc:`ValueError`).\n"
1124 " :type fallback: Any\n"
1125 " :return: angle in radians or fallback when given\n"
1126 " :rtype: float | Any\n");
1129 const int vec_num = std::min(
self->vec_num, 3);
1132 double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
1134 PyObject *fallback =
nullptr;
1136 if (!PyArg_ParseTuple(args,
"O|O:angle", &value, &fallback)) {
1147 tvec,
self->vec_num,
self->vec_num, value,
"Vector.angle(other), invalid 'other' arg") ==
1153 if (
self->vec_num > 4) {
1154 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D, 3D or 4D");
1158 for (x = 0; x < vec_num; x++) {
1164 if (!dot_self || !dot_other) {
1167 Py_INCREF(fallback);
1171 PyErr_SetString(PyExc_ValueError,
1172 "Vector.angle(other): "
1173 "zero length vectors have no valid angle");
1188 Vector_angle_signed_doc,
1189 ".. function:: angle_signed(other, fallback)\n"
1191 " Return the signed angle between two 2D vectors (clockwise is positive).\n"
1193 " :arg other: another vector to compare the angle with\n"
1194 " :type other: :class:`Vector`\n"
1195 " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1196 " (instead of raising a :exc:`ValueError`).\n"
1197 " :type fallback: Any\n"
1198 " :return: angle in radians or fallback when given\n"
1199 " :rtype: float | Any\n");
1205 PyObject *fallback =
nullptr;
1207 if (!PyArg_ParseTuple(args,
"O|O:angle_signed", &value, &fallback)) {
1216 tvec, 2, 2, value,
"Vector.angle_signed(other), invalid 'other' arg") == -1)
1221 if (
self->vec_num != 2) {
1222 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D");
1229 Py_INCREF(fallback);
1233 PyErr_SetString(PyExc_ValueError,
1234 "Vector.angle_signed(other): "
1235 "zero length vectors have no valid angle");
1250 Vector_rotation_difference_doc,
1251 ".. function:: rotation_difference(other)\n"
1253 " Returns a quaternion representing the rotational difference between this\n"
1254 " vector and another.\n"
1256 " :arg other: second vector.\n"
1257 " :type other: :class:`Vector`\n"
1258 " :return: the rotational difference between the two vectors.\n"
1259 " :rtype: :class:`Quaternion`\n"
1261 " .. note:: 2D vectors raise an :exc:`AttributeError`.\n");
1264 float quat[4], vec_a[3], vec_b[3];
1266 if (
self->vec_num < 3 ||
self->vec_num > 4) {
1267 PyErr_SetString(PyExc_ValueError,
1268 "vec.difference(value): "
1269 "expects both vectors to be size 3 or 4");
1278 vec_b, 3,
MAX_DIMENSIONS, value,
"Vector.difference(other), invalid 'other' arg") == -1)
1300 ".. function:: project(other)\n"
1302 " Return the projection of this vector onto the *other*.\n"
1304 " :arg other: second vector.\n"
1305 " :type other: :class:`Vector`\n"
1306 " :return: the parallel projection vector\n"
1307 " :rtype: :class:`Vector`\n");
1310 const int vec_num =
self->vec_num;
1312 double dot = 0.0f, dot2 = 0.0f;
1320 &tvec, vec_num, value,
"Vector.project(other), invalid 'other' arg") == -1)
1326 for (x = 0; x < vec_num; x++) {
1328 dot2 +=
double(tvec[x] * tvec[x]);
1332 for (x = 0; x < vec_num; x++) {
1347 ".. function:: lerp(other, factor)\n"
1349 " Returns the interpolation of two vectors.\n"
1351 " :arg other: value to interpolate with.\n"
1352 " :type other: :class:`Vector`\n"
1353 " :arg factor: The interpolation value in [0.0, 1.0].\n"
1354 " :type factor: float\n"
1355 " :return: The interpolated vector.\n"
1356 " :rtype: :class:`Vector`\n");
1359 const int vec_num =
self->vec_num;
1360 PyObject *value =
nullptr;
1364 if (!PyArg_ParseTuple(args,
"Of:lerp", &value, &fac)) {
1373 &tvec, vec_num, value,
"Vector.lerp(other), invalid 'other' arg") == -1)
1392 ".. function:: slerp(other, factor, fallback=None)\n"
1394 " Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
1396 " :arg other: value to interpolate with.\n"
1397 " :type other: :class:`Vector`\n"
1398 " :arg factor: The interpolation value typically in [0.0, 1.0].\n"
1399 " :type factor: float\n"
1400 " :arg fallback: return this when the vector can't be calculated (zero length "
1401 "vector or direct opposites),\n"
1402 " (instead of raising a :exc:`ValueError`).\n"
1403 " :type fallback: Any\n"
1404 " :return: The interpolated vector.\n"
1405 " :rtype: :class:`Vector`\n");
1408 const int vec_num =
self->vec_num;
1409 PyObject *value =
nullptr;
1410 float fac, cosom,
w[2];
1411 float self_vec[3], other_vec[3], ret_vec[3];
1412 float self_len_sq, other_len_sq;
1414 PyObject *fallback =
nullptr;
1416 if (!PyArg_ParseTuple(args,
"Of|O:slerp", &value, &fac, &fallback)) {
1424 if (
self->vec_num > 3) {
1425 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D or 3D");
1430 other_vec, vec_num, vec_num, value,
"Vector.slerp(other), invalid 'other' arg") == -1)
1439 if (
UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) {
1442 Py_INCREF(fallback);
1446 PyErr_SetString(PyExc_ValueError,
1448 "zero length vectors unsupported");
1456 if (
UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
1459 Py_INCREF(fallback);
1463 PyErr_SetString(PyExc_ValueError,
1465 "opposite vectors unsupported");
1471 for (x = 0; x < vec_num; x++) {
1472 ret_vec[
x] = (
w[0] * self_vec[
x]) + (
w[1] * other_vec[x]);
1487 ".. function:: rotate(other)\n"
1489 " Rotate the vector by a rotation value.\n"
1491 " .. note:: 2D vectors are a special case that can only be rotated by a 2x2 matrix.\n"
1493 " :arg other: rotation component of mathutils value\n"
1494 " :type other: :class:`Euler` | :class:`Quaternion` | :class:`Matrix`\n");
1501 if (
self->vec_num == 2) {
1503 float other_rmat[2][2];
1513 float other_rmat[3][3];
1535 ".. method:: negate()\n"
1537 " Set all values to their negative.\n");
1559 ".. function:: copy()\n"
1561 " Returns a copy of this vector.\n"
1563 " :return: A copy of the vector.\n"
1564 " :rtype: :class:`Vector`\n"
1566 " .. note:: use this to get a copy of a wrapped vector with\n"
1567 " no reference to the original data.\n");
1592 PyObject *
ret, *tuple;
1599 ret = PyUnicode_FromFormat(
"Vector(%R)", tuple);
1604#ifndef MATH_STANDALONE
1619 for (i = 0; i <
self->vec_num; i++) {
1635static PyObject *
Vector_richcmpr(PyObject *objectA, PyObject *objectB,
int comparison_type)
1639 const double epsilon = 0.000001f;
1643 if (comparison_type == Py_NE) {
1656 if (vecA->
vec_num != vecB->vec_num) {
1657 if (comparison_type == Py_NE) {
1664 switch (comparison_type) {
1679 result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1702 result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1706 printf(
"The result of the comparison could not be evaluated");
1744 return self->vec_num;
1750 i =
self->vec_num - i;
1753 if (i < 0 || i >=
self->vec_num) {
1755 PyErr_Format(PyExc_AttributeError,
1756 "Vector.%c: unavailable on %dd vector",
1757 *(((
const char *)
"xyzw") + i),
1761 PyErr_SetString(PyExc_IndexError,
"vector[index]: out of range");
1770 return PyFloat_FromDouble(
self->vec[i]);
1787 if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
1789 PyErr_SetString(PyExc_TypeError,
1790 "vector[index] = x: "
1791 "assigned value not a number");
1796 i =
self->vec_num - i;
1799 if (i < 0 || i >=
self->vec_num) {
1801 PyErr_Format(PyExc_AttributeError,
1802 "Vector.%c = x: unavailable on %dd vector",
1803 *(((
const char *)
"xyzw") + i),
1807 PyErr_SetString(PyExc_IndexError,
1808 "vector[index] = x: "
1809 "assignment index out of range");
1813 self->vec[i] = scalar;
1839 end =
self->vec_num + end + 1;
1842 begin = std::min(begin, end);
1844 tuple = PyTuple_New(end - begin);
1846 PyTuple_SET_ITEM(tuple,
count - begin, PyFloat_FromDouble(
self->vec[
count]));
1856 float *vec =
nullptr;
1864 begin = std::min(begin, end);
1866 vec_num = (end - begin);
1871 if (vec ==
nullptr) {
1872 PyErr_SetString(PyExc_MemoryError,
1874 "problem allocating pointer space");
1879 memcpy(
self->vec + begin, vec, vec_num *
sizeof(
float));
1893 if (PyIndex_Check(item)) {
1895 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1896 if (i == -1 && PyErr_Occurred()) {
1904 if (PySlice_Check(item)) {
1905 Py_ssize_t start, stop, step, slicelength;
1907 if (PySlice_GetIndicesEx(item,
self->vec_num, &start, &stop, &step, &slicelength) < 0) {
1911 if (slicelength <= 0) {
1912 return PyTuple_New(0);
1918 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
1923 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1930 if (PyIndex_Check(item)) {
1931 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1932 if (i == -1 && PyErr_Occurred()) {
1940 if (PySlice_Check(item)) {
1941 Py_ssize_t start, stop, step, slicelength;
1943 if (PySlice_GetIndicesEx(item,
self->vec_num, &start, &stop, &step, &slicelength) < 0) {
1951 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
1956 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1970 float *vec =
nullptr;
1973 PyErr_Format(PyExc_AttributeError,
1974 "Vector addition: (%s + %s) "
1975 "invalid type for this operation",
1976 Py_TYPE(v1)->tp_name,
1977 Py_TYPE(
v2)->tp_name);
1988 if (vec1->
vec_num != vec2->vec_num) {
1989 PyErr_SetString(PyExc_AttributeError,
1991 "vectors must have the same dimensions for this operation");
1995 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
1996 if (vec ==
nullptr) {
1997 PyErr_SetString(PyExc_MemoryError,
1999 "problem allocating pointer space");
2014 PyErr_Format(PyExc_AttributeError,
2015 "Vector addition: (%s += %s) "
2016 "invalid type for this operation",
2017 Py_TYPE(v1)->tp_name,
2018 Py_TYPE(
v2)->tp_name);
2024 if (vec1->
vec_num != vec2->vec_num) {
2025 PyErr_SetString(PyExc_AttributeError,
2027 "vectors must have the same dimensions for this operation");
2049 PyErr_Format(PyExc_AttributeError,
2050 "Vector subtraction: (%s - %s) "
2051 "invalid type for this operation",
2052 Py_TYPE(v1)->tp_name,
2053 Py_TYPE(
v2)->tp_name);
2063 if (vec1->
vec_num != vec2->vec_num) {
2064 PyErr_SetString(PyExc_AttributeError,
2065 "Vector subtraction: "
2066 "vectors must have the same dimensions for this operation");
2070 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2071 if (vec ==
nullptr) {
2072 PyErr_SetString(PyExc_MemoryError,
2074 "problem allocating pointer space");
2089 PyErr_Format(PyExc_AttributeError,
2090 "Vector subtraction: (%s -= %s) "
2091 "invalid type for this operation",
2092 Py_TYPE(v1)->tp_name,
2093 Py_TYPE(
v2)->tp_name);
2099 if (vec1->
vec_num != vec2->vec_num) {
2100 PyErr_SetString(PyExc_AttributeError,
2101 "Vector subtraction: "
2102 "vectors must have the same dimensions for this operation");
2122 int row,
col,
z = 0;
2129 PyErr_SetString(PyExc_ValueError,
2131 "len(matrix.col) and len(vector) must be the same, "
2132 "except for 4x4 matrix * 3D vector.");
2137 memcpy(vec_cpy, vec->vec, vec->
vec_num *
sizeof(
float));
2141 for (row = 0; row < mat->
row_num; row++) {
2154 float *tvec =
static_cast<float *
>(PyMem_Malloc(vec->
vec_num *
sizeof(
float)));
2155 if (tvec ==
nullptr) {
2156 PyErr_SetString(PyExc_MemoryError,
2158 "problem allocating pointer space");
2168 float *tvec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2169 if (tvec ==
nullptr) {
2170 PyErr_SetString(PyExc_MemoryError,
2172 "problem allocating pointer space");
2203 if (vec1->
vec_num != vec2->vec_num) {
2204 PyErr_SetString(PyExc_ValueError,
2205 "Vector multiplication: "
2206 "vectors must have the same dimensions for this operation");
2214 if (((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) == 0) {
2219 if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) {
2224 PyErr_Format(PyExc_TypeError,
2225 "Element-wise multiplication: "
2226 "not supported between '%.200s' and '%.200s' types",
2227 Py_TYPE(v1)->tp_name,
2228 Py_TYPE(
v2)->tp_name);
2258 if (vec1->
vec_num != vec2->vec_num) {
2259 PyErr_SetString(PyExc_ValueError,
2260 "Vector multiplication: "
2261 "vectors must have the same dimensions for this operation");
2268 else if (vec1 && (((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) == 0)) {
2273 PyErr_Format(PyExc_TypeError,
2274 "In place element-wise multiplication: "
2275 "not supported between '%.200s' and '%.200s' types",
2276 Py_TYPE(v1)->tp_name,
2277 Py_TYPE(
v2)->tp_name);
2309 if (vec1->
vec_num != vec2->vec_num) {
2310 PyErr_SetString(PyExc_ValueError,
2311 "Vector multiplication: "
2312 "vectors must have the same dimensions for this operation");
2342 PyErr_Format(PyExc_TypeError,
2343 "Vector multiplication: "
2344 "not supported between '%.200s' and '%.200s' types",
2345 Py_TYPE(v1)->tp_name,
2346 Py_TYPE(
v2)->tp_name);
2353 PyErr_Format(PyExc_TypeError,
2354 "In place vector multiplication: "
2355 "not supported between '%.200s' and '%.200s' types",
2356 Py_TYPE(v1)->tp_name,
2357 Py_TYPE(
v2)->tp_name);
2364 float *vec =
nullptr, scalar;
2368 PyErr_SetString(PyExc_TypeError,
2370 "Vector must be divided by a float");
2379 if ((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) {
2381 PyErr_SetString(PyExc_TypeError,
2383 "Vector must be divided by a float");
2387 if (scalar == 0.0f) {
2388 PyErr_SetString(PyExc_ZeroDivisionError,
2390 "divide by zero error");
2394 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2396 if (vec ==
nullptr) {
2397 PyErr_SetString(PyExc_MemoryError,
2399 "problem allocating pointer space");
2418 if ((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) {
2420 PyErr_SetString(PyExc_TypeError,
2422 "Vector must be divided by a float");
2426 if (scalar == 0.0f) {
2427 PyErr_SetString(PyExc_ZeroDivisionError,
2429 "divide by zero error");
2450 tvec =
static_cast<float *
>(PyMem_Malloc(
self->vec_num *
sizeof(
float)));
2542 "Vector Z axis (3D Vectors only).\n"
2548 "Vector W axis (4D Vectors only).\n"
2581 double dot = 0.0f, param;
2587 if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
2588 PyErr_SetString(PyExc_TypeError,
"length must be set to a number");
2593 PyErr_SetString(PyExc_ValueError,
"cannot set a vectors length to a negative value");
2626 Vector_length_squared_doc,
2627 "Vector length squared (v.dot(v)).\n"
2643 ":type: :class:`Vector`");
2736 uint swizzleClosure;
2747 if (axis_from >=
self->vec_num) {
2748 PyErr_SetString(PyExc_AttributeError,
2750 "specified axis not present");
2754 vec[axis_to] =
self->vec[axis_from];
2781 uint swizzleClosure;
2797 if (axis_to >=
self->vec_num) {
2798 PyErr_SetString(PyExc_AttributeError,
2800 "specified axis not present");
2807 if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) {
2811 vec_assign[i] = scalarVal;
2814 size_from = axis_from;
2816 else if ((
void)PyErr_Clear(),
2818 vec_assign, 2, 4, value,
"Vector.**** = swizzle assignment"))) ==
size_t(-1))
2823 if (axis_from != size_from) {
2824 PyErr_SetString(PyExc_AttributeError,
"Vector swizzle: size does not match swizzle");
2835 memcpy(tvec,
self->vec,
self->vec_num *
sizeof(
float));
2839 tvec[axis_to] = vec_assign[axis_from];
2846 memcpy(
self->vec, tvec,
self->vec_num *
sizeof(
float));
2856#define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
2857#define _SWIZZLE2(a, b) (_SWIZZLE1(a) | (((b) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS)))
2858#define _SWIZZLE3(a, b, c) \
2859 (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
2860#define _SWIZZLE4(a, b, c, d) \
2861 (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
2863#define SWIZZLE2(a, b) POINTER_FROM_INT(_SWIZZLE2(a, b))
2864#define SWIZZLE3(a, b, c) POINTER_FROM_INT(_SWIZZLE3(a, b, c))
2865#define SWIZZLE4(a, b, c, d) POINTER_FROM_INT(_SWIZZLE4(a, b, c, d))
2867#define VECTOR_SWIZZLE2_RW_DEF(attr, a, b) \
2869 attr, (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, Vector_swizzle_doc, \
2872#define VECTOR_SWIZZLE2_RO_DEF(attr, a, b) \
2874 attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE2(a, b), \
2876#define VECTOR_SWIZZLE3_RW_DEF(attr, a, b, c) \
2878 attr, (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, Vector_swizzle_doc, \
2879 SWIZZLE3(a, b, c), \
2881#define VECTOR_SWIZZLE3_RO_DEF(attr, a, b, c) \
2883 attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE3(a, b, c), \
2885#define VECTOR_SWIZZLE4_RW_DEF(attr, a, b, c, d) \
2887 attr, (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, Vector_swizzle_doc, \
2888 SWIZZLE4(a, b, c, d), \
2890#define VECTOR_SWIZZLE4_RO_DEF(attr, a, b, c, d) \
2892 attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE4(a, b, c, d) \
2901#if (defined(__GNUC__) && !defined(__clang__))
2902# pragma GCC diagnostic push
2903# pragma GCC diagnostic ignored "-Wcast-function-type"
2931 Vector_length_squared_doc,
3297#undef AXIS_FROM_CHAR
3307#undef VECTOR_SWIZZLE2_RW_DEF
3308#undef VECTOR_SWIZZLE2_RO_DEF
3309#undef VECTOR_SWIZZLE3_RW_DEF
3310#undef VECTOR_SWIZZLE3_RO_DEF
3311#undef VECTOR_SWIZZLE4_RW_DEF
3312#undef VECTOR_SWIZZLE4_RO_DEF
3314 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
3317#if (defined(__GNUC__) && !defined(__clang__))
3318# pragma GCC diagnostic pop
3327#if (defined(__GNUC__) && !defined(__clang__))
3328# pragma GCC diagnostic push
3329# pragma GCC diagnostic ignored "-Wcast-function-type"
3334 {
"Fill", (PyCFunction)
C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
3335 {
"Range", (PyCFunction)
C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
3336 {
"Linspace", (PyCFunction)
C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
3337 {
"Repeat", (PyCFunction)
C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
3340 {
"zero", (PyCFunction)
Vector_zero, METH_NOARGS, Vector_zero_doc},
3341 {
"negate", (PyCFunction)
Vector_negate, METH_NOARGS, Vector_negate_doc},
3344 {
"normalize", (PyCFunction)
Vector_normalize, METH_NOARGS, Vector_normalize_doc},
3345 {
"normalized", (PyCFunction)
Vector_normalized, METH_NOARGS, Vector_normalized_doc},
3347 {
"resize", (PyCFunction)
Vector_resize, METH_O, Vector_resize_doc},
3348 {
"resized", (PyCFunction)
Vector_resized, METH_O, Vector_resized_doc},
3349 {
"to_2d", (PyCFunction)
Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
3350 {
"resize_2d", (PyCFunction)
Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
3351 {
"to_3d", (PyCFunction)
Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
3352 {
"resize_3d", (PyCFunction)
Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc},
3353 {
"to_4d", (PyCFunction)
Vector_to_4d, METH_NOARGS, Vector_to_4d_doc},
3354 {
"resize_4d", (PyCFunction)
Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
3355 {
"to_tuple", (PyCFunction)
Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
3357 {
"orthogonal", (PyCFunction)
Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
3360 {
"reflect", (PyCFunction)
Vector_reflect, METH_O, Vector_reflect_doc},
3361 {
"cross", (PyCFunction)
Vector_cross, METH_O, Vector_cross_doc},
3362 {
"dot", (PyCFunction)
Vector_dot, METH_O, Vector_dot_doc},
3363 {
"angle", (PyCFunction)
Vector_angle, METH_VARARGS, Vector_angle_doc},
3364 {
"angle_signed", (PyCFunction)
Vector_angle_signed, METH_VARARGS, Vector_angle_signed_doc},
3365 {
"rotation_difference",
3368 Vector_rotation_difference_doc},
3369 {
"project", (PyCFunction)
Vector_project, METH_O, Vector_project_doc},
3370 {
"lerp", (PyCFunction)
Vector_lerp, METH_VARARGS, Vector_lerp_doc},
3371 {
"slerp", (PyCFunction)
Vector_slerp, METH_VARARGS, Vector_slerp_doc},
3372 {
"rotate", (PyCFunction)
Vector_rotate, METH_O, Vector_rotate_doc},
3377 {
"copy", (PyCFunction)
Vector_copy, METH_NOARGS, Vector_copy_doc},
3378 {
"__copy__", (PyCFunction)
Vector_copy, METH_NOARGS,
nullptr},
3379 {
"__deepcopy__", (PyCFunction)
Vector_deepcopy, METH_VARARGS,
nullptr},
3380 {
nullptr,
nullptr, 0,
nullptr},
3383#if (defined(__GNUC__) && !defined(__clang__))
3384# pragma GCC diagnostic pop
3397#ifdef MATH_STANDALONE
3398# define Vector_str nullptr
3404 ".. class:: Vector(seq)\n"
3406 " This object gives access to Vectors in Blender.\n"
3408 " :arg seq: Components of the vector, must be a sequence of at least two.\n"
3409 " :type seq: Sequence[float]\n");
3411 PyVarObject_HEAD_INIT(
nullptr, 0)
3430 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3462#ifdef MATH_STANDALONE
3463# undef Vector_str nullptr
3478 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
3482 vec_alloc =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
3483 if (
UNLIKELY(vec_alloc ==
nullptr)) {
3484 PyErr_SetString(PyExc_MemoryError,
3486 "problem allocating data");
3492 self->vec = vec_alloc;
3493 self->vec_num = vec_num;
3496 self->cb_user =
nullptr;
3497 self->cb_type =
self->cb_subtype = 0;
3500 memcpy(
self->vec, vec, vec_num *
sizeof(
float));
3505 self->vec[3] = 1.0f;
3511 PyMem_Free(vec_alloc);
3514 return (PyObject *)
self;
3522 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
3528 self->vec_num = vec_num;
3531 self->cb_user =
nullptr;
3532 self->cb_type =
self->cb_subtype = 0;
3537 return (PyObject *)
self;
3545 self->cb_user = cb_user;
3546 self->cb_type = cb_type;
3547 self->cb_subtype = cb_subtype;
3549 PyObject_GC_Track(
self);
3552 return (PyObject *)
self;
3560 self->flag &= ~BASE_MATH_FLAG_IS_WRAP;
3563 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)
typedef double(DMatrix)[4][4]
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.
draw_view in_light_buf[] float
ccl_device_inline float3 reflect(const float3 incident, const float3 unit_normal)
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 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)
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)
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_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 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 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 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
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
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)