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