diff --git a/source/blender/python/doc/examples/mathutils_vector.py b/source/blender/python/doc/examples/mathutils_vector.py index ef566a878e7..8b3dbfa5ee8 100644 --- a/source/blender/python/doc/examples/mathutils_vector.py +++ b/source/blender/python/doc/examples/mathutils_vector.py @@ -50,6 +50,6 @@ vec2d[:] = vec3d[:2] # Vectors support 'swizzle' operations # See http://en.wikipedia.org/wiki/Swizzling_(computer_graphics) vec.xyz = vec.zyx -vec.xy = vec.zw -vec.xxy = vec.wzz -vec.yzyz = vec.yxyx +vec.xy = vec4d.zw +vec.xyz = vec4d.wzz +vec4d.wxyz = vec.yxyx diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index a8452773012..d0b103ae15c 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -793,8 +793,7 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end) list = PyList_New(end - begin); for(count = begin; count < end; count++) { - PyList_SetItem(list, count - begin, - PyFloat_FromDouble(self->vec[count])); + PyList_SET_ITEM(list, count - begin, PyFloat_FromDouble(self->vec[count])); } return list; @@ -1510,6 +1509,11 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) while (swizzleClosure & SWIZZLE_VALID_AXIS) { axisB = swizzleClosure & SWIZZLE_AXIS; + if(axisB >= self->size) { + PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis."); + return NULL; + } + vec[axisA] = self->vec[axisB]; swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; axisA++; @@ -1567,11 +1571,23 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < vecVal->size) { axisA = swizzleClosure & SWIZZLE_AXIS; + + if(axisB >= vecVal->size) { + PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis."); + return -1; + } + vecTemp[axisA] = vecVal->vec[axisB]; swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; axisB++; } + + if(axisB != vecVal->size) { + PyErr_SetString(PyExc_AttributeError, "Error: vector size does not match swizzle.\n"); + return -1; + } + memcpy(self->vec, vecTemp, axisB * sizeof(float)); /* continue with BaseMathObject_WriteCallback at the end */ } @@ -1585,9 +1601,9 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur { item = PyList_GetItem(value, axisB); scalarVal = (float)PyFloat_AsDouble(item); - + if (scalarVal==-1.0 && PyErr_Occurred()) { - PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n"); + PyErr_SetString(PyExc_AttributeError, "Error: list item could not be used as a float.\n"); return -1; } @@ -1598,6 +1614,12 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; axisB++; } + + if(axisB != listLen) { + PyErr_SetString(PyExc_AttributeError, "Error: list size does not match swizzle.\n"); + return -1; + } + memcpy(self->vec, vecTemp, axisB * sizeof(float)); /* continue with BaseMathObject_WriteCallback at the end */ } @@ -1619,7 +1641,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur return -1; } - if(!BaseMath_WriteCallback(vecVal)) + if(!BaseMath_WriteCallback(self)) return -1; else return 0; @@ -1639,342 +1661,342 @@ static PyGetSetDef Vector_getseters[] = { {"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL}, /* autogenerated swizzle attrs, see python script below */ - {"xx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, NULL, SET_INT_IN_POINTER(((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<tp_alloc(base_type, 0); - else self = PyObject_NEW(VectorObject, &vector_Type); - if(size > 4 || size < 2) return NULL; + + if(base_type) self = (VectorObject *)base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(VectorObject, &vector_Type); + self->size = size; /* init callbacks as NULL */