diff options
Diffstat (limited to 'source/blender/python/generic')
21 files changed, 698 insertions, 8994 deletions
diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt index 0889c77f9ad..8dfbf476995 100644 --- a/source/blender/python/generic/CMakeLists.txt +++ b/source/blender/python/generic/CMakeLists.txt @@ -20,10 +20,10 @@ set(INC . - ../../blenlib - ../../makesdna ../../blenkernel + ../../blenlib ../../blenloader + ../../makesdna ../../../../intern/guardedalloc ) @@ -37,13 +37,6 @@ set(SRC bgl.c blf_py_api.c bpy_internal_import.c - mathutils.c - mathutils_Color.c - mathutils_Euler.c - mathutils_Matrix.c - mathutils_Quaternion.c - mathutils_Vector.c - mathutils_geometry.c noise_py_api.c py_capi_utils.c @@ -51,13 +44,6 @@ set(SRC bgl.h blf_py_api.h bpy_internal_import.h - mathutils.h - mathutils_Color.h - mathutils_Euler.h - mathutils_Matrix.h - mathutils_Quaternion.h - mathutils_Vector.h - mathutils_geometry.h noise_py_api.h py_capi_utils.h ) diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c index a807624187a..2543d34f58c 100644 --- a/source/blender/python/generic/IDProp.c +++ b/source/blender/python/generic/IDProp.c @@ -45,26 +45,31 @@ #include "py_capi_utils.h" #endif -extern PyTypeObject IDArray_Type; -extern PyTypeObject IDGroup_Iter_Type; +extern PyTypeObject BPy_IDArray_Type; +extern PyTypeObject BPy_IDGroup_Iter_Type; +extern PyTypeObject BPy_IDGroup_Type; /*********************** ID Property Main Wrapper Stuff ***************/ -static PyObject *IDGroup_repr( BPy_IDProperty *self ) +/* use for both array and group */ +static long BPy_IDGroup_hash(BPy_IDProperty *self) { - return PyUnicode_FromFormat( "<bpy ID property from \"%s\">", self->id->name); + return _Py_HashPointer(self->prop); } -extern PyTypeObject IDGroup_Type; +static PyObject *BPy_IDGroup_repr(BPy_IDProperty *self) +{ + return PyUnicode_FromFormat( "<bpy id property from \"%s\">", self->id->name); +} PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) { switch ( prop->type ) { case IDP_STRING: #ifdef USE_STRING_COERCE - return PyC_UnicodeFromByte(prop->data.pointer); + return PyC_UnicodeFromByte(IDP_Array(prop)); #else - return PyUnicode_FromString(prop->data.pointer); + return PyUnicode_FromString(IDP_Array(prop)); #endif case IDP_INT: return PyLong_FromLong( (long)prop->data.val ); @@ -75,14 +80,14 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) case IDP_GROUP: /*blegh*/ { - BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &IDGroup_Type); + BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); group->id = id; group->prop = prop; return (PyObject*) group; } case IDP_ARRAY: { - BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &IDArray_Type); + BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &BPy_IDArray_Type); array->id = id; array->prop = prop; return (PyObject*) array; @@ -135,13 +140,13 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject st = _PyUnicode_AsString(value); IDP_ResizeArray(prop, alloc_len); - memcpy(prop->data.pointer, st, alloc_len); + memcpy(IDP_Array(prop), st, alloc_len); Py_XDECREF(value_coerce); } #else st = _PyUnicode_AsString(value); IDP_ResizeArray(prop, strlen(st)+1); - strcpy(prop->data.pointer, st); + strcpy(IDP_Array(prop), st); #endif return 0; @@ -344,7 +349,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g prop = IDP_New(IDP_ARRAY, val, name); for (i=0; i<val.array.len; i++) { item = PySequence_GetItem(ob, i); - ((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item); + ((double*)IDP_Array(prop))[i] = (float)PyFloat_AsDouble(item); Py_DECREF(item); } break; @@ -352,7 +357,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g prop = IDP_New(IDP_ARRAY, val, name); for (i=0; i<val.array.len; i++) { item = PySequence_GetItem(ob, i); - ((int*)prop->data.pointer)[i] = (int)PyLong_AsSsize_t(item); + ((int*)IDP_Array(prop))[i] = (int)PyLong_AsSsize_t(item); Py_DECREF(item); } break; @@ -465,9 +470,9 @@ static int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject return BPy_Wrap_SetMapItem(self->prop, key, val); } -static PyObject *BPy_IDGroup_SpawnIterator(BPy_IDProperty *self) +static PyObject *BPy_IDGroup_iter(BPy_IDProperty *self) { - BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &IDGroup_Iter_Type); + BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type); iter->group = self; iter->mode = IDPROP_ITER_KEYS; iter->cur = self->prop->data.group.first; @@ -480,9 +485,9 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) switch (prop->type) { case IDP_STRING: #ifdef USE_STRING_COERCE - return PyC_UnicodeFromByte(prop->data.pointer); + return PyC_UnicodeFromByte(IDP_Array(prop)); #else - return PyUnicode_FromString(prop->data.pointer); + return PyUnicode_FromString(IDP_Array(prop)); #endif break; case IDP_FLOAT: @@ -504,20 +509,37 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) return NULL; } - for (i=0; i<prop->len; i++) { - if (prop->subtype == IDP_FLOAT) { - PyList_SET_ITEM(seq, i, - PyFloat_FromDouble(((float*)prop->data.pointer)[i])); + switch(prop->subtype) { + case IDP_FLOAT: + { + float *array= (float*)IDP_Array(prop); + for (i=0; i<prop->len; i++) { + PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); + } + break; } - else if (prop->subtype == IDP_DOUBLE) { - PyList_SET_ITEM(seq, i, - PyFloat_FromDouble(((double*)prop->data.pointer)[i])); + case IDP_DOUBLE: + { + double *array= (double*)IDP_Array(prop); + for (i=0; i<prop->len; i++) { + PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); + } + break; } - else { - PyList_SET_ITEM(seq, i, - PyLong_FromLong(((int*)prop->data.pointer)[i])); + case IDP_INT: + { + int *array= (int*)IDP_Array(prop); + for (i=0; i<prop->len; i++) { + PyList_SET_ITEM(seq, i, PyLong_FromLong(array[i])); + } + break; } + default: + PyErr_SetString(PyExc_RuntimeError, "invalid/corrupt array type!"); + Py_DECREF(seq); + return NULL; } + return seq; } case IDP_IDPARRAY: @@ -553,6 +575,7 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) return NULL; PyDict_SetItemString(dict, loop->name, wrap); + Py_DECREF(wrap); } return dict; } @@ -595,7 +618,7 @@ static PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value) static PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self) { - BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &IDGroup_Iter_Type); + BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type); iter->group = self; iter->mode = IDPROP_ITER_ITEMS; iter->cur = self->prop->data.group.first; @@ -731,7 +754,7 @@ static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value) Py_RETURN_NONE; } -static PyObject *BPy_IDGroup_ConvertToPy(BPy_IDProperty *self) +static PyObject *BPy_IDGroup_to_dict(BPy_IDProperty *self) { return BPy_IDGroup_MapDataToPy(self->prop); } @@ -773,7 +796,7 @@ static struct PyMethodDef BPy_IDGroup_methods[] = { "updates the values in the group with the values of another or a dict"}, {"get", (PyCFunction)BPy_IDGroup_Get, METH_VARARGS, "idprop.get(k[,d]) -> idprop[k] if k in idprop, else d. d defaults to None"}, - {"convert_to_pyobject", (PyCFunction)BPy_IDGroup_ConvertToPy, METH_NOARGS, + {"to_dict", (PyCFunction)BPy_IDGroup_to_dict, METH_NOARGS, "return a purely python version of the group"}, {NULL, NULL, 0, NULL} }; @@ -792,16 +815,16 @@ static PySequenceMethods BPy_IDGroup_Seq = { }; static PyMappingMethods BPy_IDGroup_Mapping = { - (lenfunc)BPy_IDGroup_Map_Len, /*inquiry mp_length */ - (binaryfunc)BPy_IDGroup_Map_GetItem, /*binaryfunc mp_subscript */ + (lenfunc)BPy_IDGroup_Map_Len, /*inquiry mp_length */ + (binaryfunc)BPy_IDGroup_Map_GetItem,/*binaryfunc mp_subscript */ (objobjargproc)BPy_IDGroup_Map_SetItem, /*objobjargproc mp_ass_subscript */ }; -PyTypeObject IDGroup_Type = { +PyTypeObject BPy_IDGroup_Type = { PyVarObject_HEAD_INIT(NULL, 0) /* For printing, in format "<module>.<name>" */ - "Blender IDProperty", /* char *tp_name; */ - sizeof( BPy_IDProperty ), /* int tp_basicsize; */ + "Blender IDProperty", /* char *tp_name; */ + sizeof(BPy_IDProperty), /* int tp_basicsize; */ 0, /* tp_itemsize; For allocation */ /* Methods to implement standard operations */ @@ -811,7 +834,7 @@ PyTypeObject IDGroup_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, /* cmpfunc tp_compare; */ - ( reprfunc ) IDGroup_repr, /* reprfunc tp_repr; */ + (reprfunc)BPy_IDGroup_repr, /* reprfunc tp_repr; */ /* Method suites for standard classes */ @@ -821,7 +844,7 @@ PyTypeObject IDGroup_Type = { /* More standard operations (here for binary compatibility) */ - NULL, /* hashfunc tp_hash; */ + (hashfunc)BPy_IDGroup_hash, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ NULL, /* getattrofunc tp_getattro; */ @@ -850,7 +873,7 @@ PyTypeObject IDGroup_Type = { /*** Added in release 2.2 ***/ /* Iterators */ - (getiterfunc)BPy_IDGroup_SpawnIterator, /* getiterfunc tp_iter; */ + (getiterfunc)BPy_IDGroup_iter, /* getiterfunc tp_iter; */ NULL, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ BPy_IDGroup_methods, /* struct PyMethodDef *tp_methods; */ @@ -861,7 +884,7 @@ PyTypeObject IDGroup_Type = { /*********** Main external wrapping function *******/ PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent) { - BPy_IDProperty *wrap = PyObject_New(BPy_IDProperty, &IDGroup_Type); + BPy_IDProperty *wrap = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); wrap->prop = prop; wrap->parent = parent; wrap->id = id; @@ -872,36 +895,58 @@ PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent) /********Array Wrapper********/ -static PyObject *IDArray_repr(BPy_IDArray *self) +static PyTypeObject *idp_array_py_type(BPy_IDArray *self, short *is_double) { - return PyUnicode_FromFormat("(ID Array [%d])", self->prop->len); -} + switch (self->prop->subtype) { + case IDP_FLOAT: + *is_double= 0; + return &PyFloat_Type; + case IDP_DOUBLE: + *is_double= 1; + return &PyFloat_Type; + case IDP_INT: + *is_double= 0; + return &PyLong_Type; + } + *is_double= 0; + return NULL; +} -static PyObject *BPy_IDArray_GetType(BPy_IDArray *self) +static PyObject *BPy_IDArray_repr(BPy_IDArray *self) { - return PyLong_FromSsize_t( self->prop->subtype ); + return PyUnicode_FromFormat("<bpy id property array [%d]>", self->prop->len); } -static PyObject *BPy_IDArray_GetLen(BPy_IDArray *self) +static PyObject *BPy_IDArray_GetType(BPy_IDArray *self) { - return PyLong_FromSsize_t( self->prop->len ); + switch(self->prop->subtype) { + case IDP_FLOAT: + return PyUnicode_FromString("f"); + case IDP_DOUBLE: + return PyUnicode_FromString("d"); + case IDP_INT: + return PyUnicode_FromString("i"); + } + + PyErr_SetString(PyExc_RuntimeError, "invalid/corrupt array type!"); + return NULL; } static PyGetSetDef BPy_IDArray_getseters[] = { - {(char *)"len", (getter)BPy_IDArray_GetLen, (setter)NULL, (char *)"The length of the array, can also be gotten with len(array).", NULL}, - {(char *)"type", (getter)BPy_IDArray_GetType, (setter)NULL, (char *)"The type of the data in the array, is an ant.", NULL}, + /* matches pythons array.typecode */ + {(char *)"typecode", (getter)BPy_IDArray_GetType, (setter)NULL, (char *)"The type of the data in the array, is an int.", NULL}, {NULL, NULL, NULL, NULL, NULL}, }; -static PyObject *BPy_IDArray_ConvertToPy(BPy_IDArray *self) +static PyObject *BPy_IDArray_to_list(BPy_IDArray *self) { return BPy_IDGroup_MapDataToPy(self->prop); } static PyMethodDef BPy_IDArray_methods[] = { - {"convert_to_pyobject", (PyCFunction)BPy_IDArray_ConvertToPy, METH_NOARGS, - "return a purely python version of the group"}, + {"to_list", (PyCFunction)BPy_IDArray_to_list, METH_NOARGS, + "return the array as a list"}, {NULL, NULL, 0, NULL} }; @@ -919,14 +964,11 @@ static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index) switch (self->prop->subtype) { case IDP_FLOAT: - return PyFloat_FromDouble( (double)(((float*)self->prop->data.pointer)[index])); - break; + return PyFloat_FromDouble(((float*)IDP_Array(self->prop))[index]); case IDP_DOUBLE: - return PyFloat_FromDouble( (((double*)self->prop->data.pointer)[index])); - break; + return PyFloat_FromDouble(((double*)IDP_Array(self->prop))[index]); case IDP_INT: - return PyLong_FromLong( (long)((int*)self->prop->data.pointer)[index] ); - break; + return PyLong_FromLong((long)((int*)IDP_Array(self->prop))[index]); } PyErr_SetString(PyExc_RuntimeError, "invalid/corrupt array type!"); @@ -951,7 +993,7 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value) PyErr_SetString(PyExc_TypeError, "expected a float"); return -1; } - ((float*)self->prop->data.pointer)[index] = f; + ((float*)IDP_Array(self->prop))[index] = f; break; case IDP_DOUBLE: d= PyFloat_AsDouble(value); @@ -959,7 +1001,7 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value) PyErr_SetString(PyExc_TypeError, "expected a float"); return -1; } - ((double*)self->prop->data.pointer)[index] = d; + ((double*)IDP_Array(self->prop))[index] = d; break; case IDP_INT: i= PyLong_AsSsize_t(value); @@ -968,7 +1010,7 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value) return -1; } - ((int*)self->prop->data.pointer)[index] = i; + ((int*)IDP_Array(self->prop))[index] = i; break; } return 0; @@ -988,11 +1030,156 @@ static PySequenceMethods BPy_IDArray_Seq = { NULL, /* intargfunc sq_inplace_repeat */ }; -PyTypeObject IDArray_Type = { + + +/* sequence slice (get): idparr[a:b] */ +static PyObject *BPy_IDArray_slice(BPy_IDArray *self, int begin, int end) +{ + IDProperty *prop= self->prop; + PyObject *tuple; + int count; + + CLAMP(begin, 0, prop->len); + if (end<0) end= prop->len+end+1; + CLAMP(end, 0, prop->len); + begin= MIN2(begin, end); + + tuple= PyTuple_New(end - begin); + + switch (prop->subtype) { + case IDP_FLOAT: + { + float *array= (float*)IDP_Array(prop); + for(count = begin; count < end; count++) { + PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(array[count])); + } + break; + } + case IDP_DOUBLE: + { + double *array= (double*)IDP_Array(prop); + for(count = begin; count < end; count++) { + PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(array[count])); + } + break; + } + case IDP_INT: + { + int *array= (int*)IDP_Array(prop); + for(count = begin; count < end; count++) { + PyTuple_SET_ITEM(tuple, count - begin, PyLong_FromLong(array[count])); + } + break; + } + } + + return tuple; +} +/* sequence slice (set): idparr[a:b] = value */ +static int BPy_IDArray_ass_slice(BPy_IDArray *self, int begin, int end, PyObject *seq) +{ + IDProperty *prop= self->prop; + short is_double= 0; + const PyTypeObject *py_type= idp_array_py_type(self, &is_double); + const size_t elem_size= is_double ? sizeof(double) : sizeof(float); + size_t alloc_len; + size_t size; + void *vec; + + CLAMP(begin, 0, prop->len); + CLAMP(end, 0, prop->len); + begin = MIN2(begin, end); + + size = (end - begin); + alloc_len= size * elem_size; + + vec= MEM_mallocN(alloc_len, "array assignment"); /* NOTE: we count on int/float being the same size here */ + if(PyC_AsArray(vec, seq, size, py_type, is_double, "slice assignment: ") == -1) { + MEM_freeN(vec); + return -1; + } + + memcpy((void *)(((char *)IDP_Array(prop)) + (begin * elem_size)), vec, alloc_len); + + MEM_freeN(vec); + return 0; +} + +static PyObject *BPy_IDArray_subscript(BPy_IDArray* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->prop->len; + return BPy_IDArray_GetItem(self, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((void *)item, self->prop->len, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyTuple_New(0); + } + else if (step == 1) { + return BPy_IDArray_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return NULL; + } +} + +static int BPy_IDArray_ass_subscript(BPy_IDArray* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->prop->len; + return BPy_IDArray_SetItem(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((void *)item, self->prop->len, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return BPy_IDArray_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + return -1; + } +} + +static PyMappingMethods BPy_IDArray_AsMapping = { + (lenfunc)BPy_IDArray_Len, + (binaryfunc)BPy_IDArray_subscript, + (objobjargproc)BPy_IDArray_ass_subscript +}; + + +PyTypeObject BPy_IDArray_Type = { PyVarObject_HEAD_INIT(NULL, 0) /* For printing, in format "<module>.<name>" */ "Blender IDArray", /* char *tp_name; */ - sizeof( BPy_IDArray ), /* int tp_basicsize; */ + sizeof(BPy_IDArray), /* int tp_basicsize; */ 0, /* tp_itemsize; For allocation */ /* Methods to implement standard operations */ @@ -1002,17 +1189,17 @@ PyTypeObject IDArray_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, /* cmpfunc tp_compare; */ - ( reprfunc ) IDArray_repr, /* reprfunc tp_repr; */ + (reprfunc)BPy_IDArray_repr, /* reprfunc tp_repr; */ /* Method suites for standard classes */ NULL, /* PyNumberMethods *tp_as_number; */ - &BPy_IDArray_Seq, /* PySequenceMethods *tp_as_sequence; */ - NULL, /* PyMappingMethods *tp_as_mapping; */ + &BPy_IDArray_Seq, /* PySequenceMethods *tp_as_sequence; */ + &BPy_IDArray_AsMapping, /* PyMappingMethods *tp_as_mapping; */ /* More standard operations (here for binary compatibility) */ - NULL, /* hashfunc tp_hash; */ + NULL, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ NULL, /* getattrofunc tp_getattro; */ @@ -1106,7 +1293,7 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self) } } -PyTypeObject IDGroup_Iter_Type = { +PyTypeObject BPy_IDGroup_Iter_Type = { PyVarObject_HEAD_INIT(NULL, 0) /* For printing, in format "<module>.<name>" */ "Blender IDGroup_Iter", /* char *tp_name; */ @@ -1165,7 +1352,7 @@ PyTypeObject IDGroup_Iter_Type = { void IDProp_Init_Types(void) { - PyType_Ready( &IDGroup_Type ); - PyType_Ready( &IDGroup_Iter_Type ); - PyType_Ready( &IDArray_Type ); + PyType_Ready(&BPy_IDGroup_Type); + PyType_Ready(&BPy_IDGroup_Iter_Type); + PyType_Ready(&BPy_IDArray_Type); } diff --git a/source/blender/python/generic/IDProp.h b/source/blender/python/generic/IDProp.h index 0ca8af81f7c..aca5c0195cc 100644 --- a/source/blender/python/generic/IDProp.h +++ b/source/blender/python/generic/IDProp.h @@ -37,14 +37,15 @@ struct BPy_IDGroup_Iter; typedef struct BPy_IDProperty { PyObject_VAR_HEAD struct ID *id; - struct IDProperty *prop, *parent; + struct IDProperty *prop; /* must be second member */ + struct IDProperty *parent; PyObject *data_wrap; } BPy_IDProperty; typedef struct BPy_IDArray { PyObject_VAR_HEAD struct ID *id; - struct IDProperty *prop; + struct IDProperty *prop; /* must be second member */ } BPy_IDArray; typedef struct BPy_IDGroup_Iter { diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index b5a693c397c..ae8069cf3c5 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -44,69 +44,177 @@ #include "BLI_utildefines.h" - -PyDoc_STRVAR(Method_Buffer_doc, - "(type, dimensions, [template]) - Create a new Buffer object\n\n\ -(type) - The format to store data in\n\ -(dimensions) - An int or sequence specifying the dimensions of the buffer\n\ -[template] - A sequence of matching dimensions to the buffer to be created\n\ - which will be used to initialize the Buffer.\n\n\ -If a template is not passed in all fields will be initialized to 0.\n\n\ -The type should be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE.\n\ -If the dimensions are specified as an int a linear buffer will be\n\ -created. If a sequence is passed for the dimensions the buffer\n\ -will have len(sequence) dimensions, where the size for each dimension\n\ -is determined by the value in the sequence at that index.\n\n\ -For example, passing [100, 100] will create a 2 dimensional\n\ -square buffer. Passing [16, 16, 32] will create a 3 dimensional\n\ -buffer which is twice as deep as it is wide or high." -); - -static PyObject *Method_Buffer(PyObject *self, PyObject *args); +static PyObject *Buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* Buffer sequence methods */ -static int Buffer_len(PyObject *self); -static PyObject *Buffer_item(PyObject *self, int i); -static PyObject *Buffer_slice(PyObject *self, int begin, int end); -static int Buffer_ass_item(PyObject *self, int i, PyObject *v); -static int Buffer_ass_slice(PyObject *self, int begin, int end, - PyObject *seq); +static int Buffer_len(Buffer *self); +static PyObject *Buffer_item(Buffer *self, int i); +static PyObject *Buffer_slice(Buffer *self, int begin, int end); +static int Buffer_ass_item(Buffer *self, int i, PyObject *v); +static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq); +static PyObject *Buffer_subscript(Buffer *self, PyObject *item); +static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value); static PySequenceMethods Buffer_SeqMethods = { - ( lenfunc ) Buffer_len, /*sq_length */ - ( binaryfunc ) NULL, /*sq_concat */ - ( ssizeargfunc ) NULL, /*sq_repeat */ - ( ssizeargfunc ) Buffer_item, /*sq_item */ - ( ssizessizeargfunc ) Buffer_slice, /*sq_slice, deprecated TODO, replace */ - ( ssizeobjargproc ) Buffer_ass_item, /*sq_ass_item */ - ( ssizessizeobjargproc ) Buffer_ass_slice, /*sq_ass_slice, deprecated TODO, replace */ + (lenfunc) Buffer_len, /*sq_length */ + (binaryfunc) NULL, /*sq_concat */ + (ssizeargfunc) NULL, /*sq_repeat */ + (ssizeargfunc) Buffer_item, /*sq_item */ + (ssizessizeargfunc) Buffer_slice, /*sq_slice, deprecated TODO, replace */ + (ssizeobjargproc) Buffer_ass_item, /*sq_ass_item */ + (ssizessizeobjargproc) Buffer_ass_slice, /*sq_ass_slice, deprecated TODO, replace */ (objobjproc) NULL, /* sq_contains */ (binaryfunc) NULL, /* sq_inplace_concat */ (ssizeargfunc) NULL, /* sq_inplace_repeat */ }; -static void Buffer_dealloc(PyObject *self); -static PyObject *Buffer_tolist(PyObject *self); -static PyObject *Buffer_dimensions(PyObject *self); -static PyObject *Buffer_getattr(PyObject *self, char *name); -static PyObject *Buffer_repr(PyObject *self); + +static PyMappingMethods Buffer_AsMapping = { + (lenfunc)Buffer_len, + (binaryfunc)Buffer_subscript, + (objobjargproc)Buffer_ass_subscript +}; + +static void Buffer_dealloc(Buffer *self); +static PyObject *Buffer_repr(Buffer *self); + +static PyObject *Buffer_to_list(Buffer *self) +{ + int i, len= self->dimensions[0]; + PyObject *list= PyList_New(len); + + for (i=0; i<len; i++) { + PyList_SET_ITEM(list, i, Buffer_item(self, i)); + } + + return list; +} + +static PyObject *Buffer_to_list_recursive(Buffer *self) +{ + PyObject *list; + + if(self->ndimensions > 1) { + int i, len= self->dimensions[0]; + list= PyList_New(len); + + for (i=0; i<len; i++) { + Buffer *sub= (Buffer *)Buffer_item(self, i); + PyList_SET_ITEM(list, i, Buffer_to_list_recursive(sub)); + Py_DECREF(sub); + } + } + else { + list= Buffer_to_list(self); + } + + return list; +} + +/* *DEPRECATED* 2011/7/17 bgl.Buffer.list */ +static PyObject *Buffer_list(Buffer *self, void *UNUSED(arg)) +{ + fprintf(stderr, "Warning: 'Buffer.list' deprecated, use '[:]' instead\n"); + return Buffer_to_list(self); +} + +static PyObject *Buffer_dimensions(Buffer *self, void *UNUSED(arg)) +{ + PyObject *list= PyList_New(self->ndimensions); + int i; + + for (i= 0; i<self->ndimensions; i++) { + PyList_SET_ITEM(list, i, PyLong_FromLong(self->dimensions[i])); + } + + return list; +} + +static PyMethodDef Buffer_methods[] = { + {"to_list", (PyCFunction)Buffer_to_list_recursive, METH_NOARGS, + "return the buffer as a list"}, + {NULL, NULL, 0, NULL} +}; + +static PyGetSetDef Buffer_getseters[] = { + {(char *)"list", (getter)Buffer_list, NULL, NULL, NULL}, + {(char *)"dimensions", (getter)Buffer_dimensions, NULL, NULL, NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; + PyTypeObject BGL_bufferType = { PyVarObject_HEAD_INIT(NULL, 0) - "buffer", /*tp_name */ - sizeof( Buffer ), /*tp_basicsize */ - 0, /*tp_itemsize */ - ( destructor ) Buffer_dealloc, /*tp_dealloc */ - ( printfunc ) 0, /*tp_print */ - ( getattrfunc ) Buffer_getattr, /*tp_getattr */ - ( setattrfunc ) 0, /*tp_setattr */ + "bgl.Buffer", /*tp_name */ + sizeof(Buffer), /*tp_basicsize */ + 0, /*tp_itemsize */ + (destructor)Buffer_dealloc, /*tp_dealloc */ + (printfunc)NULL, /*tp_print */ + NULL, /*tp_getattr */ + NULL, /*tp_setattr */ NULL, /*tp_compare */ - ( reprfunc ) Buffer_repr, /*tp_repr */ + (reprfunc) Buffer_repr, /*tp_repr */ NULL, /*tp_as_number */ &Buffer_SeqMethods, /*tp_as_sequence */ + &Buffer_AsMapping, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + /*** Attribute descriptor and subclassing stuff ***/ + Buffer_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + Buffer_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /*tp_base*/ + NULL, /*tp_dict*/ + NULL, /*tp_descr_get*/ + NULL, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + NULL, /*tp_init*/ + NULL, /*tp_alloc*/ + Buffer_new, /*tp_new*/ + NULL, /*tp_free*/ + NULL, /*tp_is_gc*/ + NULL, /*tp_bases*/ + NULL, /*tp_mro*/ + NULL, /*tp_cache*/ + NULL, /*tp_subclasses*/ + NULL, /*tp_weaklist*/ + NULL /*tp_del*/ }; + /* #ifndef __APPLE__ */ #define BGL_Wrap(nargs, funcname, ret, arg_list) \ @@ -174,26 +282,13 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf } else { memset(buffer->buf.asvoid, 0, length*size); - /* - for (i= 0; i<length; i++) { - if (type==GL_BYTE) - buffer->buf.asbyte[i]= 0; - else if (type==GL_SHORT) - buffer->buf.asshort[i]= 0; - else if (type==GL_INT) - buffer->buf.asint[i]= 0; - else if (type==GL_FLOAT) - buffer->buf.asfloat[i]= 0.0f; - else if (type==GL_DOUBLE) - buffer->buf.asdouble[i]= 0.0; - } - */ } return buffer; } + #define MAX_DIMENSIONS 256 -static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) +static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) { PyObject *length_ob= NULL, *init= NULL; Buffer *buffer; @@ -201,31 +296,41 @@ static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) int i, type; int ndimensions = 0; - - if (!PyArg_ParseTuple(args, "iO|O", &type, &length_ob, &init)) { - PyErr_SetString(PyExc_AttributeError, "expected an int and one or two PyObjects"); + + if(kwds && PyDict_Size(kwds)) { + PyErr_SetString(PyExc_TypeError, + "bgl.Buffer(): takes no keyword args"); + return NULL; + } + + if (!PyArg_ParseTuple(args, "iO|O: bgl.Buffer", &type, &length_ob, &init)) { return NULL; } if (!ELEM5(type, GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE)) { - PyErr_SetString(PyExc_AttributeError, "invalid first argument type, should be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE"); + PyErr_SetString(PyExc_AttributeError, + "invalid first argument type, should be one of " + "GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE"); return NULL; } if (PyLong_Check(length_ob)) { ndimensions= 1; if(((dimensions[0]= PyLong_AsLong(length_ob)) < 1)) { - PyErr_SetString(PyExc_AttributeError, "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); + PyErr_SetString(PyExc_AttributeError, + "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); return NULL; } } else if (PySequence_Check(length_ob)) { ndimensions= PySequence_Size(length_ob); if (ndimensions > MAX_DIMENSIONS) { - PyErr_SetString(PyExc_AttributeError, "too many dimensions, max is "STRINGIFY(MAX_DIMENSIONS)); + PyErr_SetString(PyExc_AttributeError, + "too many dimensions, max is "STRINGIFY(MAX_DIMENSIONS)); return NULL; } else if (ndimensions < 1) { - PyErr_SetString(PyExc_AttributeError, "sequence must have at least one dimension"); + PyErr_SetString(PyExc_AttributeError, + "sequence must have at least one dimension"); return NULL; } for (i=0; i<ndimensions; i++) { @@ -236,19 +341,22 @@ static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) Py_DECREF(ob); if(dimensions[i] < 1) { - PyErr_SetString(PyExc_AttributeError, "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); + PyErr_SetString(PyExc_AttributeError, + "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); return NULL; } } } else { - PyErr_Format(PyExc_TypeError, "invalid second argument argument expected a sequence or an int, not a %.200s", Py_TYPE(length_ob)->tp_name); + PyErr_Format(PyExc_TypeError, + "invalid second argument argument expected a sequence " + "or an int, not a %.200s", Py_TYPE(length_ob)->tp_name); return NULL; } buffer= BGL_MakeBuffer(type, ndimensions, dimensions, NULL); if (init && ndimensions) { - if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], init)) { + if (Buffer_ass_slice(buffer, 0, dimensions[0], init)) { Py_DECREF(buffer); return NULL; } @@ -259,51 +367,48 @@ static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) /*@ Buffer sequence methods */ -static int Buffer_len(PyObject *self) +static int Buffer_len(Buffer *self) { - Buffer *buf= (Buffer *) self; - return buf->dimensions[0]; + return self->dimensions[0]; } -static PyObject *Buffer_item(PyObject *self, int i) +static PyObject *Buffer_item(Buffer *self, int i) { - Buffer *buf= (Buffer *) self; - - if (i >= buf->dimensions[0]) { + if (i >= self->dimensions[0] || i < 0) { PyErr_SetString(PyExc_IndexError, "array index out of range"); return NULL; } - if (buf->ndimensions==1) { - switch (buf->type) { - case GL_BYTE: return Py_BuildValue("b", buf->buf.asbyte[i]); - case GL_SHORT: return Py_BuildValue("h", buf->buf.asshort[i]); - case GL_INT: return Py_BuildValue("i", buf->buf.asint[i]); - case GL_FLOAT: return PyFloat_FromDouble(buf->buf.asfloat[i]); - case GL_DOUBLE: return Py_BuildValue("d", buf->buf.asdouble[i]); + if (self->ndimensions==1) { + switch (self->type) { + case GL_BYTE: return Py_BuildValue("b", self->buf.asbyte[i]); + case GL_SHORT: return Py_BuildValue("h", self->buf.asshort[i]); + case GL_INT: return Py_BuildValue("i", self->buf.asint[i]); + case GL_FLOAT: return PyFloat_FromDouble(self->buf.asfloat[i]); + case GL_DOUBLE: return Py_BuildValue("d", self->buf.asdouble[i]); } } else { Buffer *newbuf; int j, length, size; - + length= 1; - for (j=1; j<buf->ndimensions; j++) { - length*= buf->dimensions[j]; + for (j=1; j < self->ndimensions; j++) { + length *= self->dimensions[j]; } - size= BGL_typeSize(buf->type); + size= BGL_typeSize(self->type); newbuf= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType); Py_INCREF(self); - newbuf->parent= self; + newbuf->parent= (PyObject *)self; - newbuf->ndimensions= buf->ndimensions-1; - newbuf->type= buf->type; - newbuf->buf.asvoid= buf->buf.asbyte + i*length*size; + newbuf->ndimensions= self->ndimensions - 1; + newbuf->type= self->type; + newbuf->buf.asvoid= self->buf.asbyte + i*length*size; newbuf->dimensions= MEM_mallocN(newbuf->ndimensions*sizeof(int), "Buffer dimensions"); - memcpy(newbuf->dimensions, buf->dimensions+1, + memcpy(newbuf->dimensions, self->dimensions+1, newbuf->ndimensions*sizeof(int)); return (PyObject *) newbuf; @@ -312,16 +417,14 @@ static PyObject *Buffer_item(PyObject *self, int i) return NULL; } -static PyObject *Buffer_slice(PyObject *self, int begin, int end) +static PyObject *Buffer_slice(Buffer *self, int begin, int end) { - Buffer *buf= (Buffer *) self; PyObject *list; int count; - if (begin<0) begin= 0; - if (end>buf->dimensions[0]) - end= buf->dimensions[0]; - if (begin>end) begin= end; + if (begin < 0) begin= 0; + if (end > self->dimensions[0]) end= self->dimensions[0]; + if (begin > end) begin= end; list= PyList_New(end-begin); @@ -331,134 +434,180 @@ static PyObject *Buffer_slice(PyObject *self, int begin, int end) return list; } -static int Buffer_ass_item(PyObject *self, int i, PyObject *v) +static int Buffer_ass_item(Buffer *self, int i, PyObject *v) { - Buffer *buf= (Buffer *) self; - - if (i >= buf->dimensions[0]) { - PyErr_SetString(PyExc_IndexError, "array assignment index out of range"); + if (i >= self->dimensions[0] || i < 0) { + PyErr_SetString(PyExc_IndexError, + "array assignment index out of range"); return -1; } - - if (buf->ndimensions!=1) { - PyObject *row= Buffer_item(self, i); - int ret; - - if (!row) return -1; - ret= Buffer_ass_slice(row, 0, buf->dimensions[1], v); - Py_DECREF(row); - return ret; - } - if (buf->type==GL_BYTE) { - if (!PyArg_Parse(v, "b:Coordinates must be ints", &buf->buf.asbyte[i])) - return -1; - } - else if (buf->type==GL_SHORT) { - if (!PyArg_Parse(v, "h:Coordinates must be ints", &buf->buf.asshort[i])) - return -1; - - } - else if (buf->type==GL_INT) { - if (!PyArg_Parse(v, "i:Coordinates must be ints", &buf->buf.asint[i])) - return -1; - } - else if (buf->type==GL_FLOAT) { - if (!PyArg_Parse(v, "f:Coordinates must be floats", &buf->buf.asfloat[i])) + if (self->ndimensions!=1) { + Buffer *row= (Buffer *)Buffer_item(self, i); + + if (row) { + int ret= Buffer_ass_slice(row, 0, self->dimensions[1], v); + Py_DECREF(row); + return ret; + } + else { return -1; + } } - else if (buf->type==GL_DOUBLE) { - if (!PyArg_Parse(v, "d:Coordinates must be floats", &buf->buf.asdouble[i])) - return -1; + + switch(self->type) { + case GL_BYTE: + return PyArg_Parse(v, "b:Expected ints", &self->buf.asbyte[i]) ? 0:-1; + case GL_SHORT: + return PyArg_Parse(v, "h:Expected ints", &self->buf.asshort[i]) ? 0:-1; + case GL_INT: + return PyArg_Parse(v, "i:Expected ints", &self->buf.asint[i]) ? 0:-1; + case GL_FLOAT: + return PyArg_Parse(v, "f:Expected floats", &self->buf.asfloat[i]) ? 0:-1; + case GL_DOUBLE: + return PyArg_Parse(v, "d:Expected floats", &self->buf.asdouble[i]) ? 0:-1; + default: + return 0; /* should never happen */ } - return 0; } -static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq) +static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq) { - Buffer *buf= (Buffer *) self; PyObject *item; int count, err=0; - if (begin<0) begin= 0; - if (end>buf->dimensions[0]) end= buf->dimensions[0]; - if (begin>end) begin= end; + if (begin < 0) begin= 0; + if (end > self->dimensions[0]) end= self->dimensions[0]; + if (begin > end) begin= end; if (!PySequence_Check(seq)) { - PyErr_SetString(PyExc_TypeError, - "illegal argument type for built-in operation"); + PyErr_Format(PyExc_TypeError, + "buffer[:] = value, invalid assignment. " + "Expected a sequence, not an %.200s type", + Py_TYPE(seq)->tp_name); return -1; } - if (PySequence_Size(seq)!=(end-begin)) { - int seq_len = PySequence_Size(seq); - char err_str[128]; - sprintf(err_str, "size mismatch in assignment. Expected size: %d (size provided: %d)", seq_len, (end-begin)); - PyErr_SetString(PyExc_TypeError, err_str); + /* re-use count var */ + if ((count= PySequence_Size(seq)) != (end - begin)) { + PyErr_Format(PyExc_TypeError, + "buffer[:] = value, size mismatch in assignment. " + "Expected: %d (given: %d)", count, end - begin); return -1; } - for (count= begin; count<end; count++) { - item= PySequence_GetItem(seq, count-begin); - err= Buffer_ass_item(self, count, item); - Py_DECREF(item); + for (count= begin; count < end; count++) { + item= PySequence_GetItem(seq, count - begin); + if(item) { + err= Buffer_ass_item(self, count, item); + Py_DECREF(item); + } + else { + err= -1; + } if (err) break; } return err; } -static void Buffer_dealloc(PyObject *self) +static PyObject *Buffer_subscript(Buffer *self, PyObject *item) { - Buffer *buf = (Buffer *)self; + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->dimensions[0]; + return Buffer_item(self, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; - if (buf->parent) Py_DECREF (buf->parent); - else MEM_freeN (buf->buf.asvoid); + if (PySlice_GetIndicesEx((void *)item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) + return NULL; - MEM_freeN (buf->dimensions); - - PyObject_DEL (self); + if (slicelength <= 0) { + return PyTuple_New(0); + } + else if (step == 1) { + return Buffer_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_IndexError, + "slice steps not supported with vectors"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "buffer indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return NULL; + } } -static PyObject *Buffer_tolist(PyObject *self) +static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value) { - int i, len= ((Buffer *)self)->dimensions[0]; - PyObject *list= PyList_New(len); - - for (i=0; i<len; i++) { - PyList_SET_ITEM(list, i, Buffer_item(self, i)); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->dimensions[0]; + return Buffer_ass_item(self, i, value); } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; - return list; + if (PySlice_GetIndicesEx((void *)item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return Buffer_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_IndexError, + "slice steps not supported with vectors"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "buffer indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return -1; + } } -static PyObject *Buffer_dimensions(PyObject *self) + +static void Buffer_dealloc(Buffer *self) { - Buffer *buffer= (Buffer *) self; - PyObject *list= PyList_New(buffer->ndimensions); - int i; + if (self->parent) Py_DECREF(self->parent); + else MEM_freeN (self->buf.asvoid); - for (i= 0; i<buffer->ndimensions; i++) { - PyList_SET_ITEM(list, i, PyLong_FromLong(buffer->dimensions[i])); - } + MEM_freeN(self->dimensions); - return list; + PyObject_DEL(self); } -static PyObject *Buffer_getattr(PyObject *self, char *name) -{ - if (strcmp(name, "list")==0) return Buffer_tolist(self); - else if (strcmp(name, "dimensions")==0) return Buffer_dimensions(self); - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} -static PyObject *Buffer_repr(PyObject *self) +static PyObject *Buffer_repr(Buffer *self) { - PyObject *list= Buffer_tolist(self); - PyObject *repr= PyObject_Repr(list); + PyObject *list= Buffer_to_list_recursive(self); + PyObject *repr; + const char *typestr= "UNKNOWN"; + + switch(self->type) { + case GL_BYTE: typestr= "GL_BYTE"; break; + case GL_SHORT: typestr= "GL_SHORT"; break; + case GL_INT: typestr= "GL_BYTE"; break; + case GL_FLOAT: typestr= "GL_FLOAT"; break; + case GL_DOUBLE: typestr= "GL_DOUBLE"; break; + } + + repr= PyUnicode_FromFormat("Buffer(%s, %R)", typestr, list); Py_DECREF(list); - + return repr; } @@ -805,7 +954,6 @@ BGLU_Wrap(9, UnProject, GLint, (GLdouble, GLdouble, GLdouble, GLdoubleP, GLdo * {"glAccum", Method_Accumfunc, METH_VARARGS} */ static struct PyMethodDef BGL_methods[] = { - {"Buffer", Method_Buffer, METH_VARARGS, Method_Buffer_doc}, /* #ifndef __APPLE__ */ MethodDef(Accum), @@ -1153,9 +1301,12 @@ PyObject *BPyInit_bgl(void) submodule= PyModule_Create(&BGL_module_def); dict= PyModule_GetDict(submodule); - if( PyType_Ready( &BGL_bufferType) < 0) + if(PyType_Ready(&BGL_bufferType) < 0) return NULL; /* should never happen */ + + PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); + #define EXPP_ADDCONST(x) PyDict_SetItemString(dict, #x, item=PyLong_FromLong((int)x)); Py_DECREF(item) /* So, for example: diff --git a/source/blender/python/generic/mathutils.c b/source/blender/python/generic/mathutils.c deleted file mode 100644 index 30f4e5b7ffe..00000000000 --- a/source/blender/python/generic/mathutils.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Joseph Gilbert, Campbell Barton - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils.c - * \ingroup pygen - */ - -#include <Python.h> - -#include "mathutils.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -PyDoc_STRVAR(M_Mathutils_doc, -"This module provides access to matrices, eulers, quaternions and vectors." -); -static int mathutils_array_parse_fast(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix) -{ - PyObject *value_fast= NULL; - PyObject *item; - - int i, size; - - /* non list/tuple cases */ - if(!(value_fast=PySequence_Fast(value, error_prefix))) { - /* PySequence_Fast sets the error */ - return -1; - } - - size= PySequence_Fast_GET_SIZE(value_fast); - - if(size > array_max || size < array_min) { - if (array_max == array_min) PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected %d", error_prefix, size, array_max); - else PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected [%d - %d]", error_prefix, size, array_min, array_max); - Py_DECREF(value_fast); - return -1; - } - - i= size; - do { - i--; - if(((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) && PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, "%.200s: sequence index %d expected a number, found '%.200s' type, ", error_prefix, i, Py_TYPE(item)->tp_name); - Py_DECREF(value_fast); - return -1; - } - } while(i); - - Py_XDECREF(value_fast); - return size; -} - -/* helper functionm returns length of the 'value', -1 on error */ -int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix) -{ -#if 1 /* approx 6x speedup for mathutils types */ - int size; - - if( (VectorObject_Check(value) && (size= ((VectorObject *)value)->size)) || - (EulerObject_Check(value) && (size= 3)) || - (QuaternionObject_Check(value) && (size= 4)) || - (ColorObject_Check(value) && (size= 3)) - ) { - if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) { - return -1; - } - - if(size > array_max || size < array_min) { - if (array_max == array_min) PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected %d", error_prefix, size, array_max); - else PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected [%d - %d]", error_prefix, size, array_min, array_max); - return -1; - } - - memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float)); - return size; - } - else -#endif - { - return mathutils_array_parse_fast(array, array_min, array_max, value, error_prefix); - } -} - -int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix) -{ - if(EulerObject_Check(value)) { - if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) { - return -1; - } - else { - eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order); - return 0; - } - } - else if (QuaternionObject_Check(value)) { - if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) { - return -1; - } - else { - float tquat[4]; - normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat); - quat_to_mat3(rmat, tquat); - return 0; - } - } - else if (MatrixObject_Check(value)) { - if(BaseMath_ReadCallback((BaseMathObject *)value) == -1) { - return -1; - } - else if(((MatrixObject *)value)->col_size < 3 || ((MatrixObject *)value)->row_size < 3) { - PyErr_Format(PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix); - return -1; - } - else { - matrix_as_3x3(rmat, (MatrixObject *)value); - normalize_m3(rmat); - return 0; - } - } - else { - PyErr_Format(PyExc_TypeError, "%.200s: expected a Euler, Quaternion or Matrix type, found %.200s", error_prefix, Py_TYPE(value)->tp_name); - return -1; - } -} - - -//----------------------------------MATRIX FUNCTIONS-------------------- - - -/* Utility functions */ - -// LomontRRDCompare4, Ever Faster Float Comparisons by Randy Dillon -#define SIGNMASK(i) (-(int)(((unsigned int)(i))>>31)) - -int EXPP_FloatsAreEqual(float af, float bf, int maxDiff) -{ // solid, fast routine across all platforms - // with constant time behavior - int ai = *(int *)(&af); - int bi = *(int *)(&bf); - int test = SIGNMASK(ai^bi); - int diff, v1, v2; - - assert((0 == test) || (0xFFFFFFFF == test)); - diff = (ai ^ (test & 0x7fffffff)) - bi; - v1 = maxDiff + diff; - v2 = maxDiff - diff; - return (v1|v2) >= 0; -} - -/*---------------------- EXPP_VectorsAreEqual ------------------------- - Builds on EXPP_FloatsAreEqual to test vectors */ -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) -{ - int x; - for (x=0; x< size; x++){ - if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) - return 0; - } - return 1; -} - - -/* Mathutils Callbacks */ - -/* for mathutils internal use only, eventually should re-alloc but to start with we only have a few users */ -static Mathutils_Callback *mathutils_callbacks[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - -int Mathutils_RegisterCallback(Mathutils_Callback *cb) -{ - int i; - - /* find the first free slot */ - for(i= 0; mathutils_callbacks[i]; i++) { - if(mathutils_callbacks[i]==cb) /* already registered? */ - return i; - } - - mathutils_callbacks[i] = cb; - return i; -} - -/* use macros to check for NULL */ -int _BaseMathObject_ReadCallback(BaseMathObject *self) -{ - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; - if(cb->get(self, self->cb_subtype) != -1) - return 0; - - if(!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "%s read, user has become invalid", Py_TYPE(self)->tp_name); - return -1; -} - -int _BaseMathObject_WriteCallback(BaseMathObject *self) -{ - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; - if(cb->set(self, self->cb_subtype) != -1) - return 0; - - if(!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "%s write, user has become invalid", Py_TYPE(self)->tp_name); - return -1; -} - -int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index) -{ - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; - if(cb->get_index(self, self->cb_subtype, index) != -1) - return 0; - - if(!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "%s read index, user has become invalid", Py_TYPE(self)->tp_name); - return -1; -} - -int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index) -{ - Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; - if(cb->set_index(self, self->cb_subtype, index) != -1) - return 0; - - if(!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "%s write index, user has become invalid", Py_TYPE(self)->tp_name); - return -1; -} - -/* BaseMathObject generic functions for all mathutils types */ -char BaseMathObject_Owner_doc[] = "The item this is wrapping or None (readonly)."; -PyObject *BaseMathObject_getOwner(BaseMathObject *self, void *UNUSED(closure)) -{ - PyObject *ret= self->cb_user ? self->cb_user : Py_None; - Py_INCREF(ret); - return ret; -} - -char BaseMathObject_Wrapped_doc[] = "True when this object wraps external data (readonly).\n\n:type: boolean"; -PyObject *BaseMathObject_getWrapped(BaseMathObject *self, void *UNUSED(closure)) -{ - return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0); -} - -int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->cb_user); - return 0; -} - -int BaseMathObject_clear(BaseMathObject *self) -{ - Py_CLEAR(self->cb_user); - return 0; -} - -void BaseMathObject_dealloc(BaseMathObject *self) -{ - /* only free non wrapped */ - if(self->wrapped != Py_WRAP) { - PyMem_Free(self->data); - } - - if(self->cb_user) { - PyObject_GC_UnTrack(self); - BaseMathObject_clear(self); - } - - Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes -} - -/*----------------------------MODULE INIT-------------------------*/ -static struct PyMethodDef M_Mathutils_methods[] = { - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef M_Mathutils_module_def = { - PyModuleDef_HEAD_INIT, - "mathutils", /* m_name */ - M_Mathutils_doc, /* m_doc */ - 0, /* m_size */ - M_Mathutils_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; - -PyMODINIT_FUNC BPyInit_mathutils(void) -{ - PyObject *submodule; - PyObject *item; - - if(PyType_Ready(&vector_Type) < 0) - return NULL; - if(PyType_Ready(&matrix_Type) < 0) - return NULL; - if(PyType_Ready(&euler_Type) < 0) - return NULL; - if(PyType_Ready(&quaternion_Type) < 0) - return NULL; - if(PyType_Ready(&color_Type) < 0) - return NULL; - - submodule = PyModule_Create(&M_Mathutils_module_def); - - /* each type has its own new() function */ - PyModule_AddObject(submodule, "Vector", (PyObject *)&vector_Type); - PyModule_AddObject(submodule, "Matrix", (PyObject *)&matrix_Type); - PyModule_AddObject(submodule, "Euler", (PyObject *)&euler_Type); - PyModule_AddObject(submodule, "Quaternion", (PyObject *)&quaternion_Type); - PyModule_AddObject(submodule, "Color", (PyObject *)&color_Type); - - /* submodule */ - PyModule_AddObject(submodule, "geometry", (item=BPyInit_mathutils_geometry())); - /* XXX, python doesnt do imports with this usefully yet - * 'from mathutils.geometry import PolyFill' - * ...fails without this. */ - PyDict_SetItemString(PyThreadState_GET()->interp->modules, "mathutils.geometry", item); - Py_INCREF(item); - - mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb); - - return submodule; -} diff --git a/source/blender/python/generic/mathutils.h b/source/blender/python/generic/mathutils.h deleted file mode 100644 index 449708d1ac1..00000000000 --- a/source/blender/python/generic/mathutils.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** -*/ - -/** \file blender/python/generic/mathutils.h - * \ingroup pygen - */ - -//Include this file for access to vector, quat, matrix, euler, etc... - -#ifndef MATHUTILS_H -#define MATHUTILS_H - -/* Can cast different mathutils types to this, use for generic funcs */ - -extern char BaseMathObject_Wrapped_doc[]; -extern char BaseMathObject_Owner_doc[]; - -#define BASE_MATH_MEMBERS(_data) \ - PyObject_VAR_HEAD \ - float *_data; /* array of data (alias), wrapped status depends on wrapped status */ \ - PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ \ - unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ \ - unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ \ - unsigned char wrapped; /* wrapped data type? */ \ - -typedef struct { - BASE_MATH_MEMBERS(data) -} BaseMathObject; - -#include "mathutils_Vector.h" -#include "mathutils_Matrix.h" -#include "mathutils_Quaternion.h" -#include "mathutils_Euler.h" -#include "mathutils_Color.h" -#include "mathutils_geometry.h" - -PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * ); -PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * ); - -int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg); -int BaseMathObject_clear(BaseMathObject *self); -void BaseMathObject_dealloc(BaseMathObject * self); - -PyMODINIT_FUNC BPyInit_mathutils(void); - -int EXPP_FloatsAreEqual(float A, float B, int floatSteps); -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); - -#define Py_NEW 1 -#define Py_WRAP 2 - -typedef struct Mathutils_Callback Mathutils_Callback; - -typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */ -typedef int (*BaseMathGetFunc)(BaseMathObject *, int); /* gets the vector from the user */ -typedef int (*BaseMathSetFunc)(BaseMathObject *, int); /* sets the users vector values once the vector is modified */ -typedef int (*BaseMathGetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */ -typedef int (*BaseMathSetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */ - -struct Mathutils_Callback { - BaseMathCheckFunc check; - BaseMathGetFunc get; - BaseMathSetFunc set; - BaseMathGetIndexFunc get_index; - BaseMathSetIndexFunc set_index; -}; - -int Mathutils_RegisterCallback(Mathutils_Callback *cb); - -int _BaseMathObject_ReadCallback(BaseMathObject *self); -int _BaseMathObject_WriteCallback(BaseMathObject *self); -int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index); -int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index); - -/* since this is called so often avoid where possible */ -#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):0)) -#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):0)) -#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):0)) -#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):0)) - -/* utility func */ -int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix); -int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix); - -#endif /* MATHUTILS_H */ diff --git a/source/blender/python/generic/mathutils_Color.c b/source/blender/python/generic/mathutils_Color.c deleted file mode 100644 index c59cb501d86..00000000000 --- a/source/blender/python/generic/mathutils_Color.c +++ /dev/null @@ -1,831 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): Campbell Barton - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils_Color.c - * \ingroup pygen - */ - - -#include <Python.h> - -#include "mathutils.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#define COLOR_SIZE 3 - -//----------------------------------mathutils.Color() ------------------- -//makes a new color for you to play with -static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - float col[3]= {0.0f, 0.0f, 0.0f}; - - if(kwds && PyDict_Size(kwds)) { - PyErr_SetString(PyExc_TypeError, "mathutils.Color(): takes no keyword args"); - return NULL; - } - - switch(PyTuple_GET_SIZE(args)) { - case 0: - break; - case 1: - if((mathutils_array_parse(col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "mathutils.Color(): more then a single arg given"); - return NULL; - } - return newColorObject(col, Py_NEW, type); -} - -//-----------------------------METHODS---------------------------- - -/* note: BaseMath_ReadCallback must be called beforehand */ -static PyObject *Color_ToTupleExt(ColorObject *self, int ndigits) -{ - PyObject *ret; - int i; - - ret= PyTuple_New(COLOR_SIZE); - - if(ndigits >= 0) { - for(i= 0; i < COLOR_SIZE; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits))); - } - } - else { - for(i= 0; i < COLOR_SIZE; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i])); - } - } - - return ret; -} - -PyDoc_STRVAR(Color_copy_doc, -".. function:: copy()\n" -"\n" -" Returns a copy of this color.\n" -"\n" -" :return: A copy of the color.\n" -" :rtype: :class:`Color`\n" -"\n" -" .. note:: use this to get a copy of a wrapped color with\n" -" no reference to the original data.\n" -); -static PyObject *Color_copy(ColorObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return newColorObject(self->col, Py_NEW, Py_TYPE(self)); -} - -//----------------------------print object (internal)-------------- -//print the object to screen - -static PyObject *Color_repr(ColorObject * self) -{ - PyObject *ret, *tuple; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - tuple= Color_ToTupleExt(self, -1); - - ret= PyUnicode_FromFormat("Color(%R)", tuple); - - Py_DECREF(tuple); - return ret; -} - -//------------------------tp_richcmpr -//returns -1 execption, 0 false, 1 true -static PyObject* Color_richcmpr(PyObject *a, PyObject *b, int op) -{ - PyObject *res; - int ok= -1; /* zero is true */ - - if (ColorObject_Check(a) && ColorObject_Check(b)) { - ColorObject *colA= (ColorObject*)a; - ColorObject *colB= (ColorObject*)b; - - if(BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1) - return NULL; - - ok= EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1; - } - - switch (op) { - case Py_NE: - ok = !ok; /* pass through */ - case Py_EQ: - res = ok ? Py_False : Py_True; - break; - - case Py_LT: - case Py_LE: - case Py_GT: - case Py_GE: - res = Py_NotImplemented; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - return Py_INCREF(res), res; -} - -//---------------------SEQUENCE PROTOCOLS------------------------ -//----------------------------len(object)------------------------ -//sequence length -static int Color_len(ColorObject *UNUSED(self)) -{ - return COLOR_SIZE; -} -//----------------------------object[]--------------------------- -//sequence accessor (get) -static PyObject *Color_item(ColorObject * self, int i) -{ - if(i<0) i= COLOR_SIZE-i; - - if(i < 0 || i >= COLOR_SIZE) { - PyErr_SetString(PyExc_IndexError, "color[attribute]: array index out of range"); - return NULL; - } - - if(BaseMath_ReadIndexCallback(self, i) == -1) - return NULL; - - return PyFloat_FromDouble(self->col[i]); - -} -//----------------------------object[]------------------------- -//sequence accessor (set) -static int Color_ass_item(ColorObject * self, int i, PyObject *value) -{ - float f = PyFloat_AsDouble(value); - - if(f == -1 && PyErr_Occurred()) { // parsed item not a number - PyErr_SetString(PyExc_TypeError, "color[attribute] = x: argument not a number"); - return -1; - } - - if(i<0) i= COLOR_SIZE-i; - - if(i < 0 || i >= COLOR_SIZE){ - PyErr_SetString(PyExc_IndexError, "color[attribute] = x: array assignment index out of range"); - return -1; - } - - self->col[i] = f; - - if(BaseMath_WriteIndexCallback(self, i) == -1) - return -1; - - return 0; -} -//----------------------------object[z:y]------------------------ -//sequence slice (get) -static PyObject *Color_slice(ColorObject * self, int begin, int end) -{ - PyObject *tuple; - int count; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - CLAMP(begin, 0, COLOR_SIZE); - if (end<0) end= (COLOR_SIZE + 1) + end; - CLAMP(end, 0, COLOR_SIZE); - begin= MIN2(begin, end); - - tuple= PyTuple_New(end - begin); - for(count= begin; count < end; count++) { - PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count])); - } - - return tuple; -} -//----------------------------object[z:y]------------------------ -//sequence slice (set) -static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq) -{ - int i, size; - float col[COLOR_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - CLAMP(begin, 0, COLOR_SIZE); - if (end<0) end= (COLOR_SIZE + 1) + end; - CLAMP(end, 0, COLOR_SIZE); - begin = MIN2(begin, end); - - if((size=mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1) - return -1; - - if(size != (end - begin)){ - PyErr_SetString(PyExc_TypeError, "color[begin:end] = []: size mismatch in slice assignment"); - return -1; - } - - for(i= 0; i < COLOR_SIZE; i++) - self->col[begin + i] = col[i]; - - (void)BaseMath_WriteCallback(self); - return 0; -} - -static PyObject *Color_subscript(ColorObject *self, PyObject *item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += COLOR_SIZE; - return Color_item(self, i); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) - return NULL; - - if (slicelength <= 0) { - return PyTuple_New(0); - } - else if (step == 1) { - return Color_slice(self, start, stop); - } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with color"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } -} - -static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += COLOR_SIZE; - return Color_ass_item(self, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) - return -1; - - if (step == 1) - return Color_ass_slice(self, start, stop, value); - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with color"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return -1; - } -} - -//-----------------PROTCOL DECLARATIONS-------------------------- -static PySequenceMethods Color_SeqMethods = { - (lenfunc) Color_len, /* sq_length */ - (binaryfunc) NULL, /* sq_concat */ - (ssizeargfunc) NULL, /* sq_repeat */ - (ssizeargfunc) Color_item, /* sq_item */ - NULL, /* sq_slice, deprecated */ - (ssizeobjargproc) Color_ass_item, /* sq_ass_item */ - NULL, /* sq_ass_slice, deprecated */ - (objobjproc) NULL, /* sq_contains */ - (binaryfunc) NULL, /* sq_inplace_concat */ - (ssizeargfunc) NULL, /* sq_inplace_repeat */ -}; - -static PyMappingMethods Color_AsMapping = { - (lenfunc)Color_len, - (binaryfunc)Color_subscript, - (objobjargproc)Color_ass_subscript -}; - -/* numeric */ - - -/* addition: obj + obj */ -static PyObject *Color_add(PyObject *v1, PyObject *v2) -{ - ColorObject *color1 = NULL, *color2 = NULL; - float col[COLOR_SIZE]; - - if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Color addition: arguments not valid for this operation"); - return NULL; - } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; - - if(BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) - return NULL; - - add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE); - - return newColorObject(col, Py_NEW, Py_TYPE(v1)); -} - -/* addition in-place: obj += obj */ -static PyObject *Color_iadd(PyObject *v1, PyObject *v2) -{ - ColorObject *color1 = NULL, *color2 = NULL; - - if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Color addition: arguments not valid for this operation"); - return NULL; - } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; - - if(BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) - return NULL; - - add_vn_vn(color1->col, color2->col, COLOR_SIZE); - - (void)BaseMath_WriteCallback(color1); - Py_INCREF(v1); - return v1; -} - -/* subtraction: obj - obj */ -static PyObject *Color_sub(PyObject *v1, PyObject *v2) -{ - ColorObject *color1 = NULL, *color2 = NULL; - float col[COLOR_SIZE]; - - if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Color subtraction: arguments not valid for this operation"); - return NULL; - } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; - - if(BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) - return NULL; - - sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE); - - return newColorObject(col, Py_NEW, Py_TYPE(v1)); -} - -/* subtraction in-place: obj -= obj */ -static PyObject *Color_isub(PyObject *v1, PyObject *v2) -{ - ColorObject *color1= NULL, *color2= NULL; - - if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Color subtraction: arguments not valid for this operation"); - return NULL; - } - color1 = (ColorObject*)v1; - color2 = (ColorObject*)v2; - - if(BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) - return NULL; - - sub_vn_vn(color1->col, color2->col, COLOR_SIZE); - - (void)BaseMath_WriteCallback(color1); - Py_INCREF(v1); - return v1; -} - -static PyObject *color_mul_float(ColorObject *color, const float scalar) -{ - float tcol[COLOR_SIZE]; - mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar); - return newColorObject(tcol, Py_NEW, Py_TYPE(color)); -} - - -static PyObject *Color_mul(PyObject *v1, PyObject *v2) -{ - ColorObject *color1 = NULL, *color2 = NULL; - float scalar; - - if ColorObject_Check(v1) { - color1= (ColorObject *)v1; - if(BaseMath_ReadCallback(color1) == -1) - return NULL; - } - if ColorObject_Check(v2) { - color2= (ColorObject *)v2; - if(BaseMath_ReadCallback(color2) == -1) - return NULL; - } - - - /* make sure v1 is always the vector */ - if (color1 && color2) { - /* col * col, dont support yet! */ - } - else if (color1) { - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR * FLOAT */ - return color_mul_float(color1, scalar); - } - } - else if (color2) { - if (((scalar= PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred())==0) { /* FLOAT * COLOR */ - return color_mul_float(color2, scalar); - } - } - else { - BLI_assert(!"internal error"); - } - - PyErr_Format(PyExc_TypeError, "Color multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); - return NULL; -} - -static PyObject *Color_div(PyObject *v1, PyObject *v2) -{ - ColorObject *color1 = NULL; - float scalar; - - if ColorObject_Check(v1) { - color1= (ColorObject *)v1; - if(BaseMath_ReadCallback(color1) == -1) - return NULL; - } - else { - PyErr_SetString(PyExc_TypeError, "Color division not supported in this order"); - return NULL; - } - - /* make sure v1 is always the vector */ - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR * FLOAT */ - if(scalar==0.0f) { - PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error"); - return NULL; - } - return color_mul_float(color1, 1.0f / scalar); - } - - PyErr_Format(PyExc_TypeError, "Color multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); - return NULL; -} - -/* mulplication in-place: obj *= obj */ -static PyObject *Color_imul(PyObject *v1, PyObject *v2) -{ - ColorObject *color = (ColorObject *)v1; - float scalar; - - if(BaseMath_ReadCallback(color) == -1) - return NULL; - - /* only support color *= float */ - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR *= FLOAT */ - mul_vn_fl(color->col, COLOR_SIZE, scalar); - } - else { - PyErr_SetString(PyExc_TypeError, "Color multiplication: arguments not acceptable for this operation"); - return NULL; - } - - (void)BaseMath_WriteCallback(color); - Py_INCREF(v1); - return v1; -} - -/* mulplication in-place: obj *= obj */ -static PyObject *Color_idiv(PyObject *v1, PyObject *v2) -{ - ColorObject *color = (ColorObject *)v1; - float scalar; - - if(BaseMath_ReadCallback(color) == -1) - return NULL; - - /* only support color /= float */ - if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* COLOR /= FLOAT */ - if(scalar==0.0f) { - PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error"); - return NULL; - } - - mul_vn_fl(color->col, COLOR_SIZE, 1.0f / scalar); - } - else { - PyErr_SetString(PyExc_TypeError, "Color multiplication: arguments not acceptable for this operation"); - return NULL; - } - - (void)BaseMath_WriteCallback(color); - Py_INCREF(v1); - return v1; -} - -/* -obj - returns the negative of this object*/ -static PyObject *Color_neg(ColorObject *self) -{ - float tcol[COLOR_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - negate_vn_vn(tcol, self->col, COLOR_SIZE); - return newColorObject(tcol, Py_NEW, Py_TYPE(self)); -} - - -static PyNumberMethods Color_NumMethods = { - (binaryfunc) Color_add, /*nb_add*/ - (binaryfunc) Color_sub, /*nb_subtract*/ - (binaryfunc) Color_mul, /*nb_multiply*/ - NULL, /*nb_remainder*/ - NULL, /*nb_divmod*/ - NULL, /*nb_power*/ - (unaryfunc) Color_neg, /*nb_negative*/ - (unaryfunc) NULL, /*tp_positive*/ - (unaryfunc) NULL, /*tp_absolute*/ - (inquiry) NULL, /*tp_bool*/ - (unaryfunc) NULL, /*nb_invert*/ - NULL, /*nb_lshift*/ - (binaryfunc)NULL, /*nb_rshift*/ - NULL, /*nb_and*/ - NULL, /*nb_xor*/ - NULL, /*nb_or*/ - NULL, /*nb_int*/ - NULL, /*nb_reserved*/ - NULL, /*nb_float*/ - Color_iadd, /* nb_inplace_add */ - Color_isub, /* nb_inplace_subtract */ - Color_imul, /* nb_inplace_multiply */ - NULL, /* nb_inplace_remainder */ - NULL, /* nb_inplace_power */ - NULL, /* nb_inplace_lshift */ - NULL, /* nb_inplace_rshift */ - NULL, /* nb_inplace_and */ - NULL, /* nb_inplace_xor */ - NULL, /* nb_inplace_or */ - NULL, /* nb_floor_divide */ - Color_div, /* nb_true_divide */ - NULL, /* nb_inplace_floor_divide */ - Color_idiv, /* nb_inplace_true_divide */ - NULL, /* nb_index */ -}; - -/* color channel, vector.r/g/b */ -static PyObject *Color_getChannel(ColorObject * self, void *type) -{ - return Color_item(self, GET_INT_FROM_POINTER(type)); -} - -static int Color_setChannel(ColorObject * self, PyObject *value, void * type) -{ - return Color_ass_item(self, GET_INT_FROM_POINTER(type), value); -} - -/* color channel (HSV), color.h/s/v */ -static PyObject *Color_getChannelHSV(ColorObject * self, void *type) -{ - float hsv[3]; - int i= GET_INT_FROM_POINTER(type); - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); - - return PyFloat_FromDouble(hsv[i]); -} - -static int Color_setChannelHSV(ColorObject * self, PyObject *value, void * type) -{ - float hsv[3]; - int i= GET_INT_FROM_POINTER(type); - float f = PyFloat_AsDouble(value); - - if(f == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "color.h/s/v = value: argument not a number"); - return -1; - } - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); - CLAMP(f, 0.0f, 1.0f); - hsv[i] = f; - hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2])); - - if(BaseMath_WriteCallback(self) == -1) - return -1; - - return 0; -} - -/* color channel (HSV), color.h/s/v */ -static PyObject *Color_getHSV(ColorObject * self, void *UNUSED(closure)) -{ - float hsv[3]; - PyObject *ret; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); - - ret= PyTuple_New(3); - PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(hsv[0])); - PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(hsv[1])); - PyTuple_SET_ITEM(ret, 2, PyFloat_FromDouble(hsv[2])); - return ret; -} - -static int Color_setHSV(ColorObject * self, PyObject *value, void *UNUSED(closure)) -{ - float hsv[3]; - - if(mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1) - return -1; - - CLAMP(hsv[0], 0.0f, 1.0f); - CLAMP(hsv[1], 0.0f, 1.0f); - CLAMP(hsv[2], 0.0f, 1.0f); - - hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2])); - - if(BaseMath_WriteCallback(self) == -1) - return -1; - - return 0; -} - -/*****************************************************************************/ -/* Python attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef Color_getseters[] = { - {(char *)"r", (getter)Color_getChannel, (setter)Color_setChannel, (char *)"Red color channel.\n\n:type: float", (void *)0}, - {(char *)"g", (getter)Color_getChannel, (setter)Color_setChannel, (char *)"Green color channel.\n\n:type: float", (void *)1}, - {(char *)"b", (getter)Color_getChannel, (setter)Color_setChannel, (char *)"Blue color channel.\n\n:type: float", (void *)2}, - - {(char *)"h", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, (char *)"HSV Hue component in [0, 1].\n\n:type: float", (void *)0}, - {(char *)"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, (char *)"HSV Saturation component in [0, 1].\n\n:type: float", (void *)1}, - {(char *)"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, (char *)"HSV Value component in [0, 1].\n\n:type: float", (void *)2}, - - {(char *)"hsv", (getter)Color_getHSV, (setter)Color_setHSV, (char *)"HSV Values in [0, 1].\n\n:type: float triplet", (void *)0}, - - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL}, - {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ -}; - - -//-----------------------METHOD DEFINITIONS ---------------------- -static struct PyMethodDef Color_methods[] = { - {"__copy__", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc}, - {"copy", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc}, - {NULL, NULL, 0, NULL} -}; - -//------------------PY_OBECT DEFINITION-------------------------- -PyDoc_STRVAR(color_doc, -"This object gives access to Colors in Blender." -); -PyTypeObject color_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "mathutils.Color", //tp_name - sizeof(ColorObject), //tp_basicsize - 0, //tp_itemsize - (destructor)BaseMathObject_dealloc, //tp_dealloc - NULL, //tp_print - NULL, //tp_getattr - NULL, //tp_setattr - NULL, //tp_compare - (reprfunc) Color_repr, //tp_repr - &Color_NumMethods, //tp_as_number - &Color_SeqMethods, //tp_as_sequence - &Color_AsMapping, //tp_as_mapping - NULL, //tp_hash - NULL, //tp_call - NULL, //tp_str - NULL, //tp_getattro - NULL, //tp_setattro - NULL, //tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags - color_doc, //tp_doc - (traverseproc)BaseMathObject_traverse, //tp_traverse - (inquiry)BaseMathObject_clear, //tp_clear - (richcmpfunc)Color_richcmpr, //tp_richcompare - 0, //tp_weaklistoffset - NULL, //tp_iter - NULL, //tp_iternext - Color_methods, //tp_methods - NULL, //tp_members - Color_getseters, //tp_getset - NULL, //tp_base - NULL, //tp_dict - NULL, //tp_descr_get - NULL, //tp_descr_set - 0, //tp_dictoffset - NULL, //tp_init - NULL, //tp_alloc - Color_new, //tp_new - NULL, //tp_free - NULL, //tp_is_gc - NULL, //tp_bases - NULL, //tp_mro - NULL, //tp_cache - NULL, //tp_subclasses - NULL, //tp_weaklist - NULL //tp_del -}; -//------------------------newColorObject (internal)------------- -//creates a new color object -/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newColorObject(float *col, int type, PyTypeObject *base_type) -{ - ColorObject *self; - - self= base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) : - (ColorObject *)PyObject_GC_New(ColorObject, &color_Type); - - if(self) { - /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; - - if(type == Py_WRAP){ - self->col = col; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW){ - self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float)); - if(col) - copy_v3_v3(self->col, col); - else - zero_v3(self->col); - - self->wrapped = Py_NEW; - } - else { - PyErr_SetString(PyExc_RuntimeError, "Color(): invalid type"); - return NULL; - } - } - - return (PyObject *)self; -} - -PyObject *newColorObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) -{ - ColorObject *self= (ColorObject *)newColorObject(NULL, Py_NEW, NULL); - if(self) { - Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; - PyObject_GC_Track(self); - } - - return (PyObject *)self; -} diff --git a/source/blender/python/generic/mathutils_Color.h b/source/blender/python/generic/mathutils_Color.h deleted file mode 100644 index 0fc880363f4..00000000000 --- a/source/blender/python/generic/mathutils_Color.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -/** \file blender/python/generic/mathutils_Color.h - * \ingroup pygen - */ - - -#ifndef MATHUTILS_COLOR_H -#define MATHUTILS_COLOR_H - -extern PyTypeObject color_Type; -#define ColorObject_Check(_v) PyObject_TypeCheck((_v), &color_Type) - -typedef struct { - BASE_MATH_MEMBERS(col) -} ColorObject; - -/*struct data contains a pointer to the actual data that the -object uses. It can use either PyMem allocated data (which will -be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ - -//prototypes -PyObject *newColorObject( float *col, int type, PyTypeObject *base_type); -PyObject *newColorObject_cb(PyObject *cb_user, int cb_type, int cb_subtype); - -#endif /* MATHUTILS_COLOR_H */ diff --git a/source/blender/python/generic/mathutils_Euler.c b/source/blender/python/generic/mathutils_Euler.c deleted file mode 100644 index 4281c7bf6c5..00000000000 --- a/source/blender/python/generic/mathutils_Euler.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils_Euler.c - * \ingroup pygen - */ - - -#include <Python.h> - -#include "mathutils.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#ifndef int32_t -#include "BLO_sys_types.h" -#endif - -#define EULER_SIZE 3 - -//----------------------------------mathutils.Euler() ------------------- -//makes a new euler for you to play with -static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *seq= NULL; - const char *order_str= NULL; - - float eul[EULER_SIZE]= {0.0f, 0.0f, 0.0f}; - short order= EULER_ORDER_XYZ; - - if(kwds && PyDict_Size(kwds)) { - PyErr_SetString(PyExc_TypeError, "mathutils.Euler(): takes no keyword args"); - return NULL; - } - - if(!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str)) - return NULL; - - switch(PyTuple_GET_SIZE(args)) { - case 0: - break; - case 2: - if((order=euler_order_from_string(order_str, "mathutils.Euler()")) == -1) - return NULL; - /* intentionally pass through */ - case 1: - if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1) - return NULL; - break; - } - return newEulerObject(eul, order, Py_NEW, type); -} - -/* internal use, assuem read callback is done */ -static const char *euler_order_str(EulerObject *self) -{ - static const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"}; - return order[self->order-EULER_ORDER_XYZ]; -} - -short euler_order_from_string(const char *str, const char *error_prefix) -{ - if((str[0] && str[1] && str[2] && str[3]=='\0')) { - switch(*((int32_t *)str)) { - case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ; - case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY; - case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ; - case 'Y'|'Z'<<8|'X'<<16: return EULER_ORDER_YZX; - case 'Z'|'X'<<8|'Y'<<16: return EULER_ORDER_ZXY; - case 'Z'|'Y'<<8|'X'<<16: return EULER_ORDER_ZYX; - } - } - - PyErr_Format(PyExc_TypeError, "%s: invalid euler order '%s'", error_prefix, str); - return -1; -} - -/* note: BaseMath_ReadCallback must be called beforehand */ -static PyObject *Euler_ToTupleExt(EulerObject *self, int ndigits) -{ - PyObject *ret; - int i; - - ret= PyTuple_New(EULER_SIZE); - - if(ndigits >= 0) { - for(i= 0; i < EULER_SIZE; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits))); - } - } - else { - for(i= 0; i < EULER_SIZE; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->eul[i])); - } - } - - return ret; -} - -//-----------------------------METHODS---------------------------- -//return a quaternion representation of the euler - -PyDoc_STRVAR(Euler_to_quaternion_doc, -".. method:: to_quaternion()\n" -"\n" -" Return a quaternion representation of the euler.\n" -"\n" -" :return: Quaternion representation of the euler.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Euler_to_quaternion(EulerObject * self) -{ - float quat[4]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - eulO_to_quat(quat, self->eul, self->order); - - return newQuaternionObject(quat, Py_NEW, NULL); -} - -//return a matrix representation of the euler -PyDoc_STRVAR(Euler_to_matrix_doc, -".. method:: to_matrix()\n" -"\n" -" Return a matrix representation of the euler.\n" -"\n" -" :return: A 3x3 roation matrix representation of the euler.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Euler_to_matrix(EulerObject * self) -{ - float mat[9]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - eulO_to_mat3((float (*)[3])mat, self->eul, self->order); - - return newMatrixObject(mat, 3, 3 , Py_NEW, NULL); -} - -PyDoc_STRVAR(Euler_zero_doc, -".. method:: zero()\n" -"\n" -" Set all values to zero.\n" -); -static PyObject *Euler_zero(EulerObject * self) -{ - zero_v3(self->eul); - - if(BaseMath_WriteCallback(self) == -1) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Euler_rotate_axis_doc, -".. method:: rotate_axis(axis, angle)\n" -"\n" -" Rotates the euler a certain amount and returning a unique euler rotation\n" -" (no 720 degree pitches).\n" -"\n" -" :arg axis: single character in ['X, 'Y', 'Z'].\n" -" :type axis: string\n" -" :arg angle: angle in radians.\n" -" :type angle: float\n" -); -static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args) -{ - float angle = 0.0f; - const char *axis; - - if(!PyArg_ParseTuple(args, "sf:rotate", &axis, &angle)){ - PyErr_SetString(PyExc_TypeError, "euler.rotate(): expected angle (float) and axis (x, y, z)"); - return NULL; - } - if(!(ELEM3(*axis, 'X', 'Y', 'Z') && axis[1]=='\0')){ - PyErr_SetString(PyExc_TypeError, "euler.rotate(): expected axis to be 'X', 'Y' or 'Z'"); - return NULL; - } - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - - rotate_eulO(self->eul, self->order, *axis, angle); - - (void)BaseMath_WriteCallback(self); - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Euler_rotate_doc, -".. method:: rotate(other)\n" -"\n" -" Rotates the euler a by another mathutils value.\n" -"\n" -" :arg other: rotation component of mathutils value\n" -" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" -); -static PyObject *Euler_rotate(EulerObject * self, PyObject *value) -{ - float self_rmat[3][3], other_rmat[3][3], rmat[3][3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1) - return NULL; - - eulO_to_mat3(self_rmat, self->eul, self->order); - mul_m3_m3m3(rmat, self_rmat, other_rmat); - - mat3_to_compatible_eulO(self->eul, self->eul, self->order, rmat); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Euler_make_compatible_doc, -".. method:: make_compatible(other)\n" -"\n" -" Make this euler compatible with another,\n" -" so interpolating between them works as intended.\n" -"\n" -" .. note:: the rotation order is not taken into account for this function.\n" -); -static PyObject *Euler_make_compatible(EulerObject * self, PyObject *value) -{ - float teul[EULER_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value, "euler.make_compatible(other), invalid 'other' arg") == -1) - return NULL; - - compatible_eul(self->eul, teul); - - (void)BaseMath_WriteCallback(self); - - Py_RETURN_NONE; -} - -//----------------------------Euler.rotate()----------------------- -// return a copy of the euler - -PyDoc_STRVAR(Euler_copy_doc, -".. function:: copy()\n" -"\n" -" Returns a copy of this euler.\n" -"\n" -" :return: A copy of the euler.\n" -" :rtype: :class:`Euler`\n" -"\n" -" .. note:: use this to get a copy of a wrapped euler with\n" -" no reference to the original data.\n" -); -static PyObject *Euler_copy(EulerObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return newEulerObject(self->eul, self->order, Py_NEW, Py_TYPE(self)); -} - -//----------------------------print object (internal)-------------- -//print the object to screen - -static PyObject *Euler_repr(EulerObject * self) -{ - PyObject *ret, *tuple; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - tuple= Euler_ToTupleExt(self, -1); - - ret= PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self)); - - Py_DECREF(tuple); - return ret; -} - -static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op) -{ - PyObject *res; - int ok= -1; /* zero is true */ - - if (EulerObject_Check(a) && EulerObject_Check(b)) { - EulerObject *eulA= (EulerObject*)a; - EulerObject *eulB= (EulerObject*)b; - - if(BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1) - return NULL; - - ok= ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1; - } - - switch (op) { - case Py_NE: - ok = !ok; /* pass through */ - case Py_EQ: - res = ok ? Py_False : Py_True; - break; - - case Py_LT: - case Py_LE: - case Py_GT: - case Py_GE: - res = Py_NotImplemented; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - return Py_INCREF(res), res; -} - -//---------------------SEQUENCE PROTOCOLS------------------------ -//----------------------------len(object)------------------------ -//sequence length -static int Euler_len(EulerObject *UNUSED(self)) -{ - return EULER_SIZE; -} -//----------------------------object[]--------------------------- -//sequence accessor (get) -static PyObject *Euler_item(EulerObject * self, int i) -{ - if(i<0) i= EULER_SIZE-i; - - if(i < 0 || i >= EULER_SIZE) { - PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range"); - return NULL; - } - - if(BaseMath_ReadIndexCallback(self, i) == -1) - return NULL; - - return PyFloat_FromDouble(self->eul[i]); - -} -//----------------------------object[]------------------------- -//sequence accessor (set) -static int Euler_ass_item(EulerObject * self, int i, PyObject *value) -{ - float f = PyFloat_AsDouble(value); - - if(f == -1 && PyErr_Occurred()) { // parsed item not a number - PyErr_SetString(PyExc_TypeError, "euler[attribute] = x: argument not a number"); - return -1; - } - - if(i<0) i= EULER_SIZE-i; - - if(i < 0 || i >= EULER_SIZE){ - PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range"); - return -1; - } - - self->eul[i] = f; - - if(BaseMath_WriteIndexCallback(self, i) == -1) - return -1; - - return 0; -} -//----------------------------object[z:y]------------------------ -//sequence slice (get) -static PyObject *Euler_slice(EulerObject * self, int begin, int end) -{ - PyObject *tuple; - int count; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - CLAMP(begin, 0, EULER_SIZE); - if (end<0) end= (EULER_SIZE + 1) + end; - CLAMP(end, 0, EULER_SIZE); - begin= MIN2(begin, end); - - tuple= PyTuple_New(end - begin); - for(count = begin; count < end; count++) { - PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->eul[count])); - } - - return tuple; -} -//----------------------------object[z:y]------------------------ -//sequence slice (set) -static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq) -{ - int i, size; - float eul[EULER_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - CLAMP(begin, 0, EULER_SIZE); - if (end<0) end= (EULER_SIZE + 1) + end; - CLAMP(end, 0, EULER_SIZE); - begin = MIN2(begin, end); - - if((size=mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1) - return -1; - - if(size != (end - begin)){ - PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: size mismatch in slice assignment"); - return -1; - } - - for(i= 0; i < EULER_SIZE; i++) - self->eul[begin + i] = eul[i]; - - (void)BaseMath_WriteCallback(self); - return 0; -} - -static PyObject *Euler_subscript(EulerObject *self, PyObject *item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += EULER_SIZE; - return Euler_item(self, i); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) - return NULL; - - if (slicelength <= 0) { - return PyTuple_New(0); - } - else if (step == 1) { - return Euler_slice(self, start, stop); - } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with eulers"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } -} - - -static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += EULER_SIZE; - return Euler_ass_item(self, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) - return -1; - - if (step == 1) - return Euler_ass_slice(self, start, stop, value); - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with euler"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return -1; - } -} - -//-----------------PROTCOL DECLARATIONS-------------------------- -static PySequenceMethods Euler_SeqMethods = { - (lenfunc) Euler_len, /* sq_length */ - (binaryfunc) NULL, /* sq_concat */ - (ssizeargfunc) NULL, /* sq_repeat */ - (ssizeargfunc) Euler_item, /* sq_item */ - (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ - (ssizeobjargproc) Euler_ass_item, /* sq_ass_item */ - (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */ - (objobjproc) NULL, /* sq_contains */ - (binaryfunc) NULL, /* sq_inplace_concat */ - (ssizeargfunc) NULL, /* sq_inplace_repeat */ -}; - -static PyMappingMethods Euler_AsMapping = { - (lenfunc)Euler_len, - (binaryfunc)Euler_subscript, - (objobjargproc)Euler_ass_subscript -}; - -/* - * euler axis, euler.x/y/z - */ -static PyObject *Euler_getAxis(EulerObject *self, void *type) -{ - return Euler_item(self, GET_INT_FROM_POINTER(type)); -} - -static int Euler_setAxis(EulerObject *self, PyObject *value, void *type) -{ - return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value); -} - -/* rotation order */ -static PyObject *Euler_getOrder(EulerObject *self, void *UNUSED(closure)) -{ - if(BaseMath_ReadCallback(self) == -1) /* can read order too */ - return NULL; - - return PyUnicode_FromString(euler_order_str(self)); -} - -static int Euler_setOrder(EulerObject *self, PyObject *value, void *UNUSED(closure)) -{ - const char *order_str= _PyUnicode_AsString(value); - short order= euler_order_from_string(order_str, "euler.order"); - - if(order == -1) - return -1; - - self->order= order; - (void)BaseMath_WriteCallback(self); /* order can be written back */ - return 0; -} - -/*****************************************************************************/ -/* Python attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef Euler_getseters[] = { - {(char *)"x", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler X axis in radians.\n\n:type: float", (void *)0}, - {(char *)"y", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler Y axis in radians.\n\n:type: float", (void *)1}, - {(char *)"z", (getter)Euler_getAxis, (setter)Euler_setAxis, (char *)"Euler Z axis in radians.\n\n:type: float", (void *)2}, - {(char *)"order", (getter)Euler_getOrder, (setter)Euler_setOrder, (char *)"Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']", (void *)NULL}, - - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, - {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ -}; - - -//-----------------------METHOD DEFINITIONS ---------------------- -static struct PyMethodDef Euler_methods[] = { - {"zero", (PyCFunction) Euler_zero, METH_NOARGS, Euler_zero_doc}, - {"to_matrix", (PyCFunction) Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc}, - {"to_quaternion", (PyCFunction) Euler_to_quaternion, METH_NOARGS, Euler_to_quaternion_doc}, - {"rotate_axis", (PyCFunction) Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc}, - {"rotate", (PyCFunction) Euler_rotate, METH_O, Euler_rotate_doc}, - {"make_compatible", (PyCFunction) Euler_make_compatible, METH_O, Euler_make_compatible_doc}, - {"__copy__", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc}, - {"copy", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc}, - {NULL, NULL, 0, NULL} -}; - -//------------------PY_OBECT DEFINITION-------------------------- -PyDoc_STRVAR(euler_doc, -"This object gives access to Eulers in Blender." -); -PyTypeObject euler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "mathutils.Euler", //tp_name - sizeof(EulerObject), //tp_basicsize - 0, //tp_itemsize - (destructor)BaseMathObject_dealloc, //tp_dealloc - NULL, //tp_print - NULL, //tp_getattr - NULL, //tp_setattr - NULL, //tp_compare - (reprfunc) Euler_repr, //tp_repr - NULL, //tp_as_number - &Euler_SeqMethods, //tp_as_sequence - &Euler_AsMapping, //tp_as_mapping - NULL, //tp_hash - NULL, //tp_call - NULL, //tp_str - NULL, //tp_getattro - NULL, //tp_setattro - NULL, //tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags - euler_doc, //tp_doc - (traverseproc)BaseMathObject_traverse, //tp_traverse - (inquiry)BaseMathObject_clear, //tp_clear - (richcmpfunc)Euler_richcmpr, //tp_richcompare - 0, //tp_weaklistoffset - NULL, //tp_iter - NULL, //tp_iternext - Euler_methods, //tp_methods - NULL, //tp_members - Euler_getseters, //tp_getset - NULL, //tp_base - NULL, //tp_dict - NULL, //tp_descr_get - NULL, //tp_descr_set - 0, //tp_dictoffset - NULL, //tp_init - NULL, //tp_alloc - Euler_new, //tp_new - NULL, //tp_free - NULL, //tp_is_gc - NULL, //tp_bases - NULL, //tp_mro - NULL, //tp_cache - NULL, //tp_subclasses - NULL, //tp_weaklist - NULL //tp_del -}; -//------------------------newEulerObject (internal)------------- -//creates a new euler object -/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_type) -{ - EulerObject *self; - - self= base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) : - (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type); - - if(self) { - /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; - - if(type == Py_WRAP) { - self->eul = eul; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW) { - self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float)); - if(eul) { - copy_v3_v3(self->eul, eul); - } - else { - zero_v3(self->eul); - } - - self->wrapped = Py_NEW; - } - else { - PyErr_SetString(PyExc_RuntimeError, "Euler(): invalid type"); - return NULL; - } - - self->order= order; - } - - return (PyObject *)self; -} - -PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype) -{ - EulerObject *self= (EulerObject *)newEulerObject(NULL, order, Py_NEW, NULL); - if(self) { - Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; - PyObject_GC_Track(self); - } - - return (PyObject *)self; -} diff --git a/source/blender/python/generic/mathutils_Euler.h b/source/blender/python/generic/mathutils_Euler.h deleted file mode 100644 index 849e16c2bb7..00000000000 --- a/source/blender/python/generic/mathutils_Euler.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -/** \file blender/python/generic/mathutils_Euler.h - * \ingroup pygen - */ - - -#ifndef MATHUTILS_EULER_H -#define MATHUTILS_EULER_H - -extern PyTypeObject euler_Type; -#define EulerObject_Check(_v) PyObject_TypeCheck((_v), &euler_Type) - -typedef struct { - BASE_MATH_MEMBERS(eul) - unsigned char order; /* rotation order */ - -} EulerObject; - -/*struct data contains a pointer to the actual data that the -object uses. It can use either PyMem allocated data (which will -be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ - -//prototypes -PyObject *newEulerObject( float *eul, short order, int type, PyTypeObject *base_type); -PyObject *newEulerObject_cb(PyObject *cb_user, short order, int cb_type, int cb_subtype); - -short euler_order_from_string(const char *str, const char *error_prefix); - - -#endif /* MATHUTILS_EULER_H */ diff --git a/source/blender/python/generic/mathutils_Matrix.c b/source/blender/python/generic/mathutils_Matrix.c deleted file mode 100644 index 4b7f9dc0d97..00000000000 --- a/source/blender/python/generic/mathutils_Matrix.c +++ /dev/null @@ -1,1934 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Michel Selten & Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils_Matrix.c - * \ingroup pygen - */ - - -#include <Python.h> - -#include "mathutils.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -static PyObject *Matrix_copy(MatrixObject *self); -static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value); -static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self); - -/* matrix vector callbacks */ -int mathutils_matrix_vector_cb_index= -1; - -static int mathutils_matrix_vector_check(BaseMathObject *bmo) -{ - MatrixObject *self= (MatrixObject *)bmo->cb_user; - return BaseMath_ReadCallback(self); -} - -static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype) -{ - MatrixObject *self= (MatrixObject *)bmo->cb_user; - int i; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - for(i=0; i < self->col_size; i++) - bmo->data[i]= self->matrix[subtype][i]; - - return 0; -} - -static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype) -{ - MatrixObject *self= (MatrixObject *)bmo->cb_user; - int i; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - for(i=0; i < self->col_size; i++) - self->matrix[subtype][i]= bmo->data[i]; - - (void)BaseMath_WriteCallback(self); - return 0; -} - -static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int subtype, int index) -{ - MatrixObject *self= (MatrixObject *)bmo->cb_user; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - bmo->data[index]= self->matrix[subtype][index]; - return 0; -} - -static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int subtype, int index) -{ - MatrixObject *self= (MatrixObject *)bmo->cb_user; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - self->matrix[subtype][index]= bmo->data[index]; - - (void)BaseMath_WriteCallback(self); - return 0; -} - -Mathutils_Callback mathutils_matrix_vector_cb = { - mathutils_matrix_vector_check, - mathutils_matrix_vector_get, - mathutils_matrix_vector_set, - mathutils_matrix_vector_get_index, - mathutils_matrix_vector_set_index -}; -/* matrix vector callbacks, this is so you can do matrix[i][j] = val */ - -//----------------------------------mathutils.Matrix() ----------------- -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. -//create a new matrix type -static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - if(kwds && PyDict_Size(kwds)) { - PyErr_SetString(PyExc_TypeError, "mathutils.Matrix(): takes no keyword args"); - return NULL; - } - - switch(PyTuple_GET_SIZE(args)) { - case 0: - return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW, type); - case 1: - { - PyObject *arg= PyTuple_GET_ITEM(args, 0); - - const unsigned short row_size= PySequence_Size(arg); /* -1 is an error, size checks will accunt for this */ - - if(row_size >= 2 && row_size <= 4) { - PyObject *item= PySequence_GetItem(arg, 0); - const unsigned short col_size= PySequence_Size(item); - Py_XDECREF(item); - - if(col_size >= 2 && col_size <= 4) { - /* sane row & col size, new matrix and assign as slice */ - PyObject *matrix= newMatrixObject(NULL, row_size, col_size, Py_NEW, type); - if(Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { - return matrix; - } - else { /* matrix ok, slice assignment not */ - Py_DECREF(matrix); - } - } - } - } - } - - /* will overwrite error */ - PyErr_SetString(PyExc_TypeError, "mathutils.Matrix(): expects no args or 2-4 numeric sequences"); - return NULL; -} - -static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self) -{ - PyObject *ret= Matrix_copy(self); - PyObject *ret_dummy= matrix_func(ret); - if(ret_dummy) { - Py_DECREF(ret_dummy); - return (PyObject *)ret; - } - else { /* error */ - Py_DECREF(ret); - return NULL; - } -} - -/* when a matrix is 4x4 size but initialized as a 3x3, re-assign values for 4x4 */ -static void matrix_3x3_as_4x4(float mat[16]) -{ - mat[10] = mat[8]; - mat[9] = mat[7]; - mat[8] = mat[6]; - mat[7] = 0.0f; - mat[6] = mat[5]; - mat[5] = mat[4]; - mat[4] = mat[3]; - mat[3] = 0.0f; -} - -/*-----------------------CLASS-METHODS----------------------------*/ - -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. -PyDoc_STRVAR(C_Matrix_Rotation_doc, -".. classmethod:: Rotation(angle, size, axis)\n" -"\n" -" Create a matrix representing a rotation.\n" -"\n" -" :arg angle: The angle of rotation desired, in radians.\n" -" :type angle: float\n" -" :arg size: The size of the rotation matrix to construct [2, 4].\n" -" :type size: int\n" -" :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object\n" -" (optional when size is 2).\n" -" :type axis: string or :class:`Vector`\n" -" :return: A new rotation matrix.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) -{ - PyObject *vec= NULL; - const char *axis= NULL; - int matSize; - double angle; /* use double because of precision problems at high values */ - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - - if(!PyArg_ParseTuple(args, "di|O", &angle, &matSize, &vec)) { - PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(angle, size, axis): expected float int and a string or vector"); - return NULL; - } - - if(vec && PyUnicode_Check(vec)) { - axis= _PyUnicode_AsString((PyObject *)vec); - if(axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') { - PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(): 3rd argument axis value must be a 3D vector or a string in 'X', 'Y', 'Z'"); - return NULL; - } - else { - /* use the string */ - vec= NULL; - } - } - - angle= angle_wrap_rad(angle); - - if(matSize != 2 && matSize != 3 && matSize != 4) { - PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix"); - return NULL; - } - if(matSize == 2 && (vec != NULL)) { - PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis"); - return NULL; - } - if((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) { - PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): axis of rotation for 3d and 4d matrices is required"); - return NULL; - } - - /* check for valid vector/axis above */ - if(vec) { - float tvec[3]; - - if (mathutils_array_parse(tvec, 3, 3, vec, "mathutils.RotationMatrix(angle, size, axis), invalid 'axis' arg") == -1) - return NULL; - - axis_angle_to_mat3((float (*)[3])mat, tvec, angle); - } - else if(matSize == 2) { - //2D rotation matrix - mat[0] = (float) cos (angle); - mat[1] = (float) sin (angle); - mat[2] = -((float) sin(angle)); - mat[3] = (float) cos(angle); - } - else if(strcmp(axis, "X") == 0) { - //rotation around X - mat[0] = 1.0f; - mat[4] = (float) cos(angle); - mat[5] = (float) sin(angle); - mat[7] = -((float) sin(angle)); - mat[8] = (float) cos(angle); - } - else if(strcmp(axis, "Y") == 0) { - //rotation around Y - mat[0] = (float) cos(angle); - mat[2] = -((float) sin(angle)); - mat[4] = 1.0f; - mat[6] = (float) sin(angle); - mat[8] = (float) cos(angle); - } - else if(strcmp(axis, "Z") == 0) { - //rotation around Z - mat[0] = (float) cos(angle); - mat[1] = (float) sin(angle); - mat[3] = -((float) sin(angle)); - mat[4] = (float) cos(angle); - mat[8] = 1.0f; - } - else { - /* should never get here */ - PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): unknown error"); - return NULL; - } - - if(matSize == 4) { - matrix_3x3_as_4x4(mat); - } - //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); -} - - -PyDoc_STRVAR(C_Matrix_Translation_doc, -".. classmethod:: Translation(vector)\n" -"\n" -" Create a matrix representing a translation.\n" -"\n" -" :arg vector: The translation vector.\n" -" :type vector: :class:`Vector`\n" -" :return: An identity matrix with a translation.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value) -{ - float mat[16], tvec[3]; - - if (mathutils_array_parse(tvec, 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1) - return NULL; - - /* create a identity matrix and add translation */ - unit_m4((float(*)[4]) mat); - copy_v3_v3(mat + 12, tvec); /* 12, 13, 14 */ - return newMatrixObject(mat, 4, 4, Py_NEW, (PyTypeObject *)cls); -} -//----------------------------------mathutils.Matrix.Scale() ------------- -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. -PyDoc_STRVAR(C_Matrix_Scale_doc, -".. classmethod:: Scale(factor, size, axis)\n" -"\n" -" Create a matrix representing a scaling.\n" -"\n" -" :arg factor: The factor of scaling to apply.\n" -" :type factor: float\n" -" :arg size: The size of the scale matrix to construct [2, 4].\n" -" :type size: int\n" -" :arg axis: Direction to influence scale. (optional).\n" -" :type axis: :class:`Vector`\n" -" :return: A new scale matrix.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) -{ - PyObject *vec= NULL; - int vec_size; - float tvec[3]; - float factor; - int matSize; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - - if(!PyArg_ParseTuple(args, "fi|O:Matrix.Scale", &factor, &matSize, &vec)) { - return NULL; - } - if(matSize != 2 && matSize != 3 && matSize != 4) { - PyErr_SetString(PyExc_AttributeError, "Matrix.Scale(): can only return a 2x2 3x3 or 4x4 matrix"); - return NULL; - } - if(vec) { - vec_size= (matSize == 2 ? 2 : 3); - if(mathutils_array_parse(tvec, vec_size, vec_size, vec, "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1) { - return NULL; - } - } - if(vec == NULL) { //scaling along axis - if(matSize == 2) { - mat[0] = factor; - mat[3] = factor; - } else { - mat[0] = factor; - mat[4] = factor; - mat[8] = factor; - } - } - else { //scaling in arbitrary direction - //normalize arbitrary axis - float norm = 0.0f; - int x; - for(x = 0; x < vec_size; x++) { - norm += tvec[x] * tvec[x]; - } - norm = (float) sqrt(norm); - for(x = 0; x < vec_size; x++) { - tvec[x] /= norm; - } - if(matSize == 2) { - mat[0] = 1 + ((factor - 1) *(tvec[0] * tvec[0])); - mat[1] = ((factor - 1) *(tvec[0] * tvec[1])); - mat[2] = ((factor - 1) *(tvec[0] * tvec[1])); - mat[3] = 1 + ((factor - 1) *(tvec[1] * tvec[1])); - } else { - mat[0] = 1 + ((factor - 1) *(tvec[0] * tvec[0])); - mat[1] = ((factor - 1) *(tvec[0] * tvec[1])); - mat[2] = ((factor - 1) *(tvec[0] * tvec[2])); - mat[3] = ((factor - 1) *(tvec[0] * tvec[1])); - mat[4] = 1 + ((factor - 1) *(tvec[1] * tvec[1])); - mat[5] = ((factor - 1) *(tvec[1] * tvec[2])); - mat[6] = ((factor - 1) *(tvec[0] * tvec[2])); - mat[7] = ((factor - 1) *(tvec[1] * tvec[2])); - mat[8] = 1 + ((factor - 1) *(tvec[2] * tvec[2])); - } - } - if(matSize == 4) { - matrix_3x3_as_4x4(mat); - } - //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); -} -//----------------------------------mathutils.Matrix.OrthoProjection() --- -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. -PyDoc_STRVAR(C_Matrix_OrthoProjection_doc, -".. classmethod:: OrthoProjection(axis, size)\n" -"\n" -" Create a matrix to represent an orthographic projection.\n" -"\n" -" :arg axis: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n" -" where a single axis is for a 2D matrix.\n" -" Or a vector for an arbitrary axis\n" -" :type axis: string or :class:`Vector`\n" -" :arg size: The size of the projection matrix to construct [2, 4].\n" -" :type size: int\n" -" :return: A new projection matrix.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) -{ - PyObject *axis; - - int matSize, x; - float norm = 0.0f; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - - if(!PyArg_ParseTuple(args, "Oi:Matrix.OrthoProjection", &axis, &matSize)) { - return NULL; - } - if(matSize != 2 && matSize != 3 && matSize != 4) { - PyErr_SetString(PyExc_AttributeError,"mathutils.Matrix.OrthoProjection(): can only return a 2x2 3x3 or 4x4 matrix"); - return NULL; - } - - if(PyUnicode_Check(axis)) { //ortho projection onto cardinal plane - Py_ssize_t plane_len; - const char *plane= _PyUnicode_AsStringAndSize(axis, &plane_len); - if(matSize == 2) { - if(plane_len == 1 && plane[0]=='X') { - mat[0]= 1.0f; - } - else if (plane_len == 1 && plane[0]=='Y') { - mat[3]= 1.0f; - } - else { - PyErr_Format(PyExc_ValueError, "mathutils.Matrix.OrthoProjection(): unknown plane, expected: X, Y, not '%.200s'", plane); - return NULL; - } - } - else { - if(plane_len == 2 && plane[0]=='X' && plane[1]=='Y') { - mat[0]= 1.0f; - mat[4]= 1.0f; - } - else if (plane_len == 2 && plane[0]=='X' && plane[1]=='Z') { - mat[0]= 1.0f; - mat[8]= 1.0f; - } - else if (plane_len == 2 && plane[0]=='Y' && plane[1]=='Z') { - mat[4]= 1.0f; - mat[8]= 1.0f; - } - else { - PyErr_Format(PyExc_ValueError, "mathutils.Matrix.OrthoProjection(): unknown plane, expected: XY, XZ, YZ, not '%.200s'", plane); - return NULL; - } - } - } - else { - //arbitrary plane - - int vec_size= (matSize == 2 ? 2 : 3); - float tvec[4]; - - if(mathutils_array_parse(tvec, vec_size, vec_size, axis, "Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1) { - return NULL; - } - - //normalize arbitrary axis - for(x = 0; x < vec_size; x++) { - norm += tvec[x] * tvec[x]; - } - norm = (float) sqrt(norm); - for(x = 0; x < vec_size; x++) { - tvec[x] /= norm; - } - if(matSize == 2) { - mat[0] = 1 - (tvec[0] * tvec[0]); - mat[1] = -(tvec[0] * tvec[1]); - mat[2] = -(tvec[0] * tvec[1]); - mat[3] = 1 - (tvec[1] * tvec[1]); - } - else if(matSize > 2) { - mat[0] = 1 - (tvec[0] * tvec[0]); - mat[1] = -(tvec[0] * tvec[1]); - mat[2] = -(tvec[0] * tvec[2]); - mat[3] = -(tvec[0] * tvec[1]); - mat[4] = 1 - (tvec[1] * tvec[1]); - mat[5] = -(tvec[1] * tvec[2]); - mat[6] = -(tvec[0] * tvec[2]); - mat[7] = -(tvec[1] * tvec[2]); - mat[8] = 1 - (tvec[2] * tvec[2]); - } - } - if(matSize == 4) { - matrix_3x3_as_4x4(mat); - } - //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); -} - -PyDoc_STRVAR(C_Matrix_Shear_doc, -".. classmethod:: Shear(plane, size, factor)\n" -"\n" -" Create a matrix to represent an shear transformation.\n" -"\n" -" :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n" -" where a single axis is for a 2D matrix only.\n" -" :type plane: string\n" -" :arg size: The size of the shear matrix to construct [2, 4].\n" -" :type size: int\n" -" :arg factor: The factor of shear to apply. For a 3 or 4 *size* matrix\n" -" pass a pair of floats corrasponding with the *plane* axis.\n" -" :type factor: float or float pair\n" -" :return: A new shear matrix.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args) -{ - int matSize; - const char *plane; - PyObject *fac; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - - if(!PyArg_ParseTuple(args, "siO:Matrix.Shear", &plane, &matSize, &fac)) { - return NULL; - } - if(matSize != 2 && matSize != 3 && matSize != 4) { - PyErr_SetString(PyExc_AttributeError,"mathutils.Matrix.Shear(): can only return a 2x2 3x3 or 4x4 matrix"); - return NULL; - } - - if(matSize == 2) { - float const factor= PyFloat_AsDouble(fac); - - if(factor==-1.0f && PyErr_Occurred()) { - PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix.Shear(): the factor to be a float"); - return NULL; - } - - /* unit */ - mat[0] = 1.0f; - mat[3] = 1.0f; - - if(strcmp(plane, "X") == 0) { - mat[2] = factor; - } - else if(strcmp(plane, "Y") == 0) { - mat[1] = factor; - } - else { - PyErr_SetString(PyExc_AttributeError, "Matrix.Shear(): expected: X, Y or wrong matrix size for shearing plane"); - return NULL; - } - } - else { - /* 3 or 4, apply as 3x3, resize later if needed */ - float factor[2]; - - if(mathutils_array_parse(factor, 2, 2, fac, "Matrix.Shear()") < 0) { - return NULL; - } - - /* unit */ - mat[0] = 1.0f; - mat[4] = 1.0f; - mat[8] = 1.0f; - - if(strcmp(plane, "XY") == 0) { - mat[6] = factor[0]; - mat[7] = factor[1]; - } - else if(strcmp(plane, "XZ") == 0) { - mat[3] = factor[0]; - mat[5] = factor[1]; - } - else if(strcmp(plane, "YZ") == 0) { - mat[1] = factor[0]; - mat[2] = factor[1]; - } - else { - PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix.Shear(): expected: X, Y, XY, XZ, YZ"); - return NULL; - } - } - - if(matSize == 4) { - matrix_3x3_as_4x4(mat); - } - //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); -} - -void matrix_as_3x3(float mat[3][3], MatrixObject *self) -{ - copy_v3_v3(mat[0], self->matrix[0]); - copy_v3_v3(mat[1], self->matrix[1]); - copy_v3_v3(mat[2], self->matrix[2]); -} - -/* assumes rowsize == colsize is checked and the read callback has run */ -static float matrix_determinant_internal(MatrixObject *self) -{ - if(self->row_size == 2) { - return determinant_m2(self->matrix[0][0], self->matrix[0][1], - self->matrix[1][0], self->matrix[1][1]); - } - else if(self->row_size == 3) { - return determinant_m3(self->matrix[0][0], self->matrix[0][1], - self->matrix[0][2], self->matrix[1][0], - self->matrix[1][1], self->matrix[1][2], - self->matrix[2][0], self->matrix[2][1], - self->matrix[2][2]); - } else { - return determinant_m4((float (*)[4])self->contigPtr); - } -} - - -/*-----------------------------METHODS----------------------------*/ -PyDoc_STRVAR(Matrix_to_quaternion_doc, -".. method:: to_quaternion()\n" -"\n" -" Return a quaternion representation of the rotation matrix.\n" -"\n" -" :return: Quaternion representation of the rotation matrix.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Matrix_to_quaternion(MatrixObject *self) -{ - float quat[4]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if((self->col_size < 3) || (self->row_size < 3) || (self->col_size != self->row_size)) { - PyErr_SetString(PyExc_AttributeError, "Matrix.to_quat(): inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } - if(self->col_size == 3){ - mat3_to_quat(quat, (float (*)[3])self->contigPtr); - } - else { - mat4_to_quat(quat, (float (*)[4])self->contigPtr); - } - - return newQuaternionObject(quat, Py_NEW, NULL); -} - -/*---------------------------Matrix.toEuler() --------------------*/ -PyDoc_STRVAR(Matrix_to_euler_doc, -".. method:: to_euler(order, euler_compat)\n" -"\n" -" Return an Euler representation of the rotation matrix\n" -" (3x3 or 4x4 matrix only).\n" -"\n" -" :arg order: Optional rotation order argument in\n" -" ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n" -" :type order: string\n" -" :arg euler_compat: Optional euler argument the new euler will be made\n" -" compatible with (no axis flipping between them).\n" -" Useful for converting a series of matrices to animation curves.\n" -" :type euler_compat: :class:`Euler`\n" -" :return: Euler representation of the matrix.\n" -" :rtype: :class:`Euler`\n" -); -static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args) -{ - const char *order_str= NULL; - short order= EULER_ORDER_XYZ; - float eul[3], eul_compatf[3]; - EulerObject *eul_compat = NULL; - - float tmat[3][3]; - float (*mat)[3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) - return NULL; - - if(eul_compat) { - if(BaseMath_ReadCallback(eul_compat) == -1) - return NULL; - - copy_v3_v3(eul_compatf, eul_compat->eul); - } - - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if(self->col_size ==3 && self->row_size ==3) { - mat= (float (*)[3])self->contigPtr; - } - else if (self->col_size ==4 && self->row_size ==4) { - copy_m3_m4(tmat, (float (*)[4])self->contigPtr); - mat= tmat; - } - else { - PyErr_SetString(PyExc_AttributeError, "Matrix.to_euler(): inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } - - if(order_str) { - order= euler_order_from_string(order_str, "Matrix.to_euler()"); - - if(order == -1) - return NULL; - } - - if(eul_compat) { - if(order == 1) mat3_to_compatible_eul(eul, eul_compatf, mat); - else mat3_to_compatible_eulO(eul, eul_compatf, order, mat); - } - else { - if(order == 1) mat3_to_eul(eul, mat); - else mat3_to_eulO(eul, order, mat); - } - - return newEulerObject(eul, order, Py_NEW, NULL); -} - -PyDoc_STRVAR(Matrix_resize_4x4_doc, -".. method:: resize_4x4()\n" -"\n" -" Resize the matrix to 4x4.\n" -); -static PyObject *Matrix_resize_4x4(MatrixObject *self) -{ - int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index; - - if(self->wrapped==Py_WRAP){ - PyErr_SetString(PyExc_TypeError, "cannot resize wrapped data - make a copy and resize that"); - return NULL; - } - if(self->cb_user){ - PyErr_SetString(PyExc_TypeError, "cannot resize owned data - make a copy and resize that"); - return NULL; - } - - self->contigPtr = PyMem_Realloc(self->contigPtr, (sizeof(float) * 16)); - if(self->contigPtr == NULL) { - PyErr_SetString(PyExc_MemoryError, "matrix.resize_4x4(): problem allocating pointer space"); - return NULL; - } - /*set row pointers*/ - for(x = 0; x < 4; x++) { - self->matrix[x] = self->contigPtr + (x * 4); - } - /*move data to new spot in array + clean*/ - for(blank_rows = (4 - self->row_size); blank_rows > 0; blank_rows--){ - for(x = 0; x < 4; x++){ - index = (4 * (self->row_size + (blank_rows - 1))) + x; - if (index == 10 || index == 15){ - self->contigPtr[index] = 1.0f; - } - else { - self->contigPtr[index] = 0.0f; - } - } - } - for(x = 1; x <= self->row_size; x++){ - first_row_elem = (self->col_size * (self->row_size - x)); - curr_pos = (first_row_elem + (self->col_size -1)); - new_pos = (4 * (self->row_size - x)) + (curr_pos - first_row_elem); - for(blank_columns = (4 - self->col_size); blank_columns > 0; blank_columns--){ - self->contigPtr[new_pos + blank_columns] = 0.0f; - } - for(curr_pos = curr_pos; curr_pos >= first_row_elem; curr_pos--){ - self->contigPtr[new_pos] = self->contigPtr[curr_pos]; - new_pos--; - } - } - self->row_size = 4; - self->col_size = 4; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Matrix_to_4x4_doc, -".. method:: to_4x4()\n" -"\n" -" Return a 4x4 copy of this matrix.\n" -"\n" -" :return: a new matrix.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Matrix_to_4x4(MatrixObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(self->col_size==4 && self->row_size==4) { - return (PyObject *)newMatrixObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self)); - } - else if(self->col_size==3 && self->row_size==3) { - float mat[4][4]; - copy_m4_m3(mat, (float (*)[3])self->contigPtr); - return (PyObject *)newMatrixObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self)); - } - /* TODO, 2x2 matrix */ - - PyErr_SetString(PyExc_TypeError, "Matrix.to_4x4(): inappropriate matrix size"); - return NULL; -} - -PyDoc_STRVAR(Matrix_to_3x3_doc, -".. method:: to_3x3()\n" -"\n" -" Return a 3x3 copy of this matrix.\n" -"\n" -" :return: a new matrix.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Matrix_to_3x3(MatrixObject *self) -{ - float mat[3][3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if((self->col_size < 3) || (self->row_size < 3)) { - PyErr_SetString(PyExc_AttributeError, "Matrix.to_3x3(): inappropriate matrix size"); - return NULL; - } - - matrix_as_3x3(mat, self); - - return newMatrixObject((float *)mat, 3, 3, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Matrix_to_translation_doc, -".. method:: to_translation()\n" -"\n" -" Return a the translation part of a 4 row matrix.\n" -"\n" -" :return: Return a the translation of a matrix.\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Matrix_to_translation(MatrixObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if((self->col_size < 3) || self->row_size < 4){ - PyErr_SetString(PyExc_AttributeError, "Matrix.to_translation(): inappropriate matrix size"); - return NULL; - } - - return newVectorObject(self->matrix[3], 3, Py_NEW, NULL); -} - -PyDoc_STRVAR(Matrix_to_scale_doc, -".. method:: to_scale()\n" -"\n" -" Return a the scale part of a 3x3 or 4x4 matrix.\n" -"\n" -" :return: Return a the scale of a matrix.\n" -" :rtype: :class:`Vector`\n" -"\n" -" .. note:: This method does not return negative a scale on any axis because it is not possible to obtain this data from the matrix alone.\n" -); -static PyObject *Matrix_to_scale(MatrixObject *self) -{ - float rot[3][3]; - float mat[3][3]; - float size[3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if((self->col_size < 3) || (self->row_size < 3)) { - PyErr_SetString(PyExc_AttributeError, "Matrix.to_scale(): inappropriate matrix size, 3x3 minimum size"); - return NULL; - } - - matrix_as_3x3(mat, self); - - /* compatible mat4_to_loc_rot_size */ - mat3_to_rot_size(rot, size, mat); - - return newVectorObject(size, 3, Py_NEW, NULL); -} - -/*---------------------------Matrix.invert() ---------------------*/ -PyDoc_STRVAR(Matrix_invert_doc, -".. method:: invert()\n" -"\n" -" Set the matrix to its inverse.\n" -"\n" -" .. note:: :exc:`ValueError` exception is raised.\n" -"\n" -" .. seealso:: <http://en.wikipedia.org/wiki/Inverse_matrix>\n" -); -static PyObject *Matrix_invert(MatrixObject *self) -{ - - int x, y, z = 0; - float det = 0.0f; - float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(self->row_size != self->col_size){ - PyErr_SetString(PyExc_AttributeError, "Matrix.invert(ed): only square matrices are supported"); - return NULL; - } - - /*calculate the determinant*/ - det = matrix_determinant_internal(self); - - if(det != 0) { - /*calculate the classical adjoint*/ - if(self->row_size == 2) { - mat[0] = self->matrix[1][1]; - mat[1] = -self->matrix[0][1]; - mat[2] = -self->matrix[1][0]; - mat[3] = self->matrix[0][0]; - } else if(self->row_size == 3) { - adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr); - } else if(self->row_size == 4) { - adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->contigPtr); - } - /*divide by determinate*/ - for(x = 0; x < (self->row_size * self->col_size); x++) { - mat[x] /= det; - } - /*set values*/ - for(x = 0; x < self->row_size; x++) { - for(y = 0; y < self->col_size; y++) { - self->matrix[x][y] = mat[z]; - z++; - } - } - /*transpose - Matrix_transpose(self);*/ - } else { - PyErr_SetString(PyExc_ValueError, "matrix does not have an inverse"); - return NULL; - } - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Matrix_inverted_doc, -".. method:: inverted()\n" -"\n" -" Return an inverted copy of the matrix.\n" -"\n" -" :return: the inverted matrix.\n" -" :rtype: :class:`Matrix`\n" -"\n" -" .. note:: :exc:`ValueError` exception is raised.\n" -); -static PyObject *Matrix_inverted(MatrixObject *self) -{ - return matrix__apply_to_copy((PyNoArgsFunction)Matrix_invert, self); -} - -PyDoc_STRVAR(Matrix_rotate_doc, -".. method:: rotate(other)\n" -"\n" -" Rotates the matrix a by another mathutils value.\n" -"\n" -" :arg other: rotation component of mathutils value\n" -" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" -"\n" -" .. note:: If any of the columns are not unit length this may not have desired results.\n" -); -static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value) -{ - float self_rmat[3][3], other_rmat[3][3], rmat[3][3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1) - return NULL; - - if(self->col_size != 3 || self->row_size != 3) { - PyErr_SetString(PyExc_ValueError, "Matrix must have 3x3 dimensions"); - return NULL; - } - - matrix_as_3x3(self_rmat, self); - mul_m3_m3m3(rmat, self_rmat, other_rmat); - - copy_m3_m3((float (*)[3])(self->contigPtr), rmat); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} - -/*---------------------------Matrix.decompose() ---------------------*/ -PyDoc_STRVAR(Matrix_decompose_doc, -".. method:: decompose()\n" -"\n" -" Return the location, rotaion and scale components of this matrix.\n" -"\n" -" :return: loc, rot, scale triple.\n" -" :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`)" -); -static PyObject *Matrix_decompose(MatrixObject *self) -{ - PyObject *ret; - float loc[3]; - float rot[3][3]; - float quat[4]; - float size[3]; - - if(self->col_size != 4 || self->row_size != 4) { - PyErr_SetString(PyExc_AttributeError, "Matrix.decompose(): inappropriate matrix size - expects 4x4 matrix"); - return NULL; - } - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->contigPtr); - mat3_to_quat(quat, rot); - - ret= PyTuple_New(3); - PyTuple_SET_ITEM(ret, 0, newVectorObject(loc, 3, Py_NEW, NULL)); - PyTuple_SET_ITEM(ret, 1, newQuaternionObject(quat, Py_NEW, NULL)); - PyTuple_SET_ITEM(ret, 2, newVectorObject(size, 3, Py_NEW, NULL)); - - return ret; -} - - - -PyDoc_STRVAR(Matrix_lerp_doc, -".. function:: lerp(other, factor)\n" -"\n" -" Returns the interpolation of two matricies.\n" -"\n" -" :arg other: value to interpolate with.\n" -" :type other: :class:`Matrix`\n" -" :arg factor: The interpolation value in [0.0, 1.0].\n" -" :type factor: float\n" -" :return: The interpolated rotation.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) -{ - MatrixObject *mat2 = NULL; - float fac, mat[MATRIX_MAX_DIM*MATRIX_MAX_DIM]; - - if(!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac)) - return NULL; - - if(self->row_size != mat2->row_size || self->col_size != mat2->col_size) { - PyErr_SetString(PyExc_AttributeError, "matrix.lerp(): expects both matrix objects of the same dimensions"); - return NULL; - } - - if(BaseMath_ReadCallback(self) == -1 || BaseMath_ReadCallback(mat2) == -1) - return NULL; - - /* TODO, different sized matrix */ - if(self->row_size==4 && self->col_size==4) { - blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->contigPtr, (float (*)[4])mat2->contigPtr, fac); - } - else if (self->row_size==3 && self->col_size==3) { - blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->contigPtr, (float (*)[3])mat2->contigPtr, fac); - } - else { - PyErr_SetString(PyExc_AttributeError, "matrix.lerp(): only 3x3 and 4x4 matrices supported"); - return NULL; - } - - return (PyObject*)newMatrixObject(mat, self->row_size, self->col_size, Py_NEW, Py_TYPE(self)); -} - -/*---------------------------Matrix.determinant() ----------------*/ -PyDoc_STRVAR(Matrix_determinant_doc, -".. method:: determinant()\n" -"\n" -" Return the determinant of a matrix.\n" -"\n" -" :return: Return a the determinant of a matrix.\n" -" :rtype: float\n" -"\n" -" .. seealso:: <http://en.wikipedia.org/wiki/Determinant>\n" -); -static PyObject *Matrix_determinant(MatrixObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(self->row_size != self->col_size){ - PyErr_SetString(PyExc_AttributeError, "Matrix.determinant: only square matrices are supported"); - return NULL; - } - - return PyFloat_FromDouble((double)matrix_determinant_internal(self)); -} -/*---------------------------Matrix.transpose() ------------------*/ -PyDoc_STRVAR(Matrix_transpose_doc, -".. method:: transpose()\n" -"\n" -" Set the matrix to its transpose.\n" -"\n" -" .. seealso:: <http://en.wikipedia.org/wiki/Transpose>\n" -); -static PyObject *Matrix_transpose(MatrixObject *self) -{ - float t = 0.0f; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(self->row_size != self->col_size){ - PyErr_SetString(PyExc_AttributeError, "Matrix.transpose(d): only square matrices are supported"); - return NULL; - } - - if(self->row_size == 2) { - t = self->matrix[1][0]; - self->matrix[1][0] = self->matrix[0][1]; - self->matrix[0][1] = t; - } else if(self->row_size == 3) { - transpose_m3((float (*)[3])self->contigPtr); - } else { - transpose_m4((float (*)[4])self->contigPtr); - } - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Matrix_transposed_doc, -".. method:: transposed()\n" -"\n" -" Return a new, transposed matrix.\n" -"\n" -" :return: a transposed matrix\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Matrix_transposed(MatrixObject *self) -{ - return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self); -} - -/*---------------------------Matrix.zero() -----------------------*/ -PyDoc_STRVAR(Matrix_zero_doc, -".. method:: zero()\n" -"\n" -" Set all the matrix values to zero.\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Matrix_zero(MatrixObject *self) -{ - fill_vn(self->contigPtr, self->row_size * self->col_size, 0.0f); - - if(BaseMath_WriteCallback(self) == -1) - return NULL; - - Py_RETURN_NONE; -} -/*---------------------------Matrix.identity(() ------------------*/ -PyDoc_STRVAR(Matrix_identity_doc, -".. method:: identity()\n" -"\n" -" Set the matrix to the identity matrix.\n" -"\n" -" .. note:: An object with zero location and rotation, a scale of one,\n" -" will have an identity matrix.\n" -"\n" -" .. seealso:: <http://en.wikipedia.org/wiki/Identity_matrix>\n" -); -static PyObject *Matrix_identity(MatrixObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(self->row_size != self->col_size){ - PyErr_SetString(PyExc_AttributeError, "Matrix.identity: only square matrices are supported"); - return NULL; - } - - if(self->row_size == 2) { - self->matrix[0][0] = 1.0f; - self->matrix[0][1] = 0.0f; - self->matrix[1][0] = 0.0f; - self->matrix[1][1] = 1.0f; - } else if(self->row_size == 3) { - unit_m3((float (*)[3])self->contigPtr); - } else { - unit_m4((float (*)[4])self->contigPtr); - } - - if(BaseMath_WriteCallback(self) == -1) - return NULL; - - Py_RETURN_NONE; -} - -/*---------------------------Matrix.copy() ------------------*/ -PyDoc_STRVAR(Matrix_copy_doc, -".. method:: copy()\n" -"\n" -" Returns a copy of this matrix.\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Matrix_copy(MatrixObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return (PyObject*)newMatrixObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self)); -} - -/*----------------------------print object (internal)-------------*/ -/*print the object to screen*/ -static PyObject *Matrix_repr(MatrixObject *self) -{ - int x, y; - PyObject *rows[MATRIX_MAX_DIM]= {NULL}; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - for(x = 0; x < self->row_size; x++){ - rows[x]= PyTuple_New(self->col_size); - for(y = 0; y < self->col_size; y++) { - PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(self->matrix[x][y])); - } - } - switch(self->row_size) { - case 2: return PyUnicode_FromFormat("Matrix(%R,\n" - " %R)", rows[0], rows[1]); - - case 3: return PyUnicode_FromFormat("Matrix(%R,\n" - " %R,\n" - " %R)", rows[0], rows[1], rows[2]); - - case 4: return PyUnicode_FromFormat("Matrix(%R,\n" - " %R,\n" - " %R,\n" - " %R)", rows[0], rows[1], rows[2], rows[3]); - } - - PyErr_SetString(PyExc_RuntimeError, "invalid matrix size"); - return NULL; -} - -static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op) -{ - PyObject *res; - int ok= -1; /* zero is true */ - - if (MatrixObject_Check(a) && MatrixObject_Check(b)) { - MatrixObject *matA= (MatrixObject*)a; - MatrixObject *matB= (MatrixObject*)b; - - if(BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1) - return NULL; - - ok= ( (matA->col_size == matB->col_size) && - (matA->row_size == matB->row_size) && - EXPP_VectorsAreEqual(matA->contigPtr, matB->contigPtr, (matA->row_size * matA->col_size), 1) - ) ? 0 : -1; - } - - switch (op) { - case Py_NE: - ok = !ok; /* pass through */ - case Py_EQ: - res = ok ? Py_False : Py_True; - break; - - case Py_LT: - case Py_LE: - case Py_GT: - case Py_GE: - res = Py_NotImplemented; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - return Py_INCREF(res), res; -} - -/*---------------------SEQUENCE PROTOCOLS------------------------ - ----------------------------len(object)------------------------ - sequence length*/ -static int Matrix_len(MatrixObject *self) -{ - return (self->row_size); -} -/*----------------------------object[]--------------------------- - sequence accessor (get) - the wrapped vector gives direct access to the matrix data*/ -static PyObject *Matrix_item(MatrixObject *self, int i) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(i < 0 || i >= self->row_size) { - PyErr_SetString(PyExc_IndexError, "matrix[attribute]: array index out of range"); - return NULL; - } - return newVectorObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, i); -} -/*----------------------------object[]------------------------- - sequence accessor (set) */ - -static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value) -{ - float vec[4]; - if(BaseMath_ReadCallback(self) == -1) - return -1; - - if(i >= self->row_size || i < 0){ - PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad column"); - return -1; - } - - if(mathutils_array_parse(vec, self->col_size, self->col_size, value, "matrix[i] = value assignment") < 0) { - return -1; - } - - memcpy(self->matrix[i], vec, self->col_size *sizeof(float)); - - (void)BaseMath_WriteCallback(self); - return 0; -} - -/*----------------------------object[z:y]------------------------ - sequence slice (get)*/ -static PyObject *Matrix_slice(MatrixObject *self, int begin, int end) -{ - - PyObject *tuple; - int count; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - CLAMP(begin, 0, self->row_size); - CLAMP(end, 0, self->row_size); - begin= MIN2(begin, end); - - tuple= PyTuple_New(end - begin); - for(count= begin; count < end; count++) { - PyTuple_SET_ITEM(tuple, count - begin, - newVectorObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, count)); - - } - - return tuple; -} -/*----------------------------object[z:y]------------------------ - sequence slice (set)*/ -static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value) -{ - PyObject *value_fast= NULL; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - CLAMP(begin, 0, self->row_size); - CLAMP(end, 0, self->row_size); - begin = MIN2(begin, end); - - /* non list/tuple cases */ - if(!(value_fast=PySequence_Fast(value, "matrix[begin:end] = value"))) { - /* PySequence_Fast sets the error */ - return -1; - } - else { - const int size= end - begin; - int i; - float mat[16]; - - if(PySequence_Fast_GET_SIZE(value_fast) != size) { - Py_DECREF(value_fast); - PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: size mismatch in slice assignment"); - return -1; - } - - /*parse sub items*/ - for (i = 0; i < size; i++) { - /*parse each sub sequence*/ - PyObject *item= PySequence_Fast_GET_ITEM(value_fast, i); - - if(mathutils_array_parse(&mat[i * self->col_size], self->col_size, self->col_size, item, "matrix[begin:end] = value assignment") < 0) { - return -1; - } - } - - Py_DECREF(value_fast); - - /*parsed well - now set in matrix*/ - memcpy(self->contigPtr + (begin * self->col_size), mat, sizeof(float) * (size * self->col_size)); - - (void)BaseMath_WriteCallback(self); - return 0; - } -} -/*------------------------NUMERIC PROTOCOLS---------------------- - ------------------------obj + obj------------------------------*/ -static PyObject *Matrix_add(PyObject *m1, PyObject *m2) -{ - float mat[16]; - MatrixObject *mat1 = NULL, *mat2 = NULL; - - mat1 = (MatrixObject*)m1; - mat2 = (MatrixObject*)m2; - - if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { - PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation"); - return NULL; - } - - if(BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) - return NULL; - - if(mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size){ - PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); - return NULL; - } - - add_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size); - - return newMatrixObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); -} -/*------------------------obj - obj------------------------------ - subtraction*/ -static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) -{ - float mat[16]; - MatrixObject *mat1 = NULL, *mat2 = NULL; - - mat1 = (MatrixObject*)m1; - mat2 = (MatrixObject*)m2; - - if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { - PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation"); - return NULL; - } - - if(BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) - return NULL; - - if(mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size){ - PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); - return NULL; - } - - sub_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size); - - return newMatrixObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); -} -/*------------------------obj * obj------------------------------ - mulplication*/ -static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) -{ - float tmat[16]; - mul_vn_vn_fl(tmat, mat->contigPtr, mat->row_size * mat->col_size, scalar); - return newMatrixObject(tmat, mat->row_size, mat->col_size, Py_NEW, Py_TYPE(mat)); -} - -static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) -{ - float scalar; - - MatrixObject *mat1 = NULL, *mat2 = NULL; - - if(MatrixObject_Check(m1)) { - mat1 = (MatrixObject*)m1; - if(BaseMath_ReadCallback(mat1) == -1) - return NULL; - } - if(MatrixObject_Check(m2)) { - mat2 = (MatrixObject*)m2; - if(BaseMath_ReadCallback(mat2) == -1) - return NULL; - } - - if(mat1 && mat2) { /*MATRIX * MATRIX*/ - if(mat1->row_size != mat2->col_size){ - PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize"); - return NULL; - } - else { - float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - double dot = 0.0f; - int x, y, z; - - for(x = 0; x < mat2->row_size; x++) { - for(y = 0; y < mat1->col_size; y++) { - for(z = 0; z < mat1->row_size; z++) { - dot += (mat1->matrix[z][y] * mat2->matrix[x][z]); - } - mat[((x * mat1->col_size) + y)] = (float)dot; - dot = 0.0f; - } - } - - return newMatrixObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); - } - } - else if(mat2) { - if (((scalar= PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */ - return matrix_mul_float(mat2, scalar); - } - } - else if(mat1) { - if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX */ - return matrix_mul_float(mat1, scalar); - } - } - else { - BLI_assert(!"internal error"); - } - - PyErr_Format(PyExc_TypeError, "Matrix multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); - return NULL; -} -static PyObject* Matrix_inv(MatrixObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return Matrix_invert(self); -} - -/*-----------------PROTOCOL DECLARATIONS--------------------------*/ -static PySequenceMethods Matrix_SeqMethods = { - (lenfunc) Matrix_len, /* sq_length */ - (binaryfunc) NULL, /* sq_concat */ - (ssizeargfunc) NULL, /* sq_repeat */ - (ssizeargfunc) Matrix_item, /* sq_item */ - (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ - (ssizeobjargproc) Matrix_ass_item, /* sq_ass_item */ - (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */ - (objobjproc) NULL, /* sq_contains */ - (binaryfunc) NULL, /* sq_inplace_concat */ - (ssizeargfunc) NULL, /* sq_inplace_repeat */ -}; - - -static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += self->row_size; - return Matrix_item(self, i); - } else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0) - return NULL; - - if (slicelength <= 0) { - return PyTuple_New(0); - } - else if (step == 1) { - return Matrix_slice(self, start, stop); - } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } -} - -static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* value) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += self->row_size; - return Matrix_ass_item(self, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0) - return -1; - - if (step == 1) - return Matrix_ass_slice(self, start, stop, value); - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return -1; - } -} - -static PyMappingMethods Matrix_AsMapping = { - (lenfunc)Matrix_len, - (binaryfunc)Matrix_subscript, - (objobjargproc)Matrix_ass_subscript -}; - - -static PyNumberMethods Matrix_NumMethods = { - (binaryfunc) Matrix_add, /*nb_add*/ - (binaryfunc) Matrix_sub, /*nb_subtract*/ - (binaryfunc) Matrix_mul, /*nb_multiply*/ - NULL, /*nb_remainder*/ - NULL, /*nb_divmod*/ - NULL, /*nb_power*/ - (unaryfunc) 0, /*nb_negative*/ - (unaryfunc) 0, /*tp_positive*/ - (unaryfunc) 0, /*tp_absolute*/ - (inquiry) 0, /*tp_bool*/ - (unaryfunc) Matrix_inv, /*nb_invert*/ - NULL, /*nb_lshift*/ - (binaryfunc)0, /*nb_rshift*/ - NULL, /*nb_and*/ - NULL, /*nb_xor*/ - NULL, /*nb_or*/ - NULL, /*nb_int*/ - NULL, /*nb_reserved*/ - NULL, /*nb_float*/ - NULL, /* nb_inplace_add */ - NULL, /* nb_inplace_subtract */ - NULL, /* nb_inplace_multiply */ - NULL, /* nb_inplace_remainder */ - NULL, /* nb_inplace_power */ - NULL, /* nb_inplace_lshift */ - NULL, /* nb_inplace_rshift */ - NULL, /* nb_inplace_and */ - NULL, /* nb_inplace_xor */ - NULL, /* nb_inplace_or */ - NULL, /* nb_floor_divide */ - NULL, /* nb_true_divide */ - NULL, /* nb_inplace_floor_divide */ - NULL, /* nb_inplace_true_divide */ - NULL, /* nb_index */ -}; - -static PyObject *Matrix_getRowSize(MatrixObject *self, void *UNUSED(closure)) -{ - return PyLong_FromLong((long) self->row_size); -} - -static PyObject *Matrix_getColSize(MatrixObject *self, void *UNUSED(closure)) -{ - return PyLong_FromLong((long) self->col_size); -} - -static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure)) -{ - float mat[3][3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if((self->col_size < 3) || (self->row_size < 3)) { - PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: inappropriate matrix size, 3x3 minimum"); - return NULL; - } - - matrix_as_3x3(mat, self); - - return PyFloat_FromDouble(mat3_to_scale(mat)); -} - -static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure)) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if(self->col_size == 4 && self->row_size == 4) - return PyBool_FromLong(is_negative_m4((float (*)[4])self->contigPtr)); - else if(self->col_size == 3 && self->row_size == 3) - return PyBool_FromLong(is_negative_m3((float (*)[3])self->contigPtr)); - else { - PyErr_SetString(PyExc_AttributeError, "Matrix.is_negative: inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } -} - -static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closure)) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - /*must be 3-4 cols, 3-4 rows, square matrix*/ - if(self->col_size == 4 && self->row_size == 4) - return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->contigPtr)); - else if(self->col_size == 3 && self->row_size == 3) - return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->contigPtr)); - else { - PyErr_SetString(PyExc_AttributeError, "Matrix.is_orthogonal: inappropriate matrix size - expects 3x3 or 4x4 matrix"); - return NULL; - } -} - -/*****************************************************************************/ -/* Python attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef Matrix_getseters[] = { - {(char *)"row_size", (getter)Matrix_getRowSize, (setter)NULL, (char *)"The row size of the matrix (readonly).\n\n:type: int", NULL}, - {(char *)"col_size", (getter)Matrix_getColSize, (setter)NULL, (char *)"The column size of the matrix (readonly).\n\n:type: int", NULL}, - {(char *)"median_scale", (getter)Matrix_median_scale_get, (setter)NULL, (char *)"The average scale applied to each axis (readonly).\n\n:type: float", NULL}, - {(char *)"is_negative", (getter)Matrix_is_negative_get, (setter)NULL, (char *)"True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL}, - {(char *)"is_orthogonal", (getter)Matrix_is_orthogonal_get, (setter)NULL, (char *)"True if this matrix is orthogonal, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner",(getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, - {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ -}; - -/*-----------------------METHOD DEFINITIONS ----------------------*/ -static struct PyMethodDef Matrix_methods[] = { - /* derived values */ - {"determinant", (PyCFunction) Matrix_determinant, METH_NOARGS, Matrix_determinant_doc}, - {"decompose", (PyCFunction) Matrix_decompose, METH_NOARGS, Matrix_decompose_doc}, - - /* in place only */ - {"zero", (PyCFunction) Matrix_zero, METH_NOARGS, Matrix_zero_doc}, - {"identity", (PyCFunction) Matrix_identity, METH_NOARGS, Matrix_identity_doc}, - - /* operate on original or copy */ - {"transpose", (PyCFunction) Matrix_transpose, METH_NOARGS, Matrix_transpose_doc}, - {"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc}, - {"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc}, - {"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc}, - {"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc}, - // TODO. {"resize_3x3", (PyCFunction) Matrix_resize3x3, METH_NOARGS, Matrix_resize3x3_doc}, - {"to_4x4", (PyCFunction) Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc}, - {"resize_4x4", (PyCFunction) Matrix_resize_4x4, METH_NOARGS, Matrix_resize_4x4_doc}, - {"rotate", (PyCFunction) Matrix_rotate, METH_O, Matrix_rotate_doc}, - - /* return converted representation */ - {"to_euler", (PyCFunction) Matrix_to_euler, METH_VARARGS, Matrix_to_euler_doc}, - {"to_quaternion", (PyCFunction) Matrix_to_quaternion, METH_NOARGS, Matrix_to_quaternion_doc}, - {"to_scale", (PyCFunction) Matrix_to_scale, METH_NOARGS, Matrix_to_scale_doc}, - {"to_translation", (PyCFunction) Matrix_to_translation, METH_NOARGS, Matrix_to_translation_doc}, - - /* operation between 2 or more types */ - {"lerp", (PyCFunction) Matrix_lerp, METH_VARARGS, Matrix_lerp_doc}, - {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, - {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, - - /* class methods */ - {"Rotation", (PyCFunction) C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc}, - {"Scale", (PyCFunction) C_Matrix_Scale, METH_VARARGS | METH_CLASS, C_Matrix_Scale_doc}, - {"Shear", (PyCFunction) C_Matrix_Shear, METH_VARARGS | METH_CLASS, C_Matrix_Shear_doc}, - {"Translation", (PyCFunction) C_Matrix_Translation, METH_O | METH_CLASS, C_Matrix_Translation_doc}, - {"OrthoProjection", (PyCFunction) C_Matrix_OrthoProjection, METH_VARARGS | METH_CLASS, C_Matrix_OrthoProjection_doc}, - {NULL, NULL, 0, NULL} -}; - -/*------------------PY_OBECT DEFINITION--------------------------*/ -PyDoc_STRVAR(matrix_doc, -"This object gives access to Matrices in Blender." -); -PyTypeObject matrix_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "mathutils.Matrix", /*tp_name*/ - sizeof(MatrixObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BaseMathObject_dealloc, /*tp_dealloc*/ - NULL, /*tp_print*/ - NULL, /*tp_getattr*/ - NULL, /*tp_setattr*/ - NULL, /*tp_compare*/ - (reprfunc) Matrix_repr, /*tp_repr*/ - &Matrix_NumMethods, /*tp_as_number*/ - &Matrix_SeqMethods, /*tp_as_sequence*/ - &Matrix_AsMapping, /*tp_as_mapping*/ - NULL, /*tp_hash*/ - NULL, /*tp_call*/ - NULL, /*tp_str*/ - NULL, /*tp_getattro*/ - NULL, /*tp_setattro*/ - NULL, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - matrix_doc, /*tp_doc*/ - (traverseproc)BaseMathObject_traverse, //tp_traverse - (inquiry)BaseMathObject_clear, //tp_clear - (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - NULL, /*tp_iter*/ - NULL, /*tp_iternext*/ - Matrix_methods, /*tp_methods*/ - NULL, /*tp_members*/ - Matrix_getseters, /*tp_getset*/ - NULL, /*tp_base*/ - NULL, /*tp_dict*/ - NULL, /*tp_descr_get*/ - NULL, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - NULL, /*tp_init*/ - NULL, /*tp_alloc*/ - Matrix_new, /*tp_new*/ - NULL, /*tp_free*/ - NULL, /*tp_is_gc*/ - NULL, /*tp_bases*/ - NULL, /*tp_mro*/ - NULL, /*tp_cache*/ - NULL, /*tp_subclasses*/ - NULL, /*tp_weaklist*/ - NULL /*tp_del*/ -}; - -/*------------------------newMatrixObject (internal)------------- -creates a new matrix object -self->matrix self->contiguous_ptr (reference to data.xxx) - [0]------------->[0] - [1] - [2] - [1]------------->[3] - [4] - [5] - -self->matrix[1][1] = self->contigPtr[4] */ - -/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsigned short colSize, int type, PyTypeObject *base_type) -{ - MatrixObject *self; - int x, row, col; - - /*matrix objects can be any 2-4row x 2-4col matrix*/ - if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4) { - PyErr_SetString(PyExc_RuntimeError, "matrix(): row and column sizes must be between 2 and 4"); - return NULL; - } - - self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) : - (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type); - - if(self) { - self->row_size = rowSize; - self->col_size = colSize; - - /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; - - if(type == Py_WRAP){ - self->contigPtr = mat; - /*pointer array points to contigous memory*/ - for(x = 0; x < rowSize; x++) { - self->matrix[x] = self->contigPtr + (x * colSize); - } - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW){ - self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float)); - if(self->contigPtr == NULL) { /*allocation failure*/ - PyErr_SetString(PyExc_MemoryError, "matrix(): problem allocating pointer space"); - return NULL; - } - /*pointer array points to contigous memory*/ - for(x = 0; x < rowSize; x++) { - self->matrix[x] = self->contigPtr + (x * colSize); - } - /*parse*/ - if(mat) { /*if a float array passed*/ - for(row = 0; row < rowSize; row++) { - for(col = 0; col < colSize; col++) { - self->matrix[row][col] = mat[(row * colSize) + col]; - } - } - } - else if (rowSize == colSize) { /*or if no arguments are passed return identity matrix for square matrices */ - PyObject *ret_dummy= Matrix_identity(self); - Py_DECREF(ret_dummy); - } - self->wrapped = Py_NEW; - } - else { - PyErr_SetString(PyExc_RuntimeError, "Matrix(): invalid type"); - return NULL; - } - } - return (PyObject *) self; -} - -PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb_type, int cb_subtype) -{ - MatrixObject *self= (MatrixObject *)newMatrixObject(NULL, rowSize, colSize, Py_NEW, NULL); - if(self) { - Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; - PyObject_GC_Track(self); - } - return (PyObject *) self; -} diff --git a/source/blender/python/generic/mathutils_Matrix.h b/source/blender/python/generic/mathutils_Matrix.h deleted file mode 100644 index aa736d1e959..00000000000 --- a/source/blender/python/generic/mathutils_Matrix.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * $Id$ - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -/** \file blender/python/generic/mathutils_Matrix.h - * \ingroup pygen - */ - - -#ifndef MATHUTILS_MATRIX_H -#define MATHUTILS_MATRIX_H - -extern PyTypeObject matrix_Type; -#define MatrixObject_Check(_v) PyObject_TypeCheck((_v), &matrix_Type) -#define MATRIX_MAX_DIM 4 - -typedef struct { - BASE_MATH_MEMBERS(contigPtr) - float *matrix[MATRIX_MAX_DIM]; /* ptr to the contigPtr (accessor) */ - unsigned short row_size; - unsigned short col_size; -} MatrixObject; - -/*struct data contains a pointer to the actual data that the -object uses. It can use either PyMem allocated data (which will -be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ - -/*prototypes*/ -PyObject *newMatrixObject(float *mat, const unsigned short row_size, const unsigned short col_size, int type, PyTypeObject *base_type); -PyObject *newMatrixObject_cb(PyObject *user, int row_size, int col_size, int cb_type, int cb_subtype); - -extern int mathutils_matrix_vector_cb_index; -extern struct Mathutils_Callback mathutils_matrix_vector_cb; - -void matrix_as_3x3(float mat[3][3], MatrixObject *self); - -#endif /* MATHUTILS_MATRIX_H */ diff --git a/source/blender/python/generic/mathutils_Quaternion.c b/source/blender/python/generic/mathutils_Quaternion.c deleted file mode 100644 index 90447e7093a..00000000000 --- a/source/blender/python/generic/mathutils_Quaternion.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils_Quaternion.c - * \ingroup pygen - */ - - -#include <Python.h> - -#include "mathutils.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#define QUAT_SIZE 4 - -static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self); -static PyObject *Quaternion_copy(QuaternionObject *self); - -//-----------------------------METHODS------------------------------ - -/* note: BaseMath_ReadCallback must be called beforehand */ -static PyObject *Quaternion_to_tuple_ext(QuaternionObject *self, int ndigits) -{ - PyObject *ret; - int i; - - ret= PyTuple_New(QUAT_SIZE); - - if(ndigits >= 0) { - for(i= 0; i < QUAT_SIZE; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->quat[i], ndigits))); - } - } - else { - for(i= 0; i < QUAT_SIZE; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->quat[i])); - } - } - - return ret; -} - -PyDoc_STRVAR(Quaternion_to_euler_doc, -".. method:: to_euler(order, euler_compat)\n" -"\n" -" Return Euler representation of the quaternion.\n" -"\n" -" :arg order: Optional rotation order argument in\n" -" ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n" -" :type order: string\n" -" :arg euler_compat: Optional euler argument the new euler will be made\n" -" compatible with (no axis flipping between them).\n" -" Useful for converting a series of matrices to animation curves.\n" -" :type euler_compat: :class:`Euler`\n" -" :return: Euler representation of the quaternion.\n" -" :rtype: :class:`Euler`\n" -); -static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args) -{ - float tquat[4]; - float eul[3]; - const char *order_str= NULL; - short order= EULER_ORDER_XYZ; - EulerObject *eul_compat = NULL; - - if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) - return NULL; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(order_str) { - order= euler_order_from_string(order_str, "Matrix.to_euler()"); - - if(order == -1) - return NULL; - } - - normalize_qt_qt(tquat, self->quat); - - if(eul_compat) { - float mat[3][3]; - - if(BaseMath_ReadCallback(eul_compat) == -1) - return NULL; - - quat_to_mat3(mat, tquat); - - if(order == EULER_ORDER_XYZ) mat3_to_compatible_eul(eul, eul_compat->eul, mat); - else mat3_to_compatible_eulO(eul, eul_compat->eul, order, mat); - } - else { - if(order == EULER_ORDER_XYZ) quat_to_eul(eul, tquat); - else quat_to_eulO(eul, order, tquat); - } - - return newEulerObject(eul, order, Py_NEW, NULL); -} -//----------------------------Quaternion.toMatrix()------------------ -PyDoc_STRVAR(Quaternion_to_matrix_doc, -".. method:: to_matrix()\n" -"\n" -" Return a matrix representation of the quaternion.\n" -"\n" -" :return: A 3x3 rotation matrix representation of the quaternion.\n" -" :rtype: :class:`Matrix`\n" -); -static PyObject *Quaternion_to_matrix(QuaternionObject *self) -{ - float mat[9]; /* all values are set */ - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - quat_to_mat3((float (*)[3])mat, self->quat); - return newMatrixObject(mat, 3, 3, Py_NEW, NULL); -} - -//----------------------------Quaternion.cross(other)------------------ -PyDoc_STRVAR(Quaternion_cross_doc, -".. method:: cross(other)\n" -"\n" -" Return the cross product of this quaternion and another.\n" -"\n" -" :arg other: The other quaternion to perform the cross product with.\n" -" :type other: :class:`Quaternion`\n" -" :return: The cross product.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value) -{ - float quat[QUAT_SIZE], tquat[QUAT_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.cross(other), invalid 'other' arg") == -1) - return NULL; - - mul_qt_qtqt(quat, self->quat, tquat); - return newQuaternionObject(quat, Py_NEW, Py_TYPE(self)); -} - -//----------------------------Quaternion.dot(other)------------------ -PyDoc_STRVAR(Quaternion_dot_doc, -".. method:: dot(other)\n" -"\n" -" Return the dot product of this quaternion and another.\n" -"\n" -" :arg other: The other quaternion to perform the dot product with.\n" -" :type other: :class:`Quaternion`\n" -" :return: The dot product.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value) -{ - float tquat[QUAT_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.dot(other), invalid 'other' arg") == -1) - return NULL; - - return PyFloat_FromDouble(dot_qtqt(self->quat, tquat)); -} - -PyDoc_STRVAR(Quaternion_rotation_difference_doc, -".. function:: difference(other)\n" -"\n" -" Returns a quaternion representing the rotational difference.\n" -"\n" -" :arg other: second quaternion.\n" -" :type other: :class:`Quaternion`\n" -" :return: the rotational difference between the two quat rotations.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject *value) -{ - float tquat[QUAT_SIZE], quat[QUAT_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.difference(other), invalid 'other' arg") == -1) - return NULL; - - rotation_between_quats_to_quat(quat, self->quat, tquat); - - return newQuaternionObject(quat, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Quaternion_slerp_doc, -".. function:: slerp(other, factor)\n" -"\n" -" Returns the interpolation of two quaternions.\n" -"\n" -" :arg other: value to interpolate with.\n" -" :type other: :class:`Quaternion`\n" -" :arg factor: The interpolation value in [0.0, 1.0].\n" -" :type factor: float\n" -" :return: The interpolated rotation.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args) -{ - PyObject *value; - float tquat[QUAT_SIZE], quat[QUAT_SIZE], fac; - - if(!PyArg_ParseTuple(args, "Of:slerp", &value, &fac)) { - PyErr_SetString(PyExc_TypeError, "quat.slerp(): expected Quaternion types and float"); - return NULL; - } - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.slerp(other), invalid 'other' arg") == -1) - return NULL; - - if(fac > 1.0f || fac < 0.0f) { - PyErr_SetString(PyExc_AttributeError, "quat.slerp(): interpolation factor must be between 0.0 and 1.0"); - return NULL; - } - - interp_qt_qtqt(quat, self->quat, tquat, fac); - - return newQuaternionObject(quat, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Quaternion_rotate_doc, -".. method:: rotate(other)\n" -"\n" -" Rotates the quaternion a by another mathutils value.\n" -"\n" -" :arg other: rotation component of mathutils value\n" -" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" -); -static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value) -{ - float self_rmat[3][3], other_rmat[3][3], rmat[3][3]; - float tquat[4], length; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_any_to_rotmat(other_rmat, value, "quaternion.rotate(value)") == -1) - return NULL; - - length= normalize_qt_qt(tquat, self->quat); - quat_to_mat3(self_rmat, tquat); - mul_m3_m3m3(rmat, self_rmat, other_rmat); - - mat3_to_quat(self->quat, rmat); - mul_qt_fl(self->quat, length); /* maintain length after rotating */ - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} - -//----------------------------Quaternion.normalize()---------------- -//normalize the axis of rotation of [theta, vector] -PyDoc_STRVAR(Quaternion_normalize_doc, -".. function:: normalize()\n" -"\n" -" Normalize the quaternion.\n" -); -static PyObject *Quaternion_normalize(QuaternionObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - normalize_qt(self->quat); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} -PyDoc_STRVAR(Quaternion_normalized_doc, -".. function:: normalized()\n" -"\n" -" Return a new normalized quaternion.\n" -"\n" -" :return: a normalized copy.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_normalized(QuaternionObject *self) -{ - return quat__apply_to_copy((PyNoArgsFunction)Quaternion_normalize, self); -} - -//----------------------------Quaternion.invert()------------------ -PyDoc_STRVAR(Quaternion_invert_doc, -".. function:: invert()\n" -"\n" -" Set the quaternion to its inverse.\n" -); -static PyObject *Quaternion_invert(QuaternionObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - invert_qt(self->quat); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} -PyDoc_STRVAR(Quaternion_inverted_doc, -".. function:: inverted()\n" -"\n" -" Return a new, inverted quaternion.\n" -"\n" -" :return: the inverted value.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_inverted(QuaternionObject *self) -{ - return quat__apply_to_copy((PyNoArgsFunction)Quaternion_invert, self); -} - -//----------------------------Quaternion.identity()----------------- -PyDoc_STRVAR(Quaternion_identity_doc, -".. function:: identity()\n" -"\n" -" Set the quaternion to an identity quaternion.\n" -"\n" -" :return: an instance of itself.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_identity(QuaternionObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - unit_qt(self->quat); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} -//----------------------------Quaternion.negate()------------------- -PyDoc_STRVAR(Quaternion_negate_doc, -".. function:: negate()\n" -"\n" -" Set the quaternion to its negative.\n" -"\n" -" :return: an instance of itself.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_negate(QuaternionObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - mul_qt_fl(self->quat, -1.0f); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} -//----------------------------Quaternion.conjugate()---------------- -PyDoc_STRVAR(Quaternion_conjugate_doc, -".. function:: conjugate()\n" -"\n" -" Set the quaternion to its conjugate (negate x, y, z).\n" -); -static PyObject *Quaternion_conjugate(QuaternionObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - conjugate_qt(self->quat); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} -PyDoc_STRVAR(Quaternion_conjugated_doc, -".. function:: conjugated()\n" -"\n" -" Return a new conjugated quaternion.\n" -"\n" -" :return: a new quaternion.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Quaternion_conjugated(QuaternionObject *self) -{ - return quat__apply_to_copy((PyNoArgsFunction)Quaternion_conjugate, self); -} - -//----------------------------Quaternion.copy()---------------- -PyDoc_STRVAR(Quaternion_copy_doc, -".. function:: copy()\n" -"\n" -" Returns a copy of this quaternion.\n" -"\n" -" :return: A copy of the quaternion.\n" -" :rtype: :class:`Quaternion`\n" -"\n" -" .. note:: use this to get a copy of a wrapped quaternion with\n" -" no reference to the original data.\n" -); -static PyObject *Quaternion_copy(QuaternionObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return newQuaternionObject(self->quat, Py_NEW, Py_TYPE(self)); -} - -//----------------------------print object (internal)-------------- -//print the object to screen -static PyObject *Quaternion_repr(QuaternionObject *self) -{ - PyObject *ret, *tuple; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - tuple= Quaternion_to_tuple_ext(self, -1); - - ret= PyUnicode_FromFormat("Quaternion(%R)", tuple); - - Py_DECREF(tuple); - return ret; -} - -static PyObject* Quaternion_richcmpr(PyObject *a, PyObject *b, int op) -{ - PyObject *res; - int ok= -1; /* zero is true */ - - if (QuaternionObject_Check(a) && QuaternionObject_Check(b)) { - QuaternionObject *quatA= (QuaternionObject *)a; - QuaternionObject *quatB= (QuaternionObject *)b; - - if(BaseMath_ReadCallback(quatA) == -1 || BaseMath_ReadCallback(quatB) == -1) - return NULL; - - ok= (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1; - } - - switch (op) { - case Py_NE: - ok = !ok; /* pass through */ - case Py_EQ: - res = ok ? Py_False : Py_True; - break; - - case Py_LT: - case Py_LE: - case Py_GT: - case Py_GE: - res = Py_NotImplemented; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - return Py_INCREF(res), res; -} - -//---------------------SEQUENCE PROTOCOLS------------------------ -//----------------------------len(object)------------------------ -//sequence length -static int Quaternion_len(QuaternionObject *UNUSED(self)) -{ - return QUAT_SIZE; -} -//----------------------------object[]--------------------------- -//sequence accessor (get) -static PyObject *Quaternion_item(QuaternionObject *self, int i) -{ - if(i<0) i= QUAT_SIZE-i; - - if(i < 0 || i >= QUAT_SIZE) { - PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range"); - return NULL; - } - - if(BaseMath_ReadIndexCallback(self, i) == -1) - return NULL; - - return PyFloat_FromDouble(self->quat[i]); - -} -//----------------------------object[]------------------------- -//sequence accessor (set) -static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob) -{ - float scalar= (float)PyFloat_AsDouble(ob); - if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ - PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: index argument not a number"); - return -1; - } - - if(i<0) i= QUAT_SIZE-i; - - if(i < 0 || i >= QUAT_SIZE){ - PyErr_SetString(PyExc_IndexError, "quaternion[attribute] = x: array assignment index out of range"); - return -1; - } - self->quat[i] = scalar; - - if(BaseMath_WriteIndexCallback(self, i) == -1) - return -1; - - return 0; -} -//----------------------------object[z:y]------------------------ -//sequence slice (get) -static PyObject *Quaternion_slice(QuaternionObject *self, int begin, int end) -{ - PyObject *tuple; - int count; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - CLAMP(begin, 0, QUAT_SIZE); - if (end<0) end= (QUAT_SIZE + 1) + end; - CLAMP(end, 0, QUAT_SIZE); - begin= MIN2(begin, end); - - tuple= PyTuple_New(end - begin); - for(count= begin; count < end; count++) { - PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->quat[count])); - } - - return tuple; -} -//----------------------------object[z:y]------------------------ -//sequence slice (set) -static int Quaternion_ass_slice(QuaternionObject *self, int begin, int end, PyObject *seq) -{ - int i, size; - float quat[QUAT_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - CLAMP(begin, 0, QUAT_SIZE); - if (end<0) end= (QUAT_SIZE + 1) + end; - CLAMP(end, 0, QUAT_SIZE); - begin = MIN2(begin, end); - - if((size=mathutils_array_parse(quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1) - return -1; - - if(size != (end - begin)){ - PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: size mismatch in slice assignment"); - return -1; - } - - /* parsed well - now set in vector */ - for(i= 0; i < size; i++) - self->quat[begin + i] = quat[i]; - - (void)BaseMath_WriteCallback(self); - return 0; -} - - -static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += QUAT_SIZE; - return Quaternion_item(self, i); - } else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) - return NULL; - - if (slicelength <= 0) { - return PyTuple_New(0); - } - else if (step == 1) { - return Quaternion_slice(self, start, stop); - } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with quaternions"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, "quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } -} - - -static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyObject *value) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += QUAT_SIZE; - return Quaternion_ass_item(self, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) - return -1; - - if (step == 1) - return Quaternion_ass_slice(self, start, stop, value); - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with quaternion"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, "quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return -1; - } -} - -//------------------------NUMERIC PROTOCOLS---------------------- -//------------------------obj + obj------------------------------ -//addition -static PyObject *Quaternion_add(PyObject *q1, PyObject *q2) -{ - float quat[QUAT_SIZE]; - QuaternionObject *quat1 = NULL, *quat2 = NULL; - - if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) { - PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation"); - return NULL; - } - quat1 = (QuaternionObject*)q1; - quat2 = (QuaternionObject*)q2; - - if(BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) - return NULL; - - add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f); - return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1)); -} -//------------------------obj - obj------------------------------ -//subtraction -static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2) -{ - int x; - float quat[QUAT_SIZE]; - QuaternionObject *quat1 = NULL, *quat2 = NULL; - - if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) { - PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation"); - return NULL; - } - - quat1 = (QuaternionObject*)q1; - quat2 = (QuaternionObject*)q2; - - if(BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) - return NULL; - - for(x = 0; x < QUAT_SIZE; x++) { - quat[x] = quat1->quat[x] - quat2->quat[x]; - } - - return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1)); -} - -static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar) -{ - float tquat[4]; - copy_qt_qt(tquat, quat->quat); - mul_qt_fl(tquat, scalar); - return newQuaternionObject(tquat, Py_NEW, Py_TYPE(quat)); -} - -//------------------------obj * obj------------------------------ -//mulplication -static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) -{ - float quat[QUAT_SIZE], scalar; - QuaternionObject *quat1 = NULL, *quat2 = NULL; - - if(QuaternionObject_Check(q1)) { - quat1 = (QuaternionObject*)q1; - if(BaseMath_ReadCallback(quat1) == -1) - return NULL; - } - if(QuaternionObject_Check(q2)) { - quat2 = (QuaternionObject*)q2; - if(BaseMath_ReadCallback(quat2) == -1) - return NULL; - } - - if(quat1 && quat2) { /* QUAT*QUAT (cross product) */ - mul_qt_qtqt(quat, quat1->quat, quat2->quat); - return newQuaternionObject(quat, Py_NEW, Py_TYPE(q1)); - } - /* the only case this can happen (for a supported type is "FLOAT*QUAT") */ - else if(quat2) { /* FLOAT*QUAT */ - if(((scalar= PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred())==0) { - return quat_mul_float(quat2, scalar); - } - } - else if (quat1) { /* QUAT*FLOAT */ - if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) { - return quat_mul_float(quat1, scalar); - } - } - else { - BLI_assert(!"internal error"); - } - - PyErr_Format(PyExc_TypeError, "Quaternion multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); - return NULL; -} - -/* -obj - returns the negative of this object*/ -static PyObject *Quaternion_neg(QuaternionObject *self) -{ - float tquat[QUAT_SIZE]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - negate_v4_v4(tquat, self->quat); - return newQuaternionObject(tquat, Py_NEW, Py_TYPE(self)); -} - - -//-----------------PROTOCOL DECLARATIONS-------------------------- -static PySequenceMethods Quaternion_SeqMethods = { - (lenfunc) Quaternion_len, /* sq_length */ - (binaryfunc) NULL, /* sq_concat */ - (ssizeargfunc) NULL, /* sq_repeat */ - (ssizeargfunc) Quaternion_item, /* sq_item */ - (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ - (ssizeobjargproc) Quaternion_ass_item, /* sq_ass_item */ - (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */ - (objobjproc) NULL, /* sq_contains */ - (binaryfunc) NULL, /* sq_inplace_concat */ - (ssizeargfunc) NULL, /* sq_inplace_repeat */ -}; - -static PyMappingMethods Quaternion_AsMapping = { - (lenfunc)Quaternion_len, - (binaryfunc)Quaternion_subscript, - (objobjargproc)Quaternion_ass_subscript -}; - -static PyNumberMethods Quaternion_NumMethods = { - (binaryfunc) Quaternion_add, /*nb_add*/ - (binaryfunc) Quaternion_sub, /*nb_subtract*/ - (binaryfunc) Quaternion_mul, /*nb_multiply*/ - NULL, /*nb_remainder*/ - NULL, /*nb_divmod*/ - NULL, /*nb_power*/ - (unaryfunc) Quaternion_neg, /*nb_negative*/ - (unaryfunc) 0, /*tp_positive*/ - (unaryfunc) 0, /*tp_absolute*/ - (inquiry) 0, /*tp_bool*/ - (unaryfunc) 0, /*nb_invert*/ - NULL, /*nb_lshift*/ - (binaryfunc)0, /*nb_rshift*/ - NULL, /*nb_and*/ - NULL, /*nb_xor*/ - NULL, /*nb_or*/ - NULL, /*nb_int*/ - NULL, /*nb_reserved*/ - NULL, /*nb_float*/ - NULL, /* nb_inplace_add */ - NULL, /* nb_inplace_subtract */ - NULL, /* nb_inplace_multiply */ - NULL, /* nb_inplace_remainder */ - NULL, /* nb_inplace_power */ - NULL, /* nb_inplace_lshift */ - NULL, /* nb_inplace_rshift */ - NULL, /* nb_inplace_and */ - NULL, /* nb_inplace_xor */ - NULL, /* nb_inplace_or */ - NULL, /* nb_floor_divide */ - NULL, /* nb_true_divide */ - NULL, /* nb_inplace_floor_divide */ - NULL, /* nb_inplace_true_divide */ - NULL, /* nb_index */ -}; - -static PyObject *Quaternion_getAxis(QuaternionObject *self, void *type) -{ - return Quaternion_item(self, GET_INT_FROM_POINTER(type)); -} - -static int Quaternion_setAxis(QuaternionObject *self, PyObject *value, void *type) -{ - return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value); -} - -static PyObject *Quaternion_getMagnitude(QuaternionObject *self, void *UNUSED(closure)) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return PyFloat_FromDouble(sqrt(dot_qtqt(self->quat, self->quat))); -} - -static PyObject *Quaternion_getAngle(QuaternionObject *self, void *UNUSED(closure)) -{ - float tquat[4]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - normalize_qt_qt(tquat, self->quat); - return PyFloat_FromDouble(2.0f * (saacos(tquat[0]))); -} - -static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) -{ - float tquat[4]; - float len; - - float axis[3], angle_dummy; - double angle; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - len= normalize_qt_qt(tquat, self->quat); - quat_to_axis_angle(axis, &angle_dummy, tquat); - - angle= PyFloat_AsDouble(value); - - if(angle==-1.0 && PyErr_Occurred()) { /* parsed item not a number */ - PyErr_SetString(PyExc_TypeError, "quaternion.angle = value: float expected"); - return -1; - } - - angle= angle_wrap_rad(angle); - - /* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */ - if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[2], 0.0f, 10) - ) { - axis[0] = 1.0f; - } - - axis_angle_to_quat(self->quat, axis, angle); - mul_qt_fl(self->quat, len); - - if(BaseMath_WriteCallback(self) == -1) - return -1; - - return 0; -} - -static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(closure)) -{ - float tquat[4]; - - float axis[3]; - float angle; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - normalize_qt_qt(tquat, self->quat); - quat_to_axis_angle(axis, &angle, tquat); - - /* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */ - if( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[2], 0.0f, 10) - ) { - axis[0] = 1.0f; - } - - return (PyObject *) newVectorObject(axis, 3, Py_NEW, NULL); -} - -static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) -{ - float tquat[4]; - float len; - - float axis[3]; - float angle; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - len= normalize_qt_qt(tquat, self->quat); - quat_to_axis_angle(axis, &angle, tquat); /* axis value is unused */ - - if (mathutils_array_parse(axis, 3, 3, value, "quat.axis = other") == -1) - return -1; - - axis_angle_to_quat(self->quat, axis, angle); - mul_qt_fl(self->quat, len); - - if(BaseMath_WriteCallback(self) == -1) - return -1; - - return 0; -} - -//----------------------------------mathutils.Quaternion() -------------- -static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *seq= NULL; - double angle = 0.0f; - float quat[QUAT_SIZE]= {0.0f, 0.0f, 0.0f, 0.0f}; - - if(kwds && PyDict_Size(kwds)) { - PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): takes no keyword args"); - return NULL; - } - - if(!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle)) - return NULL; - - switch(PyTuple_GET_SIZE(args)) { - case 0: - break; - case 1: - if (mathutils_array_parse(quat, QUAT_SIZE, QUAT_SIZE, seq, "mathutils.Quaternion()") == -1) - return NULL; - break; - case 2: - if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1) - return NULL; - angle= angle_wrap_rad(angle); /* clamp because of precision issues */ - axis_angle_to_quat(quat, quat, angle); - break; - /* PyArg_ParseTuple assures no more then 2 */ - } - return newQuaternionObject(quat, Py_NEW, type); -} - -static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self) -{ - PyObject *ret= Quaternion_copy(self); - PyObject *ret_dummy= quat_func(ret); - if(ret_dummy) { - Py_DECREF(ret_dummy); - return (PyObject *)ret; - } - else { /* error */ - Py_DECREF(ret); - return NULL; - } -} - -//-----------------------METHOD DEFINITIONS ---------------------- -static struct PyMethodDef Quaternion_methods[] = { - /* in place only */ - {"identity", (PyCFunction) Quaternion_identity, METH_NOARGS, Quaternion_identity_doc}, - {"negate", (PyCFunction) Quaternion_negate, METH_NOARGS, Quaternion_negate_doc}, - - /* operate on original or copy */ - {"conjugate", (PyCFunction) Quaternion_conjugate, METH_NOARGS, Quaternion_conjugate_doc}, - {"conjugated", (PyCFunction) Quaternion_conjugated, METH_NOARGS, Quaternion_conjugated_doc}, - - {"invert", (PyCFunction) Quaternion_invert, METH_NOARGS, Quaternion_invert_doc}, - {"inverted", (PyCFunction) Quaternion_inverted, METH_NOARGS, Quaternion_inverted_doc}, - - {"normalize", (PyCFunction) Quaternion_normalize, METH_NOARGS, Quaternion_normalize_doc}, - {"normalized", (PyCFunction) Quaternion_normalized, METH_NOARGS, Quaternion_normalized_doc}, - - /* return converted representation */ - {"to_euler", (PyCFunction) Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc}, - {"to_matrix", (PyCFunction) Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc}, - - /* operation between 2 or more types */ - {"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc}, - {"dot", (PyCFunction) Quaternion_dot, METH_O, Quaternion_dot_doc}, - {"rotation_difference", (PyCFunction) Quaternion_rotation_difference, METH_O, Quaternion_rotation_difference_doc}, - {"slerp", (PyCFunction) Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc}, - {"rotate", (PyCFunction) Quaternion_rotate, METH_O, Quaternion_rotate_doc}, - - {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, - {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, - {NULL, NULL, 0, NULL} -}; - -/*****************************************************************************/ -/* Python attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef Quaternion_getseters[] = { - {(char *)"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion W value.\n\n:type: float", (void *)0}, - {(char *)"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion X axis.\n\n:type: float", (void *)1}, - {(char *)"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion Y axis.\n\n:type: float", (void *)2}, - {(char *)"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, (char *)"Quaternion Z axis.\n\n:type: float", (void *)3}, - {(char *)"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, (char *)"Size of the quaternion (readonly).\n\n:type: float", NULL}, - {(char *)"angle", (getter)Quaternion_getAngle, (setter)Quaternion_setAngle, (char *)"angle of the quaternion.\n\n:type: float", NULL}, - {(char *)"axis",(getter)Quaternion_getAxisVec, (setter)Quaternion_setAxisVec, (char *)"quaternion axis as a vector.\n\n:type: :class:`Vector`", NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, - {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ -}; - -//------------------PY_OBECT DEFINITION-------------------------- -PyDoc_STRVAR(quaternion_doc, -"This object gives access to Quaternions in Blender." -); -PyTypeObject quaternion_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "mathutils.Quaternion", //tp_name - sizeof(QuaternionObject), //tp_basicsize - 0, //tp_itemsize - (destructor)BaseMathObject_dealloc, //tp_dealloc - NULL, //tp_print - NULL, //tp_getattr - NULL, //tp_setattr - NULL, //tp_compare - (reprfunc) Quaternion_repr, //tp_repr - &Quaternion_NumMethods, //tp_as_number - &Quaternion_SeqMethods, //tp_as_sequence - &Quaternion_AsMapping, //tp_as_mapping - NULL, //tp_hash - NULL, //tp_call - NULL, //tp_str - NULL, //tp_getattro - NULL, //tp_setattro - NULL, //tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags - quaternion_doc, //tp_doc - (traverseproc)BaseMathObject_traverse, //tp_traverse - (inquiry)BaseMathObject_clear, //tp_clear - (richcmpfunc)Quaternion_richcmpr, //tp_richcompare - 0, //tp_weaklistoffset - NULL, //tp_iter - NULL, //tp_iternext - Quaternion_methods, //tp_methods - NULL, //tp_members - Quaternion_getseters, //tp_getset - NULL, //tp_base - NULL, //tp_dict - NULL, //tp_descr_get - NULL, //tp_descr_set - 0, //tp_dictoffset - NULL, //tp_init - NULL, //tp_alloc - Quaternion_new, //tp_new - NULL, //tp_free - NULL, //tp_is_gc - NULL, //tp_bases - NULL, //tp_mro - NULL, //tp_cache - NULL, //tp_subclasses - NULL, //tp_weaklist - NULL, //tp_del -}; -//------------------------newQuaternionObject (internal)------------- -//creates a new quaternion object -/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type) -{ - QuaternionObject *self; - - self= base_type ? (QuaternionObject *)base_type->tp_alloc(base_type, 0) : - (QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type); - - if(self) { - /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; - - if(type == Py_WRAP){ - self->quat = quat; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW){ - self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float)); - if(!quat) { //new empty - unit_qt(self->quat); - } - else { - QUATCOPY(self->quat, quat); - } - self->wrapped = Py_NEW; - } - else { - PyErr_SetString(PyExc_RuntimeError, "Quaternion(): invalid type"); - return NULL; - } - } - return (PyObject *) self; -} - -PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) -{ - QuaternionObject *self= (QuaternionObject *)newQuaternionObject(NULL, Py_NEW, NULL); - if(self) { - Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; - PyObject_GC_Track(self); - } - - return (PyObject *)self; -} - diff --git a/source/blender/python/generic/mathutils_Quaternion.h b/source/blender/python/generic/mathutils_Quaternion.h deleted file mode 100644 index d606621390a..00000000000 --- a/source/blender/python/generic/mathutils_Quaternion.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -/** \file blender/python/generic/mathutils_Quaternion.h - * \ingroup pygen - */ - - -#ifndef MATHUTILS_QUAT_H -#define MATHUTILS_QUAT_H - -extern PyTypeObject quaternion_Type; -#define QuaternionObject_Check(_v) PyObject_TypeCheck((_v), &quaternion_Type) - -typedef struct { - BASE_MATH_MEMBERS(quat) -} QuaternionObject; - -/*struct data contains a pointer to the actual data that the -object uses. It can use either PyMem allocated data (which will -be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ - -//prototypes -PyObject *newQuaternionObject( float *quat, int type, PyTypeObject *base_type); -PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype); - -#endif /* MATHUTILS_QUAT_H */ diff --git a/source/blender/python/generic/mathutils_Vector.c b/source/blender/python/generic/mathutils_Vector.c deleted file mode 100644 index d0ba94474d4..00000000000 --- a/source/blender/python/generic/mathutils_Vector.c +++ /dev/null @@ -1,2307 +0,0 @@ -/* - * $Id$ - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * - * Contributor(s): Willian P. Germano, Joseph Gilbert, Ken Hughes, Alex Fraser, Campbell Barton - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils_Vector.c - * \ingroup pygen - */ - - -#include <Python.h> - -#include "mathutils.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#define MAX_DIMENSIONS 4 - -/* Swizzle axes get packed into a single value that is used as a closure. Each - axis uses SWIZZLE_BITS_PER_AXIS bits. The first bit (SWIZZLE_VALID_AXIS) is - used as a sentinel: if it is unset, the axis is not valid. */ -#define SWIZZLE_BITS_PER_AXIS 3 -#define SWIZZLE_VALID_AXIS 0x4 -#define SWIZZLE_AXIS 0x3 - -static PyObject *Vector_copy(VectorObject *self); -static PyObject *Vector_to_tuple_ext(VectorObject *self, int ndigits); - -/* Supports 2D, 3D, and 4D vector objects both int and float values - * accepted. Mixed float and int values accepted. Ints are parsed to float - */ -static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) -{ - float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f}; - int size= 3; /* default to a 3D vector */ - - switch(PyTuple_GET_SIZE(args)) { - case 0: - break; - case 1: - if((size=mathutils_array_parse(vec, 2, 4, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): more then a single arg given"); - return NULL; - } - return newVectorObject(vec, size, Py_NEW, type); -} - -static PyObject *vec__apply_to_copy(PyNoArgsFunction vec_func, VectorObject *self) -{ - PyObject *ret= Vector_copy(self); - PyObject *ret_dummy= vec_func(ret); - if(ret_dummy) { - Py_DECREF(ret_dummy); - return (PyObject *)ret; - } - else { /* error */ - Py_DECREF(ret); - return NULL; - } -} - -/*-----------------------------METHODS---------------------------- */ -PyDoc_STRVAR(Vector_zero_doc, -".. method:: zero()\n" -"\n" -" Set all values to zero.\n" -); -static PyObject *Vector_zero(VectorObject *self) -{ - fill_vn(self->vec, self->size, 0.0f); - - if(BaseMath_WriteCallback(self) == -1) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Vector_normalize_doc, -".. method:: normalize()\n" -"\n" -" Normalize the vector, making the length of the vector always 1.0.\n" -"\n" -" .. warning:: Normalizing a vector where all values are zero results\n" -" in all axis having a nan value (not a number).\n" -"\n" -" .. note:: Normalize works for vectors of all sizes,\n" -" however 4D Vectors w axis is left untouched.\n" -); -static PyObject *Vector_normalize(VectorObject *self) -{ - int i; - float norm = 0.0f; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - for(i = 0; i < self->size; i++) { - norm += self->vec[i] * self->vec[i]; - } - norm = (float) sqrt(norm); - for(i = 0; i < self->size; i++) { - self->vec[i] /= norm; - } - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} -PyDoc_STRVAR(Vector_normalized_doc, -".. method:: normalized()\n" -"\n" -" Return a new, normalized vector.\n" -"\n" -" :return: a normalized copy of the vector\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_normalized(VectorObject *self) -{ - return vec__apply_to_copy((PyNoArgsFunction)Vector_normalize, self); -} - -PyDoc_STRVAR(Vector_resize_2d_doc, -".. method:: resize_2d()\n" -"\n" -" Resize the vector to 2D (x, y).\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_resize_2d(VectorObject *self) -{ - if(self->wrapped==Py_WRAP) { - PyErr_SetString(PyExc_TypeError, "vector.resize_2d(): cannot resize wrapped data - only python vectors"); - return NULL; - } - if(self->cb_user) { - PyErr_SetString(PyExc_TypeError, "vector.resize_2d(): cannot resize a vector that has an owner"); - return NULL; - } - - self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2)); - if(self->vec == NULL) { - PyErr_SetString(PyExc_MemoryError, "vector.resize_2d(): problem allocating pointer space"); - return NULL; - } - - self->size = 2; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Vector_resize_3d_doc, -".. method:: resize_3d()\n" -"\n" -" Resize the vector to 3D (x, y, z).\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_resize_3d(VectorObject *self) -{ - if (self->wrapped==Py_WRAP) { - PyErr_SetString(PyExc_TypeError, "vector.resize_3d(): cannot resize wrapped data - only python vectors"); - return NULL; - } - if(self->cb_user) { - PyErr_SetString(PyExc_TypeError, "vector.resize_3d(): cannot resize a vector that has an owner"); - return NULL; - } - - self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3)); - if(self->vec == NULL) { - PyErr_SetString(PyExc_MemoryError, "vector.resize_3d(): problem allocating pointer space"); - return NULL; - } - - if(self->size == 2) - self->vec[2] = 0.0f; - - self->size = 3; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Vector_resize_4d_doc, -".. method:: resize_4d()\n" -"\n" -" Resize the vector to 4D (x, y, z, w).\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_resize_4d(VectorObject *self) -{ - if(self->wrapped==Py_WRAP) { - PyErr_SetString(PyExc_TypeError, "vector.resize_4d(): cannot resize wrapped data - only python vectors"); - return NULL; - } - if(self->cb_user) { - PyErr_SetString(PyExc_TypeError, "vector.resize_4d(): cannot resize a vector that has an owner"); - return NULL; - } - - self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4)); - if(self->vec == NULL) { - PyErr_SetString(PyExc_MemoryError, "vector.resize_4d(): problem allocating pointer space"); - return NULL; - } - - if(self->size == 2){ - self->vec[2] = 0.0f; - self->vec[3] = 1.0f; - } - else if(self->size == 3){ - self->vec[3] = 1.0f; - } - self->size = 4; - Py_RETURN_NONE; -} -PyDoc_STRVAR(Vector_to_2d_doc, -".. method:: to_2d()\n" -"\n" -" Return a 2d copy of the vector.\n" -"\n" -" :return: a new vector\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_to_2d(VectorObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return newVectorObject(self->vec, 2, Py_NEW, Py_TYPE(self)); -} -PyDoc_STRVAR(Vector_to_3d_doc, -".. method:: to_3d()\n" -"\n" -" Return a 3d copy of the vector.\n" -"\n" -" :return: a new vector\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_to_3d(VectorObject *self) -{ - float tvec[3]= {0.0f}; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3)); - return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(self)); -} -PyDoc_STRVAR(Vector_to_4d_doc, -".. method:: to_4d()\n" -"\n" -" Return a 4d copy of the vector.\n" -"\n" -" :return: a new vector\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_to_4d(VectorObject *self) -{ - float tvec[4]= {0.0f, 0.0f, 0.0f, 1.0f}; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4)); - return newVectorObject(tvec, 4, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Vector_to_tuple_doc, -".. method:: to_tuple(precision=-1)\n" -"\n" -" Return this vector as a tuple with.\n" -"\n" -" :arg precision: The number to round the value to in [-1, 21].\n" -" :type precision: int\n" -" :return: the values of the vector rounded by *precision*\n" -" :rtype: tuple\n" -); -/* note: BaseMath_ReadCallback must be called beforehand */ -static PyObject *Vector_to_tuple_ext(VectorObject *self, int ndigits) -{ - PyObject *ret; - int i; - - ret= PyTuple_New(self->size); - - if(ndigits >= 0) { - for(i = 0; i < self->size; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->vec[i], ndigits))); - } - } - else { - for(i = 0; i < self->size; i++) { - PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->vec[i])); - } - } - - return ret; -} - -static PyObject *Vector_to_tuple(VectorObject *self, PyObject *args) -{ - int ndigits= 0; - - if(!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits)) - return NULL; - - if(ndigits > 22 || ndigits < 0) { - PyErr_SetString(PyExc_ValueError, "vector.to_tuple(ndigits): ndigits must be between 0 and 21"); - return NULL; - } - - if(PyTuple_GET_SIZE(args)==0) - ndigits= -1; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return Vector_to_tuple_ext(self, ndigits); -} - -PyDoc_STRVAR(Vector_to_track_quat_doc, -".. method:: to_track_quat(track, up)\n" -"\n" -" Return a quaternion rotation from the vector and the track and up axis.\n" -"\n" -" :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n" -" :type track: string\n" -" :arg up: Up axis in ['X', 'Y', 'Z'].\n" -" :type up: string\n" -" :return: rotation from the vector and the track and up axis.\n" -" :rtype: :class:`Quaternion`\n" -); -static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args) -{ - float vec[3], quat[4]; - const char *strack, *sup; - short track = 2, up = 1; - - if(!PyArg_ParseTuple(args, "|ss:to_track_quat", &strack, &sup)) - return NULL; - - if (self->size != 3) { - PyErr_SetString(PyExc_TypeError, "only for 3D vectors"); - return NULL; - } - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if (strack) { - if (strlen(strack) == 2) { - if (strack[0] == '-') { - switch(strack[1]) { - case 'X': - track = 3; - break; - case 'Y': - track = 4; - break; - case 'Z': - track = 5; - break; - default: - PyErr_SetString(PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis"); - return NULL; - } - } - else { - PyErr_SetString(PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis"); - return NULL; - } - } - else if (strlen(strack) == 1) { - switch(strack[0]) { - case '-': - case 'X': - track = 0; - break; - case 'Y': - track = 1; - break; - case 'Z': - track = 2; - break; - default: - PyErr_SetString(PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis"); - return NULL; - } - } - else { - PyErr_SetString(PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis"); - return NULL; - } - } - - if (sup) { - if (strlen(sup) == 1) { - switch(*sup) { - case 'X': - up = 0; - break; - case 'Y': - up = 1; - break; - case 'Z': - up = 2; - break; - default: - PyErr_SetString(PyExc_ValueError, "only X, Y or Z for up axis"); - return NULL; - } - } - else { - PyErr_SetString(PyExc_ValueError, "only X, Y or Z for up axis"); - return NULL; - } - } - - if (track == up) { - PyErr_SetString(PyExc_ValueError, "Can't have the same axis for track and up"); - return NULL; - } - - /* - flip vector around, since vectoquat expect a vector from target to tracking object - and the python function expects the inverse (a vector to the target). - */ - negate_v3_v3(vec, self->vec); - - vec_to_quat(quat, vec, track, up); - - return newQuaternionObject(quat, Py_NEW, NULL); -} - -/* - * Vector.reflect(mirror): return a reflected vector on the mirror normal - * vec - ((2 * DotVecs(vec, mirror)) * mirror) - */ -PyDoc_STRVAR(Vector_reflect_doc, -".. method:: reflect(mirror)\n" -"\n" -" Return the reflection vector from the *mirror* argument.\n" -"\n" -" :arg mirror: This vector could be a normal from the reflecting surface.\n" -" :type mirror: :class:`Vector`\n" -" :return: The reflected vector matching the size of this vector.\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_reflect(VectorObject *self, PyObject *value) -{ - int value_size; - float mirror[3], vec[3]; - float reflect[3] = {0.0f}; - float tvec[MAX_DIMENSIONS]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if((value_size= mathutils_array_parse(tvec, 2, 4, value, "vector.reflect(other), invalid 'other' arg")) == -1) - return NULL; - - mirror[0] = tvec[0]; - mirror[1] = tvec[1]; - if (value_size > 2) mirror[2] = tvec[2]; - else mirror[2] = 0.0; - - vec[0] = self->vec[0]; - vec[1] = self->vec[1]; - if (self->size > 2) vec[2] = self->vec[2]; - else vec[2] = 0.0; - - normalize_v3(mirror); - reflect_v3_v3v3(reflect, vec, mirror); - - return newVectorObject(reflect, self->size, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Vector_cross_doc, -".. method:: cross(other)\n" -"\n" -" Return the cross product of this vector and another.\n" -"\n" -" :arg other: The other vector to perform the cross product with.\n" -" :type other: :class:`Vector`\n" -" :return: The cross product.\n" -" :rtype: :class:`Vector`\n" -"\n" -" .. note:: both vectors must be 3D\n" -); -static PyObject *Vector_cross(VectorObject *self, PyObject *value) -{ - VectorObject *ret; - float tvec[MAX_DIMENSIONS]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tvec, self->size, self->size, value, "vector.cross(other), invalid 'other' arg") == -1) - return NULL; - - ret= (VectorObject *)newVectorObject(NULL, 3, Py_NEW, Py_TYPE(self)); - cross_v3_v3v3(ret->vec, self->vec, tvec); - return (PyObject *)ret; -} - -PyDoc_STRVAR(Vector_dot_doc, -".. method:: dot(other)\n" -"\n" -" Return the dot product of this vector and another.\n" -"\n" -" :arg other: The other vector to perform the dot product with.\n" -" :type other: :class:`Vector`\n" -" :return: The dot product.\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_dot(VectorObject *self, PyObject *value) -{ - float tvec[MAX_DIMENSIONS]; - double dot = 0.0; - int x; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tvec, self->size, self->size, value, "vector.dot(other), invalid 'other' arg") == -1) - return NULL; - - for(x = 0; x < self->size; x++) { - dot += (double)(self->vec[x] * tvec[x]); - } - - return PyFloat_FromDouble(dot); -} - -PyDoc_STRVAR(Vector_angle_doc, -".. function:: angle(other, fallback)\n" -"\n" -" Return the angle between two vectors.\n" -"\n" -" :arg other: another vector to compare the angle with\n" -" :type other: :class:`Vector`\n" -" :arg fallback: return this value when the angle cant be calculated\n" -" (zero length vector)\n" -" :type fallback: any\n" -" :return: angle in radians or fallback when given\n" -" :rtype: float\n" -"\n" -" .. note:: Zero length vectors raise an :exc:`AttributeError`.\n" -); -static PyObject *Vector_angle(VectorObject *self, PyObject *args) -{ - const int size= self->size; - float tvec[MAX_DIMENSIONS]; - PyObject *value; - double dot = 0.0f, test_v1 = 0.0f, test_v2 = 0.0f; - int x; - PyObject *fallback= NULL; - - if(!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback)) - return NULL; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tvec, size, size, value, "vector.angle(other), invalid 'other' arg") == -1) - return NULL; - - for(x = 0; x < size; x++) { - test_v1 += (double)(self->vec[x] * self->vec[x]); - test_v2 += (double)(tvec[x] * tvec[x]); - } - if (!test_v1 || !test_v2){ - /* avoid exception */ - if(fallback) { - Py_INCREF(fallback); - return fallback; - } - else { - PyErr_SetString(PyExc_ValueError, "vector.angle(other): zero length vectors have no valid angle"); - return NULL; - } - } - - //dot product - for(x = 0; x < self->size; x++) { - dot += (double)(self->vec[x] * tvec[x]); - } - dot /= (sqrt(test_v1) * sqrt(test_v2)); - - return PyFloat_FromDouble(saacos(dot)); -} - -PyDoc_STRVAR(Vector_rotation_difference_doc, -".. function:: difference(other)\n" -"\n" -" Returns a quaternion representing the rotational difference between this\n" -" vector and another.\n" -"\n" -" :arg other: second vector.\n" -" :type other: :class:`Vector`\n" -" :return: the rotational difference between the two vectors.\n" -" :rtype: :class:`Quaternion`\n" -"\n" -" .. note:: 2D vectors raise an :exc:`AttributeError`.\n" -); -static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value) -{ - float quat[4], vec_a[3], vec_b[3]; - - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vec.difference(value): expects both vectors to be size 3 or 4"); - return NULL; - } - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(vec_b, 3, MAX_DIMENSIONS, value, "vector.difference(other), invalid 'other' arg") == -1) - return NULL; - - normalize_v3_v3(vec_a, self->vec); - normalize_v3(vec_b); - - rotation_between_vecs_to_quat(quat, vec_a, vec_b); - - return newQuaternionObject(quat, Py_NEW, NULL); -} - -PyDoc_STRVAR(Vector_project_doc, -".. function:: project(other)\n" -"\n" -" Return the projection of this vector onto the *other*.\n" -"\n" -" :arg other: second vector.\n" -" :type other: :class:`Vector`\n" -" :return: the parallel projection vector\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_project(VectorObject *self, PyObject *value) -{ - const int size= self->size; - float tvec[MAX_DIMENSIONS]; - float vec[MAX_DIMENSIONS]; - double dot = 0.0f, dot2 = 0.0f; - int x; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_array_parse(tvec, size, size, value, "vector.project(other), invalid 'other' arg") == -1) - return NULL; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - //get dot products - for(x = 0; x < size; x++) { - dot += (double)(self->vec[x] * tvec[x]); - dot2 += (double)(tvec[x] * tvec[x]); - } - //projection - dot /= dot2; - for(x = 0; x < size; x++) { - vec[x] = (float)dot * tvec[x]; - } - return newVectorObject(vec, size, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Vector_lerp_doc, -".. function:: lerp(other, factor)\n" -"\n" -" Returns the interpolation of two vectors.\n" -"\n" -" :arg other: value to interpolate with.\n" -" :type other: :class:`Vector`\n" -" :arg factor: The interpolation value in [0.0, 1.0].\n" -" :type factor: float\n" -" :return: The interpolated rotation.\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_lerp(VectorObject *self, PyObject *args) -{ - const int size= self->size; - PyObject *value= NULL; - float fac, ifac; - float tvec[MAX_DIMENSIONS], vec[MAX_DIMENSIONS]; - int x; - - if(!PyArg_ParseTuple(args, "Of:lerp", &value, &fac)) - return NULL; - - if(mathutils_array_parse(tvec, size, size, value, "vector.lerp(other), invalid 'other' arg") == -1) - return NULL; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - ifac= 1.0f - fac; - - for(x = 0; x < size; x++) { - vec[x] = (ifac * self->vec[x]) + (fac * tvec[x]); - } - return newVectorObject(vec, size, Py_NEW, Py_TYPE(self)); -} - -PyDoc_STRVAR(Vector_rotate_doc, -".. function:: rotate(other)\n" -"\n" -" Return vector by a rotation value.\n" -"\n" -" :arg other: rotation component of mathutils value\n" -" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n" -); -static PyObject *Vector_rotate(VectorObject *self, PyObject *value) -{ - float other_rmat[3][3]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - if(mathutils_any_to_rotmat(other_rmat, value, "vector.rotate(value)") == -1) - return NULL; - - if(self->size < 3) { - PyErr_SetString(PyExc_ValueError, "Vector must be 3D or 4D"); - return NULL; - } - - mul_m3_v3(other_rmat, self->vec); - - (void)BaseMath_WriteCallback(self); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(Vector_copy_doc, -".. function:: copy()\n" -"\n" -" Returns a copy of this vector.\n" -"\n" -" :return: A copy of the vector.\n" -" :rtype: :class:`Vector`\n" -"\n" -" .. note:: use this to get a copy of a wrapped vector with\n" -" no reference to the original data.\n" -); -static PyObject *Vector_copy(VectorObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - return newVectorObject(self->vec, self->size, Py_NEW, Py_TYPE(self)); -} - -static PyObject *Vector_repr(VectorObject *self) -{ - PyObject *ret, *tuple; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - tuple= Vector_to_tuple_ext(self, -1); - ret= PyUnicode_FromFormat("Vector(%R)", tuple); - Py_DECREF(tuple); - return ret; -} - -/* Sequence Protocol */ -/* sequence length len(vector) */ -static int Vector_len(VectorObject *self) -{ - return self->size; -} -/* sequence accessor (get): vector[index] */ -static PyObject *vector_item_internal(VectorObject *self, int i, const int is_attr) -{ - if(i<0) i= self->size-i; - - if(i < 0 || i >= self->size) { - if(is_attr) PyErr_Format(PyExc_AttributeError,"vector.%c: unavailable on %dd vector", *(((char *)"xyzw") + i), self->size); - else PyErr_SetString(PyExc_IndexError,"vector[index]: out of range"); - return NULL; - } - - if(BaseMath_ReadIndexCallback(self, i) == -1) - return NULL; - - return PyFloat_FromDouble(self->vec[i]); -} - -static PyObject *Vector_item(VectorObject *self, int i) -{ - return vector_item_internal(self, i, FALSE); -} -/* sequence accessor (set): vector[index] = value */ -static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const int is_attr) -{ - float scalar; - if((scalar=PyFloat_AsDouble(value))==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ - PyErr_SetString(PyExc_TypeError, "vector[index] = x: index argument not a number"); - return -1; - } - - if(i<0) i= self->size-i; - - if(i < 0 || i >= self->size){ - if(is_attr) PyErr_Format(PyExc_AttributeError,"vector.%c = x: unavailable on %dd vector", *(((char *)"xyzw") + i), self->size); - else PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range"); - return -1; - } - self->vec[i] = scalar; - - if(BaseMath_WriteIndexCallback(self, i) == -1) - return -1; - return 0; -} - -static int Vector_ass_item(VectorObject *self, int i, PyObject *value) -{ - return vector_ass_item_internal(self, i, value, FALSE); -} - -/* sequence slice (get): vector[a:b] */ -static PyObject *Vector_slice(VectorObject *self, int begin, int end) -{ - PyObject *tuple; - int count; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - CLAMP(begin, 0, self->size); - if (end<0) end= self->size+end+1; - CLAMP(end, 0, self->size); - begin= MIN2(begin, end); - - tuple= PyTuple_New(end - begin); - for(count = begin; count < end; count++) { - PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->vec[count])); - } - - return tuple; -} -/* sequence slice (set): vector[a:b] = value */ -static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq) -{ - int y, size = 0; - float vec[MAX_DIMENSIONS]; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - CLAMP(begin, 0, self->size); - CLAMP(end, 0, self->size); - begin = MIN2(begin, end); - - size = (end - begin); - if(mathutils_array_parse(vec, size, size, seq, "vector[begin:end] = [...]") == -1) - return -1; - - /*parsed well - now set in vector*/ - for(y = 0; y < size; y++){ - self->vec[begin + y] = vec[y]; - } - - if(BaseMath_WriteCallback(self) == -1) - return -1; - - return 0; -} - -/* Numeric Protocols */ -/* addition: obj + obj */ -static PyObject *Vector_add(PyObject *v1, PyObject *v2) -{ - VectorObject *vec1 = NULL, *vec2 = NULL; - float vec[MAX_DIMENSIONS]; - - if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation"); - return NULL; - } - vec1 = (VectorObject*)v1; - vec2 = (VectorObject*)v2; - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) - return NULL; - - /*VECTOR + VECTOR*/ - if(vec1->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation"); - return NULL; - } - - add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size); - - return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(v1)); -} - -/* addition in-place: obj += obj */ -static PyObject *Vector_iadd(PyObject *v1, PyObject *v2) -{ - VectorObject *vec1 = NULL, *vec2 = NULL; - - if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation"); - return NULL; - } - vec1 = (VectorObject*)v1; - vec2 = (VectorObject*)v2; - - if(vec1->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) - return NULL; - - add_vn_vn(vec1->vec, vec2->vec, vec1->size); - - (void)BaseMath_WriteCallback(vec1); - Py_INCREF(v1); - return v1; -} - -/* subtraction: obj - obj */ -static PyObject *Vector_sub(PyObject *v1, PyObject *v2) -{ - VectorObject *vec1 = NULL, *vec2 = NULL; - float vec[MAX_DIMENSIONS]; - - if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Vector subtraction: arguments not valid for this operation"); - return NULL; - } - vec1 = (VectorObject*)v1; - vec2 = (VectorObject*)v2; - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) - return NULL; - - if(vec1->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation"); - return NULL; - } - - sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size); - - return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(v1)); -} - -/* subtraction in-place: obj -= obj */ -static PyObject *Vector_isub(PyObject *v1, PyObject *v2) -{ - VectorObject *vec1= NULL, *vec2= NULL; - - if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { - PyErr_SetString(PyExc_AttributeError, "Vector subtraction: arguments not valid for this operation"); - return NULL; - } - vec1 = (VectorObject*)v1; - vec2 = (VectorObject*)v2; - - if(vec1->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) - return NULL; - - sub_vn_vn(vec1->vec, vec2->vec, vec1->size); - - (void)BaseMath_WriteCallback(vec1); - Py_INCREF(v1); - return v1; -} - -/*------------------------obj * obj------------------------------ - mulplication*/ - - -/* COLUMN VECTOR Multiplication (Vector X Matrix) - * [a] * [1][4][7] - * [b] * [2][5][8] - * [c] * [3][6][9] - * - * note: vector/matrix multiplication IS NOT COMMUTATIVE!!!! - * note: assume read callbacks have been done first. - */ -static int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat) -{ - float vec_cpy[MAX_DIMENSIONS]; - double dot = 0.0f; - int x, y, z = 0; - - if(mat->row_size != vec->size){ - if(mat->row_size == 4 && vec->size == 3) { - vec_cpy[3] = 1.0f; - } - else { - PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix.row_size and len(vector) must be the same, except for 3D vector * 4x4 matrix."); - return -1; - } - } - - memcpy(vec_cpy, vec->vec, vec->size * sizeof(float)); - - rvec[3] = 1.0f; - - for(x = 0; x < mat->col_size; x++) { - for(y = 0; y < mat->row_size; y++) { - dot += (double)(mat->matrix[y][x] * vec_cpy[y]); - } - rvec[z++] = (float)dot; - dot = 0.0f; - } - - return 0; -} - -static PyObject *vector_mul_float(VectorObject *vec, const float scalar) -{ - float tvec[MAX_DIMENSIONS]; - mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar); - return newVectorObject(tvec, vec->size, Py_NEW, Py_TYPE(vec)); -} - -static PyObject *Vector_mul(PyObject *v1, PyObject *v2) -{ - VectorObject *vec1 = NULL, *vec2 = NULL; - float scalar; - - if VectorObject_Check(v1) { - vec1= (VectorObject *)v1; - if(BaseMath_ReadCallback(vec1) == -1) - return NULL; - } - if VectorObject_Check(v2) { - vec2= (VectorObject *)v2; - if(BaseMath_ReadCallback(vec2) == -1) - return NULL; - } - - - /* make sure v1 is always the vector */ - if (vec1 && vec2) { - int i; - double dot = 0.0f; - - if(vec1->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "Vector multiplication: vectors must have the same dimensions for this operation"); - return NULL; - } - - /*dot product*/ - for(i = 0; i < vec1->size; i++) { - dot += (double)(vec1->vec[i] * vec2->vec[i]); - } - return PyFloat_FromDouble(dot); - } - else if (vec1) { - if (MatrixObject_Check(v2)) { - /* VEC * MATRIX */ - float tvec[MAX_DIMENSIONS]; - if(BaseMath_ReadCallback((MatrixObject *)v2) == -1) - return NULL; - if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) { - return NULL; - } - - return newVectorObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1)); - } - else if (QuaternionObject_Check(v2)) { - /* VEC * QUAT */ - QuaternionObject *quat2 = (QuaternionObject*)v2; - float tvec[3]; - - if(vec1->size != 3) { - PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported"); - return NULL; - } - if(BaseMath_ReadCallback(quat2) == -1) { - return NULL; - } - copy_v3_v3(tvec, vec1->vec); - mul_qt_v3(quat2->quat, tvec); - return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1)); - } - else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC * FLOAT */ - return vector_mul_float(vec1, scalar); - } - } - else if (vec2) { - if (((scalar= PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred())==0) { /* FLOAT * VEC */ - return vector_mul_float(vec2, scalar); - } - } - else { - BLI_assert(!"internal error"); - } - - PyErr_Format(PyExc_TypeError, "Vector multiplication: not supported between '%.200s' and '%.200s' types", Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); - return NULL; -} - -/* mulplication in-place: obj *= obj */ -static PyObject *Vector_imul(PyObject *v1, PyObject *v2) -{ - VectorObject *vec = (VectorObject *)v1; - float scalar; - - if(BaseMath_ReadCallback(vec) == -1) - return NULL; - - /* only support vec*=float and vec*=mat - vec*=vec result is a float so that wont work */ - if (MatrixObject_Check(v2)) { - float rvec[MAX_DIMENSIONS]; - if(BaseMath_ReadCallback((MatrixObject *)v2) == -1) - return NULL; - - if(column_vector_multiplication(rvec, vec, (MatrixObject*)v2) == -1) - return NULL; - - memcpy(vec->vec, rvec, sizeof(float) * vec->size); - } - else if (QuaternionObject_Check(v2)) { - /* VEC *= QUAT */ - QuaternionObject *quat2 = (QuaternionObject*)v2; - - if(vec->size != 3) { - PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported"); - return NULL; - } - - if(BaseMath_ReadCallback(quat2) == -1) { - return NULL; - } - mul_qt_v3(quat2->quat, vec->vec); - } - else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC *= FLOAT */ - mul_vn_fl(vec->vec, vec->size, scalar); - } - else { - PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation"); - return NULL; - } - - (void)BaseMath_WriteCallback(vec); - Py_INCREF(v1); - return v1; -} - -/* divid: obj / obj */ -static PyObject *Vector_div(PyObject *v1, PyObject *v2) -{ - int i; - float vec[4], scalar; - VectorObject *vec1 = NULL; - - if(!VectorObject_Check(v1)) { /* not a vector */ - PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float"); - return NULL; - } - vec1 = (VectorObject*)v1; /* vector */ - - if(BaseMath_ReadCallback(vec1) == -1) - return NULL; - - if((scalar=PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ - PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float"); - return NULL; - } - - if(scalar==0.0f) { - PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error"); - return NULL; - } - - for(i = 0; i < vec1->size; i++) { - vec[i] = vec1->vec[i] / scalar; - } - return newVectorObject(vec, vec1->size, Py_NEW, Py_TYPE(v1)); -} - -/* divide in-place: obj /= obj */ -static PyObject *Vector_idiv(PyObject *v1, PyObject *v2) -{ - int i; - float scalar; - VectorObject *vec1 = (VectorObject*)v1; - - if(BaseMath_ReadCallback(vec1) == -1) - return NULL; - - if((scalar=PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ - PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float"); - return NULL; - } - - if(scalar==0.0f) { - PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error"); - return NULL; - } - for(i = 0; i < vec1->size; i++) { - vec1->vec[i] /= scalar; - } - - (void)BaseMath_WriteCallback(vec1); - - Py_INCREF(v1); - return v1; -} - -/* -obj - returns the negative of this object*/ -static PyObject *Vector_neg(VectorObject *self) -{ - float tvec[MAX_DIMENSIONS]; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - negate_vn_vn(tvec, self->vec, self->size); - return newVectorObject(tvec, self->size, Py_NEW, Py_TYPE(self)); -} - -/*------------------------vec_magnitude_nosqrt (internal) - for comparing only */ -static double vec_magnitude_nosqrt(float *data, int size) -{ - double dot = 0.0f; - int i; - - for(i=0; i<size; i++){ - dot += (double)data[i]; - } - /*return (double)sqrt(dot);*/ - /* warning, line above removed because we are not using the length, - rather the comparing the sizes and for this we do not need the sqrt - for the actual length, the dot must be sqrt'd */ - return dot; -} - - -/*------------------------tp_richcmpr - returns -1 execption, 0 false, 1 true */ -static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type) -{ - VectorObject *vecA = NULL, *vecB = NULL; - int result = 0; - double epsilon = .000001f; - double lenA, lenB; - - if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)){ - if (comparison_type == Py_NE){ - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } - } - vecA = (VectorObject*)objectA; - vecB = (VectorObject*)objectB; - - if(BaseMath_ReadCallback(vecA) == -1 || BaseMath_ReadCallback(vecB) == -1) - return NULL; - - if (vecA->size != vecB->size){ - if (comparison_type == Py_NE){ - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } - } - - switch (comparison_type){ - case Py_LT: - lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size); - lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size); - if(lenA < lenB){ - result = 1; - } - break; - case Py_LE: - lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size); - lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size); - if(lenA < lenB){ - result = 1; - } - else { - result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB)); - } - break; - case Py_EQ: - result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); - break; - case Py_NE: - result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1); - break; - case Py_GT: - lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size); - lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size); - if(lenA > lenB){ - result = 1; - } - break; - case Py_GE: - lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size); - lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size); - if(lenA > lenB){ - result = 1; - } - else { - result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB)); - } - break; - default: - printf("The result of the comparison could not be evaluated"); - break; - } - if (result == 1){ - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -/*-----------------PROTCOL DECLARATIONS--------------------------*/ -static PySequenceMethods Vector_SeqMethods = { - (lenfunc) Vector_len, /* sq_length */ - (binaryfunc) NULL, /* sq_concat */ - (ssizeargfunc) NULL, /* sq_repeat */ - (ssizeargfunc) Vector_item, /* sq_item */ - NULL, /* py3 deprecated slice func */ - (ssizeobjargproc) Vector_ass_item, /* sq_ass_item */ - NULL, /* py3 deprecated slice assign func */ - (objobjproc) NULL, /* sq_contains */ - (binaryfunc) NULL, /* sq_inplace_concat */ - (ssizeargfunc) NULL, /* sq_inplace_repeat */ -}; - -static PyObject *Vector_subscript(VectorObject* self, PyObject* item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += self->size; - return Vector_item(self, i); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, self->size, &start, &stop, &step, &slicelength) < 0) - return NULL; - - if (slicelength <= 0) { - return PyTuple_New(0); - } - else if (step == 1) { - return Vector_slice(self, start, stop); - } - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } -} - -static int Vector_ass_subscript(VectorObject* self, PyObject* item, PyObject* value) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += self->size; - return Vector_ass_item(self, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx((void *)item, self->size, &start, &stop, &step, &slicelength) < 0) - return -1; - - if (step == 1) - return Vector_ass_slice(self, start, stop, value); - else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); - return -1; - } -} - -static PyMappingMethods Vector_AsMapping = { - (lenfunc)Vector_len, - (binaryfunc)Vector_subscript, - (objobjargproc)Vector_ass_subscript -}; - - -static PyNumberMethods Vector_NumMethods = { - (binaryfunc) Vector_add, /*nb_add*/ - (binaryfunc) Vector_sub, /*nb_subtract*/ - (binaryfunc) Vector_mul, /*nb_multiply*/ - NULL, /*nb_remainder*/ - NULL, /*nb_divmod*/ - NULL, /*nb_power*/ - (unaryfunc) Vector_neg, /*nb_negative*/ - (unaryfunc) NULL, /*tp_positive*/ - (unaryfunc) NULL, /*tp_absolute*/ - (inquiry) NULL, /*tp_bool*/ - (unaryfunc) NULL, /*nb_invert*/ - NULL, /*nb_lshift*/ - (binaryfunc)NULL, /*nb_rshift*/ - NULL, /*nb_and*/ - NULL, /*nb_xor*/ - NULL, /*nb_or*/ - NULL, /*nb_int*/ - NULL, /*nb_reserved*/ - NULL, /*nb_float*/ - Vector_iadd, /* nb_inplace_add */ - Vector_isub, /* nb_inplace_subtract */ - Vector_imul, /* nb_inplace_multiply */ - NULL, /* nb_inplace_remainder */ - NULL, /* nb_inplace_power */ - NULL, /* nb_inplace_lshift */ - NULL, /* nb_inplace_rshift */ - NULL, /* nb_inplace_and */ - NULL, /* nb_inplace_xor */ - NULL, /* nb_inplace_or */ - NULL, /* nb_floor_divide */ - Vector_div, /* nb_true_divide */ - NULL, /* nb_inplace_floor_divide */ - Vector_idiv, /* nb_inplace_true_divide */ - NULL, /* nb_index */ -}; - -/*------------------PY_OBECT DEFINITION--------------------------*/ - -/* - * vector axis, vector.x/y/z/w - */ - -static PyObject *Vector_getAxis(VectorObject *self, void *type) -{ - return vector_item_internal(self, GET_INT_FROM_POINTER(type), TRUE); -} - -static int Vector_setAxis(VectorObject *self, PyObject *value, void *type) -{ - return vector_ass_item_internal(self, GET_INT_FROM_POINTER(type), value, TRUE); -} - -/* vector.length */ -static PyObject *Vector_getLength(VectorObject *self, void *UNUSED(closure)) -{ - double dot = 0.0f; - int i; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - for(i = 0; i < self->size; i++){ - dot += (double)(self->vec[i] * self->vec[i]); - } - return PyFloat_FromDouble(sqrt(dot)); -} - -static int Vector_setLength(VectorObject *self, PyObject *value) -{ - double dot = 0.0f, param; - int i; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - if((param=PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "length must be set to a number"); - return -1; - } - - if (param < 0.0) { - PyErr_SetString(PyExc_TypeError, "cannot set a vectors length to a negative value"); - return -1; - } - if (param == 0.0) { - fill_vn(self->vec, self->size, 0.0f); - return 0; - } - - for(i = 0; i < self->size; i++){ - dot += (double)(self->vec[i] * self->vec[i]); - } - - if (!dot) /* cant sqrt zero */ - return 0; - - dot = sqrt(dot); - - if (dot==param) - return 0; - - dot= dot/param; - - for(i = 0; i < self->size; i++){ - self->vec[i]= self->vec[i] / (float)dot; - } - - (void)BaseMath_WriteCallback(self); /* checked already */ - - return 0; -} - -/* Get a new Vector according to the provided swizzle. This function has little - error checking, as we are in control of the inputs: the closure is set by us - in Vector_createSwizzleGetSeter. */ -static PyObject *Vector_getSwizzle(VectorObject *self, void *closure) -{ - size_t axis_to; - size_t axis_from; - float vec[MAX_DIMENSIONS]; - unsigned int swizzleClosure; - - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - /* Unpack the axes from the closure into an array. */ - axis_to = 0; - swizzleClosure = GET_INT_FROM_POINTER(closure); - while (swizzleClosure & SWIZZLE_VALID_AXIS) - { - axis_from = swizzleClosure & SWIZZLE_AXIS; - if(axis_from >= self->size) { - PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis"); - return NULL; - } - - vec[axis_to] = self->vec[axis_from]; - swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; - axis_to++; - } - - return newVectorObject(vec, axis_to, Py_NEW, Py_TYPE(self)); -} - -/* Set the items of this vector using a swizzle. - - If value is a vector or list this operates like an array copy, except that - the destination is effectively re-ordered as defined by the swizzle. At - most min(len(source), len(dest)) values will be copied. - - If the value is scalar, it is copied to all axes listed in the swizzle. - - If an axis appears more than once in the swizzle, the final occurrence is - the one that determines its value. - - Returns 0 on success and -1 on failure. On failure, the vector will be - unchanged. */ -static int Vector_setSwizzle(VectorObject *self, PyObject *value, void *closure) -{ - size_t size_from; - float scalarVal; - - size_t axis_from; - size_t axis_to; - - unsigned int swizzleClosure; - - float tvec[MAX_DIMENSIONS]; - float vec_assign[MAX_DIMENSIONS]; - - if(BaseMath_ReadCallback(self) == -1) - return -1; - - /* Check that the closure can be used with this vector: even 2D vectors have - swizzles defined for axes z and w, but they would be invalid. */ - swizzleClosure = GET_INT_FROM_POINTER(closure); - axis_from= 0; - while (swizzleClosure & SWIZZLE_VALID_AXIS) - { - axis_to = swizzleClosure & SWIZZLE_AXIS; - if (axis_to >= self->size) - { - PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis"); - return -1; - } - swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; - axis_from++; - } - - if (((scalarVal=PyFloat_AsDouble(value)) == -1 && PyErr_Occurred())==0) { - int i; - for(i=0; i < MAX_DIMENSIONS; i++) - vec_assign[i]= scalarVal; - - size_from= axis_from; - } - else if((size_from=mathutils_array_parse(vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) { - return -1; - } - - if(axis_from != size_from) { - PyErr_SetString(PyExc_AttributeError, "Error: vector size does not match swizzle"); - return -1; - } - - /* Copy vector contents onto swizzled axes. */ - axis_from = 0; - swizzleClosure = GET_INT_FROM_POINTER(closure); - while (swizzleClosure & SWIZZLE_VALID_AXIS) - { - axis_to = swizzleClosure & SWIZZLE_AXIS; - tvec[axis_to] = vec_assign[axis_from]; - swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; - axis_from++; - } - - memcpy(self->vec, tvec, axis_from * sizeof(float)); - /* continue with BaseMathObject_WriteCallback at the end */ - - if(BaseMath_WriteCallback(self) == -1) - return -1; - else - return 0; -} - -/*****************************************************************************/ -/* Python attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef Vector_getseters[] = { - {(char *)"x", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector X axis.\n\n:type: float", (void *)0}, - {(char *)"y", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector Y axis.\n\n:type: float", (void *)1}, - {(char *)"z", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector Z axis (3D Vectors only).\n\n:type: float", (void *)2}, - {(char *)"w", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector W axis (4D Vectors only).\n\n:type: float", (void *)3}, - {(char *)"length", (getter)Vector_getLength, (setter)Vector_setLength, (char *)"Vector Length.\n\n:type: float", NULL}, - {(char *)"magnitude", (getter)Vector_getLength, (setter)Vector_setLength, (char *)"Vector Length.\n\n:type: float", NULL}, - {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, - {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, - - /* autogenerated swizzle attrs, see python script below */ - {(char *)"xx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 36 - {(char *)"xxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 292 - {(char *)"xxxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2340 - {(char *)"xxxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2852 - {(char *)"xxxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3364 - {(char *)"xxxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3876 - {(char *)"xxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 356 - {(char *)"xxyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2404 - {(char *)"xxyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2916 - {(char *)"xxyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3428 - {(char *)"xxyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3940 - {(char *)"xxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 420 - {(char *)"xxzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2468 - {(char *)"xxzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2980 - {(char *)"xxzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3492 - {(char *)"xxzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4004 - {(char *)"xxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 484 - {(char *)"xxwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2532 - {(char *)"xxwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3044 - {(char *)"xxwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3556 - {(char *)"xxww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4068 - {(char *)"xy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 44 - {(char *)"xyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 300 - {(char *)"xyxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2348 - {(char *)"xyxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2860 - {(char *)"xyxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3372 - {(char *)"xyxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3884 - {(char *)"xyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 364 - {(char *)"xyyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2412 - {(char *)"xyyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2924 - {(char *)"xyyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3436 - {(char *)"xyyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3948 - {(char *)"xyz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 428 - {(char *)"xyzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2476 - {(char *)"xyzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2988 - {(char *)"xyzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3500 - {(char *)"xyzw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4012 - {(char *)"xyw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 492 - {(char *)"xywx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2540 - {(char *)"xywy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3052 - {(char *)"xywz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3564 - {(char *)"xyww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4076 - {(char *)"xz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 52 - {(char *)"xzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 308 - {(char *)"xzxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2356 - {(char *)"xzxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2868 - {(char *)"xzxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3380 - {(char *)"xzxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3892 - {(char *)"xzy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 372 - {(char *)"xzyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2420 - {(char *)"xzyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2932 - {(char *)"xzyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3444 - {(char *)"xzyw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3956 - {(char *)"xzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 436 - {(char *)"xzzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2484 - {(char *)"xzzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2996 - {(char *)"xzzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3508 - {(char *)"xzzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4020 - {(char *)"xzw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 500 - {(char *)"xzwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2548 - {(char *)"xzwy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3060 - {(char *)"xzwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3572 - {(char *)"xzww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4084 - {(char *)"xw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 60 - {(char *)"xwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 316 - {(char *)"xwxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2364 - {(char *)"xwxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2876 - {(char *)"xwxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3388 - {(char *)"xwxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3900 - {(char *)"xwy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 380 - {(char *)"xwyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2428 - {(char *)"xwyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2940 - {(char *)"xwyz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3452 - {(char *)"xwyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3964 - {(char *)"xwz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 444 - {(char *)"xwzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2492 - {(char *)"xwzy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3004 - {(char *)"xwzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3516 - {(char *)"xwzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4028 - {(char *)"xww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 508 - {(char *)"xwwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2556 - {(char *)"xwwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3068 - {(char *)"xwwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3580 - {(char *)"xwww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4092 - {(char *)"yx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 37 - {(char *)"yxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 293 - {(char *)"yxxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2341 - {(char *)"yxxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2853 - {(char *)"yxxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3365 - {(char *)"yxxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3877 - {(char *)"yxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 357 - {(char *)"yxyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2405 - {(char *)"yxyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2917 - {(char *)"yxyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3429 - {(char *)"yxyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3941 - {(char *)"yxz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 421 - {(char *)"yxzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2469 - {(char *)"yxzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2981 - {(char *)"yxzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3493 - {(char *)"yxzw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4005 - {(char *)"yxw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 485 - {(char *)"yxwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2533 - {(char *)"yxwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3045 - {(char *)"yxwz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3557 - {(char *)"yxww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4069 - {(char *)"yy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 45 - {(char *)"yyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 301 - {(char *)"yyxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2349 - {(char *)"yyxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2861 - {(char *)"yyxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3373 - {(char *)"yyxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3885 - {(char *)"yyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 365 - {(char *)"yyyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2413 - {(char *)"yyyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2925 - {(char *)"yyyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3437 - {(char *)"yyyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3949 - {(char *)"yyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 429 - {(char *)"yyzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2477 - {(char *)"yyzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2989 - {(char *)"yyzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3501 - {(char *)"yyzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4013 - {(char *)"yyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 493 - {(char *)"yywx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2541 - {(char *)"yywy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3053 - {(char *)"yywz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3565 - {(char *)"yyww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4077 - {(char *)"yz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 53 - {(char *)"yzx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 309 - {(char *)"yzxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2357 - {(char *)"yzxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2869 - {(char *)"yzxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3381 - {(char *)"yzxw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3893 - {(char *)"yzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 373 - {(char *)"yzyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2421 - {(char *)"yzyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2933 - {(char *)"yzyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3445 - {(char *)"yzyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3957 - {(char *)"yzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 437 - {(char *)"yzzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2485 - {(char *)"yzzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2997 - {(char *)"yzzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3509 - {(char *)"yzzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4021 - {(char *)"yzw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 501 - {(char *)"yzwx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2549 - {(char *)"yzwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3061 - {(char *)"yzwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3573 - {(char *)"yzww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4085 - {(char *)"yw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 61 - {(char *)"ywx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 317 - {(char *)"ywxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2365 - {(char *)"ywxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2877 - {(char *)"ywxz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3389 - {(char *)"ywxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3901 - {(char *)"ywy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 381 - {(char *)"ywyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2429 - {(char *)"ywyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2941 - {(char *)"ywyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3453 - {(char *)"ywyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3965 - {(char *)"ywz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 445 - {(char *)"ywzx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2493 - {(char *)"ywzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3005 - {(char *)"ywzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3517 - {(char *)"ywzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4029 - {(char *)"yww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 509 - {(char *)"ywwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2557 - {(char *)"ywwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3069 - {(char *)"ywwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3581 - {(char *)"ywww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((1|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4093 - {(char *)"zx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 38 - {(char *)"zxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 294 - {(char *)"zxxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2342 - {(char *)"zxxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2854 - {(char *)"zxxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3366 - {(char *)"zxxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3878 - {(char *)"zxy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 358 - {(char *)"zxyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2406 - {(char *)"zxyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2918 - {(char *)"zxyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3430 - {(char *)"zxyw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3942 - {(char *)"zxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 422 - {(char *)"zxzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2470 - {(char *)"zxzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2982 - {(char *)"zxzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3494 - {(char *)"zxzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4006 - {(char *)"zxw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 486 - {(char *)"zxwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2534 - {(char *)"zxwy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3046 - {(char *)"zxwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3558 - {(char *)"zxww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4070 - {(char *)"zy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 46 - {(char *)"zyx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 302 - {(char *)"zyxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2350 - {(char *)"zyxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2862 - {(char *)"zyxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3374 - {(char *)"zyxw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3886 - {(char *)"zyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 366 - {(char *)"zyyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2414 - {(char *)"zyyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2926 - {(char *)"zyyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3438 - {(char *)"zyyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3950 - {(char *)"zyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 430 - {(char *)"zyzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2478 - {(char *)"zyzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2990 - {(char *)"zyzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3502 - {(char *)"zyzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4014 - {(char *)"zyw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 494 - {(char *)"zywx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2542 - {(char *)"zywy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3054 - {(char *)"zywz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3566 - {(char *)"zyww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4078 - {(char *)"zz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 54 - {(char *)"zzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 310 - {(char *)"zzxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2358 - {(char *)"zzxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2870 - {(char *)"zzxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3382 - {(char *)"zzxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3894 - {(char *)"zzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 374 - {(char *)"zzyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2422 - {(char *)"zzyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2934 - {(char *)"zzyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3446 - {(char *)"zzyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3958 - {(char *)"zzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 438 - {(char *)"zzzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2486 - {(char *)"zzzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2998 - {(char *)"zzzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3510 - {(char *)"zzzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4022 - {(char *)"zzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 502 - {(char *)"zzwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2550 - {(char *)"zzwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3062 - {(char *)"zzwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3574 - {(char *)"zzww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4086 - {(char *)"zw", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 62 - {(char *)"zwx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 318 - {(char *)"zwxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2366 - {(char *)"zwxy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2878 - {(char *)"zwxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3390 - {(char *)"zwxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3902 - {(char *)"zwy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 382 - {(char *)"zwyx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2430 - {(char *)"zwyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2942 - {(char *)"zwyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3454 - {(char *)"zwyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3966 - {(char *)"zwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 446 - {(char *)"zwzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2494 - {(char *)"zwzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3006 - {(char *)"zwzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3518 - {(char *)"zwzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4030 - {(char *)"zww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 510 - {(char *)"zwwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2558 - {(char *)"zwwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3070 - {(char *)"zwwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3582 - {(char *)"zwww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((2|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4094 - {(char *)"wx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 39 - {(char *)"wxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 295 - {(char *)"wxxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2343 - {(char *)"wxxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2855 - {(char *)"wxxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3367 - {(char *)"wxxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3879 - {(char *)"wxy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 359 - {(char *)"wxyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2407 - {(char *)"wxyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2919 - {(char *)"wxyz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3431 - {(char *)"wxyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3943 - {(char *)"wxz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 423 - {(char *)"wxzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2471 - {(char *)"wxzy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2983 - {(char *)"wxzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3495 - {(char *)"wxzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4007 - {(char *)"wxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 487 - {(char *)"wxwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2535 - {(char *)"wxwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3047 - {(char *)"wxwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3559 - {(char *)"wxww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4071 - {(char *)"wy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 47 - {(char *)"wyx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 303 - {(char *)"wyxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2351 - {(char *)"wyxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2863 - {(char *)"wyxz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3375 - {(char *)"wyxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3887 - {(char *)"wyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 367 - {(char *)"wyyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2415 - {(char *)"wyyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2927 - {(char *)"wyyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3439 - {(char *)"wyyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3951 - {(char *)"wyz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 431 - {(char *)"wyzx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2479 - {(char *)"wyzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2991 - {(char *)"wyzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3503 - {(char *)"wyzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4015 - {(char *)"wyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 495 - {(char *)"wywx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2543 - {(char *)"wywy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3055 - {(char *)"wywz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3567 - {(char *)"wyww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4079 - {(char *)"wz", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 55 - {(char *)"wzx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 311 - {(char *)"wzxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2359 - {(char *)"wzxy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2871 - {(char *)"wzxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3383 - {(char *)"wzxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3895 - {(char *)"wzy", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 375 - {(char *)"wzyx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2423 - {(char *)"wzyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2935 - {(char *)"wzyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3447 - {(char *)"wzyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3959 - {(char *)"wzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 439 - {(char *)"wzzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2487 - {(char *)"wzzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2999 - {(char *)"wzzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3511 - {(char *)"wzzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4023 - {(char *)"wzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 503 - {(char *)"wzwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2551 - {(char *)"wzwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3063 - {(char *)"wzwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3575 - {(char *)"wzww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4087 - {(char *)"ww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS)))}, // 63 - {(char *)"wwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 319 - {(char *)"wwxx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2367 - {(char *)"wwxy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2879 - {(char *)"wwxz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3391 - {(char *)"wwxw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3903 - {(char *)"wwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 383 - {(char *)"wwyx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2431 - {(char *)"wwyy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2943 - {(char *)"wwyz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3455 - {(char *)"wwyw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3967 - {(char *)"wwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 447 - {(char *)"wwzx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2495 - {(char *)"wwzy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3007 - {(char *)"wwzz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3519 - {(char *)"wwzw", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4031 - {(char *)"www", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2))))}, // 511 - {(char *)"wwwx", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((0|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 2559 - {(char *)"wwwy", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((1|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3071 - {(char *)"wwwz", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((2|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 3583 - {(char *)"wwww", (getter)Vector_getSwizzle, (setter)NULL, NULL, SET_INT_IN_POINTER(((3|SWIZZLE_VALID_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((3|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) )}, // 4095 - {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ -}; - -/* Python script used to make swizzle array */ -/* -SWIZZLE_BITS_PER_AXIS = 3 -SWIZZLE_VALID_AXIS = 0x4 - -axis_dict = {} -axis_pos = {'x':0, 'y':1, 'z':2, 'w':3} -axises = 'xyzw' -while len(axises) >= 2: - - for axis_0 in axises: - axis_0_pos = axis_pos[axis_0] - for axis_1 in axises: - axis_1_pos = axis_pos[axis_1] - axis_dict[axis_0+axis_1] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS))' % (axis_0_pos, axis_1_pos) - if len(axises)>2: - for axis_2 in axises: - axis_2_pos = axis_pos[axis_2] - axis_dict[axis_0+axis_1+axis_2] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)))' % (axis_0_pos, axis_1_pos, axis_2_pos) - if len(axises)>3: - for axis_3 in axises: - axis_3_pos = axis_pos[axis_3] - axis_dict[axis_0+axis_1+axis_2+axis_3] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<SWIZZLE_BITS_PER_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*2)) | ((%s|SWIZZLE_VALID_AXIS)<<(SWIZZLE_BITS_PER_AXIS*3))) ' % (axis_0_pos, axis_1_pos, axis_2_pos, axis_3_pos) - - axises = axises[:-1] - - -items = axis_dict.items() -items.sort(key = lambda a: a[0].replace('x', '0').replace('y', '1').replace('z', '2').replace('w', '3')) - -unique = set() -for key, val in items: - num = eval(val) - set_str = 'Vector_setSwizzle' if (len(set(key)) == len(key)) else 'NULL' - print '\t{"%s", %s(getter)Vector_getSwizzle, (setter)%s, NULL, SET_INT_IN_POINTER(%s)}, // %s' % (key, (' '*(4-len(key))), set_str, axis_dict[key], num) - unique.add(num) - -if len(unique) != len(items): - print "ERROR" -*/ - -#if 0 -//ROW VECTOR Multiplication - Vector X Matrix -//[x][y][z] * [1][4][7] -// [2][5][8] -// [3][6][9] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat) -{ - float vec_cpy[4]; - double dot = 0.0f; - int x, y, z = 0, vec_size = vec->size; - - if(mat->colSize != vec_size){ - if(mat->colSize == 4 && vec_size != 3){ - PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); - return -1; - } - else { - vec_cpy[3] = 1.0f; - } - } - - if(BaseMath_ReadCallback(vec) == -1 || BaseMath_ReadCallback(mat) == -1) - return -1; - - memcpy(vec_cpy, vec->vec, vec_size * sizeof(float)); - - rvec[3] = 1.0f; - //muliplication - for(x = 0; x < mat->rowSize; x++) { - for(y = 0; y < mat->colSize; y++) { - dot += mat->matrix[x][y] * vec_cpy[y]; - } - rvec[z++] = (float)dot; - dot = 0.0f; - } - return 0; -} -#endif - -/*----------------------------Vector.negate() -------------------- */ -PyDoc_STRVAR(Vector_negate_doc, -".. method:: negate()\n" -"\n" -" Set all values to their negative.\n" -"\n" -" :return: an instance of itself\n" -" :rtype: :class:`Vector`\n" -); -static PyObject *Vector_negate(VectorObject *self) -{ - if(BaseMath_ReadCallback(self) == -1) - return NULL; - - negate_vn(self->vec, self->size); - - (void)BaseMath_WriteCallback(self); // already checked for error - Py_RETURN_NONE; -} - -static struct PyMethodDef Vector_methods[] = { - /* in place only */ - {"zero", (PyCFunction) Vector_zero, METH_NOARGS, Vector_zero_doc}, - {"negate", (PyCFunction) Vector_negate, METH_NOARGS, Vector_negate_doc}, - - /* operate on original or copy */ - {"normalize", (PyCFunction) Vector_normalize, METH_NOARGS, Vector_normalize_doc}, - {"normalized", (PyCFunction) Vector_normalized, METH_NOARGS, Vector_normalized_doc}, - - {"to_2d", (PyCFunction) Vector_to_2d, METH_NOARGS, Vector_to_2d_doc}, - {"resize_2d", (PyCFunction) Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc}, - {"to_3d", (PyCFunction) Vector_to_3d, METH_NOARGS, Vector_to_3d_doc}, - {"resize_3d", (PyCFunction) Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc}, - {"to_4d", (PyCFunction) Vector_to_4d, METH_NOARGS, Vector_to_4d_doc}, - {"resize_4d", (PyCFunction) Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc}, - {"to_tuple", (PyCFunction) Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc}, - {"to_track_quat", (PyCFunction) Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc}, - - /* operation between 2 or more types */ - {"reflect", (PyCFunction) Vector_reflect, METH_O, Vector_reflect_doc}, - {"cross", (PyCFunction) Vector_cross, METH_O, Vector_cross_doc}, - {"dot", (PyCFunction) Vector_dot, METH_O, Vector_dot_doc}, - {"angle", (PyCFunction) Vector_angle, METH_VARARGS, Vector_angle_doc}, - {"rotation_difference", (PyCFunction) Vector_rotation_difference, METH_O, Vector_rotation_difference_doc}, - {"project", (PyCFunction) Vector_project, METH_O, Vector_project_doc}, - {"lerp", (PyCFunction) Vector_lerp, METH_VARARGS, Vector_lerp_doc}, - {"rotate", (PyCFunction) Vector_rotate, METH_O, Vector_rotate_doc}, - - {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, - {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL}, - {NULL, NULL, 0, NULL} -}; - - -/* Note - Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing - but this means for eg that - vec*mat and mat*vec both get sent to Vector_mul and it neesd to sort out the order -*/ - -PyDoc_STRVAR(vector_doc, -"This object gives access to Vectors in Blender." -); -PyTypeObject vector_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - /* For printing, in format "<module>.<name>" */ - "mathutils.Vector", /* char *tp_name; */ - sizeof(VectorObject), /* int tp_basicsize; */ - 0, /* tp_itemsize; For allocation */ - - /* Methods to implement standard operations */ - - (destructor) BaseMathObject_dealloc,/* destructor tp_dealloc; */ - NULL, /* printfunc tp_print; */ - NULL, /* getattrfunc tp_getattr; */ - NULL, /* setattrfunc tp_setattr; */ - NULL, /* cmpfunc tp_compare; */ - (reprfunc)Vector_repr, /* reprfunc tp_repr; */ - - /* Method suites for standard classes */ - - &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */ - &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */ - &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */ - - /* More standard operations (here for binary compatibility) */ - - NULL, /* hashfunc tp_hash; */ - NULL, /* ternaryfunc tp_call; */ - NULL, /* reprfunc tp_str; */ - NULL, /* getattrofunc tp_getattro; */ - NULL, /* setattrofunc tp_setattro; */ - - /* Functions to access object as input/output buffer */ - NULL, /* PyBufferProcs *tp_as_buffer; */ - - /*** Flags to define presence of optional/expanded features ***/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - vector_doc, /* char *tp_doc; Documentation string */ - /*** Assigned meaning in release 2.0 ***/ - - /* call function for all accessible objects */ - (traverseproc)BaseMathObject_traverse, //tp_traverse - - /* delete references to contained objects */ - (inquiry)BaseMathObject_clear, //tp_clear - - /*** Assigned meaning in release 2.1 ***/ - /*** rich comparisons ***/ - (richcmpfunc)Vector_richcmpr, /* richcmpfunc tp_richcompare; */ - - /*** weak reference enabler ***/ - 0, /* long tp_weaklistoffset; */ - - /*** Added in release 2.2 ***/ - /* Iterators */ - NULL, /* getiterfunc tp_iter; */ - NULL, /* iternextfunc tp_iternext; */ - - /*** Attribute descriptor and subclassing stuff ***/ - Vector_methods, /* struct PyMethodDef *tp_methods; */ - NULL, /* struct PyMemberDef *tp_members; */ - Vector_getseters, /* struct PyGetSetDef *tp_getset; */ - NULL, /* struct _typeobject *tp_base; */ - NULL, /* PyObject *tp_dict; */ - NULL, /* descrgetfunc tp_descr_get; */ - NULL, /* descrsetfunc tp_descr_set; */ - 0, /* long tp_dictoffset; */ - NULL, /* initproc tp_init; */ - NULL, /* allocfunc tp_alloc; */ - Vector_new, /* newfunc tp_new; */ - /* Low-level free-memory routine */ - NULL, /* freefunc tp_free; */ - /* For PyObject_IS_GC */ - NULL, /* inquiry tp_is_gc; */ - NULL, /* PyObject *tp_bases; */ - /* method resolution order */ - NULL, /* PyObject *tp_mro; */ - NULL, /* PyObject *tp_cache; */ - NULL, /* PyObject *tp_subclasses; */ - NULL, /* PyObject *tp_weaklist; */ - NULL -}; - -/*------------------------newVectorObject (internal)------------- - creates a new vector object - pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObject *base_type) -{ - VectorObject *self; - - if(size > 4 || size < 2) { - PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size"); - return NULL; - } - - self= base_type ? (VectorObject *)base_type->tp_alloc(base_type, 0) : - (VectorObject *)PyObject_GC_New(VectorObject, &vector_Type); - - if(self) { - self->size = size; - - /* init callbacks as NULL */ - self->cb_user= NULL; - self->cb_type= self->cb_subtype= 0; - - if(type == Py_WRAP) { - self->vec = vec; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW) { - self->vec= PyMem_Malloc(size * sizeof(float)); - if(vec) { - memcpy(self->vec, vec, size * sizeof(float)); - } - else { /* new empty */ - fill_vn(self->vec, size, 0.0f); - if(size == 4) { /* do the homogenous thing */ - self->vec[3] = 1.0f; - } - } - self->wrapped = Py_NEW; - } - else { - PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid type"); - return NULL; - } - } - return (PyObject *) self; -} - -PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype) -{ - float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */ - VectorObject *self= (VectorObject *)newVectorObject(dummy, size, Py_NEW, NULL); - if(self) { - Py_INCREF(cb_user); - self->cb_user= cb_user; - self->cb_type= (unsigned char)cb_type; - self->cb_subtype= (unsigned char)cb_subtype; - PyObject_GC_Track(self); - } - - return (PyObject *)self; -} diff --git a/source/blender/python/generic/mathutils_Vector.h b/source/blender/python/generic/mathutils_Vector.h deleted file mode 100644 index 0ede836ce44..00000000000 --- a/source/blender/python/generic/mathutils_Vector.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Willian P. Germano & Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -/** \file blender/python/generic/mathutils_Vector.h - * \ingroup pygen - */ - - -#ifndef MATHUTILS_VECTOR_H -#define MATHUTILS_VECTOR_H - -extern PyTypeObject vector_Type; -#define VectorObject_Check(_v) PyObject_TypeCheck((_v), &vector_Type) - -typedef struct { - BASE_MATH_MEMBERS(vec) - - unsigned char size; /* vec size 2,3 or 4 */ -} VectorObject; - -/*prototypes*/ -PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObject *base_type); -PyObject *newVectorObject_cb(PyObject *user, int size, int callback_type, int subtype); - -#endif /* MATHUTILS_VECTOR_H */ diff --git a/source/blender/python/generic/mathutils_geometry.c b/source/blender/python/generic/mathutils_geometry.c deleted file mode 100644 index 53c066d1a85..00000000000 --- a/source/blender/python/generic/mathutils_geometry.c +++ /dev/null @@ -1,946 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Joseph Gilbert, Campbell Barton - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/generic/mathutils_geometry.c - * \ingroup pygen - */ - - -#include <Python.h> - -#include "mathutils_geometry.h" - -/* Used for PolyFill */ -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_boxpack2d.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "BKE_displist.h" - -#include "BKE_curve.h" - -#define SWAP_FLOAT(a, b, tmp) tmp=a; a=b; b=tmp -#define eps 0.000001 - - -/*-------------------------DOC STRINGS ---------------------------*/ -PyDoc_STRVAR(M_Geometry_doc, -"The Blender geometry module" -); - -//---------------------------------INTERSECTION FUNCTIONS-------------------- - -PyDoc_STRVAR(M_Geometry_intersect_ray_tri_doc, -".. function:: intersect_ray_tri(v1, v2, v3, ray, orig, clip=True)\n" -"\n" -" Returns the intersection between a ray and a triangle, if possible, returns None otherwise.\n" -"\n" -" :arg v1: Point1\n" -" :type v1: :class:`mathutils.Vector`\n" -" :arg v2: Point2\n" -" :type v2: :class:`mathutils.Vector`\n" -" :arg v3: Point3\n" -" :type v3: :class:`mathutils.Vector`\n" -" :arg ray: Direction of the projection\n" -" :type ray: :class:`mathutils.Vector`\n" -" :arg orig: Origin\n" -" :type orig: :class:`mathutils.Vector`\n" -" :arg clip: When False, don't restrict the intersection to the area of the triangle, use the infinite plane defined by the triangle.\n" -" :type clip: boolean\n" -" :return: The point of intersection or None if no intersection is found\n" -" :rtype: :class:`mathutils.Vector` or None\n" -); -static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *ray, *ray_off, *vec1, *vec2, *vec3; - float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3]; - float det, inv_det, u, v, t; - int clip= 1; - - if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i:intersect_ray_tri", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) { - return NULL; - } - if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) { - PyErr_SetString(PyExc_ValueError, "only 3D vectors for all parameters"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(ray) == -1 || BaseMath_ReadCallback(ray_off) == -1) - return NULL; - - VECCOPY(v1, vec1->vec); - VECCOPY(v2, vec2->vec); - VECCOPY(v3, vec3->vec); - - VECCOPY(dir, ray->vec); - normalize_v3(dir); - - VECCOPY(orig, ray_off->vec); - - /* find vectors for two edges sharing v1 */ - sub_v3_v3v3(e1, v2, v1); - sub_v3_v3v3(e2, v3, v1); - - /* begin calculating determinant - also used to calculated U parameter */ - cross_v3_v3v3(pvec, dir, e2); - - /* if determinant is near zero, ray lies in plane of triangle */ - det= dot_v3v3(e1, pvec); - - if (det > -0.000001f && det < 0.000001f) { - Py_RETURN_NONE; - } - - inv_det= 1.0f / det; - - /* calculate distance from v1 to ray origin */ - sub_v3_v3v3(tvec, orig, v1); - - /* calculate U parameter and test bounds */ - u= dot_v3v3(tvec, pvec) * inv_det; - if (clip && (u < 0.0f || u > 1.0f)) { - Py_RETURN_NONE; - } - - /* prepare to test the V parameter */ - cross_v3_v3v3(qvec, tvec, e1); - - /* calculate V parameter and test bounds */ - v= dot_v3v3(dir, qvec) * inv_det; - - if (clip && (v < 0.0f || u + v > 1.0f)) { - Py_RETURN_NONE; - } - - /* calculate t, ray intersects triangle */ - t= dot_v3v3(e2, qvec) * inv_det; - - mul_v3_fl(dir, t); - add_v3_v3v3(pvec, orig, dir); - - return newVectorObject(pvec, 3, Py_NEW, NULL); -} - -/* Line-Line intersection using algorithm from mathworld.wolfram.com */ - -PyDoc_STRVAR(M_Geometry_intersect_line_line_doc, -".. function:: intersect_line_line(v1, v2, v3, v4)\n" -"\n" -" Returns a tuple with the points on each line respectively closest to the other.\n" -"\n" -" :arg v1: First point of the first line\n" -" :type v1: :class:`mathutils.Vector`\n" -" :arg v2: Second point of the first line\n" -" :type v2: :class:`mathutils.Vector`\n" -" :arg v3: First point of the second line\n" -" :type v3: :class:`mathutils.Vector`\n" -" :arg v4: Second point of the second line\n" -" :type v4: :class:`mathutils.Vector`\n" -" :rtype: tuple of :class:`mathutils.Vector`'s\n" -); -static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject *args) -{ - PyObject *tuple; - VectorObject *vec1, *vec2, *vec3, *vec4; - float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3]; - - if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) { - return NULL; - } - if(vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) { - PyErr_SetString(PyExc_ValueError,"vectors must be of the same size"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(vec4) == -1) - return NULL; - - if(vec1->size == 3 || vec1->size == 2) { - int result; - - if (vec1->size == 3) { - VECCOPY(v1, vec1->vec); - VECCOPY(v2, vec2->vec); - VECCOPY(v3, vec3->vec); - VECCOPY(v4, vec4->vec); - } - else { - v1[0]= vec1->vec[0]; - v1[1]= vec1->vec[1]; - v1[2]= 0.0f; - - v2[0]= vec2->vec[0]; - v2[1]= vec2->vec[1]; - v2[2]= 0.0f; - - v3[0]= vec3->vec[0]; - v3[1]= vec3->vec[1]; - v3[2]= 0.0f; - - v4[0]= vec4->vec[0]; - v4[1]= vec4->vec[1]; - v4[2]= 0.0f; - } - - result= isect_line_line_v3(v1, v2, v3, v4, i1, i2); - - if (result == 0) { - /* colinear */ - Py_RETURN_NONE; - } - else { - tuple= PyTuple_New(2); - PyTuple_SET_ITEM(tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL)); - PyTuple_SET_ITEM(tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL)); - return tuple; - } - } - else { - PyErr_SetString(PyExc_ValueError, "2D/3D vectors only"); - return NULL; - } -} - - - - -//----------------------------geometry.normal() ------------------- -PyDoc_STRVAR(M_Geometry_normal_doc, -".. function:: normal(v1, v2, v3, v4=None)\n" -"\n" -" Returns the normal of the 3D tri or quad.\n" -"\n" -" :arg v1: Point1\n" -" :type v1: :class:`mathutils.Vector`\n" -" :arg v2: Point2\n" -" :type v2: :class:`mathutils.Vector`\n" -" :arg v3: Point3\n" -" :type v3: :class:`mathutils.Vector`\n" -" :arg v4: Point4 (optional)\n" -" :type v4: :class:`mathutils.Vector`\n" -" :rtype: :class:`mathutils.Vector`\n" -); -static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *vec1, *vec2, *vec3, *vec4; - float n[3]; - - if(PyTuple_GET_SIZE(args) == 3) { - if(!PyArg_ParseTuple(args, "O!O!O!:normal", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) { - return NULL; - } - if(vec1->size != vec2->size || vec1->size != vec3->size) { - PyErr_SetString(PyExc_ValueError, "vectors must be of the same size"); - return NULL; - } - if(vec1->size < 3) { - PyErr_SetString(PyExc_ValueError, "2D vectors unsupported"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1) - return NULL; - - normal_tri_v3(n, vec1->vec, vec2->vec, vec3->vec); - } - else { - if(!PyArg_ParseTuple(args, "O!O!O!O!:normal", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) { - return NULL; - } - if(vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) { - PyErr_SetString(PyExc_ValueError,"vectors must be of the same size"); - return NULL; - } - if(vec1->size < 3) { - PyErr_SetString(PyExc_ValueError, "2D vectors unsupported"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(vec4) == -1) - return NULL; - - normal_quad_v3(n, vec1->vec, vec2->vec, vec3->vec, vec4->vec); - } - - return newVectorObject(n, 3, Py_NEW, NULL); -} - -//--------------------------------- AREA FUNCTIONS-------------------- - -PyDoc_STRVAR(M_Geometry_area_tri_doc, -".. function:: area_tri(v1, v2, v3)\n" -"\n" -" Returns the area size of the 2D or 3D triangle defined.\n" -"\n" -" :arg v1: Point1\n" -" :type v1: :class:`mathutils.Vector`\n" -" :arg v2: Point2\n" -" :type v2: :class:`mathutils.Vector`\n" -" :arg v3: Point3\n" -" :type v3: :class:`mathutils.Vector`\n" -" :rtype: float\n" -); -static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *vec1, *vec2, *vec3; - - if(!PyArg_ParseTuple(args, "O!O!O!:area_tri", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) { - return NULL; - } - - if(vec1->size != vec2->size || vec1->size != vec3->size) { - PyErr_SetString(PyExc_ValueError, "vectors must be of the same size"); - return NULL; - } - - if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1) - return NULL; - - if (vec1->size == 3) { - return PyFloat_FromDouble(area_tri_v3(vec1->vec, vec2->vec, vec3->vec)); - } - else if (vec1->size == 2) { - return PyFloat_FromDouble(area_tri_v2(vec1->vec, vec2->vec, vec3->vec)); - } - else { - PyErr_SetString(PyExc_ValueError, "only 2D,3D vectors are supported"); - return NULL; - } -} - -/*----------------------------------geometry.PolyFill() -------------------*/ -PyDoc_STRVAR(M_Geometry_tesselate_polygon_doc, -".. function:: tesselate_polygon(veclist_list)\n" -"\n" -" Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.\n" -"\n" -" :arg veclist_list: list of polylines\n" -" :rtype: list\n" -); -/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */ -static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *polyLineSeq) -{ - PyObject *tri_list; /*return this list of tri's */ - PyObject *polyLine, *polyVec; - int i, len_polylines, len_polypoints, ls_error= 0; - - /* display listbase */ - ListBase dispbase={NULL, NULL}; - DispList *dl; - float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */ - int index, *dl_face, totpoints=0; - - if(!PySequence_Check(polyLineSeq)) { - PyErr_SetString(PyExc_TypeError, "expected a sequence of poly lines"); - return NULL; - } - - len_polylines= PySequence_Size(polyLineSeq); - - for(i= 0; i < len_polylines; ++i) { - polyLine= PySequence_GetItem(polyLineSeq, i); - if (!PySequence_Check(polyLine)) { - freedisplist(&dispbase); - Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/ - PyErr_SetString(PyExc_TypeError, "One or more of the polylines is not a sequence of mathutils.Vector's"); - return NULL; - } - - len_polypoints= PySequence_Size(polyLine); - if (len_polypoints>0) { /* dont bother adding edges as polylines */ -#if 0 - if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) { - freedisplist(&dispbase); - Py_DECREF(polyLine); - PyErr_SetString(PyExc_TypeError, "A point in one of the polylines is not a mathutils.Vector type"); - return NULL; - } -#endif - dl= MEM_callocN(sizeof(DispList), "poly disp"); - BLI_addtail(&dispbase, dl); - dl->type= DL_INDEX3; - dl->nr= len_polypoints; - dl->type= DL_POLY; - dl->parts= 1; /* no faces, 1 edge loop */ - dl->col= 0; /* no material */ - dl->verts= fp= MEM_callocN(sizeof(float)*3*len_polypoints, "dl verts"); - dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index"); - - for(index= 0; index<len_polypoints; ++index, fp+=3) { - polyVec= PySequence_GetItem(polyLine, index); - if(VectorObject_Check(polyVec)) { - - if(BaseMath_ReadCallback((VectorObject *)polyVec) == -1) - ls_error= 1; - - fp[0]= ((VectorObject *)polyVec)->vec[0]; - fp[1]= ((VectorObject *)polyVec)->vec[1]; - if(((VectorObject *)polyVec)->size > 2) - fp[2]= ((VectorObject *)polyVec)->vec[2]; - else - fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ - } - else { - ls_error= 1; - } - - totpoints++; - Py_DECREF(polyVec); - } - } - Py_DECREF(polyLine); - } - - if(ls_error) { - freedisplist(&dispbase); /* possible some dl was allocated */ - PyErr_SetString(PyExc_TypeError, "A point in one of the polylines is not a mathutils.Vector type"); - return NULL; - } - else if (totpoints) { - /* now make the list to return */ - filldisplist(&dispbase, &dispbase, 0); - - /* The faces are stored in a new DisplayList - thats added to the head of the listbase */ - dl= dispbase.first; - - tri_list= PyList_New(dl->parts); - if(!tri_list) { - freedisplist(&dispbase); - PyErr_SetString(PyExc_RuntimeError, "geometry.PolyFill failed to make a new list"); - return NULL; - } - - index= 0; - dl_face= dl->index; - while(index < dl->parts) { - PyList_SET_ITEM(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2])); - dl_face+= 3; - index++; - } - freedisplist(&dispbase); - } - else { - /* no points, do this so scripts dont barf */ - freedisplist(&dispbase); /* possible some dl was allocated */ - tri_list= PyList_New(0); - } - - return tri_list; -} - -PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc, -".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n" -"\n" -" Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n" -"\n" -" :arg lineA_p1: First point of the first line\n" -" :type lineA_p1: :class:`mathutils.Vector`\n" -" :arg lineA_p2: Second point of the first line\n" -" :type lineA_p2: :class:`mathutils.Vector`\n" -" :arg lineB_p1: First point of the second line\n" -" :type lineB_p1: :class:`mathutils.Vector`\n" -" :arg lineB_p2: Second point of the second line\n" -" :type lineB_p2: :class:`mathutils.Vector`\n" -" :return: The point of intersection or None when not found\n" -" :rtype: :class:`mathutils.Vector` or None\n" -); -static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *line_a1, *line_a2, *line_b1, *line_b2; - float vi[2]; - if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line_2d", - &vector_Type, &line_a1, - &vector_Type, &line_a2, - &vector_Type, &line_b1, - &vector_Type, &line_b2) - ) { - return NULL; - } - - if(BaseMath_ReadCallback(line_a1) == -1 || BaseMath_ReadCallback(line_a2) == -1 || BaseMath_ReadCallback(line_b1) == -1 || BaseMath_ReadCallback(line_b2) == -1) - return NULL; - - if(isect_seg_seg_v2_point(line_a1->vec, line_a2->vec, line_b1->vec, line_b2->vec, vi) == 1) { - return newVectorObject(vi, 2, Py_NEW, NULL); - } - else { - Py_RETURN_NONE; - } -} - - -PyDoc_STRVAR(M_Geometry_intersect_line_plane_doc, -".. function:: intersect_line_plane(line_a, line_b, plane_co, plane_no, no_flip=False)\n" -"\n" -" Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n" -"\n" -" :arg line_a: First point of the first line\n" -" :type line_a: :class:`mathutils.Vector`\n" -" :arg line_b: Second point of the first line\n" -" :type line_b: :class:`mathutils.Vector`\n" -" :arg plane_co: A point on the plane\n" -" :type plane_co: :class:`mathutils.Vector`\n" -" :arg plane_no: The direction the plane is facing\n" -" :type plane_no: :class:`mathutils.Vector`\n" -" :arg no_flip: Always return an intersection on the directon defined bt line_a -> line_b\n" -" :type no_flip: :boolean\n" -" :return: The point of intersection or None when not found\n" -" :rtype: :class:`mathutils.Vector` or None\n" -); -static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *line_a, *line_b, *plane_co, *plane_no; - int no_flip= 0; - float isect[3]; - if(!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_line_2d", - &vector_Type, &line_a, - &vector_Type, &line_b, - &vector_Type, &plane_co, - &vector_Type, &plane_no, - &no_flip) - ) { - return NULL; - } - - if( BaseMath_ReadCallback(line_a) == -1 || - BaseMath_ReadCallback(line_b) == -1 || - BaseMath_ReadCallback(plane_co) == -1 || - BaseMath_ReadCallback(plane_no) == -1 - ) { - return NULL; - } - - if(ELEM4(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) { - PyErr_SetString(PyExc_RuntimeError, "geometry.intersect_line_plane(...) can't use 2D Vectors"); - return NULL; - } - - if(isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec, no_flip) == 1) { - return newVectorObject(isect, 3, Py_NEW, NULL); - } - else { - Py_RETURN_NONE; - } -} - -PyDoc_STRVAR(M_Geometry_intersect_point_line_doc, -".. function:: intersect_point_line(pt, line_p1, line_p2)\n" -"\n" -" Takes a point and a line and returns a tuple with the closest point on the line and its distance from the first point of the line as a percentage of the length of the line.\n" -"\n" -" :arg pt: Point\n" -" :type pt: :class:`mathutils.Vector`\n" -" :arg line_p1: First point of the line\n" -" :type line_p1: :class:`mathutils.Vector`\n" -" :arg line_p1: Second point of the line\n" -" :type line_p1: :class:`mathutils.Vector`\n" -" :rtype: (:class:`mathutils.Vector`, float)\n" -); -static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *pt, *line_1, *line_2; - float pt_in[3], pt_out[3], l1[3], l2[3]; - float lambda; - PyObject *ret; - - if(!PyArg_ParseTuple(args, "O!O!O!:intersect_point_line", - &vector_Type, &pt, - &vector_Type, &line_1, - &vector_Type, &line_2) - ) { - return NULL; - } - - if(BaseMath_ReadCallback(pt) == -1 || BaseMath_ReadCallback(line_1) == -1 || BaseMath_ReadCallback(line_2) == -1) - return NULL; - - /* accept 2d verts */ - if (pt->size==3) { VECCOPY(pt_in, pt->vec);} - else { pt_in[2]=0.0; VECCOPY2D(pt_in, pt->vec) } - - if (line_1->size==3) { VECCOPY(l1, line_1->vec);} - else { l1[2]=0.0; VECCOPY2D(l1, line_1->vec) } - - if (line_2->size==3) { VECCOPY(l2, line_2->vec);} - else { l2[2]=0.0; VECCOPY2D(l2, line_2->vec) } - - /* do the calculation */ - lambda= closest_to_line_v3(pt_out, pt_in, l1, l2); - - ret= PyTuple_New(2); - PyTuple_SET_ITEM(ret, 0, newVectorObject(pt_out, 3, Py_NEW, NULL)); - PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda)); - return ret; -} - -PyDoc_STRVAR(M_Geometry_intersect_point_tri_2d_doc, -".. function:: intersect_point_tri_2d(pt, tri_p1, tri_p2, tri_p3)\n" -"\n" -" Takes 4 vectors (using only the x and y coordinates): one is the point and the next 3 define the triangle. Returns 1 if the point is within the triangle, otherwise 0.\n" -"\n" -" :arg pt: Point\n" -" :type v1: :class:`mathutils.Vector`\n" -" :arg tri_p1: First point of the triangle\n" -" :type tri_p1: :class:`mathutils.Vector`\n" -" :arg tri_p2: Second point of the triangle\n" -" :type tri_p2: :class:`mathutils.Vector`\n" -" :arg tri_p3: Third point of the triangle\n" -" :type tri_p3: :class:`mathutils.Vector`\n" -" :rtype: int\n" -); -static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3; - - if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_point_tri_2d", - &vector_Type, &pt_vec, - &vector_Type, &tri_p1, - &vector_Type, &tri_p2, - &vector_Type, &tri_p3) - ) { - return NULL; - } - - if(BaseMath_ReadCallback(pt_vec) == -1 || BaseMath_ReadCallback(tri_p1) == -1 || BaseMath_ReadCallback(tri_p2) == -1 || BaseMath_ReadCallback(tri_p3) == -1) - return NULL; - - return PyLong_FromLong(isect_point_tri_v2(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec)); -} - -PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc, -".. function:: intersect_point_quad_2d(pt, quad_p1, quad_p2, quad_p3, quad_p4)\n" -"\n" -" Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n" -"\n" -" :arg pt: Point\n" -" :type v1: :class:`mathutils.Vector`\n" -" :arg quad_p1: First point of the quad\n" -" :type quad_p1: :class:`mathutils.Vector`\n" -" :arg quad_p2: Second point of the quad\n" -" :type quad_p2: :class:`mathutils.Vector`\n" -" :arg quad_p3: Third point of the quad\n" -" :type quad_p3: :class:`mathutils.Vector`\n" -" :arg quad_p4: Forth point of the quad\n" -" :type quad_p4: :class:`mathutils.Vector`\n" -" :rtype: int\n" -); -static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *pt_vec, *quad_p1, *quad_p2, *quad_p3, *quad_p4; - - if(!PyArg_ParseTuple(args, "O!O!O!O!O!:intersect_point_quad_2d", - &vector_Type, &pt_vec, - &vector_Type, &quad_p1, - &vector_Type, &quad_p2, - &vector_Type, &quad_p3, - &vector_Type, &quad_p4) - ) { - return NULL; - } - - if(BaseMath_ReadCallback(pt_vec) == -1 || BaseMath_ReadCallback(quad_p1) == -1 || BaseMath_ReadCallback(quad_p2) == -1 || BaseMath_ReadCallback(quad_p3) == -1 || BaseMath_ReadCallback(quad_p4) == -1) - return NULL; - - return PyLong_FromLong(isect_point_quad_v2(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec)); -} - -static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray) -{ - int len, i; - PyObject *list_item, *item_1, *item_2; - boxPack *box; - - - /* Error checking must already be done */ - if(!PyList_Check(value)) { - PyErr_SetString(PyExc_TypeError, "can only back a list of [x, y, w, h]"); - return -1; - } - - len= PyList_Size(value); - - (*boxarray)= MEM_mallocN(len*sizeof(boxPack), "boxPack box"); - - - for(i= 0; i < len; i++) { - list_item= PyList_GET_ITEM(value, i); - if(!PyList_Check(list_item) || PyList_Size(list_item) < 4) { - MEM_freeN(*boxarray); - PyErr_SetString(PyExc_TypeError, "can only pack a list of [x, y, w, h]"); - return -1; - } - - box= (*boxarray)+i; - - item_1= PyList_GET_ITEM(list_item, 2); - item_2= PyList_GET_ITEM(list_item, 3); - - box->w= (float)PyFloat_AsDouble(item_1); - box->h= (float)PyFloat_AsDouble(item_2); - box->index= i; - - if (box->w < 0.0f || box->h < 0.0f) { - MEM_freeN(*boxarray); - PyErr_SetString(PyExc_TypeError, "error parsing width and height values from list: [x, y, w, h], not numbers or below zero"); - return -1; - } - - /* verts will be added later */ - } - return 0; -} - -static void boxPack_ToPyObject(PyObject *value, boxPack **boxarray) -{ - int len, i; - PyObject *list_item; - boxPack *box; - - len= PyList_Size(value); - - for(i= 0; i < len; i++) { - box= (*boxarray)+i; - list_item= PyList_GET_ITEM(value, box->index); - PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x)); - PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y)); - } - MEM_freeN(*boxarray); -} - -PyDoc_STRVAR(M_Geometry_box_pack_2d_doc, -".. function:: box_pack_2d(boxes)\n" -"\n" -" Returns the normal of the 3D tri or quad.\n" -"\n" -" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n" -" :type boxes: list\n" -" :return: the width and height of the packed bounding box\n" -" :rtype: tuple, pair of floats\n" -); -static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist) -{ - float tot_width= 0.0f, tot_height= 0.0f; - int len; - - PyObject *ret; - - if(!PyList_Check(boxlist)) { - PyErr_SetString(PyExc_TypeError, "expected a list of boxes [[x, y, w, h], ... ]"); - return NULL; - } - - len= PyList_GET_SIZE(boxlist); - if (len) { - boxPack *boxarray= NULL; - if(boxPack_FromPyObject(boxlist, &boxarray) == -1) { - return NULL; /* exception set */ - } - - /* Non Python function */ - boxPack2D(boxarray, len, &tot_width, &tot_height); - - boxPack_ToPyObject(boxlist, &boxarray); - } - - ret= PyTuple_New(2); - PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width)); - PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width)); - return ret; -} - -PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc, -".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n" -"\n" -" Interpolate a bezier spline segment.\n" -"\n" -" :arg knot1: First bezier spline point.\n" -" :type knot1: :class:`mathutils.Vector`\n" -" :arg handle1: First bezier spline handle.\n" -" :type handle1: :class:`mathutils.Vector`\n" -" :arg handle2: Second bezier spline handle.\n" -" :type handle2: :class:`mathutils.Vector`\n" -" :arg knot2: Second bezier spline point.\n" -" :type knot2: :class:`mathutils.Vector`\n" -" :arg resolution: Number of points to return.\n" -" :type resolution: int\n" -" :return: The interpolated points\n" -" :rtype: list of :class:`mathutils.Vector`'s\n" -); -static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args) -{ - VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2; - int resolu; - int dims; - int i; - float *coord_array, *fp; - PyObject *list; - - float k1[4]= {0.0, 0.0, 0.0, 0.0}; - float h1[4]= {0.0, 0.0, 0.0, 0.0}; - float k2[4]= {0.0, 0.0, 0.0, 0.0}; - float h2[4]= {0.0, 0.0, 0.0, 0.0}; - - - if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier", - &vector_Type, &vec_k1, - &vector_Type, &vec_h1, - &vector_Type, &vec_h2, - &vector_Type, &vec_k2, &resolu) - ) { - return NULL; - } - - if(resolu <= 1) { - PyErr_SetString(PyExc_ValueError, "resolution must be 2 or over"); - return NULL; - } - - if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1) - return NULL; - - dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); - - for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; - for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i]; - for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i]; - for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i]; - - coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier"); - for(i=0; i<dims; i++) { - forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims); - } - - list= PyList_New(resolu); - fp= coord_array; - for(i=0; i<resolu; i++, fp= fp+dims) { - PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL)); - } - MEM_freeN(coord_array); - return list; -} - -PyDoc_STRVAR(M_Geometry_barycentric_transform_doc, -".. function:: barycentric_transform(point, tri_a1, tri_a2, tri_a3, tri_b1, tri_b2, tri_b3)\n" -"\n" -" Return a transformed point, the transformation is defined by 2 triangles.\n" -"\n" -" :arg point: The point to transform.\n" -" :type point: :class:`mathutils.Vector`\n" -" :arg tri_a1: source triangle vertex.\n" -" :type tri_a1: :class:`mathutils.Vector`\n" -" :arg tri_a2: source triangle vertex.\n" -" :type tri_a2: :class:`mathutils.Vector`\n" -" :arg tri_a3: source triangle vertex.\n" -" :type tri_a3: :class:`mathutils.Vector`\n" -" :arg tri_a1: target triangle vertex.\n" -" :type tri_a1: :class:`mathutils.Vector`\n" -" :arg tri_a2: target triangle vertex.\n" -" :type tri_a2: :class:`mathutils.Vector`\n" -" :arg tri_a3: target triangle vertex.\n" -" :type tri_a3: :class:`mathutils.Vector`\n" -" :return: The transformed point\n" -" :rtype: :class:`mathutils.Vector`'s\n" -); -static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args) -{ - VectorObject *vec_pt; - VectorObject *vec_t1_tar, *vec_t2_tar, *vec_t3_tar; - VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src; - float vec[3]; - - if(!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!:barycentric_transform", - &vector_Type, &vec_pt, - &vector_Type, &vec_t1_src, - &vector_Type, &vec_t2_src, - &vector_Type, &vec_t3_src, - &vector_Type, &vec_t1_tar, - &vector_Type, &vec_t2_tar, - &vector_Type, &vec_t3_tar) - ) { - return NULL; - } - - if( vec_pt->size != 3 || - vec_t1_src->size != 3 || - vec_t2_src->size != 3 || - vec_t3_src->size != 3 || - vec_t1_tar->size != 3 || - vec_t2_tar->size != 3 || - vec_t3_tar->size != 3) - { - PyErr_SetString(PyExc_ValueError, "One of more of the vector arguments wasnt a 3D vector"); - return NULL; - } - - barycentric_transform(vec, vec_pt->vec, - vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec, - vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec); - - return newVectorObject(vec, 3, Py_NEW, NULL); -} - -static PyMethodDef M_Geometry_methods[]= { - {"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc}, - {"intersect_point_line", (PyCFunction) M_Geometry_intersect_point_line, METH_VARARGS, M_Geometry_intersect_point_line_doc}, - {"intersect_point_tri_2d", (PyCFunction) M_Geometry_intersect_point_tri_2d, METH_VARARGS, M_Geometry_intersect_point_tri_2d_doc}, - {"intersect_point_quad_2d", (PyCFunction) M_Geometry_intersect_point_quad_2d, METH_VARARGS, M_Geometry_intersect_point_quad_2d_doc}, - {"intersect_line_line", (PyCFunction) M_Geometry_intersect_line_line, METH_VARARGS, M_Geometry_intersect_line_line_doc}, - {"intersect_line_line_2d", (PyCFunction) M_Geometry_intersect_line_line_2d, METH_VARARGS, M_Geometry_intersect_line_line_2d_doc}, - {"intersect_line_plane", (PyCFunction) M_Geometry_intersect_line_plane, METH_VARARGS, M_Geometry_intersect_line_plane_doc}, - {"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc}, - {"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc}, - {"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc}, - {"tesselate_polygon", (PyCFunction) M_Geometry_tesselate_polygon, METH_O, M_Geometry_tesselate_polygon_doc}, - {"box_pack_2d", (PyCFunction) M_Geometry_box_pack_2d, METH_O, M_Geometry_box_pack_2d_doc}, - {"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc}, - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef M_Geometry_module_def= { - PyModuleDef_HEAD_INIT, - "mathutils.geometry", /* m_name */ - M_Geometry_doc, /* m_doc */ - 0, /* m_size */ - M_Geometry_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; - -/*----------------------------MODULE INIT-------------------------*/ -PyMODINIT_FUNC BPyInit_mathutils_geometry(void) -{ - PyObject *submodule= PyModule_Create(&M_Geometry_module_def); - return submodule; -} diff --git a/source/blender/python/generic/mathutils_geometry.h b/source/blender/python/generic/mathutils_geometry.h deleted file mode 100644 index 929b8cc8d75..00000000000 --- a/source/blender/python/generic/mathutils_geometry.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** -*/ - -/** \file blender/python/generic/mathutils_geometry.h - * \ingroup pygen - */ - -/*Include this file for access to vector, quat, matrix, euler, etc...*/ - -#ifndef MATHUTILS_GEOMETRY_H -#define MATHUTILS_GEOMETRY_H - -#include "mathutils.h" - -PyMODINIT_FUNC BPyInit_mathutils_geometry(void); - -#endif /* MATHUTILS_GEOMETRY_H */ diff --git a/source/blender/python/generic/noise_py_api.c b/source/blender/python/generic/noise_py_api.c index f5761f713a6..7be0998c0a1 100644 --- a/source/blender/python/generic/noise_py_api.c +++ b/source/blender/python/generic/noise_py_api.c @@ -210,8 +210,8 @@ static void randuvec(float v[3]) if((r = 1.f - v[2] * v[2]) > 0.f) { float a = (float)(6.283185307f * frand()); r = (float)sqrt(r); - v[0] = (float)(r * cos(a)); - v[1] = (float)(r * sin(a)); + v[0] = (float)(r * cosf(a)); + v[1] = (float)(r * sinf(a)); } else { v[2] = 1.f; @@ -254,7 +254,7 @@ static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args) if(!PyArg_ParseTuple(args, "(fff)|i:noise", &x, &y, &z, &nb)) return NULL; - return PyFloat_FromDouble((2.0 * BLI_gNoise(1.0, x, y, z, 0, nb) - 1.0)); + return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, x, y, z, 0, nb) - 1.0f)); } /*-------------------------------------------------------------------------*/ @@ -264,11 +264,11 @@ static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args) static void noise_vector(float x, float y, float z, int nb, float v[3]) { /* Simply evaluate noise at 3 different positions */ - v[0] = (float)(2.0 * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, - nb) - 1.0); - v[1] = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0); - v[2] = (float)(2.0 * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, - nb) - 1.0); + v[0]= (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, + nb) - 1.0f); + v[1]= (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); + v[2]= (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, + nb) - 1.0f); } static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args) @@ -291,7 +291,7 @@ static float turb(float x, float y, float z, int oct, int hard, int nb, float amp, out, t; int i; amp = 1.f; - out = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0); + out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); if(hard) out = (float)fabs(out); for(i = 1; i < oct; i++) { @@ -299,7 +299,7 @@ static float turb(float x, float y, float z, int oct, int hard, int nb, x *= freqscale; y *= freqscale; z *= freqscale; - t = (float)(amp * (2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0)); + t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f)); if(hard) t = (float)fabs(t); out += t; diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index ec774f44075..b7e67ec5a93 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -36,7 +36,75 @@ #include "BLI_path_util.h" #endif -#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL) +/* array utility function */ +int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix) +{ + PyObject *value_fast; + int value_len; + int i; + + if(!(value_fast=PySequence_Fast(value, error_prefix))) { + return -1; + } + + value_len= PySequence_Fast_GET_SIZE(value_fast); + + if(value_len != length) { + Py_DECREF(value); + PyErr_Format(PyExc_TypeError, + "%.200s: invalid sequence length. expected %d, got %d", + error_prefix, length, value_len); + return -1; + } + + /* for each type */ + if(type == &PyFloat_Type) { + if(is_double) { + double *array_double= array; + for(i=0; i<length; i++) { + array_double[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i)); + } + } + else { + float *array_float= array; + for(i=0; i<length; i++) { + array_float[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i)); + } + } + } + else if(type == &PyLong_Type) { + /* could use is_double for 'long int' but no use now */ + int *array_int= array; + for(i=0; i<length; i++) { + array_int[i]= PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)); + } + } + else if(type == &PyBool_Type) { + int *array_bool= array; + for(i=0; i<length; i++) { + array_bool[i]= (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0); + } + } + else { + Py_DECREF(value_fast); + PyErr_Format(PyExc_TypeError, + "%s: internal error %s is invalid", + error_prefix, type->tp_name); + return -1; + } + + Py_DECREF(value_fast); + + if(PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%s: one or more items could not be used as a %s", + error_prefix, type->tp_name); + return -1; + } + + return 0; +} + /* for debugging */ void PyC_ObSpit(const char *name, PyObject *var) { @@ -140,77 +208,34 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) return item; } -/* returns the exception string as a new PyUnicode object, depends on external StringIO module */ +/* returns the exception string as a new PyUnicode object, depends on external traceback module */ PyObject *PyC_ExceptionBuffer(void) { - PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */ - PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */ - PyObject *string_io = NULL; - PyObject *string_io_buf = NULL; - PyObject *string_io_mod= NULL; - PyObject *string_io_getvalue= NULL; - - PyObject *error_type, *error_value, *error_traceback; - - if (!PyErr_Occurred()) - return NULL; - - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - PyErr_Clear(); - - /* import io - * string_io = io.StringIO() - */ - - if(! (string_io_mod= PyImport_ImportModule("io")) ) { + PyObject *traceback_mod= NULL; + PyObject *format_tb_func= NULL; + PyObject *ret= NULL; + + if(! (traceback_mod= PyImport_ImportModule("traceback")) ) { goto error_cleanup; } - else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) { + else if (! (format_tb_func= PyObject_GetAttrString(traceback_mod, "format_exc"))) { goto error_cleanup; } - else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) { - goto error_cleanup; + + ret= PyObject_CallObject(format_tb_func, NULL); + + if(ret == Py_None) { + Py_DECREF(ret); + ret= NULL; } - - Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced. - Py_INCREF(stderr_backup); - - PySys_SetObject("stdout", string_io); // both of these are free'd when restoring - PySys_SetObject("stderr", string_io); - - PyErr_Restore(error_type, error_value, error_traceback); - PyErr_Print(); /* print the error */ - PyErr_Clear(); - - string_io_buf = PyObject_CallObject(string_io_getvalue, NULL); - - PySys_SetObject("stdout", stdout_backup); - PySys_SetObject("stderr", stderr_backup); - - Py_DECREF(stdout_backup); /* now sys owns the ref again */ - Py_DECREF(stderr_backup); - - Py_DECREF(string_io_mod); - Py_DECREF(string_io_getvalue); - Py_DECREF(string_io); /* free the original reference */ - - PyErr_Clear(); - return string_io_buf; - - + error_cleanup: /* could not import the module so print the error and close */ - Py_XDECREF(string_io_mod); - Py_XDECREF(string_io); - - PyErr_Restore(error_type, error_value, error_traceback); - PyErr_Print(); /* print the error */ - PyErr_Clear(); - - return NULL; -} + Py_XDECREF(traceback_mod); + Py_XDECREF(format_tb_func); + return ret; +} /* string conversion, escape non-unicode chars, coerce must be set to NULL */ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 1730ad71721..96c93ab71f8 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -35,7 +35,7 @@ void PyC_LineSpit(void); PyObject * PyC_ExceptionBuffer(void); PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...); void PyC_FileAndNum(const char **filename, int *lineno); -int PyC_AsArray(void *array, PyObject *value, int length, PyTypeObject *type, const char *error_prefix); +int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix); /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); @@ -50,4 +50,6 @@ void PyC_MainModule_Restore(PyObject *main_mod); void PyC_SetHomePath(const char *py_path_bundle); +#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL) + #endif // PY_CAPI_UTILS_H |