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