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++) {
91 r_vec[
z++] = float(
dot);
101 Py_DECREF(ret_dummy);
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");
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");
502 if ((vec_num = PyC_Long_AsI32(value)) == -1) {
503 PyErr_SetString(PyExc_TypeError,
504 "Vector.resize(size): "
505 "expected size argument to be an integer");
510 PyErr_SetString(PyExc_RuntimeError,
"Vector.resize(): invalid size");
514 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec, (vec_num *
sizeof(
float))));
515 if (
self->vec ==
nullptr) {
516 PyErr_SetString(PyExc_MemoryError,
518 "problem allocating pointer space");
523 if (vec_num >
self->vec_num) {
527 self->vec_num = vec_num;
534 ".. method:: resized(size=3)\n"
536 " Return a resized copy of the vector with size number of elements.\n"
538 " :return: a new vector\n"
539 " :rtype: :class:`Vector`\n");
545 if ((vec_num = PyLong_AsLong(value)) == -1) {
550 PyErr_SetString(PyExc_RuntimeError,
"Vector.resized(): invalid size");
554 vec =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
556 if (vec ==
nullptr) {
557 PyErr_SetString(PyExc_MemoryError,
559 "problem allocating pointer space");
564 memcpy(vec,
self->vec,
self->vec_num *
sizeof(
float));
571 Vector_resize_2d_doc,
572 ".. method:: resize_2d()\n"
574 " Resize the vector to 2D (x, y).\n");
582 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[2])));
583 if (
self->vec ==
nullptr) {
584 PyErr_SetString(PyExc_MemoryError,
585 "Vector.resize_2d(): "
586 "problem allocating pointer space");
596 Vector_resize_3d_doc,
597 ".. method:: resize_3d()\n"
599 " Resize the vector to 3D (x, y, z).\n");
607 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[3])));
608 if (
self->vec ==
nullptr) {
609 PyErr_SetString(PyExc_MemoryError,
610 "Vector.resize_3d(): "
611 "problem allocating pointer space");
615 if (
self->vec_num == 2) {
625 Vector_resize_4d_doc,
626 ".. method:: resize_4d()\n"
628 " Resize the vector to 4D (x, y, z, w).\n");
636 self->vec =
static_cast<float *
>(PyMem_Realloc(
self->vec,
sizeof(
float[4])));
637 if (
self->vec ==
nullptr) {
638 PyErr_SetString(PyExc_MemoryError,
639 "Vector.resize_4d(): "
640 "problem allocating pointer space");
644 if (
self->vec_num == 2) {
648 else if (
self->vec_num == 3) {
664 ".. method:: to_2d()\n"
666 " Return a 2d copy of the vector.\n"
668 " :return: a new vector\n"
669 " :rtype: :class:`Vector`\n");
681 ".. method:: to_3d()\n"
683 " Return a 3d copy of the vector.\n"
685 " :return: a new vector\n"
686 " :rtype: :class:`Vector`\n");
689 float tvec[3] = {0.0f};
695 memcpy(tvec,
self->vec,
sizeof(
float) * std::min(
self->vec_num, 3));
701 ".. method:: to_4d()\n"
703 " Return a 4d copy of the vector.\n"
705 " :return: a new vector\n"
706 " :rtype: :class:`Vector`\n");
709 float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f};
715 memcpy(tvec,
self->vec,
sizeof(
float) * std::min(
self->vec_num, 4));
728 ".. method:: to_tuple(precision=-1)\n"
730 " Return this vector as a tuple with.\n"
732 " :arg precision: The number to round the value to in [-1, 21].\n"
733 " :type precision: int\n"
734 " :return: the values of the vector rounded by *precision*\n"
735 " :rtype: tuple[float, ...]\n");
740 if (!PyArg_ParseTuple(args,
"|i:to_tuple", &ndigits)) {
744 if (ndigits > 22 || ndigits < -1) {
745 PyErr_SetString(PyExc_ValueError,
746 "Vector.to_tuple(precision): "
747 "precision must be between -1 and 21");
766 Vector_to_track_quat_doc,
767 ".. method:: to_track_quat(track, up)\n"
769 " Return a quaternion rotation from the vector and the track and up axis.\n"
771 " :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n"
772 " :type track: str\n"
773 " :arg up: Up axis in ['X', 'Y', 'Z'].\n"
775 " :return: rotation from the vector and the track and up axis.\n"
776 " :rtype: :class:`Quaternion`\n");
779 float vec[3], quat[4];
780 const char *strack =
nullptr;
781 const char *sup =
nullptr;
782 short track = 2, up = 1;
784 if (!PyArg_ParseTuple(args,
"|ss:to_track_quat", &strack, &sup)) {
788 if (
self->vec_num != 3) {
789 PyErr_SetString(PyExc_TypeError,
790 "Vector.to_track_quat(): "
791 "only for 3D vectors");
800 const char *axis_err_msg =
"only X, -X, Y, -Y, Z or -Z for track axis";
802 if (strlen(strack) == 2) {
803 if (strack[0] ==
'-') {
815 PyErr_SetString(PyExc_ValueError, axis_err_msg);
820 PyErr_SetString(PyExc_ValueError, axis_err_msg);
824 else if (strlen(strack) == 1) {
837 PyErr_SetString(PyExc_ValueError, axis_err_msg);
842 PyErr_SetString(PyExc_ValueError, axis_err_msg);
848 const char *axis_err_msg =
"only X, Y or Z for up axis";
849 if (strlen(sup) == 1) {
861 PyErr_SetString(PyExc_ValueError, axis_err_msg);
866 PyErr_SetString(PyExc_ValueError, axis_err_msg);
872 PyErr_SetString(PyExc_ValueError,
"Can't have the same axis for track and up");
893 Vector_orthogonal_doc,
894 ".. method:: orthogonal()\n"
896 " Return a perpendicular vector.\n"
898 " :return: a new vector 90 degrees from this vector.\n"
899 " :rtype: :class:`Vector`\n"
901 " .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n");
906 if (
self->vec_num > 3) {
907 PyErr_SetString(PyExc_TypeError,
908 "Vector.orthogonal(): "
909 "Vector must be 3D or 2D");
917 if (
self->vec_num == 3) {
939 ".. method:: reflect(mirror)\n"
941 " Return the reflection vector from the *mirror* argument.\n"
943 " :arg mirror: This vector could be a normal from the reflecting surface.\n"
944 " :type mirror: :class:`Vector`\n"
945 " :return: The reflected vector matching the size of this vector.\n"
946 " :rtype: :class:`Vector`\n");
950 float mirror[3], vec[3];
959 tvec, 2, 4, value,
"Vector.reflect(other), invalid 'other' arg")) == -1)
964 if (
self->vec_num < 2 ||
self->vec_num > 4) {
965 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D, 3D or 4D");
971 mirror[2] = (value_num > 2) ? tvec[2] : 0.0f;
973 vec[0] =
self->vec[0];
974 vec[1] =
self->vec[1];
975 vec[2] = (value_num > 2) ?
self->vec[2] : 0.0f;
992 ".. method:: cross(other)\n"
994 " Return the cross product of this vector and another.\n"
996 " :arg other: The other vector to perform the cross product with.\n"
997 " :type other: :class:`Vector`\n"
998 " :return: The cross product as a vector or a float when 2D vectors are used.\n"
999 " :rtype: :class:`Vector` | float\n"
1001 " .. note:: both vectors must be 2D or 3D\n");
1011 if (
self->vec_num > 3) {
1012 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D or 3D");
1017 tvec,
self->vec_num,
self->vec_num, value,
"Vector.cross(other), invalid 'other' arg") ==
1023 if (
self->vec_num == 3) {
1043 ".. method:: dot(other)\n"
1045 " Return the dot product of this vector and another.\n"
1047 " :arg other: The other vector to perform the dot product with.\n"
1048 " :type other: :class:`Vector`\n"
1049 " :return: The dot product.\n"
1050 " :rtype: float\n");
1061 &tvec,
self->vec_num, value,
"Vector.dot(other), invalid 'other' arg") == -1)
1080 ".. function:: angle(other, fallback=None)\n"
1082 " Return the angle between two vectors.\n"
1084 " :arg other: another vector to compare the angle with\n"
1085 " :type other: :class:`Vector`\n"
1086 " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1087 " (instead of raising a :exc:`ValueError`).\n"
1088 " :type fallback: Any\n"
1089 " :return: angle in radians or fallback when given\n"
1090 " :rtype: float | Any\n");
1093 const int vec_num = std::min(
self->vec_num, 3);
1096 double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
1098 PyObject *fallback =
nullptr;
1100 if (!PyArg_ParseTuple(args,
"O|O:angle", &value, &fallback)) {
1111 tvec,
self->vec_num,
self->vec_num, value,
"Vector.angle(other), invalid 'other' arg") ==
1117 if (
self->vec_num > 4) {
1118 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D, 3D or 4D");
1122 for (
x = 0;
x < vec_num;
x++) {
1123 dot_self += double(
self->vec[
x]) * double(
self->vec[
x]);
1124 dot_other += double(tvec[
x]) * double(tvec[
x]);
1125 dot += double(
self->vec[
x]) * double(tvec[
x]);
1128 if (!dot_self || !dot_other) {
1131 Py_INCREF(fallback);
1135 PyErr_SetString(PyExc_ValueError,
1136 "Vector.angle(other): "
1137 "zero length vectors have no valid angle");
1152 Vector_angle_signed_doc,
1153 ".. function:: angle_signed(other, fallback=None)\n"
1155 " Return the signed angle between two 2D vectors (clockwise is positive).\n"
1157 " :arg other: another vector to compare the angle with\n"
1158 " :type other: :class:`Vector`\n"
1159 " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1160 " (instead of raising a :exc:`ValueError`).\n"
1161 " :type fallback: Any\n"
1162 " :return: angle in radians or fallback when given\n"
1163 " :rtype: float | Any\n");
1169 PyObject *fallback =
nullptr;
1171 if (!PyArg_ParseTuple(args,
"O|O:angle_signed", &value, &fallback)) {
1180 tvec, 2, 2, value,
"Vector.angle_signed(other), invalid 'other' arg") == -1)
1185 if (
self->vec_num != 2) {
1186 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D");
1193 Py_INCREF(fallback);
1197 PyErr_SetString(PyExc_ValueError,
1198 "Vector.angle_signed(other): "
1199 "zero length vectors have no valid angle");
1214 Vector_rotation_difference_doc,
1215 ".. function:: rotation_difference(other)\n"
1217 " Returns a quaternion representing the rotational difference between this\n"
1218 " vector and another.\n"
1220 " :arg other: second vector.\n"
1221 " :type other: :class:`Vector`\n"
1222 " :return: the rotational difference between the two vectors.\n"
1223 " :rtype: :class:`Quaternion`\n"
1225 " .. note:: 2D vectors raise an :exc:`AttributeError`.\n");
1228 float quat[4], vec_a[3], vec_b[3];
1230 if (
self->vec_num < 3 ||
self->vec_num > 4) {
1231 PyErr_SetString(PyExc_ValueError,
1232 "vec.difference(value): "
1233 "expects both vectors to be size 3 or 4");
1242 vec_b, 3,
MAX_DIMENSIONS, value,
"Vector.difference(other), invalid 'other' arg") == -1)
1264 ".. function:: project(other)\n"
1266 " Return the projection of this vector onto the *other*.\n"
1268 " :arg other: second vector.\n"
1269 " :type other: :class:`Vector`\n"
1270 " :return: the parallel projection vector\n"
1271 " :rtype: :class:`Vector`\n");
1274 const int vec_num =
self->vec_num;
1276 double dot = 0.0f, dot2 = 0.0f;
1284 &tvec, vec_num, value,
"Vector.project(other), invalid 'other' arg") == -1)
1290 for (
x = 0;
x < vec_num;
x++) {
1292 dot2 += double(tvec[
x] * tvec[
x]);
1296 for (
x = 0;
x < vec_num;
x++) {
1297 tvec[
x] *= float(
dot);
1311 ".. function:: lerp(other, factor)\n"
1313 " Returns the interpolation of two vectors.\n"
1315 " :arg other: value to interpolate with.\n"
1316 " :type other: :class:`Vector`\n"
1317 " :arg factor: The interpolation value in [0.0, 1.0].\n"
1318 " :type factor: float\n"
1319 " :return: The interpolated vector.\n"
1320 " :rtype: :class:`Vector`\n");
1323 const int vec_num =
self->vec_num;
1324 PyObject *value =
nullptr;
1328 if (!PyArg_ParseTuple(args,
"Of:lerp", &value, &fac)) {
1337 &tvec, vec_num, value,
"Vector.lerp(other), invalid 'other' arg") == -1)
1356 ".. function:: slerp(other, factor, fallback=None)\n"
1358 " Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
1360 " :arg other: value to interpolate with.\n"
1361 " :type other: :class:`Vector`\n"
1362 " :arg factor: The interpolation value typically in [0.0, 1.0].\n"
1363 " :type factor: float\n"
1364 " :arg fallback: return this when the vector can't be calculated (zero length "
1365 "vector or direct opposites),\n"
1366 " (instead of raising a :exc:`ValueError`).\n"
1367 " :type fallback: Any\n"
1368 " :return: The interpolated vector.\n"
1369 " :rtype: :class:`Vector`\n");
1372 const int vec_num =
self->vec_num;
1373 PyObject *value =
nullptr;
1374 float fac, cosom,
w[2];
1375 float self_vec[3], other_vec[3], ret_vec[3];
1376 float self_len_sq, other_len_sq;
1378 PyObject *fallback =
nullptr;
1380 if (!PyArg_ParseTuple(args,
"Of|O:slerp", &value, &fac, &fallback)) {
1388 if (
self->vec_num > 3) {
1389 PyErr_SetString(PyExc_ValueError,
"Vector must be 2D or 3D");
1394 other_vec, vec_num, vec_num, value,
"Vector.slerp(other), invalid 'other' arg") == -1)
1403 if (
UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) {
1406 Py_INCREF(fallback);
1410 PyErr_SetString(PyExc_ValueError,
1412 "zero length vectors unsupported");
1417 cosom = float(
dot_vn_vn(self_vec, other_vec, vec_num));
1420 if (
UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
1423 Py_INCREF(fallback);
1427 PyErr_SetString(PyExc_ValueError,
1429 "opposite vectors unsupported");
1435 for (
x = 0;
x < vec_num;
x++) {
1436 ret_vec[
x] = (
w[0] * self_vec[
x]) + (
w[1] * other_vec[
x]);
1451 ".. function:: rotate(other)\n"
1453 " Rotate the vector by a rotation value.\n"
1455 " .. note:: 2D vectors are a special case that can only be rotated by a 2x2 matrix.\n"
1457 " :arg other: rotation component of mathutils value\n"
1458 " :type other: :class:`Euler` | :class:`Quaternion` | :class:`Matrix`\n");
1465 if (
self->vec_num == 2) {
1467 float other_rmat[2][2];
1477 float other_rmat[3][3];
1499 ".. method:: negate()\n"
1501 " Set all values to their negative.\n");
1523 ".. function:: copy()\n"
1525 " Returns a copy of this vector.\n"
1527 " :return: A copy of the vector.\n"
1528 " :rtype: :class:`Vector`\n"
1530 " .. note:: use this to get a copy of a wrapped vector with\n"
1531 " no reference to the original data.\n");
1556 PyObject *
ret, *tuple;
1563 ret = PyUnicode_FromFormat(
"Vector(%R)", tuple);
1568#ifndef MATH_STANDALONE
1583 for (
i = 0;
i <
self->vec_num;
i++) {
1599static PyObject *
Vector_richcmpr(PyObject *objectA, PyObject *objectB,
int comparison_type)
1603 const double epsilon = 0.000001f;
1607 if (comparison_type == Py_NE) {
1620 if (vecA->
vec_num != vecB->vec_num) {
1621 if (comparison_type == Py_NE) {
1628 switch (comparison_type) {
1643 result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1666 result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1670 printf(
"The result of the comparison could not be evaluated");
1708 return self->vec_num;
1719 PyErr_Format(PyExc_AttributeError,
1720 "Vector.%c: unavailable on %dd vector",
1721 *(((
const char *)
"xyzw") +
i),
1725 PyErr_SetString(PyExc_IndexError,
"vector[index]: out of range");
1734 return PyFloat_FromDouble(
self->vec[
i]);
1751 if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
1753 PyErr_SetString(PyExc_TypeError,
1754 "vector[index] = x: "
1755 "assigned value not a number");
1765 PyErr_Format(PyExc_AttributeError,
1766 "Vector.%c = x: unavailable on %dd vector",
1767 *(((
const char *)
"xyzw") +
i),
1771 PyErr_SetString(PyExc_IndexError,
1772 "vector[index] = x: "
1773 "assignment index out of range");
1777 self->vec[
i] = scalar;
1803 end =
self->vec_num + end + 1;
1808 tuple = PyTuple_New(end -
begin);
1820 float *vec =
nullptr;
1830 vec_num = (end -
begin);
1835 if (vec ==
nullptr) {
1836 PyErr_SetString(PyExc_MemoryError,
1838 "problem allocating pointer space");
1843 memcpy(
self->vec +
begin, vec, vec_num *
sizeof(
float));
1857 if (PyIndex_Check(item)) {
1859 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1860 if (
i == -1 && PyErr_Occurred()) {
1868 if (PySlice_Check(item)) {
1869 Py_ssize_t start,
stop,
step, slicelength;
1871 if (PySlice_GetIndicesEx(item,
self->vec_num, &start, &
stop, &
step, &slicelength) < 0) {
1875 if (slicelength <= 0) {
1876 return PyTuple_New(0);
1882 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
1887 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1894 if (PyIndex_Check(item)) {
1895 Py_ssize_t
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) {
1915 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
1920 PyExc_TypeError,
"vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1934 float *vec =
nullptr;
1937 PyErr_Format(PyExc_AttributeError,
1938 "Vector addition: (%s + %s) "
1939 "invalid type for this operation",
1940 Py_TYPE(v1)->tp_name,
1941 Py_TYPE(
v2)->tp_name);
1952 if (vec1->
vec_num != vec2->vec_num) {
1953 PyErr_SetString(PyExc_AttributeError,
1955 "vectors must have the same dimensions for this operation");
1959 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
1960 if (vec ==
nullptr) {
1961 PyErr_SetString(PyExc_MemoryError,
1963 "problem allocating pointer space");
1978 PyErr_Format(PyExc_AttributeError,
1979 "Vector addition: (%s += %s) "
1980 "invalid type for this operation",
1981 Py_TYPE(v1)->tp_name,
1982 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");
2013 PyErr_Format(PyExc_AttributeError,
2014 "Vector subtraction: (%s - %s) "
2015 "invalid type for this operation",
2016 Py_TYPE(v1)->tp_name,
2017 Py_TYPE(
v2)->tp_name);
2027 if (vec1->
vec_num != vec2->vec_num) {
2028 PyErr_SetString(PyExc_AttributeError,
2029 "Vector subtraction: "
2030 "vectors must have the same dimensions for this operation");
2034 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2035 if (vec ==
nullptr) {
2036 PyErr_SetString(PyExc_MemoryError,
2038 "problem allocating pointer space");
2053 PyErr_Format(PyExc_AttributeError,
2054 "Vector subtraction: (%s -= %s) "
2055 "invalid type for this operation",
2056 Py_TYPE(v1)->tp_name,
2057 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");
2086 int row,
col,
z = 0;
2093 PyErr_SetString(PyExc_ValueError,
2095 "len(matrix.col) and len(vector) must be the same, "
2096 "except for 4x4 matrix * 3D vector.");
2101 memcpy(vec_cpy, vec->vec, vec->
vec_num *
sizeof(
float));
2105 for (row = 0; row < mat->
row_num; row++) {
2110 r_vec[
z++] = float(
dot);
2118 float *tvec =
static_cast<float *
>(PyMem_Malloc(vec->
vec_num *
sizeof(
float)));
2119 if (tvec ==
nullptr) {
2120 PyErr_SetString(PyExc_MemoryError,
2122 "problem allocating pointer space");
2132 float *tvec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2133 if (tvec ==
nullptr) {
2134 PyErr_SetString(PyExc_MemoryError,
2136 "problem allocating pointer space");
2167 if (vec1->
vec_num != vec2->vec_num) {
2168 PyErr_SetString(PyExc_ValueError,
2169 "Vector multiplication: "
2170 "vectors must have the same dimensions for this operation");
2178 if (((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) == 0) {
2183 if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) {
2188 PyErr_Format(PyExc_TypeError,
2189 "Element-wise multiplication: "
2190 "not supported between '%.200s' and '%.200s' types",
2191 Py_TYPE(v1)->tp_name,
2192 Py_TYPE(
v2)->tp_name);
2222 if (vec1->
vec_num != vec2->vec_num) {
2223 PyErr_SetString(PyExc_ValueError,
2224 "Vector multiplication: "
2225 "vectors must have the same dimensions for this operation");
2232 else if (vec1 && (((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) == 0)) {
2237 PyErr_Format(PyExc_TypeError,
2238 "In place element-wise multiplication: "
2239 "not supported between '%.200s' and '%.200s' types",
2240 Py_TYPE(v1)->tp_name,
2241 Py_TYPE(
v2)->tp_name);
2273 if (vec1->
vec_num != vec2->vec_num) {
2274 PyErr_SetString(PyExc_ValueError,
2275 "Vector multiplication: "
2276 "vectors must have the same dimensions for this operation");
2306 PyErr_Format(PyExc_TypeError,
2307 "Vector multiplication: "
2308 "not supported between '%.200s' and '%.200s' types",
2309 Py_TYPE(v1)->tp_name,
2310 Py_TYPE(
v2)->tp_name);
2317 PyErr_Format(PyExc_TypeError,
2318 "In place vector multiplication: "
2319 "not supported between '%.200s' and '%.200s' types",
2320 Py_TYPE(v1)->tp_name,
2321 Py_TYPE(
v2)->tp_name);
2328 float *vec =
nullptr, scalar;
2332 PyErr_SetString(PyExc_TypeError,
2334 "Vector must be divided by a float");
2343 if ((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) {
2345 PyErr_SetString(PyExc_TypeError,
2347 "Vector must be divided by a float");
2351 if (scalar == 0.0f) {
2352 PyErr_SetString(PyExc_ZeroDivisionError,
2354 "divide by zero error");
2358 vec =
static_cast<float *
>(PyMem_Malloc(vec1->
vec_num *
sizeof(
float)));
2360 if (vec ==
nullptr) {
2361 PyErr_SetString(PyExc_MemoryError,
2363 "problem allocating pointer space");
2382 if ((scalar = PyFloat_AsDouble(
v2)) == -1.0f && PyErr_Occurred()) {
2384 PyErr_SetString(PyExc_TypeError,
2386 "Vector must be divided by a float");
2390 if (scalar == 0.0f) {
2391 PyErr_SetString(PyExc_ZeroDivisionError,
2393 "divide by zero error");
2414 tvec =
static_cast<float *
>(PyMem_Malloc(
self->vec_num *
sizeof(
float)));
2506 "Vector Z axis (3D Vectors only).\n"
2512 "Vector W axis (4D Vectors only).\n"
2545 double dot = 0.0f, param;
2551 if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
2552 PyErr_SetString(PyExc_TypeError,
"length must be set to a number");
2557 PyErr_SetString(PyExc_ValueError,
"cannot set a vectors length to a negative value");
2590 Vector_length_squared_doc,
2591 "Vector length squared (v.dot(v)).\n"
2607 ":type: :class:`Vector`");
2700 uint swizzleClosure;
2711 if (axis_from >=
self->vec_num) {
2712 PyErr_SetString(PyExc_AttributeError,
2714 "specified axis not present");
2718 vec[axis_to] =
self->vec[axis_from];
2745 uint swizzleClosure;
2761 if (axis_to >=
self->vec_num) {
2762 PyErr_SetString(PyExc_AttributeError,
2764 "specified axis not present");
2771 if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) {
2775 vec_assign[
i] = scalarVal;
2778 size_from = axis_from;
2780 else if (PyErr_Clear(),
2782 vec_assign, 2, 4, value,
"Vector.**** = swizzle assignment"))) ==
size_t(-1))
2787 if (axis_from != size_from) {
2788 PyErr_SetString(PyExc_AttributeError,
"Vector swizzle: size does not match swizzle");
2799 memcpy(tvec,
self->vec,
self->vec_num *
sizeof(
float));
2803 tvec[axis_to] = vec_assign[axis_from];
2810 memcpy(
self->vec, tvec,
self->vec_num *
sizeof(
float));
2820#define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
2821#define _SWIZZLE2(a, b) (_SWIZZLE1(a) | (((b) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS)))
2822#define _SWIZZLE3(a, b, c) \
2823 (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
2824#define _SWIZZLE4(a, b, c, d) \
2825 (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
2827#define SWIZZLE2(a, b) POINTER_FROM_INT(_SWIZZLE2(a, b))
2828#define SWIZZLE3(a, b, c) POINTER_FROM_INT(_SWIZZLE3(a, b, c))
2829#define SWIZZLE4(a, b, c, d) POINTER_FROM_INT(_SWIZZLE4(a, b, c, d))
2831#define VECTOR_SWIZZLE2_RW_DEF(attr, a, b) \
2833 attr, (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, Vector_swizzle_doc, \
2836#define VECTOR_SWIZZLE2_RO_DEF(attr, a, b) \
2838 attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE2(a, b), \
2840#define VECTOR_SWIZZLE3_RW_DEF(attr, a, b, c) \
2842 attr, (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, Vector_swizzle_doc, \
2843 SWIZZLE3(a, b, c), \
2845#define VECTOR_SWIZZLE3_RO_DEF(attr, a, b, c) \
2847 attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE3(a, b, c), \
2849#define VECTOR_SWIZZLE4_RW_DEF(attr, a, b, c, d) \
2851 attr, (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, Vector_swizzle_doc, \
2852 SWIZZLE4(a, b, c, d), \
2854#define VECTOR_SWIZZLE4_RO_DEF(attr, a, b, c, d) \
2856 attr, (getter)Vector_swizzle_get, (setter) nullptr, Vector_swizzle_doc, SWIZZLE4(a, b, c, d) \
2867# pragma clang diagnostic push
2868# pragma clang diagnostic ignored "-Wcast-function-type"
2870# pragma GCC diagnostic push
2871# pragma GCC diagnostic ignored "-Wcast-function-type"
2900 Vector_length_squared_doc,
3266#undef AXIS_FROM_CHAR
3276#undef VECTOR_SWIZZLE2_RW_DEF
3277#undef VECTOR_SWIZZLE2_RO_DEF
3278#undef VECTOR_SWIZZLE3_RW_DEF
3279#undef VECTOR_SWIZZLE3_RO_DEF
3280#undef VECTOR_SWIZZLE4_RW_DEF
3281#undef VECTOR_SWIZZLE4_RO_DEF
3283 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
3288# pragma clang diagnostic pop
3290# pragma GCC diagnostic pop
3302# pragma clang diagnostic push
3303# pragma clang diagnostic ignored "-Wcast-function-type"
3305# pragma GCC diagnostic push
3306# pragma GCC diagnostic ignored "-Wcast-function-type"
3312 {
"Fill", (PyCFunction)
C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
3313 {
"Range", (PyCFunction)
C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
3314 {
"Linspace", (PyCFunction)
C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
3315 {
"Repeat", (PyCFunction)
C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
3318 {
"zero", (PyCFunction)
Vector_zero, METH_NOARGS, Vector_zero_doc},
3319 {
"negate", (PyCFunction)
Vector_negate, METH_NOARGS, Vector_negate_doc},
3322 {
"normalize", (PyCFunction)
Vector_normalize, METH_NOARGS, Vector_normalize_doc},
3323 {
"normalized", (PyCFunction)
Vector_normalized, METH_NOARGS, Vector_normalized_doc},
3325 {
"resize", (PyCFunction)
Vector_resize, METH_O, Vector_resize_doc},
3326 {
"resized", (PyCFunction)
Vector_resized, METH_O, Vector_resized_doc},
3327 {
"to_2d", (PyCFunction)
Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
3328 {
"resize_2d", (PyCFunction)
Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
3329 {
"to_3d", (PyCFunction)
Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
3330 {
"resize_3d", (PyCFunction)
Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc},
3331 {
"to_4d", (PyCFunction)
Vector_to_4d, METH_NOARGS, Vector_to_4d_doc},
3332 {
"resize_4d", (PyCFunction)
Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
3333 {
"to_tuple", (PyCFunction)
Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
3335 {
"orthogonal", (PyCFunction)
Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
3338 {
"reflect", (PyCFunction)
Vector_reflect, METH_O, Vector_reflect_doc},
3339 {
"cross", (PyCFunction)
Vector_cross, METH_O, Vector_cross_doc},
3340 {
"dot", (PyCFunction)
Vector_dot, METH_O, Vector_dot_doc},
3341 {
"angle", (PyCFunction)
Vector_angle, METH_VARARGS, Vector_angle_doc},
3342 {
"angle_signed", (PyCFunction)
Vector_angle_signed, METH_VARARGS, Vector_angle_signed_doc},
3343 {
"rotation_difference",
3346 Vector_rotation_difference_doc},
3347 {
"project", (PyCFunction)
Vector_project, METH_O, Vector_project_doc},
3348 {
"lerp", (PyCFunction)
Vector_lerp, METH_VARARGS, Vector_lerp_doc},
3349 {
"slerp", (PyCFunction)
Vector_slerp, METH_VARARGS, Vector_slerp_doc},
3350 {
"rotate", (PyCFunction)
Vector_rotate, METH_O, Vector_rotate_doc},
3355 {
"copy", (PyCFunction)
Vector_copy, METH_NOARGS, Vector_copy_doc},
3356 {
"__copy__", (PyCFunction)
Vector_copy, METH_NOARGS,
nullptr},
3357 {
"__deepcopy__", (PyCFunction)
Vector_deepcopy, METH_VARARGS,
nullptr},
3358 {
nullptr,
nullptr, 0,
nullptr},
3363# pragma clang diagnostic pop
3365# pragma GCC diagnostic pop
3379#ifdef MATH_STANDALONE
3380# define Vector_str nullptr
3386 ".. class:: Vector(seq)\n"
3388 " This object gives access to Vectors in Blender.\n"
3390 " :arg seq: Components of the vector, must be a sequence of at least two.\n"
3391 " :type seq: Sequence[float]\n");
3393 PyVarObject_HEAD_INIT(
nullptr, 0)
3412 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3444#ifdef MATH_STANDALONE
3445# undef Vector_str nullptr
3460 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
3464 vec_alloc =
static_cast<float *
>(PyMem_Malloc(vec_num *
sizeof(
float)));
3465 if (
UNLIKELY(vec_alloc ==
nullptr)) {
3466 PyErr_SetString(PyExc_MemoryError,
3468 "problem allocating data");
3474 self->vec = vec_alloc;
3475 self->vec_num = vec_num;
3478 self->cb_user =
nullptr;
3479 self->cb_type =
self->cb_subtype = 0;
3482 memcpy(
self->vec, vec, vec_num *
sizeof(
float));
3487 self->vec[3] = 1.0f;
3493 PyMem_Free(vec_alloc);
3496 return (PyObject *)
self;
3504 PyErr_SetString(PyExc_RuntimeError,
"Vector(): invalid size");
3510 self->vec_num = vec_num;
3513 self->cb_user =
nullptr;
3514 self->cb_type =
self->cb_subtype = 0;
3519 return (PyObject *)
self;
3527 self->cb_user = cb_user;
3528 self->cb_type = cb_type;
3529 self->cb_subtype = cb_subtype;
3531 PyObject_GC_Track(
self);
3534 return (PyObject *)
self;
3545 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_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)