Blender  V3.3
mathutils_Vector.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <Python.h>
8 
9 #include "mathutils.h"
10 
11 #include "BLI_math.h"
12 #include "BLI_utildefines.h"
13 
14 #include "../generic/py_capi_utils.h"
15 
16 #ifndef MATH_STANDALONE
17 # include "BLI_dynstr.h"
18 #endif
19 
25 #define MAX_DIMENSIONS 4
26 
32 #define SWIZZLE_BITS_PER_AXIS 3
33 #define SWIZZLE_VALID_AXIS 0x4
34 #define SWIZZLE_AXIS 0x3
35 
36 static PyObject *Vector_copy(VectorObject *self);
37 static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args);
38 
39 /* -------------------------------------------------------------------- */
52 static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS],
53  VectorObject *vec,
54  MatrixObject *mat)
55 {
56  float vec_cpy[MAX_DIMENSIONS];
57  int row, col, z = 0, vec_num = vec->vec_num;
58 
59  if (mat->row_num != vec_num) {
60  if (mat->row_num == 4 && vec_num == 3) {
61  vec_cpy[3] = 1.0f;
62  }
63  else {
64  PyErr_SetString(PyExc_ValueError,
65  "vector * matrix: matrix column size "
66  "and the vector size must be the same");
67  return -1;
68  }
69  }
70 
71  if (BaseMath_ReadCallback(vec) == -1 || BaseMath_ReadCallback(mat) == -1) {
72  return -1;
73  }
74 
75  memcpy(vec_cpy, vec->vec, vec_num * sizeof(float));
76 
77  r_vec[3] = 1.0f;
78  /* Multiplication. */
79  for (col = 0; col < mat->col_num; col++) {
80  double dot = 0.0;
81  for (row = 0; row < mat->row_num; row++) {
82  dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[row]);
83  }
84  r_vec[z++] = (float)dot;
85  }
86  return 0;
87 }
88 
89 static PyObject *vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), VectorObject *self)
90 {
91  PyObject *ret = Vector_copy(self);
92  PyObject *ret_dummy = vec_func((VectorObject *)ret);
93  if (ret_dummy) {
94  Py_DECREF(ret_dummy);
95  return (PyObject *)ret;
96  }
97  /* error */
98  Py_DECREF(ret);
99  return NULL;
100 }
101 
103 static PyObject *Vector_to_tuple_ex(VectorObject *self, int ndigits)
104 {
105  PyObject *ret;
106  int i;
107 
108  ret = PyTuple_New(self->vec_num);
109 
110  if (ndigits >= 0) {
111  for (i = 0; i < self->vec_num; i++) {
112  PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->vec[i], ndigits)));
113  }
114  }
115  else {
116  for (i = 0; i < self->vec_num; i++) {
117  PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->vec[i]));
118  }
119  }
120 
121  return ret;
122 }
123 
126 /* -------------------------------------------------------------------- */
134 static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
135 {
136  float *vec = NULL;
137  int vec_num = 3; /* default to a 3D vector */
138 
139  if (kwds && PyDict_Size(kwds)) {
140  PyErr_SetString(PyExc_TypeError,
141  "Vector(): "
142  "takes no keyword args");
143  return NULL;
144  }
145 
146  switch (PyTuple_GET_SIZE(args)) {
147  case 0:
148  vec = PyMem_Malloc(vec_num * sizeof(float));
149 
150  if (vec == NULL) {
151  PyErr_SetString(PyExc_MemoryError,
152  "Vector(): "
153  "problem allocating pointer space");
154  return NULL;
155  }
156 
157  copy_vn_fl(vec, vec_num, 0.0f);
158  break;
159  case 1:
160  if ((vec_num = mathutils_array_parse_alloc(
161  &vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
162  return NULL;
163  }
164  break;
165  default:
166  PyErr_SetString(PyExc_TypeError,
167  "mathutils.Vector(): "
168  "more than a single arg given");
169  return NULL;
170  }
171  return Vector_CreatePyObject_alloc(vec, vec_num, type);
172 }
173 
176 /* -------------------------------------------------------------------- */
180 PyDoc_STRVAR(C_Vector_Fill_doc,
181  ".. classmethod:: Fill(size, fill=0.0)\n"
182  "\n"
183  " Create a vector of length size with all values set to fill.\n"
184  "\n"
185  " :arg size: The length of the vector to be created.\n"
186  " :type size: int\n"
187  " :arg fill: The value used to fill the vector.\n"
188  " :type fill: float\n");
189 static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args)
190 {
191  float *vec;
192  int vec_num;
193  float fill = 0.0f;
194 
195  if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &vec_num, &fill)) {
196  return NULL;
197  }
198 
199  if (vec_num < 2) {
200  PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
201  return NULL;
202  }
203 
204  vec = PyMem_Malloc(vec_num * sizeof(float));
205 
206  if (vec == NULL) {
207  PyErr_SetString(PyExc_MemoryError,
208  "Vector.Fill(): "
209  "problem allocating pointer space");
210  return NULL;
211  }
212 
213  copy_vn_fl(vec, vec_num, fill);
214 
215  return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
216 }
217 
218 PyDoc_STRVAR(C_Vector_Range_doc,
219  ".. classmethod:: Range(start, stop, step=1)\n"
220  "\n"
221  " Create a filled with a range of values.\n"
222  "\n"
223  " :arg start: The start of the range used to fill the vector.\n"
224  " :type start: int\n"
225  " :arg stop: The end of the range used to fill the vector.\n"
226  " :type stop: int\n"
227  " :arg step: The step between successive values in the vector.\n"
228  " :type step: int\n");
229 static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
230 {
231  float *vec;
232  int stop, vec_num;
233  int start = 0;
234  int step = 1;
235 
236  if (!PyArg_ParseTuple(args, "i|ii:Vector.Range", &start, &stop, &step)) {
237  return NULL;
238  }
239 
240  switch (PyTuple_GET_SIZE(args)) {
241  case 1:
242  vec_num = start;
243  start = 0;
244  break;
245  case 2:
246  if (start >= stop) {
247  PyErr_SetString(PyExc_RuntimeError,
248  "Start value is larger "
249  "than the stop value");
250  return NULL;
251  }
252 
253  vec_num = stop - start;
254  break;
255  default:
256  if (start >= stop) {
257  PyErr_SetString(PyExc_RuntimeError,
258  "Start value is larger "
259  "than the stop value");
260  return NULL;
261  }
262 
263  vec_num = (stop - start);
264 
265  if ((vec_num % step) != 0) {
266  vec_num += step;
267  }
268 
269  vec_num /= step;
270 
271  break;
272  }
273 
274  if (vec_num < 2) {
275  PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
276  return NULL;
277  }
278 
279  vec = PyMem_Malloc(vec_num * sizeof(float));
280 
281  if (vec == NULL) {
282  PyErr_SetString(PyExc_MemoryError,
283  "Vector.Range(): "
284  "problem allocating pointer space");
285  return NULL;
286  }
287 
288  range_vn_fl(vec, vec_num, (float)start, (float)step);
289 
290  return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
291 }
292 
293 PyDoc_STRVAR(C_Vector_Linspace_doc,
294  ".. classmethod:: Linspace(start, stop, size)\n"
295  "\n"
296  " Create a vector of the specified size which is filled with linearly spaced "
297  "values between start and stop values.\n"
298  "\n"
299  " :arg start: The start of the range used to fill the vector.\n"
300  " :type start: int\n"
301  " :arg stop: The end of the range used to fill the vector.\n"
302  " :type stop: int\n"
303  " :arg size: The size of the vector to be created.\n"
304  " :type size: int\n");
305 static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args)
306 {
307  float *vec;
308  int vec_num;
309  float start, end, step;
310 
311  if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &vec_num)) {
312  return NULL;
313  }
314 
315  if (vec_num < 2) {
316  PyErr_SetString(PyExc_RuntimeError, "Vector.Linspace(): invalid size");
317  return NULL;
318  }
319 
320  step = (end - start) / (float)(vec_num - 1);
321 
322  vec = PyMem_Malloc(vec_num * sizeof(float));
323 
324  if (vec == NULL) {
325  PyErr_SetString(PyExc_MemoryError,
326  "Vector.Linspace(): "
327  "problem allocating pointer space");
328  return NULL;
329  }
330 
331  range_vn_fl(vec, vec_num, start, step);
332 
333  return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
334 }
335 
337  C_Vector_Repeat_doc,
338  ".. classmethod:: Repeat(vector, size)\n"
339  "\n"
340  " Create a vector by repeating the values in vector until the required size is reached.\n"
341  "\n"
342  " :arg tuple: The vector to draw values from.\n"
343  " :type tuple: :class:`mathutils.Vector`\n"
344  " :arg size: The size of the vector to be created.\n"
345  " :type size: int\n");
346 static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args)
347 {
348  float *vec;
349  float *iter_vec = NULL;
350  int i, vec_num, value_num;
351  PyObject *value;
352 
353  if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &vec_num)) {
354  return NULL;
355  }
356 
357  if (vec_num < 2) {
358  PyErr_SetString(PyExc_RuntimeError, "Vector.Repeat(): invalid vec_num");
359  return NULL;
360  }
361 
362  if ((value_num = mathutils_array_parse_alloc(
363  &iter_vec, 2, value, "Vector.Repeat(vector, vec_num), invalid 'vector' arg")) == -1) {
364  return NULL;
365  }
366 
367  if (iter_vec == NULL) {
368  PyErr_SetString(PyExc_MemoryError,
369  "Vector.Repeat(): "
370  "problem allocating pointer space");
371  return NULL;
372  }
373 
374  vec = PyMem_Malloc(vec_num * sizeof(float));
375 
376  if (vec == NULL) {
377  PyMem_Free(iter_vec);
378  PyErr_SetString(PyExc_MemoryError,
379  "Vector.Repeat(): "
380  "problem allocating pointer space");
381  return NULL;
382  }
383 
384  i = 0;
385  while (i < vec_num) {
386  vec[i] = iter_vec[i % value_num];
387  i++;
388  }
389 
390  PyMem_Free(iter_vec);
391 
392  return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
393 }
394 
397 /* -------------------------------------------------------------------- */
401 PyDoc_STRVAR(Vector_zero_doc,
402  ".. method:: zero()\n"
403  "\n"
404  " Set all values to zero.\n");
405 static PyObject *Vector_zero(VectorObject *self)
406 {
407  if (BaseMath_Prepare_ForWrite(self) == -1) {
408  return NULL;
409  }
410 
411  copy_vn_fl(self->vec, self->vec_num, 0.0f);
412 
413  if (BaseMath_WriteCallback(self) == -1) {
414  return NULL;
415  }
416 
417  Py_RETURN_NONE;
418 }
419 
422 /* -------------------------------------------------------------------- */
426 PyDoc_STRVAR(Vector_normalize_doc,
427  ".. method:: normalize()\n"
428  "\n"
429  " Normalize the vector, making the length of the vector always 1.0.\n"
430  "\n"
431  " .. warning:: Normalizing a vector where all values are zero has no effect.\n"
432  "\n"
433  " .. note:: Normalize works for vectors of all sizes,\n"
434  " however 4D Vectors w axis is left untouched.\n");
435 static PyObject *Vector_normalize(VectorObject *self)
436 {
437  const int vec_num = (self->vec_num == 4 ? 3 : self->vec_num);
438  if (BaseMath_ReadCallback_ForWrite(self) == -1) {
439  return NULL;
440  }
441 
442  normalize_vn(self->vec, vec_num);
443 
445  Py_RETURN_NONE;
446 }
447 PyDoc_STRVAR(Vector_normalized_doc,
448  ".. method:: normalized()\n"
449  "\n"
450  " Return a new, normalized vector.\n"
451  "\n"
452  " :return: a normalized copy of the vector\n"
453  " :rtype: :class:`Vector`\n");
454 static PyObject *Vector_normalized(VectorObject *self)
455 {
456  return vec__apply_to_copy(Vector_normalize, self);
457 }
458 
461 /* -------------------------------------------------------------------- */
465 PyDoc_STRVAR(Vector_resize_doc,
466  ".. method:: resize(size=3)\n"
467  "\n"
468  " Resize the vector to have size number of elements.\n");
469 static PyObject *Vector_resize(VectorObject *self, PyObject *value)
470 {
471  int vec_num;
472 
473  if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
474  PyErr_SetString(PyExc_TypeError,
475  "Vector.resize(): "
476  "cannot resize wrapped data - only python vectors");
477  return NULL;
478  }
479  if (self->cb_user) {
480  PyErr_SetString(PyExc_TypeError,
481  "Vector.resize(): "
482  "cannot resize a vector that has an owner");
483  return NULL;
484  }
485 
486  if ((vec_num = PyC_Long_AsI32(value)) == -1) {
487  PyErr_SetString(PyExc_TypeError,
488  "Vector.resize(size): "
489  "expected size argument to be an integer");
490  return NULL;
491  }
492 
493  if (vec_num < 2) {
494  PyErr_SetString(PyExc_RuntimeError, "Vector.resize(): invalid size");
495  return NULL;
496  }
497 
498  self->vec = PyMem_Realloc(self->vec, (vec_num * sizeof(float)));
499  if (self->vec == NULL) {
500  PyErr_SetString(PyExc_MemoryError,
501  "Vector.resize(): "
502  "problem allocating pointer space");
503  return NULL;
504  }
505 
506  /* If the vector has increased in length, set all new elements to 0.0f */
507  if (vec_num > self->vec_num) {
508  copy_vn_fl(self->vec + self->vec_num, vec_num - self->vec_num, 0.0f);
509  }
510 
511  self->vec_num = vec_num;
512  Py_RETURN_NONE;
513 }
514 
515 PyDoc_STRVAR(Vector_resized_doc,
516  ".. method:: resized(size=3)\n"
517  "\n"
518  " Return a resized copy of the vector with size number of elements.\n"
519  "\n"
520  " :return: a new vector\n"
521  " :rtype: :class:`Vector`\n");
522 static PyObject *Vector_resized(VectorObject *self, PyObject *value)
523 {
524  int vec_num;
525  float *vec;
526 
527  if ((vec_num = PyLong_AsLong(value)) == -1) {
528  return NULL;
529  }
530 
531  if (vec_num < 2) {
532  PyErr_SetString(PyExc_RuntimeError, "Vector.resized(): invalid size");
533  return NULL;
534  }
535 
536  vec = PyMem_Malloc(vec_num * sizeof(float));
537 
538  if (vec == NULL) {
539  PyErr_SetString(PyExc_MemoryError,
540  "Vector.resized(): "
541  "problem allocating pointer space");
542  return NULL;
543  }
544 
545  copy_vn_fl(vec, vec_num, 0.0f);
546  memcpy(vec, self->vec, self->vec_num * sizeof(float));
547 
548  return Vector_CreatePyObject_alloc(vec, vec_num, NULL);
549 }
550 
551 PyDoc_STRVAR(Vector_resize_2d_doc,
552  ".. method:: resize_2d()\n"
553  "\n"
554  " Resize the vector to 2D (x, y).\n");
555 static PyObject *Vector_resize_2d(VectorObject *self)
556 {
557  if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
558  PyErr_SetString(PyExc_TypeError,
559  "Vector.resize_2d(): "
560  "cannot resize wrapped data - only python vectors");
561  return NULL;
562  }
563  if (self->cb_user) {
564  PyErr_SetString(PyExc_TypeError,
565  "Vector.resize_2d(): "
566  "cannot resize a vector that has an owner");
567  return NULL;
568  }
569 
570  self->vec = PyMem_Realloc(self->vec, sizeof(float[2]));
571  if (self->vec == NULL) {
572  PyErr_SetString(PyExc_MemoryError,
573  "Vector.resize_2d(): "
574  "problem allocating pointer space");
575  return NULL;
576  }
577 
578  self->vec_num = 2;
579  Py_RETURN_NONE;
580 }
581 
582 PyDoc_STRVAR(Vector_resize_3d_doc,
583  ".. method:: resize_3d()\n"
584  "\n"
585  " Resize the vector to 3D (x, y, z).\n");
586 static PyObject *Vector_resize_3d(VectorObject *self)
587 {
588  if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
589  PyErr_SetString(PyExc_TypeError,
590  "Vector.resize_3d(): "
591  "cannot resize wrapped data - only python vectors");
592  return NULL;
593  }
594  if (self->cb_user) {
595  PyErr_SetString(PyExc_TypeError,
596  "Vector.resize_3d(): "
597  "cannot resize a vector that has an owner");
598  return NULL;
599  }
600 
601  self->vec = PyMem_Realloc(self->vec, sizeof(float[3]));
602  if (self->vec == NULL) {
603  PyErr_SetString(PyExc_MemoryError,
604  "Vector.resize_3d(): "
605  "problem allocating pointer space");
606  return NULL;
607  }
608 
609  if (self->vec_num == 2) {
610  self->vec[2] = 0.0f;
611  }
612 
613  self->vec_num = 3;
614  Py_RETURN_NONE;
615 }
616 
617 PyDoc_STRVAR(Vector_resize_4d_doc,
618  ".. method:: resize_4d()\n"
619  "\n"
620  " Resize the vector to 4D (x, y, z, w).\n");
621 static PyObject *Vector_resize_4d(VectorObject *self)
622 {
623  if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
624  PyErr_SetString(PyExc_TypeError,
625  "Vector.resize_4d(): "
626  "cannot resize wrapped data - only python vectors");
627  return NULL;
628  }
629  if (self->cb_user) {
630  PyErr_SetString(PyExc_TypeError,
631  "Vector.resize_4d(): "
632  "cannot resize a vector that has an owner");
633  return NULL;
634  }
635 
636  self->vec = PyMem_Realloc(self->vec, sizeof(float[4]));
637  if (self->vec == NULL) {
638  PyErr_SetString(PyExc_MemoryError,
639  "Vector.resize_4d(): "
640  "problem allocating pointer space");
641  return NULL;
642  }
643 
644  if (self->vec_num == 2) {
645  self->vec[2] = 0.0f;
646  self->vec[3] = 1.0f;
647  }
648  else if (self->vec_num == 3) {
649  self->vec[3] = 1.0f;
650  }
651  self->vec_num = 4;
652  Py_RETURN_NONE;
653 }
654 
657 /* -------------------------------------------------------------------- */
661 PyDoc_STRVAR(Vector_to_2d_doc,
662  ".. method:: to_2d()\n"
663  "\n"
664  " Return a 2d copy of the vector.\n"
665  "\n"
666  " :return: a new vector\n"
667  " :rtype: :class:`Vector`\n");
668 static PyObject *Vector_to_2d(VectorObject *self)
669 {
670  if (BaseMath_ReadCallback(self) == -1) {
671  return NULL;
672  }
673 
674  return Vector_CreatePyObject(self->vec, 2, Py_TYPE(self));
675 }
676 PyDoc_STRVAR(Vector_to_3d_doc,
677  ".. method:: to_3d()\n"
678  "\n"
679  " Return a 3d copy of the vector.\n"
680  "\n"
681  " :return: a new vector\n"
682  " :rtype: :class:`Vector`\n");
683 static PyObject *Vector_to_3d(VectorObject *self)
684 {
685  float tvec[3] = {0.0f};
686 
687  if (BaseMath_ReadCallback(self) == -1) {
688  return NULL;
689  }
690 
691  memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 3));
692  return Vector_CreatePyObject(tvec, 3, Py_TYPE(self));
693 }
694 PyDoc_STRVAR(Vector_to_4d_doc,
695  ".. method:: to_4d()\n"
696  "\n"
697  " Return a 4d copy of the vector.\n"
698  "\n"
699  " :return: a new vector\n"
700  " :rtype: :class:`Vector`\n");
701 static PyObject *Vector_to_4d(VectorObject *self)
702 {
703  float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f};
704 
705  if (BaseMath_ReadCallback(self) == -1) {
706  return NULL;
707  }
708 
709  memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 4));
710  return Vector_CreatePyObject(tvec, 4, Py_TYPE(self));
711 }
712 
715 /* -------------------------------------------------------------------- */
719 PyDoc_STRVAR(Vector_to_tuple_doc,
720  ".. method:: to_tuple(precision=-1)\n"
721  "\n"
722  " Return this vector as a tuple with.\n"
723  "\n"
724  " :arg precision: The number to round the value to in [-1, 21].\n"
725  " :type precision: int\n"
726  " :return: the values of the vector rounded by *precision*\n"
727  " :rtype: tuple\n");
728 static PyObject *Vector_to_tuple(VectorObject *self, PyObject *args)
729 {
730  int ndigits = 0;
731 
732  if (!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits)) {
733  return NULL;
734  }
735 
736  if (ndigits > 22 || ndigits < 0) {
737  PyErr_SetString(PyExc_ValueError,
738  "Vector.to_tuple(ndigits): "
739  "ndigits must be between 0 and 21");
740  return NULL;
741  }
742 
743  if (PyTuple_GET_SIZE(args) == 0) {
744  ndigits = -1;
745  }
746 
747  if (BaseMath_ReadCallback(self) == -1) {
748  return NULL;
749  }
750 
751  return Vector_to_tuple_ex(self, ndigits);
752 }
753 
756 /* -------------------------------------------------------------------- */
760 PyDoc_STRVAR(Vector_to_track_quat_doc,
761  ".. method:: to_track_quat(track, up)\n"
762  "\n"
763  " Return a quaternion rotation from the vector and the track and up axis.\n"
764  "\n"
765  " :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n"
766  " :type track: string\n"
767  " :arg up: Up axis in ['X', 'Y', 'Z'].\n"
768  " :type up: string\n"
769  " :return: rotation from the vector and the track and up axis.\n"
770  " :rtype: :class:`Quaternion`\n");
771 static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
772 {
773  float vec[3], quat[4];
774  const char *strack = NULL;
775  const char *sup = NULL;
776  short track = 2, up = 1;
777 
778  if (!PyArg_ParseTuple(args, "|ss:to_track_quat", &strack, &sup)) {
779  return NULL;
780  }
781 
782  if (self->vec_num != 3) {
783  PyErr_SetString(PyExc_TypeError,
784  "Vector.to_track_quat(): "
785  "only for 3D vectors");
786  return NULL;
787  }
788 
789  if (BaseMath_ReadCallback(self) == -1) {
790  return NULL;
791  }
792 
793  if (strack) {
794  const char *axis_err_msg = "only X, -X, Y, -Y, Z or -Z for track axis";
795 
796  if (strlen(strack) == 2) {
797  if (strack[0] == '-') {
798  switch (strack[1]) {
799  case 'X':
800  track = 3;
801  break;
802  case 'Y':
803  track = 4;
804  break;
805  case 'Z':
806  track = 5;
807  break;
808  default:
809  PyErr_SetString(PyExc_ValueError, axis_err_msg);
810  return NULL;
811  }
812  }
813  else {
814  PyErr_SetString(PyExc_ValueError, axis_err_msg);
815  return NULL;
816  }
817  }
818  else if (strlen(strack) == 1) {
819  switch (strack[0]) {
820  case '-':
821  case 'X':
822  track = 0;
823  break;
824  case 'Y':
825  track = 1;
826  break;
827  case 'Z':
828  track = 2;
829  break;
830  default:
831  PyErr_SetString(PyExc_ValueError, axis_err_msg);
832  return NULL;
833  }
834  }
835  else {
836  PyErr_SetString(PyExc_ValueError, axis_err_msg);
837  return NULL;
838  }
839  }
840 
841  if (sup) {
842  const char *axis_err_msg = "only X, Y or Z for up axis";
843  if (strlen(sup) == 1) {
844  switch (*sup) {
845  case 'X':
846  up = 0;
847  break;
848  case 'Y':
849  up = 1;
850  break;
851  case 'Z':
852  up = 2;
853  break;
854  default:
855  PyErr_SetString(PyExc_ValueError, axis_err_msg);
856  return NULL;
857  }
858  }
859  else {
860  PyErr_SetString(PyExc_ValueError, axis_err_msg);
861  return NULL;
862  }
863  }
864 
865  if (track == up) {
866  PyErr_SetString(PyExc_ValueError, "Can't have the same axis for track and up");
867  return NULL;
868  }
869 
870  /* Flip vector around, since #vec_to_quat expect a vector from target to tracking object
871  * and the python function expects the inverse (a vector to the target). */
872  negate_v3_v3(vec, self->vec);
873 
874  vec_to_quat(quat, vec, track, up);
875 
876  return Quaternion_CreatePyObject(quat, NULL);
877 }
878 
881 /* -------------------------------------------------------------------- */
886  Vector_orthogonal_doc,
887  ".. method:: orthogonal()\n"
888  "\n"
889  " Return a perpendicular vector.\n"
890  "\n"
891  " :return: a new vector 90 degrees from this vector.\n"
892  " :rtype: :class:`Vector`\n"
893  "\n"
894  " .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n");
895 static PyObject *Vector_orthogonal(VectorObject *self)
896 {
897  float vec[3];
898 
899  if (self->vec_num > 3) {
900  PyErr_SetString(PyExc_TypeError,
901  "Vector.orthogonal(): "
902  "Vector must be 3D or 2D");
903  return NULL;
904  }
905 
906  if (BaseMath_ReadCallback(self) == -1) {
907  return NULL;
908  }
909 
910  if (self->vec_num == 3) {
911  ortho_v3_v3(vec, self->vec);
912  }
913  else {
914  ortho_v2_v2(vec, self->vec);
915  }
916 
917  return Vector_CreatePyObject(vec, self->vec_num, Py_TYPE(self));
918 }
919 
922 /* -------------------------------------------------------------------- */
929 PyDoc_STRVAR(Vector_reflect_doc,
930  ".. method:: reflect(mirror)\n"
931  "\n"
932  " Return the reflection vector from the *mirror* argument.\n"
933  "\n"
934  " :arg mirror: This vector could be a normal from the reflecting surface.\n"
935  " :type mirror: :class:`Vector`\n"
936  " :return: The reflected vector matching the size of this vector.\n"
937  " :rtype: :class:`Vector`\n");
938 static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
939 {
940  int value_num;
941  float mirror[3], vec[3];
942  float reflect[3] = {0.0f};
943  float tvec[MAX_DIMENSIONS];
944 
945  if (BaseMath_ReadCallback(self) == -1) {
946  return NULL;
947  }
948 
949  if ((value_num = mathutils_array_parse(
950  tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) {
951  return NULL;
952  }
953 
954  if (self->vec_num < 2 || self->vec_num > 4) {
955  PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D");
956  return NULL;
957  }
958 
959  mirror[0] = tvec[0];
960  mirror[1] = tvec[1];
961  mirror[2] = (value_num > 2) ? tvec[2] : 0.0f;
962 
963  vec[0] = self->vec[0];
964  vec[1] = self->vec[1];
965  vec[2] = (value_num > 2) ? self->vec[2] : 0.0f;
966 
967  normalize_v3(mirror);
968  reflect_v3_v3v3(reflect, vec, mirror);
969 
970  return Vector_CreatePyObject(reflect, self->vec_num, Py_TYPE(self));
971 }
972 
975 /* -------------------------------------------------------------------- */
979 PyDoc_STRVAR(Vector_cross_doc,
980  ".. method:: cross(other)\n"
981  "\n"
982  " Return the cross product of this vector and another.\n"
983  "\n"
984  " :arg other: The other vector to perform the cross product with.\n"
985  " :type other: :class:`Vector`\n"
986  " :return: The cross product.\n"
987  " :rtype: :class:`Vector` or float when 2D vectors are used\n"
988  "\n"
989  " .. note:: both vectors must be 2D or 3D\n");
990 static PyObject *Vector_cross(VectorObject *self, PyObject *value)
991 {
992  PyObject *ret;
993  float tvec[3];
994 
995  if (BaseMath_ReadCallback(self) == -1) {
996  return NULL;
997  }
998 
999  if (self->vec_num > 3) {
1000  PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D");
1001  return NULL;
1002  }
1003 
1005  tvec, self->vec_num, self->vec_num, value, "Vector.cross(other), invalid 'other' arg") ==
1006  -1) {
1007  return NULL;
1008  }
1009 
1010  if (self->vec_num == 3) {
1011  ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self));
1012  cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec);
1013  }
1014  else {
1015  /* size == 2 */
1016  ret = PyFloat_FromDouble(cross_v2v2(self->vec, tvec));
1017  }
1018  return ret;
1019 }
1020 
1023 /* -------------------------------------------------------------------- */
1027 PyDoc_STRVAR(Vector_dot_doc,
1028  ".. method:: dot(other)\n"
1029  "\n"
1030  " Return the dot product of this vector and another.\n"
1031  "\n"
1032  " :arg other: The other vector to perform the dot product with.\n"
1033  " :type other: :class:`Vector`\n"
1034  " :return: The dot product.\n"
1035  " :rtype: float\n");
1036 static PyObject *Vector_dot(VectorObject *self, PyObject *value)
1037 {
1038  float *tvec;
1039  PyObject *ret;
1040 
1041  if (BaseMath_ReadCallback(self) == -1) {
1042  return NULL;
1043  }
1044 
1046  &tvec, self->vec_num, value, "Vector.dot(other), invalid 'other' arg") == -1) {
1047  return NULL;
1048  }
1049 
1050  ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->vec_num));
1051  PyMem_Free(tvec);
1052  return ret;
1053 }
1054 
1057 /* -------------------------------------------------------------------- */
1062  Vector_angle_doc,
1063  ".. function:: angle(other, fallback=None)\n"
1064  "\n"
1065  " Return the angle between two vectors.\n"
1066  "\n"
1067  " :arg other: another vector to compare the angle with\n"
1068  " :type other: :class:`Vector`\n"
1069  " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1070  " (instead of raising a :exc:`ValueError`).\n"
1071  " :type fallback: any\n"
1072  " :return: angle in radians or fallback when given\n"
1073  " :rtype: float\n");
1074 static PyObject *Vector_angle(VectorObject *self, PyObject *args)
1075 {
1076  const int vec_num = MIN2(self->vec_num, 3); /* 4D angle makes no sense */
1077  float tvec[MAX_DIMENSIONS];
1078  PyObject *value;
1079  double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
1080  int x;
1081  PyObject *fallback = NULL;
1082 
1083  if (!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback)) {
1084  return NULL;
1085  }
1086 
1087  if (BaseMath_ReadCallback(self) == -1) {
1088  return NULL;
1089  }
1090 
1091  /* don't use clamped size, rule of thumb is vector sizes must match,
1092  * even though n this case 'w' is ignored */
1094  tvec, self->vec_num, self->vec_num, value, "Vector.angle(other), invalid 'other' arg") ==
1095  -1) {
1096  return NULL;
1097  }
1098 
1099  if (self->vec_num > 4) {
1100  PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D");
1101  return NULL;
1102  }
1103 
1104  for (x = 0; x < vec_num; x++) {
1105  dot_self += (double)self->vec[x] * (double)self->vec[x];
1106  dot_other += (double)tvec[x] * (double)tvec[x];
1107  dot += (double)self->vec[x] * (double)tvec[x];
1108  }
1109 
1110  if (!dot_self || !dot_other) {
1111  /* avoid exception */
1112  if (fallback) {
1113  Py_INCREF(fallback);
1114  return fallback;
1115  }
1116 
1117  PyErr_SetString(PyExc_ValueError,
1118  "Vector.angle(other): "
1119  "zero length vectors have no valid angle");
1120  return NULL;
1121  }
1122 
1123  return PyFloat_FromDouble(saacos(dot / (sqrt(dot_self) * sqrt(dot_other))));
1124 }
1125 
1128 /* -------------------------------------------------------------------- */
1133  Vector_angle_signed_doc,
1134  ".. function:: angle_signed(other, fallback)\n"
1135  "\n"
1136  " Return the signed angle between two 2D vectors (clockwise is positive).\n"
1137  "\n"
1138  " :arg other: another vector to compare the angle with\n"
1139  " :type other: :class:`Vector`\n"
1140  " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
1141  " (instead of raising a :exc:`ValueError`).\n"
1142  " :type fallback: any\n"
1143  " :return: angle in radians or fallback when given\n"
1144  " :rtype: float\n");
1145 static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args)
1146 {
1147  float tvec[2];
1148 
1149  PyObject *value;
1150  PyObject *fallback = NULL;
1151 
1152  if (!PyArg_ParseTuple(args, "O|O:angle_signed", &value, &fallback)) {
1153  return NULL;
1154  }
1155 
1156  if (BaseMath_ReadCallback(self) == -1) {
1157  return NULL;
1158  }
1159 
1161  tvec, 2, 2, value, "Vector.angle_signed(other), invalid 'other' arg") == -1) {
1162  return NULL;
1163  }
1164 
1165  if (self->vec_num != 2) {
1166  PyErr_SetString(PyExc_ValueError, "Vector must be 2D");
1167  return NULL;
1168  }
1169 
1170  if (is_zero_v2(self->vec) || is_zero_v2(tvec)) {
1171  /* avoid exception */
1172  if (fallback) {
1173  Py_INCREF(fallback);
1174  return fallback;
1175  }
1176 
1177  PyErr_SetString(PyExc_ValueError,
1178  "Vector.angle_signed(other): "
1179  "zero length vectors have no valid angle");
1180  return NULL;
1181  }
1182 
1183  return PyFloat_FromDouble(angle_signed_v2v2(self->vec, tvec));
1184 }
1185 
1188 /* -------------------------------------------------------------------- */
1192 PyDoc_STRVAR(Vector_rotation_difference_doc,
1193  ".. function:: rotation_difference(other)\n"
1194  "\n"
1195  " Returns a quaternion representing the rotational difference between this\n"
1196  " vector and another.\n"
1197  "\n"
1198  " :arg other: second vector.\n"
1199  " :type other: :class:`Vector`\n"
1200  " :return: the rotational difference between the two vectors.\n"
1201  " :rtype: :class:`Quaternion`\n"
1202  "\n"
1203  " .. note:: 2D vectors raise an :exc:`AttributeError`.\n");
1204 static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
1205 {
1206  float quat[4], vec_a[3], vec_b[3];
1207 
1208  if (self->vec_num < 3 || self->vec_num > 4) {
1209  PyErr_SetString(PyExc_ValueError,
1210  "vec.difference(value): "
1211  "expects both vectors to be size 3 or 4");
1212  return NULL;
1213  }
1214 
1215  if (BaseMath_ReadCallback(self) == -1) {
1216  return NULL;
1217  }
1218 
1220  vec_b, 3, MAX_DIMENSIONS, value, "Vector.difference(other), invalid 'other' arg") ==
1221  -1) {
1222  return NULL;
1223  }
1224 
1225  normalize_v3_v3(vec_a, self->vec);
1226  normalize_v3(vec_b);
1227 
1228  rotation_between_vecs_to_quat(quat, vec_a, vec_b);
1229 
1230  return Quaternion_CreatePyObject(quat, NULL);
1231 }
1232 
1235 /* -------------------------------------------------------------------- */
1239 PyDoc_STRVAR(Vector_project_doc,
1240  ".. function:: project(other)\n"
1241  "\n"
1242  " Return the projection of this vector onto the *other*.\n"
1243  "\n"
1244  " :arg other: second vector.\n"
1245  " :type other: :class:`Vector`\n"
1246  " :return: the parallel projection vector\n"
1247  " :rtype: :class:`Vector`\n");
1248 static PyObject *Vector_project(VectorObject *self, PyObject *value)
1249 {
1250  const int vec_num = self->vec_num;
1251  float *tvec;
1252  double dot = 0.0f, dot2 = 0.0f;
1253  int x;
1254 
1255  if (BaseMath_ReadCallback(self) == -1) {
1256  return NULL;
1257  }
1258 
1260  &tvec, vec_num, value, "Vector.project(other), invalid 'other' arg") == -1) {
1261  return NULL;
1262  }
1263 
1264  /* get dot products */
1265  for (x = 0; x < vec_num; x++) {
1266  dot += (double)(self->vec[x] * tvec[x]);
1267  dot2 += (double)(tvec[x] * tvec[x]);
1268  }
1269  /* projection */
1270  dot /= dot2;
1271  for (x = 0; x < vec_num; x++) {
1272  tvec[x] *= (float)dot;
1273  }
1274  return Vector_CreatePyObject_alloc(tvec, vec_num, Py_TYPE(self));
1275 }
1276 
1279 /* -------------------------------------------------------------------- */
1283 PyDoc_STRVAR(Vector_lerp_doc,
1284  ".. function:: lerp(other, factor)\n"
1285  "\n"
1286  " Returns the interpolation of two vectors.\n"
1287  "\n"
1288  " :arg other: value to interpolate with.\n"
1289  " :type other: :class:`Vector`\n"
1290  " :arg factor: The interpolation value in [0.0, 1.0].\n"
1291  " :type factor: float\n"
1292  " :return: The interpolated vector.\n"
1293  " :rtype: :class:`Vector`\n");
1294 static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
1295 {
1296  const int vec_num = self->vec_num;
1297  PyObject *value = NULL;
1298  float fac;
1299  float *tvec;
1300 
1301  if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac)) {
1302  return NULL;
1303  }
1304 
1305  if (BaseMath_ReadCallback(self) == -1) {
1306  return NULL;
1307  }
1308 
1310  &tvec, vec_num, value, "Vector.lerp(other), invalid 'other' arg") == -1) {
1311  return NULL;
1312  }
1313 
1314  interp_vn_vn(tvec, self->vec, 1.0f - fac, vec_num);
1315 
1316  return Vector_CreatePyObject_alloc(tvec, vec_num, Py_TYPE(self));
1317 }
1318 
1321 /* -------------------------------------------------------------------- */
1325 PyDoc_STRVAR(Vector_slerp_doc,
1326  ".. function:: slerp(other, factor, fallback=None)\n"
1327  "\n"
1328  " Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
1329  "\n"
1330  " :arg other: value to interpolate with.\n"
1331  " :type other: :class:`Vector`\n"
1332  " :arg factor: The interpolation value typically in [0.0, 1.0].\n"
1333  " :type factor: float\n"
1334  " :arg fallback: return this when the vector can't be calculated (zero length "
1335  "vector or direct opposites),\n"
1336  " (instead of raising a :exc:`ValueError`).\n"
1337  " :type fallback: any\n"
1338  " :return: The interpolated vector.\n"
1339  " :rtype: :class:`Vector`\n");
1340 static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
1341 {
1342  const int vec_num = self->vec_num;
1343  PyObject *value = NULL;
1344  float fac, cosom, w[2];
1345  float self_vec[3], other_vec[3], ret_vec[3];
1346  float self_len_sq, other_len_sq;
1347  int x;
1348  PyObject *fallback = NULL;
1349 
1350  if (!PyArg_ParseTuple(args, "Of|O:slerp", &value, &fac, &fallback)) {
1351  return NULL;
1352  }
1353 
1354  if (BaseMath_ReadCallback(self) == -1) {
1355  return NULL;
1356  }
1357 
1358  if (self->vec_num > 3) {
1359  PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D");
1360  return NULL;
1361  }
1362 
1364  other_vec, vec_num, vec_num, value, "Vector.slerp(other), invalid 'other' arg") == -1) {
1365  return NULL;
1366  }
1367 
1368  self_len_sq = normalize_vn_vn(self_vec, self->vec, vec_num);
1369  other_len_sq = normalize_vn(other_vec, vec_num);
1370 
1371  /* use fallbacks for zero length vectors */
1372  if (UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) {
1373  /* avoid exception */
1374  if (fallback) {
1375  Py_INCREF(fallback);
1376  return fallback;
1377  }
1378 
1379  PyErr_SetString(PyExc_ValueError,
1380  "Vector.slerp(): "
1381  "zero length vectors unsupported");
1382  return NULL;
1383  }
1384 
1385  /* We have sane state, execute slerp */
1386  cosom = (float)dot_vn_vn(self_vec, other_vec, vec_num);
1387 
1388  /* direct opposite, can't slerp */
1389  if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
1390  /* avoid exception */
1391  if (fallback) {
1392  Py_INCREF(fallback);
1393  return fallback;
1394  }
1395 
1396  PyErr_SetString(PyExc_ValueError,
1397  "Vector.slerp(): "
1398  "opposite vectors unsupported");
1399  return NULL;
1400  }
1401 
1402  interp_dot_slerp(fac, cosom, w);
1403 
1404  for (x = 0; x < vec_num; x++) {
1405  ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]);
1406  }
1407 
1408  return Vector_CreatePyObject(ret_vec, vec_num, Py_TYPE(self));
1409 }
1410 
1413 /* -------------------------------------------------------------------- */
1418  Vector_rotate_doc,
1419  ".. function:: rotate(other)\n"
1420  "\n"
1421  " Rotate the vector by a rotation value.\n"
1422  "\n"
1423  " .. note:: 2D vectors are a special case that can only be rotated by a 2x2 matrix.\n"
1424  "\n"
1425  " :arg other: rotation component of mathutils value\n"
1426  " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n");
1427 static PyObject *Vector_rotate(VectorObject *self, PyObject *value)
1428 {
1429  if (BaseMath_ReadCallback_ForWrite(self) == -1) {
1430  return NULL;
1431  }
1432 
1433  if (self->vec_num == 2) {
1434  /* Special case for 2D Vector with 2x2 matrix, so we avoid resizing it to a 3x3. */
1435  float other_rmat[2][2];
1436  MatrixObject *pymat;
1437  if (!Matrix_Parse2x2(value, &pymat)) {
1438  return NULL;
1439  }
1440  normalize_m2_m2(other_rmat, (const float(*)[2])pymat->matrix);
1441  /* Equivalent to a rotation along the Z axis. */
1442  mul_m2_v2(other_rmat, self->vec);
1443  }
1444  else {
1445  float other_rmat[3][3];
1446 
1447  if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1) {
1448  return NULL;
1449  }
1450 
1451  mul_m3_v3(other_rmat, self->vec);
1452  }
1453 
1455  Py_RETURN_NONE;
1456 }
1457 
1460 /* -------------------------------------------------------------------- */
1464 PyDoc_STRVAR(Vector_negate_doc,
1465  ".. method:: negate()\n"
1466  "\n"
1467  " Set all values to their negative.\n");
1468 static PyObject *Vector_negate(VectorObject *self)
1469 {
1470  if (BaseMath_ReadCallback(self) == -1) {
1471  return NULL;
1472  }
1473 
1474  negate_vn(self->vec, self->vec_num);
1475 
1476  (void)BaseMath_WriteCallback(self); /* already checked for error */
1477  Py_RETURN_NONE;
1478 }
1479 
1482 /* -------------------------------------------------------------------- */
1486 PyDoc_STRVAR(Vector_copy_doc,
1487  ".. function:: copy()\n"
1488  "\n"
1489  " Returns a copy of this vector.\n"
1490  "\n"
1491  " :return: A copy of the vector.\n"
1492  " :rtype: :class:`Vector`\n"
1493  "\n"
1494  " .. note:: use this to get a copy of a wrapped vector with\n"
1495  " no reference to the original data.\n");
1496 static PyObject *Vector_copy(VectorObject *self)
1497 {
1498  if (BaseMath_ReadCallback(self) == -1) {
1499  return NULL;
1500  }
1501 
1502  return Vector_CreatePyObject(self->vec, self->vec_num, Py_TYPE(self));
1503 }
1504 static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args)
1505 {
1506  if (!PyC_CheckArgs_DeepCopy(args)) {
1507  return NULL;
1508  }
1509  return Vector_copy(self);
1510 }
1511 
1514 /* -------------------------------------------------------------------- */
1518 static PyObject *Vector_repr(VectorObject *self)
1519 {
1520  PyObject *ret, *tuple;
1521 
1522  if (BaseMath_ReadCallback(self) == -1) {
1523  return NULL;
1524  }
1525 
1526  tuple = Vector_to_tuple_ex(self, -1);
1527  ret = PyUnicode_FromFormat("Vector(%R)", tuple);
1528  Py_DECREF(tuple);
1529  return ret;
1530 }
1531 
1532 #ifndef MATH_STANDALONE
1533 static PyObject *Vector_str(VectorObject *self)
1534 {
1535  int i;
1536 
1537  DynStr *ds;
1538 
1539  if (BaseMath_ReadCallback(self) == -1) {
1540  return NULL;
1541  }
1542 
1543  ds = BLI_dynstr_new();
1544 
1545  BLI_dynstr_append(ds, "<Vector (");
1546 
1547  for (i = 0; i < self->vec_num; i++) {
1548  BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]);
1549  }
1550 
1551  BLI_dynstr_append(ds, ")>");
1552 
1553  return mathutils_dynstr_to_py(ds); /* frees ds */
1554 }
1555 #endif
1556 
1559 /* -------------------------------------------------------------------- */
1563 static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
1564 {
1565  VectorObject *vecA = NULL, *vecB = NULL;
1566  int result = 0;
1567  const double epsilon = 0.000001f;
1568  double lenA, lenB;
1569 
1570  if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)) {
1571  if (comparison_type == Py_NE) {
1572  Py_RETURN_TRUE;
1573  }
1574 
1575  Py_RETURN_FALSE;
1576  }
1577  vecA = (VectorObject *)objectA;
1578  vecB = (VectorObject *)objectB;
1579 
1580  if (BaseMath_ReadCallback(vecA) == -1 || BaseMath_ReadCallback(vecB) == -1) {
1581  return NULL;
1582  }
1583 
1584  if (vecA->vec_num != vecB->vec_num) {
1585  if (comparison_type == Py_NE) {
1586  Py_RETURN_TRUE;
1587  }
1588 
1589  Py_RETURN_FALSE;
1590  }
1591 
1592  switch (comparison_type) {
1593  case Py_LT:
1594  lenA = len_squared_vn(vecA->vec, vecA->vec_num);
1595  lenB = len_squared_vn(vecB->vec, vecB->vec_num);
1596  if (lenA < lenB) {
1597  result = 1;
1598  }
1599  break;
1600  case Py_LE:
1601  lenA = len_squared_vn(vecA->vec, vecA->vec_num);
1602  lenB = len_squared_vn(vecB->vec, vecB->vec_num);
1603  if (lenA < lenB) {
1604  result = 1;
1605  }
1606  else {
1607  result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1608  }
1609  break;
1610  case Py_EQ:
1611  result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->vec_num, 1);
1612  break;
1613  case Py_NE:
1614  result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->vec_num, 1);
1615  break;
1616  case Py_GT:
1617  lenA = len_squared_vn(vecA->vec, vecA->vec_num);
1618  lenB = len_squared_vn(vecB->vec, vecB->vec_num);
1619  if (lenA > lenB) {
1620  result = 1;
1621  }
1622  break;
1623  case Py_GE:
1624  lenA = len_squared_vn(vecA->vec, vecA->vec_num);
1625  lenB = len_squared_vn(vecB->vec, vecB->vec_num);
1626  if (lenA > lenB) {
1627  result = 1;
1628  }
1629  else {
1630  result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
1631  }
1632  break;
1633  default:
1634  printf("The result of the comparison could not be evaluated");
1635  break;
1636  }
1637  if (result == 1) {
1638  Py_RETURN_TRUE;
1639  }
1640 
1641  Py_RETURN_FALSE;
1642 }
1643 
1646 /* -------------------------------------------------------------------- */
1650 static Py_hash_t Vector_hash(VectorObject *self)
1651 {
1652  if (BaseMath_ReadCallback(self) == -1) {
1653  return -1;
1654  }
1655 
1656  if (BaseMathObject_Prepare_ForHash(self) == -1) {
1657  return -1;
1658  }
1659 
1660  return mathutils_array_hash(self->vec, self->vec_num);
1661 }
1662 
1665 /* -------------------------------------------------------------------- */
1670 static int Vector_len(VectorObject *self)
1671 {
1672  return self->vec_num;
1673 }
1674 
1675 static PyObject *vector_item_internal(VectorObject *self, int i, const bool is_attr)
1676 {
1677  if (i < 0) {
1678  i = self->vec_num - i;
1679  }
1680 
1681  if (i < 0 || i >= self->vec_num) {
1682  if (is_attr) {
1683  PyErr_Format(PyExc_AttributeError,
1684  "Vector.%c: unavailable on %dd vector",
1685  *(((const char *)"xyzw") + i),
1686  self->vec_num);
1687  }
1688  else {
1689  PyErr_SetString(PyExc_IndexError, "vector[index]: out of range");
1690  }
1691  return NULL;
1692  }
1693 
1694  if (BaseMath_ReadIndexCallback(self, i) == -1) {
1695  return NULL;
1696  }
1697 
1698  return PyFloat_FromDouble(self->vec[i]);
1699 }
1700 
1702 static PyObject *Vector_item(VectorObject *self, int i)
1703 {
1704  return vector_item_internal(self, i, false);
1705 }
1706 
1707 static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const bool is_attr)
1708 {
1709  float scalar;
1710 
1711  if (BaseMath_Prepare_ForWrite(self) == -1) {
1712  return -1;
1713  }
1714 
1715  if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
1716  /* parsed item not a number */
1717  PyErr_SetString(PyExc_TypeError,
1718  "vector[index] = x: "
1719  "assigned value not a number");
1720  return -1;
1721  }
1722 
1723  if (i < 0) {
1724  i = self->vec_num - i;
1725  }
1726 
1727  if (i < 0 || i >= self->vec_num) {
1728  if (is_attr) {
1729  PyErr_Format(PyExc_AttributeError,
1730  "Vector.%c = x: unavailable on %dd vector",
1731  *(((const char *)"xyzw") + i),
1732  self->vec_num);
1733  }
1734  else {
1735  PyErr_SetString(PyExc_IndexError,
1736  "vector[index] = x: "
1737  "assignment index out of range");
1738  }
1739  return -1;
1740  }
1741  self->vec[i] = scalar;
1742 
1743  if (BaseMath_WriteIndexCallback(self, i) == -1) {
1744  return -1;
1745  }
1746  return 0;
1747 }
1748 
1750 static int Vector_ass_item(VectorObject *self, int i, PyObject *value)
1751 {
1752  return vector_ass_item_internal(self, i, value, false);
1753 }
1754 
1756 static PyObject *Vector_slice(VectorObject *self, int begin, int end)
1757 {
1758  PyObject *tuple;
1759  int count;
1760 
1761  if (BaseMath_ReadCallback(self) == -1) {
1762  return NULL;
1763  }
1764 
1765  CLAMP(begin, 0, self->vec_num);
1766  if (end < 0) {
1767  end = self->vec_num + end + 1;
1768  }
1769  CLAMP(end, 0, self->vec_num);
1770  begin = MIN2(begin, end);
1771 
1772  tuple = PyTuple_New(end - begin);
1773  for (count = begin; count < end; count++) {
1774  PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->vec[count]));
1775  }
1776 
1777  return tuple;
1778 }
1779 
1781 static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
1782 {
1783  int vec_num = 0;
1784  float *vec = NULL;
1785 
1786  if (BaseMath_ReadCallback_ForWrite(self) == -1) {
1787  return -1;
1788  }
1789 
1790  CLAMP(begin, 0, self->vec_num);
1791  CLAMP(end, 0, self->vec_num);
1792  begin = MIN2(begin, end);
1793 
1794  vec_num = (end - begin);
1795  if (mathutils_array_parse_alloc(&vec, vec_num, seq, "vector[begin:end] = [...]") == -1) {
1796  return -1;
1797  }
1798 
1799  if (vec == NULL) {
1800  PyErr_SetString(PyExc_MemoryError,
1801  "vec[:] = seq: "
1802  "problem allocating pointer space");
1803  return -1;
1804  }
1805 
1806  /* Parsed well - now set in vector. */
1807  memcpy(self->vec + begin, vec, vec_num * sizeof(float));
1808 
1809  PyMem_Free(vec);
1810 
1811  if (BaseMath_WriteCallback(self) == -1) {
1812  return -1;
1813  }
1814 
1815  return 0;
1816 }
1817 
1819 static PyObject *Vector_subscript(VectorObject *self, PyObject *item)
1820 {
1821  if (PyIndex_Check(item)) {
1822  Py_ssize_t i;
1823  i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1824  if (i == -1 && PyErr_Occurred()) {
1825  return NULL;
1826  }
1827  if (i < 0) {
1828  i += self->vec_num;
1829  }
1830  return Vector_item(self, i);
1831  }
1832  if (PySlice_Check(item)) {
1833  Py_ssize_t start, stop, step, slicelength;
1834 
1835  if (PySlice_GetIndicesEx(item, self->vec_num, &start, &stop, &step, &slicelength) < 0) {
1836  return NULL;
1837  }
1838 
1839  if (slicelength <= 0) {
1840  return PyTuple_New(0);
1841  }
1842  if (step == 1) {
1843  return Vector_slice(self, start, stop);
1844  }
1845 
1846  PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
1847  return NULL;
1848  }
1849 
1850  PyErr_Format(
1851  PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1852  return NULL;
1853 }
1854 
1856 static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *value)
1857 {
1858  if (PyIndex_Check(item)) {
1859  Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1860  if (i == -1 && PyErr_Occurred()) {
1861  return -1;
1862  }
1863  if (i < 0) {
1864  i += self->vec_num;
1865  }
1866  return Vector_ass_item(self, i, value);
1867  }
1868  if (PySlice_Check(item)) {
1869  Py_ssize_t start, stop, step, slicelength;
1870 
1871  if (PySlice_GetIndicesEx(item, self->vec_num, &start, &stop, &step, &slicelength) < 0) {
1872  return -1;
1873  }
1874 
1875  if (step == 1) {
1876  return Vector_ass_slice(self, start, stop, value);
1877  }
1878 
1879  PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
1880  return -1;
1881  }
1882 
1883  PyErr_Format(
1884  PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
1885  return -1;
1886 }
1887 
1890 /* -------------------------------------------------------------------- */
1895 static PyObject *Vector_add(PyObject *v1, PyObject *v2)
1896 {
1897  VectorObject *vec1 = NULL, *vec2 = NULL;
1898  float *vec = NULL;
1899 
1901  PyErr_Format(PyExc_AttributeError,
1902  "Vector addition: (%s + %s) "
1903  "invalid type for this operation",
1904  Py_TYPE(v1)->tp_name,
1905  Py_TYPE(v2)->tp_name);
1906  return NULL;
1907  }
1908  vec1 = (VectorObject *)v1;
1909  vec2 = (VectorObject *)v2;
1910 
1911  if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
1912  return NULL;
1913  }
1914 
1915  /* VECTOR + VECTOR. */
1916  if (vec1->vec_num != vec2->vec_num) {
1917  PyErr_SetString(PyExc_AttributeError,
1918  "Vector addition: "
1919  "vectors must have the same dimensions for this operation");
1920  return NULL;
1921  }
1922 
1923  vec = PyMem_Malloc(vec1->vec_num * sizeof(float));
1924  if (vec == NULL) {
1925  PyErr_SetString(PyExc_MemoryError,
1926  "Vector(): "
1927  "problem allocating pointer space");
1928  return NULL;
1929  }
1930 
1931  add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->vec_num);
1932 
1933  return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1));
1934 }
1935 
1937 static PyObject *Vector_iadd(PyObject *v1, PyObject *v2)
1938 {
1939  VectorObject *vec1 = NULL, *vec2 = NULL;
1940 
1942  PyErr_Format(PyExc_AttributeError,
1943  "Vector addition: (%s += %s) "
1944  "invalid type for this operation",
1945  Py_TYPE(v1)->tp_name,
1946  Py_TYPE(v2)->tp_name);
1947  return NULL;
1948  }
1949  vec1 = (VectorObject *)v1;
1950  vec2 = (VectorObject *)v2;
1951 
1952  if (vec1->vec_num != vec2->vec_num) {
1953  PyErr_SetString(PyExc_AttributeError,
1954  "Vector addition: "
1955  "vectors must have the same dimensions for this operation");
1956  return NULL;
1957  }
1958 
1959  if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
1960  return NULL;
1961  }
1962 
1963  add_vn_vn(vec1->vec, vec2->vec, vec1->vec_num);
1964 
1966  Py_INCREF(v1);
1967  return v1;
1968 }
1969 
1971 static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
1972 {
1973  VectorObject *vec1 = NULL, *vec2 = NULL;
1974  float *vec;
1975 
1977  PyErr_Format(PyExc_AttributeError,
1978  "Vector subtraction: (%s - %s) "
1979  "invalid type for this operation",
1980  Py_TYPE(v1)->tp_name,
1981  Py_TYPE(v2)->tp_name);
1982  return NULL;
1983  }
1984  vec1 = (VectorObject *)v1;
1985  vec2 = (VectorObject *)v2;
1986 
1987  if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
1988  return NULL;
1989  }
1990 
1991  if (vec1->vec_num != vec2->vec_num) {
1992  PyErr_SetString(PyExc_AttributeError,
1993  "Vector subtraction: "
1994  "vectors must have the same dimensions for this operation");
1995  return NULL;
1996  }
1997 
1998  vec = PyMem_Malloc(vec1->vec_num * sizeof(float));
1999  if (vec == NULL) {
2000  PyErr_SetString(PyExc_MemoryError,
2001  "Vector(): "
2002  "problem allocating pointer space");
2003  return NULL;
2004  }
2005 
2006  sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->vec_num);
2007 
2008  return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1));
2009 }
2010 
2012 static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
2013 {
2014  VectorObject *vec1 = NULL, *vec2 = NULL;
2015 
2017  PyErr_Format(PyExc_AttributeError,
2018  "Vector subtraction: (%s -= %s) "
2019  "invalid type for this operation",
2020  Py_TYPE(v1)->tp_name,
2021  Py_TYPE(v2)->tp_name);
2022  return NULL;
2023  }
2024  vec1 = (VectorObject *)v1;
2025  vec2 = (VectorObject *)v2;
2026 
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");
2031  return NULL;
2032  }
2033 
2034  if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
2035  return NULL;
2036  }
2037 
2038  sub_vn_vn(vec1->vec, vec2->vec, vec1->vec_num);
2039 
2041  Py_INCREF(v1);
2042  return v1;
2043 }
2044 
2045 /* Multiply internal implementation `object * object`, `object *= object`. */
2046 
2048 {
2049  float vec_cpy[MAX_DIMENSIONS];
2050  int row, col, z = 0;
2051 
2052  if (mat->col_num != vec->vec_num) {
2053  if (mat->col_num == 4 && vec->vec_num == 3) {
2054  vec_cpy[3] = 1.0f;
2055  }
2056  else {
2057  PyErr_SetString(PyExc_ValueError,
2058  "matrix * vector: "
2059  "len(matrix.col) and len(vector) must be the same, "
2060  "except for 4x4 matrix * 3D vector.");
2061  return -1;
2062  }
2063  }
2064 
2065  memcpy(vec_cpy, vec->vec, vec->vec_num * sizeof(float));
2066 
2067  r_vec[3] = 1.0f;
2068 
2069  for (row = 0; row < mat->row_num; row++) {
2070  double dot = 0.0f;
2071  for (col = 0; col < mat->col_num; col++) {
2072  dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]);
2073  }
2074  r_vec[z++] = (float)dot;
2075  }
2076 
2077  return 0;
2078 }
2079 
2080 static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
2081 {
2082  float *tvec = PyMem_Malloc(vec->vec_num * sizeof(float));
2083  if (tvec == NULL) {
2084  PyErr_SetString(PyExc_MemoryError,
2085  "vec * float: "
2086  "problem allocating pointer space");
2087  return NULL;
2088  }
2089 
2090  mul_vn_vn_fl(tvec, vec->vec, vec->vec_num, scalar);
2091  return Vector_CreatePyObject_alloc(tvec, vec->vec_num, Py_TYPE(vec));
2092 }
2093 
2094 static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
2095 {
2096  float *tvec = PyMem_Malloc(vec1->vec_num * sizeof(float));
2097  if (tvec == NULL) {
2098  PyErr_SetString(PyExc_MemoryError,
2099  "vec * vec: "
2100  "problem allocating pointer space");
2101  return NULL;
2102  }
2103 
2104  mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->vec_num);
2105  return Vector_CreatePyObject_alloc(tvec, vec1->vec_num, Py_TYPE(vec1));
2106 }
2107 
2109 static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
2110 {
2111  VectorObject *vec1 = NULL, *vec2 = NULL;
2112  float scalar;
2113 
2114  if (VectorObject_Check(v1)) {
2115  vec1 = (VectorObject *)v1;
2116  if (BaseMath_ReadCallback(vec1) == -1) {
2117  return NULL;
2118  }
2119  }
2120  if (VectorObject_Check(v2)) {
2121  vec2 = (VectorObject *)v2;
2122  if (BaseMath_ReadCallback(vec2) == -1) {
2123  return NULL;
2124  }
2125  }
2126 
2127  /* Intentionally don't support (Quaternion) here, uses reverse order instead. */
2128 
2129  /* make sure v1 is always the vector */
2130  if (vec1 && vec2) {
2131  if (vec1->vec_num != vec2->vec_num) {
2132  PyErr_SetString(PyExc_ValueError,
2133  "Vector multiplication: "
2134  "vectors must have the same dimensions for this operation");
2135  return NULL;
2136  }
2137 
2138  /* element-wise product */
2139  return vector_mul_vec(vec1, vec2);
2140  }
2141  if (vec1) {
2142  if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */
2143  return vector_mul_float(vec1, scalar);
2144  }
2145  }
2146  else if (vec2) {
2147  if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * VEC */
2148  return vector_mul_float(vec2, scalar);
2149  }
2150  }
2151 
2152  PyErr_Format(PyExc_TypeError,
2153  "Element-wise multiplication: "
2154  "not supported between '%.200s' and '%.200s' types",
2155  Py_TYPE(v1)->tp_name,
2156  Py_TYPE(v2)->tp_name);
2157  return NULL;
2158 }
2159 
2161 static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
2162 {
2163  VectorObject *vec1 = NULL, *vec2 = NULL;
2164  float scalar;
2165 
2166  if (VectorObject_Check(v1)) {
2167  vec1 = (VectorObject *)v1;
2168  if (BaseMath_ReadCallback(vec1) == -1) {
2169  return NULL;
2170  }
2171  }
2172  if (VectorObject_Check(v2)) {
2173  vec2 = (VectorObject *)v2;
2174  if (BaseMath_ReadCallback(vec2) == -1) {
2175  return NULL;
2176  }
2177  }
2178 
2179  if (BaseMath_ReadCallback_ForWrite(vec1) == -1) {
2180  return NULL;
2181  }
2182 
2183  /* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */
2184 
2185  if (vec1 && vec2) {
2186  if (vec1->vec_num != vec2->vec_num) {
2187  PyErr_SetString(PyExc_ValueError,
2188  "Vector multiplication: "
2189  "vectors must have the same dimensions for this operation");
2190  return NULL;
2191  }
2192 
2193  /* Element-wise product in-place. */
2194  mul_vn_vn(vec1->vec, vec2->vec, vec1->vec_num);
2195  }
2196  else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) ==
2197  0)) { /* VEC *= FLOAT */
2198  mul_vn_fl(vec1->vec, vec1->vec_num, scalar);
2199  }
2200  else {
2201  PyErr_Format(PyExc_TypeError,
2202  "In place element-wise multiplication: "
2203  "not supported between '%.200s' and '%.200s' types",
2204  Py_TYPE(v1)->tp_name,
2205  Py_TYPE(v2)->tp_name);
2206  return NULL;
2207  }
2208 
2210  Py_INCREF(v1);
2211  return v1;
2212 }
2213 
2215 static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
2216 {
2217  VectorObject *vec1 = NULL, *vec2 = NULL;
2218  int vec_num;
2219 
2220  if (VectorObject_Check(v1)) {
2221  vec1 = (VectorObject *)v1;
2222  if (BaseMath_ReadCallback(vec1) == -1) {
2223  return NULL;
2224  }
2225  }
2226  if (VectorObject_Check(v2)) {
2227  vec2 = (VectorObject *)v2;
2228  if (BaseMath_ReadCallback(vec2) == -1) {
2229  return NULL;
2230  }
2231  }
2232 
2233  /* Intentionally don't support (Quaternion) here, uses reverse order instead. */
2234 
2235  /* make sure v1 is always the vector */
2236  if (vec1 && vec2) {
2237  if (vec1->vec_num != vec2->vec_num) {
2238  PyErr_SetString(PyExc_ValueError,
2239  "Vector multiplication: "
2240  "vectors must have the same dimensions for this operation");
2241  return NULL;
2242  }
2243 
2244  /* Dot product. */
2245  return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->vec_num));
2246  }
2247  if (vec1) {
2248  if (MatrixObject_Check(v2)) {
2249  /* VEC @ MATRIX */
2250  float tvec[MAX_DIMENSIONS];
2251 
2252  if (BaseMath_ReadCallback((MatrixObject *)v2) == -1) {
2253  return NULL;
2254  }
2255  if (row_vector_multiplication(tvec, vec1, (MatrixObject *)v2) == -1) {
2256  return NULL;
2257  }
2258 
2259  if (((MatrixObject *)v2)->row_num == 4 && vec1->vec_num == 3) {
2260  vec_num = 3;
2261  }
2262  else {
2263  vec_num = ((MatrixObject *)v2)->col_num;
2264  }
2265 
2266  return Vector_CreatePyObject(tvec, vec_num, Py_TYPE(vec1));
2267  }
2268  }
2269 
2270  PyErr_Format(PyExc_TypeError,
2271  "Vector multiplication: "
2272  "not supported between '%.200s' and '%.200s' types",
2273  Py_TYPE(v1)->tp_name,
2274  Py_TYPE(v2)->tp_name);
2275  return NULL;
2276 }
2277 
2279 static PyObject *Vector_imatmul(PyObject *v1, PyObject *v2)
2280 {
2281  PyErr_Format(PyExc_TypeError,
2282  "In place vector multiplication: "
2283  "not supported between '%.200s' and '%.200s' types",
2284  Py_TYPE(v1)->tp_name,
2285  Py_TYPE(v2)->tp_name);
2286  return NULL;
2287 }
2288 
2290 static PyObject *Vector_div(PyObject *v1, PyObject *v2)
2291 {
2292  float *vec = NULL, scalar;
2293  VectorObject *vec1 = NULL;
2294 
2295  if (!VectorObject_Check(v1)) { /* not a vector */
2296  PyErr_SetString(PyExc_TypeError,
2297  "Vector division: "
2298  "Vector must be divided by a float");
2299  return NULL;
2300  }
2301  vec1 = (VectorObject *)v1; /* vector */
2302 
2303  if (BaseMath_ReadCallback(vec1) == -1) {
2304  return NULL;
2305  }
2306 
2307  if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) {
2308  /* parsed item not a number */
2309  PyErr_SetString(PyExc_TypeError,
2310  "Vector division: "
2311  "Vector must be divided by a float");
2312  return NULL;
2313  }
2314 
2315  if (scalar == 0.0f) {
2316  PyErr_SetString(PyExc_ZeroDivisionError,
2317  "Vector division: "
2318  "divide by zero error");
2319  return NULL;
2320  }
2321 
2322  vec = PyMem_Malloc(vec1->vec_num * sizeof(float));
2323 
2324  if (vec == NULL) {
2325  PyErr_SetString(PyExc_MemoryError,
2326  "vec / value: "
2327  "problem allocating pointer space");
2328  return NULL;
2329  }
2330 
2331  mul_vn_vn_fl(vec, vec1->vec, vec1->vec_num, 1.0f / scalar);
2332 
2333  return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1));
2334 }
2335 
2337 static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
2338 {
2339  float scalar;
2340  VectorObject *vec1 = (VectorObject *)v1;
2341 
2342  if (BaseMath_ReadCallback_ForWrite(vec1) == -1) {
2343  return NULL;
2344  }
2345 
2346  if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) {
2347  /* parsed item not a number */
2348  PyErr_SetString(PyExc_TypeError,
2349  "Vector division: "
2350  "Vector must be divided by a float");
2351  return NULL;
2352  }
2353 
2354  if (scalar == 0.0f) {
2355  PyErr_SetString(PyExc_ZeroDivisionError,
2356  "Vector division: "
2357  "divide by zero error");
2358  return NULL;
2359  }
2360 
2361  mul_vn_fl(vec1->vec, vec1->vec_num, 1.0f / scalar);
2362 
2364 
2365  Py_INCREF(v1);
2366  return v1;
2367 }
2368 
2370 static PyObject *Vector_neg(VectorObject *self)
2371 {
2372  float *tvec;
2373 
2374  if (BaseMath_ReadCallback(self) == -1) {
2375  return NULL;
2376  }
2377 
2378  tvec = PyMem_Malloc(self->vec_num * sizeof(float));
2379  negate_vn_vn(tvec, self->vec, self->vec_num);
2380  return Vector_CreatePyObject_alloc(tvec, self->vec_num, Py_TYPE(self));
2381 }
2382 
2385 /* -------------------------------------------------------------------- */
2389 static PySequenceMethods Vector_SeqMethods = {
2390  (lenfunc)Vector_len, /*sq_length*/
2391  (binaryfunc)NULL, /*sq_concat*/
2392  (ssizeargfunc)NULL, /*sq_repeat*/
2393  (ssizeargfunc)Vector_item, /*sq_item*/
2394  NULL, /*sq_slice(DEPRECATED)*/
2395  (ssizeobjargproc)Vector_ass_item, /*sq_ass_item*/
2396  NULL, /*sq_ass_slice(DEPRECATED)*/
2397  (objobjproc)NULL, /*sq_contains*/
2398  (binaryfunc)NULL, /*sq_inplace_concat */
2399  (ssizeargfunc)NULL, /*sq_inplace_repeat */
2400 };
2401 
2402 static PyMappingMethods Vector_AsMapping = {
2403  (lenfunc)Vector_len,
2404  (binaryfunc)Vector_subscript,
2405  (objobjargproc)Vector_ass_subscript,
2406 };
2407 
2408 static PyNumberMethods Vector_NumMethods = {
2409  (binaryfunc)Vector_add, /*nb_add*/
2410  (binaryfunc)Vector_sub, /*nb_subtract*/
2411  (binaryfunc)Vector_mul, /*nb_multiply*/
2412  NULL, /*nb_remainder*/
2413  NULL, /*nb_divmod*/
2414  NULL, /*nb_power*/
2415  (unaryfunc)Vector_neg, /*nb_negative*/
2416  (unaryfunc)Vector_copy, /*tp_positive*/
2417  (unaryfunc)NULL, /*tp_absolute*/
2418  (inquiry)NULL, /*tp_bool*/
2419  (unaryfunc)NULL, /*nb_invert*/
2420  NULL, /*nb_lshift*/
2421  (binaryfunc)NULL, /*nb_rshift*/
2422  NULL, /*nb_and*/
2423  NULL, /*nb_xor*/
2424  NULL, /*nb_or*/
2425  NULL, /*nb_int*/
2426  NULL, /*nb_reserved*/
2427  NULL, /*nb_float*/
2428  Vector_iadd, /*nb_inplace_add*/
2429  Vector_isub, /*nb_inplace_subtract*/
2430  Vector_imul, /*nb_inplace_multiply*/
2431  NULL, /*nb_inplace_remainder*/
2432  NULL, /*nb_inplace_power*/
2433  NULL, /*nb_inplace_lshift*/
2434  NULL, /*nb_inplace_rshift*/
2435  NULL, /*nb_inplace_and*/
2436  NULL, /*nb_inplace_xor*/
2437  NULL, /*nb_inplace_or*/
2438  NULL, /*nb_floor_divide*/
2439  Vector_div, /*nb_true_divide*/
2440  NULL, /*nb_inplace_floor_divide*/
2441  Vector_idiv, /*nb_inplace_true_divide*/
2442  NULL, /*nb_index*/
2443  (binaryfunc)Vector_matmul, /*nb_matrix_multiply*/
2444  (binaryfunc)Vector_imatmul, /*nb_inplace_matrix_multiply*/
2445 };
2446 
2449 /* -------------------------------------------------------------------- */
2453 /* Vector axis: `vector.x/y/z/w`. */
2454 
2455 PyDoc_STRVAR(Vector_axis_x_doc, "Vector X axis.\n\n:type: float");
2456 PyDoc_STRVAR(Vector_axis_y_doc, "Vector Y axis.\n\n:type: float");
2457 PyDoc_STRVAR(Vector_axis_z_doc, "Vector Z axis (3D Vectors only).\n\n:type: float");
2458 PyDoc_STRVAR(Vector_axis_w_doc, "Vector W axis (4D Vectors only).\n\n:type: float");
2459 
2460 static PyObject *Vector_axis_get(VectorObject *self, void *type)
2461 {
2462  return vector_item_internal(self, POINTER_AS_INT(type), true);
2463 }
2464 
2465 static int Vector_axis_set(VectorObject *self, PyObject *value, void *type)
2466 {
2467  return vector_ass_item_internal(self, POINTER_AS_INT(type), value, true);
2468 }
2469 
2470 /* `Vector.length`. */
2471 
2472 PyDoc_STRVAR(Vector_length_doc, "Vector Length.\n\n:type: float");
2473 static PyObject *Vector_length_get(VectorObject *self, void *UNUSED(closure))
2474 {
2475  if (BaseMath_ReadCallback(self) == -1) {
2476  return NULL;
2477  }
2478 
2479  return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->vec_num)));
2480 }
2481 
2482 static int Vector_length_set(VectorObject *self, PyObject *value)
2483 {
2484  double dot = 0.0f, param;
2485 
2486  if (BaseMath_ReadCallback_ForWrite(self) == -1) {
2487  return -1;
2488  }
2489 
2490  if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
2491  PyErr_SetString(PyExc_TypeError, "length must be set to a number");
2492  return -1;
2493  }
2494 
2495  if (param < 0.0) {
2496  PyErr_SetString(PyExc_ValueError, "cannot set a vectors length to a negative value");
2497  return -1;
2498  }
2499  if (param == 0.0) {
2500  copy_vn_fl(self->vec, self->vec_num, 0.0f);
2501  return 0;
2502  }
2503 
2504  dot = dot_vn_vn(self->vec, self->vec, self->vec_num);
2505 
2506  if (!dot) {
2507  /* can't sqrt zero */
2508  return 0;
2509  }
2510 
2511  dot = sqrt(dot);
2512 
2513  if (dot == param) {
2514  return 0;
2515  }
2516 
2517  dot = dot / param;
2518 
2519  mul_vn_fl(self->vec, self->vec_num, 1.0 / dot);
2520 
2521  (void)BaseMath_WriteCallback(self); /* checked already */
2522 
2523  return 0;
2524 }
2525 
2526 /* `Vector.length_squared`. */
2527 PyDoc_STRVAR(Vector_length_squared_doc, "Vector length squared (v.dot(v)).\n\n:type: float");
2528 static PyObject *Vector_length_squared_get(VectorObject *self, void *UNUSED(closure))
2529 {
2530  if (BaseMath_ReadCallback(self) == -1) {
2531  return NULL;
2532  }
2533 
2534  return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->vec_num));
2535 }
2536 
2598 static PyObject *Vector_swizzle_get(VectorObject *self, void *closure)
2599 {
2600  size_t axis_to;
2601  size_t axis_from;
2602  float vec[MAX_DIMENSIONS];
2603  uint swizzleClosure;
2604 
2605  if (BaseMath_ReadCallback(self) == -1) {
2606  return NULL;
2607  }
2608 
2609  /* Unpack the axes from the closure into an array. */
2610  axis_to = 0;
2611  swizzleClosure = POINTER_AS_INT(closure);
2612  while (swizzleClosure & SWIZZLE_VALID_AXIS) {
2613  axis_from = swizzleClosure & SWIZZLE_AXIS;
2614  if (axis_from >= self->vec_num) {
2615  PyErr_SetString(PyExc_AttributeError,
2616  "Vector swizzle: "
2617  "specified axis not present");
2618  return NULL;
2619  }
2620 
2621  vec[axis_to] = self->vec[axis_from];
2622  swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
2623  axis_to++;
2624  }
2625 
2626  return Vector_CreatePyObject(vec, axis_to, Py_TYPE(self));
2627 }
2628 
2640 static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure)
2641 {
2642  size_t size_from;
2643  float scalarVal;
2644 
2645  size_t axis_from;
2646  size_t axis_to;
2647 
2648  uint swizzleClosure;
2649 
2650  float tvec[MAX_DIMENSIONS];
2651  float vec_assign[MAX_DIMENSIONS];
2652 
2653  if (BaseMath_ReadCallback_ForWrite(self) == -1) {
2654  return -1;
2655  }
2656 
2657  /* Check that the closure can be used with this vector: even 2D vectors have
2658  * swizzles defined for axes z and w, but they would be invalid. */
2659  swizzleClosure = POINTER_AS_INT(closure);
2660  axis_from = 0;
2661 
2662  while (swizzleClosure & SWIZZLE_VALID_AXIS) {
2663  axis_to = swizzleClosure & SWIZZLE_AXIS;
2664  if (axis_to >= self->vec_num) {
2665  PyErr_SetString(PyExc_AttributeError,
2666  "Vector swizzle: "
2667  "specified axis not present");
2668  return -1;
2669  }
2670  swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
2671  axis_from++;
2672  }
2673 
2674  if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) {
2675  int i;
2676 
2677  for (i = 0; i < MAX_DIMENSIONS; i++) {
2678  vec_assign[i] = scalarVal;
2679  }
2680 
2681  size_from = axis_from;
2682  }
2683  else if (((void)PyErr_Clear()), /* run but ignore the result */
2684  (size_from = mathutils_array_parse(
2685  vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) {
2686  return -1;
2687  }
2688 
2689  if (axis_from != size_from) {
2690  PyErr_SetString(PyExc_AttributeError, "Vector swizzle: size does not match swizzle");
2691  return -1;
2692  }
2693 
2694  /* Copy vector contents onto swizzled axes. */
2695  axis_from = 0;
2696  swizzleClosure = POINTER_AS_INT(closure);
2697 
2698  /* We must first copy current vec into tvec, else some org values may be lost.
2699  * See T31760.
2700  * Assuming self->vec_num can't be higher than MAX_DIMENSIONS! */
2701  memcpy(tvec, self->vec, self->vec_num * sizeof(float));
2702 
2703  while (swizzleClosure & SWIZZLE_VALID_AXIS) {
2704  axis_to = swizzleClosure & SWIZZLE_AXIS;
2705  tvec[axis_to] = vec_assign[axis_from];
2706  swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
2707  axis_from++;
2708  }
2709 
2710  /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...).
2711  * See T31760. */
2712  memcpy(self->vec, tvec, self->vec_num * sizeof(float));
2713  /* continue with BaseMathObject_WriteCallback at the end */
2714 
2715  if (BaseMath_WriteCallback(self) == -1) {
2716  return -1;
2717  }
2718 
2719  return 0;
2720 }
2721 
2722 #define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
2723 #define _SWIZZLE2(a, b) (_SWIZZLE1(a) | (((b) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS)))
2724 #define _SWIZZLE3(a, b, c) \
2725  (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
2726 #define _SWIZZLE4(a, b, c, d) \
2727  (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
2728 
2729 #define SWIZZLE2(a, b) POINTER_FROM_INT(_SWIZZLE2(a, b))
2730 #define SWIZZLE3(a, b, c) POINTER_FROM_INT(_SWIZZLE3(a, b, c))
2731 #define SWIZZLE4(a, b, c, d) POINTER_FROM_INT(_SWIZZLE4(a, b, c, d))
2732 
2735 /* -------------------------------------------------------------------- */
2739 static PyGetSetDef Vector_getseters[] = {
2740  {"x", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_x_doc, (void *)0},
2741  {"y", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_y_doc, (void *)1},
2742  {"z", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_z_doc, (void *)2},
2743  {"w", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_w_doc, (void *)3},
2744  {"length", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL},
2745  {"length_squared",
2746  (getter)Vector_length_squared_get,
2747  (setter)NULL,
2748  Vector_length_squared_doc,
2749  NULL},
2750  {"magnitude", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL},
2751  {"is_wrapped",
2753  (setter)NULL,
2755  NULL},
2756  {"is_frozen",
2758  (setter)NULL,
2760  NULL},
2761  {"is_valid",
2763  (setter)NULL,
2765  NULL},
2766  {"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
2767 
2768  /* Auto-generated swizzle attributes, see Python script above. */
2769  {"xx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(0, 0)},
2770  {"xxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 0)},
2771  {"xxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 0)},
2772  {"xxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 1)},
2773  {"xxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 2)},
2774  {"xxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 3)},
2775  {"xxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 1)},
2776  {"xxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 0)},
2777  {"xxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 1)},
2778  {"xxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 2)},
2779  {"xxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 3)},
2780  {"xxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 2)},
2781  {"xxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 0)},
2782  {"xxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 1)},
2783  {"xxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 2)},
2784  {"xxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 3)},
2785  {"xxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 3)},
2786  {"xxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 0)},
2787  {"xxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 1)},
2788  {"xxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 2)},
2789  {"xxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 3)},
2790  {"xy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 1)},
2791  {"xyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 1, 0)},
2792  {"xyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 0)},
2793  {"xyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 1)},
2794  {"xyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 2)},
2795  {"xyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 3)},
2796  {"xyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 1, 1)},
2797  {"xyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 0)},
2798  {"xyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 1)},
2799  {"xyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 2)},
2800  {"xyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 3)},
2801  {"xyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 1, 2)},
2802  {"xyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 0)},
2803  {"xyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 1)},
2804  {"xyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 2)},
2805  {"xyzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 1, 2, 3)},
2806  {"xyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 1, 3)},
2807  {"xywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 0)},
2808  {"xywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 1)},
2809  {"xywz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 1, 3, 2)},
2810  {"xyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 3)},
2811  {"xz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 2)},
2812  {"xzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 2, 0)},
2813  {"xzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 0)},
2814  {"xzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 1)},
2815  {"xzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 2)},
2816  {"xzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 3)},
2817  {"xzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 2, 1)},
2818  {"xzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 0)},
2819  {"xzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 1)},
2820  {"xzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 2)},
2821  {"xzyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 2, 1, 3)},
2822  {"xzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 2, 2)},
2823  {"xzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 0)},
2824  {"xzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 1)},
2825  {"xzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 2)},
2826  {"xzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 3)},
2827  {"xzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 2, 3)},
2828  {"xzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 0)},
2829  {"xzwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 2, 3, 1)},
2830  {"xzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 2)},
2831  {"xzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 3)},
2832  {"xw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 3)},
2833  {"xwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 3, 0)},
2834  {"xwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 0)},
2835  {"xwxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 1)},
2836  {"xwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 2)},
2837  {"xwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 3)},
2838  {"xwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 3, 1)},
2839  {"xwyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 0)},
2840  {"xwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 1)},
2841  {"xwyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 3, 1, 2)},
2842  {"xwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 3)},
2843  {"xwz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 3, 2)},
2844  {"xwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 0)},
2845  {"xwzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 3, 2, 1)},
2846  {"xwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 2)},
2847  {"xwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 3)},
2848  {"xww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 3, 3)},
2849  {"xwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 0)},
2850  {"xwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 1)},
2851  {"xwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 2)},
2852  {"xwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 3)},
2853  {"yx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 0)},
2854  {"yxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 0, 0)},
2855  {"yxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 0)},
2856  {"yxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 1)},
2857  {"yxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 2)},
2858  {"yxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 3)},
2859  {"yxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 0, 1)},
2860  {"yxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 0)},
2861  {"yxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 1)},
2862  {"yxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 2)},
2863  {"yxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 3)},
2864  {"yxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 0, 2)},
2865  {"yxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 0)},
2866  {"yxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 1)},
2867  {"yxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 2)},
2868  {"yxzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 0, 2, 3)},
2869  {"yxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 0, 3)},
2870  {"yxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 0)},
2871  {"yxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 1)},
2872  {"yxwz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 0, 3, 2)},
2873  {"yxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 3)},
2874  {"yy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(1, 1)},
2875  {"yyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 0)},
2876  {"yyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 0)},
2877  {"yyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 1)},
2878  {"yyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 2)},
2879  {"yyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 3)},
2880  {"yyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 1)},
2881  {"yyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 0)},
2882  {"yyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 1)},
2883  {"yyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 2)},
2884  {"yyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 3)},
2885  {"yyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 2)},
2886  {"yyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 0)},
2887  {"yyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 1)},
2888  {"yyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 2)},
2889  {"yyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 3)},
2890  {"yyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 3)},
2891  {"yywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 0)},
2892  {"yywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 1)},
2893  {"yywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 2)},
2894  {"yyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 3)},
2895  {"yz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 2)},
2896  {"yzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 2, 0)},
2897  {"yzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 0)},
2898  {"yzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 1)},
2899  {"yzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 2)},
2900  {"yzxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 2, 0, 3)},
2901  {"yzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 2, 1)},
2902  {"yzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 0)},
2903  {"yzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 1)},
2904  {"yzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 2)},
2905  {"yzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 3)},
2906  {"yzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 2, 2)},
2907  {"yzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 0)},
2908  {"yzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 1)},
2909  {"yzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 2)},
2910  {"yzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 3)},
2911  {"yzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 2, 3)},
2912  {"yzwx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 2, 3, 0)},
2913  {"yzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 1)},
2914  {"yzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 2)},
2915  {"yzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 3)},
2916  {"yw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 3)},
2917  {"ywx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 3, 0)},
2918  {"ywxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 0)},
2919  {"ywxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 1)},
2920  {"ywxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 3, 0, 2)},
2921  {"ywxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 3)},
2922  {"ywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 3, 1)},
2923  {"ywyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 0)},
2924  {"ywyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 1)},
2925  {"ywyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 2)},
2926  {"ywyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 3)},
2927  {"ywz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 3, 2)},
2928  {"ywzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 3, 2, 0)},
2929  {"ywzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 1)},
2930  {"ywzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 2)},
2931  {"ywzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 3)},
2932  {"yww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 3, 3)},
2933  {"ywwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 0)},
2934  {"ywwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 1)},
2935  {"ywwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 2)},
2936  {"ywww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 3)},
2937  {"zx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 0)},
2938  {"zxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 0, 0)},
2939  {"zxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 0)},
2940  {"zxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 1)},
2941  {"zxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 2)},
2942  {"zxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 3)},
2943  {"zxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 0, 1)},
2944  {"zxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 0)},
2945  {"zxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 1)},
2946  {"zxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 2)},
2947  {"zxyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 0, 1, 3)},
2948  {"zxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 0, 2)},
2949  {"zxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 0)},
2950  {"zxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 1)},
2951  {"zxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 2)},
2952  {"zxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 3)},
2953  {"zxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 0, 3)},
2954  {"zxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 0)},
2955  {"zxwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 0, 3, 1)},
2956  {"zxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 2)},
2957  {"zxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 3)},
2958  {"zy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 1)},
2959  {"zyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 1, 0)},
2960  {"zyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 0)},
2961  {"zyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 1)},
2962  {"zyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 2)},
2963  {"zyxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 1, 0, 3)},
2964  {"zyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 1, 1)},
2965  {"zyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 0)},
2966  {"zyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 1)},
2967  {"zyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 2)},
2968  {"zyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 3)},
2969  {"zyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 1, 2)},
2970  {"zyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 0)},
2971  {"zyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 1)},
2972  {"zyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 2)},
2973  {"zyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 3)},
2974  {"zyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 1, 3)},
2975  {"zywx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 1, 3, 0)},
2976  {"zywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 1)},
2977  {"zywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 2)},
2978  {"zyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 3)},
2979  {"zz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(2, 2)},
2980  {"zzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 0)},
2981  {"zzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 0)},
2982  {"zzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 1)},
2983  {"zzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 2)},
2984  {"zzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 3)},
2985  {"zzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 1)},
2986  {"zzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 0)},
2987  {"zzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 1)},
2988  {"zzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 2)},
2989  {"zzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 3)},
2990  {"zzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 2)},
2991  {"zzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 0)},
2992  {"zzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 1)},
2993  {"zzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 2)},
2994  {"zzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 3)},
2995  {"zzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 3)},
2996  {"zzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 0)},
2997  {"zzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 1)},
2998  {"zzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 2)},
2999  {"zzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 3)},
3000  {"zw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 3)},
3001  {"zwx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 3, 0)},
3002  {"zwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 0)},
3003  {"zwxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 3, 0, 1)},
3004  {"zwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 2)},
3005  {"zwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 3)},
3006  {"zwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 3, 1)},
3007  {"zwyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 3, 1, 0)},
3008  {"zwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 1)},
3009  {"zwyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 2)},
3010  {"zwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 3)},
3011  {"zwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 3, 2)},
3012  {"zwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 0)},
3013  {"zwzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 1)},
3014  {"zwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 2)},
3015  {"zwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 3)},
3016  {"zww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 3, 3)},
3017  {"zwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 0)},
3018  {"zwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 1)},
3019  {"zwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 2)},
3020  {"zwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 3)},
3021  {"wx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 0)},
3022  {"wxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 0, 0)},
3023  {"wxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 0)},
3024  {"wxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 1)},
3025  {"wxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 2)},
3026  {"wxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 3)},
3027  {"wxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 0, 1)},
3028  {"wxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 0)},
3029  {"wxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 1)},
3030  {"wxyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 0, 1, 2)},
3031  {"wxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 3)},
3032  {"wxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 0, 2)},
3033  {"wxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 0)},
3034  {"wxzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 0, 2, 1)},
3035  {"wxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 2)},
3036  {"wxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 3)},
3037  {"wxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 0, 3)},
3038  {"wxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 0)},
3039  {"wxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 1)},
3040  {"wxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 2)},
3041  {"wxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 3)},
3042  {"wy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 1)},
3043  {"wyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 1, 0)},
3044  {"wyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 0)},
3045  {"wyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 1)},
3046  {"wyxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 1, 0, 2)},
3047  {"wyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 3)},
3048  {"wyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 1, 1)},
3049  {"wyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 0)},
3050  {"wyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 1)},
3051  {"wyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 2)},
3052  {"wyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 3)},
3053  {"wyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 1, 2)},
3054  {"wyzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 1, 2, 0)},
3055  {"wyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 1)},
3056  {"wyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 2)},
3057  {"wyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 3)},
3058  {"wyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 1, 3)},
3059  {"wywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 0)},
3060  {"wywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 1)},
3061  {"wywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 2)},
3062  {"wyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 3)},
3063  {"wz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 2)},
3064  {"wzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 2, 0)},
3065  {"wzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 0)},
3066  {"wzxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 2, 0, 1)},
3067  {"wzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 2)},
3068  {"wzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 3)},
3069  {"wzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 2, 1)},
3070  {"wzyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 2, 1, 0)},
3071  {"wzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 1)},
3072  {"wzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 2)},
3073  {"wzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 3)},
3074  {"wzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 2, 2)},
3075  {"wzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 0)},
3076  {"wzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 1)},
3077  {"wzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 2)},
3078  {"wzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 3)},
3079  {"wzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 2, 3)},
3080  {"wzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 0)},
3081  {"wzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 1)},
3082  {"wzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 2)},
3083  {"wzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 3)},
3084  {"ww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(3, 3)},
3085  {"wwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 0)},
3086  {"wwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 0)},
3087  {"wwxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 1)},
3088  {"wwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 2)},
3089  {"wwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 3)},
3090  {"wwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 1)},
3091  {"wwyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 0)},
3092  {"wwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 1)},
3093  {"wwyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 2)},
3094  {"wwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 3)},
3095  {"wwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 2)},
3096  {"wwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 0)},
3097  {"wwzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 1)},
3098  {"wwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 2)},
3099  {"wwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 3)},
3100  {"www", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 3)},
3101  {"wwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 0)},
3102  {"wwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 1)},
3103  {"wwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 2)},
3104  {"wwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 3)},
3105 
3106 #undef AXIS_FROM_CHAR
3107 #undef SWIZZLE1
3108 #undef SWIZZLE2
3109 #undef SWIZZLE3
3110 #undef SWIZZLE4
3111 #undef _SWIZZLE1
3112 #undef _SWIZZLE2
3113 #undef _SWIZZLE3
3114 #undef _SWIZZLE4
3115 
3116  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
3117 };
3118 
3121 /* -------------------------------------------------------------------- */
3125 static struct PyMethodDef Vector_methods[] = {
3126  /* Class Methods */
3127  {"Fill", (PyCFunction)C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
3128  {"Range", (PyCFunction)C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
3129  {"Linspace", (PyCFunction)C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
3130  {"Repeat", (PyCFunction)C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
3131 
3132  /* In place only. */
3133  {"zero", (PyCFunction)Vector_zero, METH_NOARGS, Vector_zero_doc},
3134  {"negate", (PyCFunction)Vector_negate, METH_NOARGS, Vector_negate_doc},
3135 
3136  /* Operate on original or copy. */
3137  {"normalize", (PyCFunction)Vector_normalize, METH_NOARGS, Vector_normalize_doc},
3138  {"normalized", (PyCFunction)Vector_normalized, METH_NOARGS, Vector_normalized_doc},
3139 
3140  {"resize", (PyCFunction)Vector_resize, METH_O, Vector_resize_doc},
3141  {"resized", (PyCFunction)Vector_resized, METH_O, Vector_resized_doc},
3142  {"to_2d", (PyCFunction)Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
3143  {"resize_2d", (PyCFunction)Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
3144  {"to_3d", (PyCFunction)Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
3145  {"resize_3d", (PyCFunction)Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc},
3146  {"to_4d", (PyCFunction)Vector_to_4d, METH_NOARGS, Vector_to_4d_doc},
3147  {"resize_4d", (PyCFunction)Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
3148  {"to_tuple", (PyCFunction)Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
3149  {"to_track_quat", (PyCFunction)Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc},
3150  {"orthogonal", (PyCFunction)Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
3151 
3152  /* Operation between 2 or more types. */
3153  {"reflect", (PyCFunction)Vector_reflect, METH_O, Vector_reflect_doc},
3154  {"cross", (PyCFunction)Vector_cross, METH_O, Vector_cross_doc},
3155  {"dot", (PyCFunction)Vector_dot, METH_O, Vector_dot_doc},
3156  {"angle", (PyCFunction)Vector_angle, METH_VARARGS, Vector_angle_doc},
3157  {"angle_signed", (PyCFunction)Vector_angle_signed, METH_VARARGS, Vector_angle_signed_doc},
3158  {"rotation_difference",
3159  (PyCFunction)Vector_rotation_difference,
3160  METH_O,
3161  Vector_rotation_difference_doc},
3162  {"project", (PyCFunction)Vector_project, METH_O, Vector_project_doc},
3163  {"lerp", (PyCFunction)Vector_lerp, METH_VARARGS, Vector_lerp_doc},
3164  {"slerp", (PyCFunction)Vector_slerp, METH_VARARGS, Vector_slerp_doc},
3165  {"rotate", (PyCFunction)Vector_rotate, METH_O, Vector_rotate_doc},
3166 
3167  /* Base-math methods. */
3168  {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
3169 
3170  {"copy", (PyCFunction)Vector_copy, METH_NOARGS, Vector_copy_doc},
3171  {"__copy__", (PyCFunction)Vector_copy, METH_NOARGS, NULL},
3172  {"__deepcopy__", (PyCFunction)Vector_deepcopy, METH_VARARGS, NULL},
3173  {NULL, NULL, 0, NULL},
3174 };
3175 
3178 /* -------------------------------------------------------------------- */
3186 PyDoc_STRVAR(vector_doc,
3187  ".. class:: Vector(seq)\n"
3188  "\n"
3189  " This object gives access to Vectors in Blender.\n"
3190  "\n"
3191  " :param seq: Components of the vector, must be a sequence of at least two\n"
3192  " :type seq: sequence of numbers\n");
3193 PyTypeObject vector_Type = {
3194  PyVarObject_HEAD_INIT(NULL, 0)
3195  /* For printing, in format "<module>.<name>" */
3196  "Vector", /* char *tp_name; */
3197  sizeof(VectorObject), /* int tp_basicsize; */
3198  0, /* tp_itemsize; For allocation */
3199 
3200  /* Methods to implement standard operations */
3201 
3202  (destructor)BaseMathObject_dealloc, /* destructor tp_dealloc; */
3203  0, /* tp_vectorcall_offset */
3204  NULL, /* getattrfunc tp_getattr; */
3205  NULL, /* setattrfunc tp_setattr; */
3206  NULL, /* cmpfunc tp_compare; */
3207  (reprfunc)Vector_repr, /* reprfunc tp_repr; */
3208 
3209  /* Method suites for standard classes */
3210 
3211  &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */
3212  &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */
3213  &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */
3214 
3215  /* More standard operations (here for binary compatibility) */
3216 
3217  (hashfunc)Vector_hash, /* hashfunc tp_hash; */
3218  NULL, /* ternaryfunc tp_call; */
3219 #ifndef MATH_STANDALONE
3220  (reprfunc)Vector_str, /* reprfunc tp_str; */
3221 #else
3222  NULL, /* reprfunc tp_str; */
3223 #endif
3224  NULL, /* getattrofunc tp_getattro; */
3225  NULL, /* setattrofunc tp_setattro; */
3226 
3227  /* Functions to access object as input/output buffer */
3228  NULL, /* PyBufferProcs *tp_as_buffer; */
3229 
3230  /*** Flags to define presence of optional/expanded features ***/
3231  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3232  vector_doc, /* char *tp_doc; Documentation string */
3233  /*** Assigned meaning in release 2.0 ***/
3234 
3235  /* call function for all accessible objects */
3236  (traverseproc)BaseMathObject_traverse, /* tp_traverse */
3237 
3238  /* delete references to contained objects */
3239  (inquiry)BaseMathObject_clear, /* tp_clear */
3240 
3241  /*** Assigned meaning in release 2.1 ***/
3242  /*** rich comparisons ***/
3243  (richcmpfunc)Vector_richcmpr, /* richcmpfunc tp_richcompare; */
3244 
3245  /*** weak reference enabler ***/
3246  0, /* long tp_weaklistoffset; */
3247 
3248  /*** Added in release 2.2 ***/
3249  /* Iterators */
3250  NULL, /* getiterfunc tp_iter; */
3251  NULL, /* iternextfunc tp_iternext; */
3252 
3253  /*** Attribute descriptor and subclassing stuff ***/
3254  Vector_methods, /* struct PyMethodDef *tp_methods; */
3255  NULL, /* struct PyMemberDef *tp_members; */
3256  Vector_getseters, /* struct PyGetSetDef *tp_getset; */
3257  NULL, /* struct _typeobject *tp_base; */
3258  NULL, /* PyObject *tp_dict; */
3259  NULL, /* descrgetfunc tp_descr_get; */
3260  NULL, /* descrsetfunc tp_descr_set; */
3261  0, /* long tp_dictoffset; */
3262  NULL, /* initproc tp_init; */
3263  NULL, /* allocfunc tp_alloc; */
3264  Vector_new, /* newfunc tp_new; */
3265  /* Low-level free-memory routine */
3266  NULL, /* freefunc tp_free; */
3267  /* For PyObject_IS_GC */
3268  NULL, /* inquiry tp_is_gc; */
3269  NULL, /* PyObject *tp_bases; */
3270  /* method resolution order */
3271  NULL, /* PyObject *tp_mro; */
3272  NULL, /* PyObject *tp_cache; */
3273  NULL, /* PyObject *tp_subclasses; */
3274  NULL, /* PyObject *tp_weaklist; */
3275  NULL,
3276 };
3277 
3280 /* -------------------------------------------------------------------- */
3284 PyObject *Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
3285 {
3286  VectorObject *self;
3287  float *vec_alloc;
3288 
3289  if (vec_num < 2) {
3290  PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
3291  return NULL;
3292  }
3293 
3294  vec_alloc = PyMem_Malloc(vec_num * sizeof(float));
3295  if (UNLIKELY(vec_alloc == NULL)) {
3296  PyErr_SetString(PyExc_MemoryError,
3297  "Vector(): "
3298  "problem allocating data");
3299  return NULL;
3300  }
3301 
3302  self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
3303  if (self) {
3304  self->vec = vec_alloc;
3305  self->vec_num = vec_num;
3306 
3307  /* init callbacks as NULL */
3308  self->cb_user = NULL;
3309  self->cb_type = self->cb_subtype = 0;
3310 
3311  if (vec) {
3312  memcpy(self->vec, vec, vec_num * sizeof(float));
3313  }
3314  else { /* new empty */
3315  copy_vn_fl(self->vec, vec_num, 0.0f);
3316  if (vec_num == 4) { /* do the homogeneous thing */
3317  self->vec[3] = 1.0f;
3318  }
3319  }
3320  self->flag = BASE_MATH_FLAG_DEFAULT;
3321  }
3322  else {
3323  PyMem_Free(vec_alloc);
3324  }
3325 
3326  return (PyObject *)self;
3327 }
3328 
3329 PyObject *Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type)
3330 {
3331  VectorObject *self;
3332 
3333  if (vec_num < 2) {
3334  PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
3335  return NULL;
3336  }
3337 
3338  self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
3339  if (self) {
3340  self->vec_num = vec_num;
3341 
3342  /* init callbacks as NULL */
3343  self->cb_user = NULL;
3344  self->cb_type = self->cb_subtype = 0;
3345 
3346  self->vec = vec;
3348  }
3349  return (PyObject *)self;
3350 }
3351 
3352 PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
3353 {
3355  if (self) {
3356  Py_INCREF(cb_user);
3357  self->cb_user = cb_user;
3358  self->cb_type = cb_type;
3359  self->cb_subtype = cb_subtype;
3360  PyObject_GC_Track(self);
3361  }
3362 
3363  return (PyObject *)self;
3364 }
3365 
3366 PyObject *Vector_CreatePyObject_alloc(float *vec, const int vec_num, PyTypeObject *base_type)
3367 {
3368  VectorObject *self;
3369  self = (VectorObject *)Vector_CreatePyObject_wrap(vec, vec_num, base_type);
3370  if (self) {
3371  self->flag &= ~BASE_MATH_FLAG_IS_WRAP;
3372  }
3373 
3374  return (PyObject *)self;
3375 }
3376 
typedef float(TangentPoint)[2]
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_dynstr.c:50
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()
Definition: BLI_dynstr.c:75
sqrt(x)+1/max(0
MINLINE float saacos(float fac)
double double_round(double x, int ndigits)
Definition: math_base.c:27
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void normalize_m2_m2(float R[2][2], const float M[2][2]) ATTR_NONNULL()
Definition: math_matrix.c:1897
void mul_m2_v2(const float M[2][2], float v[2])
Definition: math_matrix.c:785
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)
Definition: math_vector.c:1112
double len_squared_vn(const float *array, int size) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:990
void mul_vn_fl(float *array_tar, int size, float f)
Definition: math_vector.c:1093
void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3])
Definition: math_vector.c:691
float normalize_vn(float *array_tar, int size)
Definition: math_vector.c:1016
void negate_vn(float *array_tar, int size)
Definition: math_vector.c:1050
MINLINE float normalize_v3(float r[3])
void range_vn_fl(float *array_tar, int size, float start, float step)
Definition: math_vector.c:1041
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
Definition: math_vector.c:1171
void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
Definition: math_vector.c:1122
MINLINE void negate_v3_v3(float r[3], const float a[3])
void copy_vn_fl(float *array_tar, int size, float val)
Definition: math_vector.c:1259
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)
Definition: math_vector.c:1001
void ortho_v3_v3(float out[3], const float v[3])
Definition: math_vector.c:732
double dot_vn_vn(const float *array_src_a, const float *array_src_b, int size) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:978
float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:439
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)
Definition: math_vector.c:1069
void ortho_v2_v2(float out[2], const float v[2])
Definition: math_vector.c:757
void negate_vn_vn(float *array_tar, const float *array_src, int size)
Definition: math_vector.c:1059
MINLINE bool is_zero_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
void mul_vn_vn_fl(float *array_tar, const float *array_src, int size, float f)
Definition: math_vector.c:1102
void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
Definition: math_vector.c:1079
void interp_vn_vn(float *array_tar, const float *array_src, float t, int size)
Definition: math_vector.c:1210
void sub_vn_vn(float *array_tar, const float *array_src, int size)
Definition: math_vector.c:1161
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define MIN2(a, b)
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
ATTR_WARN_UNUSED_RESULT const BMVert * v2
PyObject * self
Definition: bpy_driver.c:165
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SyclQueue void void size_t num_bytes void
uint col
int count
ccl_device_inline float3 reflect(const float3 incident, const float3 normal)
Definition: math_float3.h:429
PyObject * BaseMathObject_freeze(BaseMathObject *self)
Definition: mathutils.c:681
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:661
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:654
PyObject * mathutils_dynstr_to_py(struct DynStr *ds)
Definition: mathutils.c:531
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
Definition: mathutils.c:66
void BaseMathObject_dealloc(BaseMathObject *self)
Definition: mathutils.c:705
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
Definition: mathutils.c:519
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition: mathutils.c:98
char BaseMathObject_is_valid_doc[]
Definition: mathutils.c:666
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:646
char BaseMathObject_is_wrapped_doc[]
Definition: mathutils.c:652
char BaseMathObject_is_frozen_doc[]
Definition: mathutils.c:659
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
Definition: mathutils.c:439
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:668
char BaseMathObject_owner_doc[]
Definition: mathutils.c:645
char BaseMathObject_freeze_doc[]
Definition: mathutils.c:673
int mathutils_array_parse_alloc(float **array, int array_num, PyObject *value, const char *error_prefix)
Definition: mathutils.c:193
int BaseMathObject_clear(BaseMathObject *self)
Definition: mathutils.c:699
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
Definition: mathutils.c:693
@ BASE_MATH_FLAG_IS_WRAP
Definition: mathutils.h:31
#define BaseMath_ReadCallback_ForWrite(_self)
Definition: mathutils.h:129
#define BaseMath_ReadIndexCallback(_self, _index)
Definition: mathutils.h:123
#define BaseMath_WriteCallback(_self)
Definition: mathutils.h:121
#define BASE_MATH_NEW(struct_name, root_type, base_type)
Definition: mathutils.h:20
#define BaseMathObject_Prepare_ForHash(_self)
Definition: mathutils.h:144
#define BASE_MATH_FLAG_DEFAULT
Definition: mathutils.h:38
#define BaseMath_Prepare_ForWrite(_self)
Definition: mathutils.h:139
#define BaseMath_ReadCallback(_self)
Definition: mathutils.h:119
#define BaseMath_WriteIndexCallback(_self, _index)
Definition: mathutils.h:125
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_subscript(VectorObject *self, PyObject *item)
static PyObject * Vector_slice(VectorObject *self, int begin, int end)
static PySequenceMethods Vector_SeqMethods
static PyObject * Vector_zero(VectorObject *self)
static PyObject * Vector_swizzle_get(VectorObject *self, void *closure)
static PyObject * C_Vector_Fill(PyObject *cls, PyObject *args)
static PyObject * Vector_angle(VectorObject *self, PyObject *args)
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 struct PyMethodDef Vector_methods[]
#define SWIZZLE4(a, b, c, d)
static PyObject * Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
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)
static PyObject * vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), VectorObject *self)
static int Vector_len(VectorObject *self)
static PyObject * C_Vector_Linspace(PyObject *cls, PyObject *args)
PyTypeObject vector_Type
static PyObject * Vector_orthogonal(VectorObject *self)
static PyObject * Vector_to_tuple_ex(VectorObject *self, int ndigits)
#define SWIZZLE_VALID_AXIS
PyObject * Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type)
static PyObject * Vector_dot(VectorObject *self, PyObject *value)
static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *value)
PyObject * Vector_CreatePyObject_alloc(float *vec, const int vec_num, PyTypeObject *base_type)
#define MAX_DIMENSIONS
static PyObject * vector_mul_float(VectorObject *vec, const float scalar)
static Py_hash_t Vector_hash(VectorObject *self)
static PyObject * Vector_imatmul(PyObject *v1, PyObject *v2)
static PyObject * Vector_rotation_difference(VectorObject *self, PyObject *value)
static PyObject * Vector_to_track_quat(VectorObject *self, PyObject *args)
static PyObject * Vector_negate(VectorObject *self)
static PyObject * Vector_repr(VectorObject *self)
static PyObject * Vector_div(PyObject *v1, PyObject *v2)
static PyObject * Vector_slerp(VectorObject *self, PyObject *args)
PyObject * Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
static PyObject * Vector_mul(PyObject *v1, PyObject *v2)
static PyObject * Vector_isub(PyObject *v1, PyObject *v2)
static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
static PyObject * Vector_cross(VectorObject *self, PyObject *value)
static PyNumberMethods Vector_NumMethods
static PyObject * C_Vector_Range(PyObject *cls, PyObject *args)
static PyObject * Vector_idiv(PyObject *v1, PyObject *v2)
static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
static PyObject * Vector_normalize(VectorObject *self)
static PyObject * Vector_axis_get(VectorObject *self, void *type)
static PyObject * Vector_resized(VectorObject *self, PyObject *value)
static PyObject * Vector_copy(VectorObject *self)
static PyObject * Vector_resize_4d(VectorObject *self)
static PyObject * Vector_lerp(VectorObject *self, PyObject *args)
static PyObject * Vector_iadd(PyObject *v1, PyObject *v2)
static PyObject * Vector_resize_2d(VectorObject *self)
#define SWIZZLE2(a, b)
static PyObject * Vector_neg(VectorObject *self)
static PyObject * Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
static PyObject * Vector_str(VectorObject *self)
static PyObject * vector_item_internal(VectorObject *self, int i, const bool is_attr)
static PyObject * Vector_rotate(VectorObject *self, PyObject *value)
static int Vector_length_set(VectorObject *self, PyObject *value)
static PyObject * Vector_deepcopy(VectorObject *self, PyObject *args)
static PyObject * Vector_to_2d(VectorObject *self)
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
static PyObject * Vector_to_3d(VectorObject *self)
static PyObject * Vector_angle_signed(VectorObject *self, PyObject *args)
static PyObject * Vector_length_squared_get(VectorObject *self, void *UNUSED(closure))
#define SWIZZLE_AXIS
static PyObject * Vector_reflect(VectorObject *self, PyObject *value)
static PyObject * Vector_project(VectorObject *self, PyObject *value)
static PyObject * Vector_to_tuple(VectorObject *self, PyObject *args)
static PyObject * Vector_normalized(VectorObject *self)
static PyObject * Vector_to_4d(VectorObject *self)
static PyObject * Vector_length_get(VectorObject *self, void *UNUSED(closure))
static PyObject * Vector_matmul(PyObject *v1, PyObject *v2)
#define SWIZZLE_BITS_PER_AXIS
static PyObject * C_Vector_Repeat(PyObject *cls, PyObject *args)
static PyObject * Vector_imul(PyObject *v1, PyObject *v2)
static PyObject * Vector_add(PyObject *v1, PyObject *v2)
static PyGetSetDef Vector_getseters[]
static PyObject * Vector_sub(PyObject *v1, PyObject *v2)
static int Vector_axis_set(VectorObject *self, PyObject *value, void *type)
static PyMappingMethods Vector_AsMapping
#define SWIZZLE3(a, b, c)
static PyObject * Vector_resize(VectorObject *self, PyObject *value)
static int Vector_ass_item(VectorObject *self, int i, PyObject *value)
int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
static PyObject * Vector_resize_3d(VectorObject *self)
static PyObject * vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
static PyObject * Vector_item(VectorObject *self, int i)
#define VectorObject_Check(v)
static double epsilon
int PyC_CheckArgs_DeepCopy(PyObject *args)
return ret