diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-04-25 23:27:59 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-04-25 23:27:59 +0400 |
commit | 873d4a3f05872bd32f40449a61de5f14e10a2f3d (patch) | |
tree | f1ed0b3786421d94bea7df636bdf1f11c5306950 /source/blender | |
parent | 4f6e3dad47946490facbb8121a35d7ac727d2416 (diff) |
py api
- mathutils.Color.hsv attribute. eg. material.diffuse_color.hsv = 0.2, 0.8, 0.4
- Vector/Euler/Quaternion/Color now only take a single seq arg.
- internal function for parsing arrays. (cleanup messy internal list/vector/tuple/seq parsing)
- didnt update rigify yet.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/python/generic/mathutils.c | 37 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils.h | 3 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_color.c | 91 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_euler.c | 54 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_quat.c | 99 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_vector.c | 180 |
6 files changed, 175 insertions, 289 deletions
diff --git a/source/blender/python/generic/mathutils.c b/source/blender/python/generic/mathutils.c index e1e1cd2ae69..a9a682bf998 100644 --- a/source/blender/python/generic/mathutils.c +++ b/source/blender/python/generic/mathutils.c @@ -29,6 +29,7 @@ /* Note: Changes to Mathutils since 2.4x * use radians rather then degrees + * - Mathutils.Vector/Euler/Quaternion(), now only take single sequence arguments. * - Mathutils.MidpointVecs --> vector.lerp(other, fac) * - Mathutils.AngleBetweenVecs --> vector.angle(other) * - Mathutils.ProjectVecs --> vector.project(other) @@ -55,6 +56,42 @@ static char M_Mathutils_doc[] = "This module provides access to matrices, eulers, quaternions and vectors."; +/* 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) +{ + PyObject *value_fast= NULL; + + 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(PySequence_Fast_GET_ITEM(value_fast, i))) == -1.0) && PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, "%.200s: sequence index %d is not a float", error_prefix, i); + Py_DECREF(value_fast); + return -1; + } + } while(i); + + Py_XDECREF(value_fast); + return size; +} + //-----------------------------METHODS---------------------------- //-----------------quat_rotation (internal)----------- //This function multiplies a vector/point * quat or vice versa diff --git a/source/blender/python/generic/mathutils.h b/source/blender/python/generic/mathutils.h index f5bbcfcf666..eb6ddf3492e 100644 --- a/source/blender/python/generic/mathutils.h +++ b/source/blender/python/generic/mathutils.h @@ -115,4 +115,7 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index); #define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1)) #define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1)) +/* utility func */ +int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix); + #endif /* EXPP_Mathutils_H */ diff --git a/source/blender/python/generic/mathutils_color.c b/source/blender/python/generic/mathutils_color.c index 5b401eb0669..9d770c0e6fd 100644 --- a/source/blender/python/generic/mathutils_color.c +++ b/source/blender/python/generic/mathutils_color.c @@ -31,50 +31,20 @@ //makes a new color for you to play with static PyObject *Color_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) { - PyObject *listObject = NULL; - int size, i; - float col[3]; - PyObject *e; - + float col[3]= {0.0f, 0.0f, 0.0f}; - size = PyTuple_GET_SIZE(args); - if (size == 1) { - listObject = PyTuple_GET_ITEM(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - } else { // Single argument was not a sequence - PyErr_SetString(PyExc_TypeError, "mathutils.Color(): 3d numeric sequence expected\n"); + switch(PyTuple_GET_SIZE(args)) { + case 0: + break; + case 1: + if((mathutils_array_parse(col, 3, 3, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1) return NULL; - } - } else if (size == 0) { - //returns a new empty 3d color - return newColorObject(NULL, Py_NEW, NULL); - } else { - listObject = args; - } - - if (size != 3) { // Invalid color size - PyErr_SetString(PyExc_AttributeError, "mathutils.Color(): 3d numeric sequence expected\n"); + break; + default: + PyErr_SetString(PyExc_TypeError, "mathutils.Color(): more then a single arg given"); return NULL; } - - for (i=0; i<size; i++) { - e = PySequence_GetItem(listObject, i); - if (e == NULL) { // Failed to read sequence - Py_DECREF(listObject); - PyErr_SetString(PyExc_RuntimeError, "mathutils.Color(): 3d numeric sequence expected\n"); - return NULL; - } - - col[i]= (float)PyFloat_AsDouble(e); - Py_DECREF(e); - - if(col[i]==-1 && PyErr_Occurred()) { // parsed item is not a number - PyErr_SetString(PyExc_TypeError, "mathutils.Color(): 3d numeric sequence expected\n"); - return NULL; - } - } - return newColorObject(col, Py_NEW, NULL); + return newColorObject(col, Py_NEW, type); } //-----------------------------METHODS---------------------------- @@ -131,7 +101,7 @@ static PyObject *Color_repr(ColorObject * self) tuple= Color_ToTupleExt(self, -1); - ret= PyUnicode_FromFormat("Color%R", tuple); + ret= PyUnicode_FromFormat("Color(%R)", tuple); Py_DECREF(tuple); return ret; @@ -363,6 +333,43 @@ static int Color_setChannelHSV(ColorObject * self, PyObject * value, void * type return 0; } +/* color channel (HSV), color.h/s/v */ +static PyObject *Color_getHSV(ColorObject * self, void *type) +{ + float hsv[3]; + PyObject *ret; + + if(!BaseMath_ReadCallback(self)) + 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 * type) +{ + 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)) + return -1; + + return 0; +} + /*****************************************************************************/ /* Python attributes get/set structure: */ /*****************************************************************************/ @@ -375,6 +382,8 @@ static PyGetSetDef Color_getseters[] = { {"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Saturation component in [0, 1]. **type** float", (void *)1}, {"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Value component in [0, 1]. **type** float", (void *)2}, + {"hsv", (getter)Color_getHSV, (setter)Color_setHSV, "HSV Values in [0, 1]. **type** float triplet", (void *)0}, + {"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL}, {"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ diff --git a/source/blender/python/generic/mathutils_euler.c b/source/blender/python/generic/mathutils_euler.c index 5ff932d93d1..2c8dbf41997 100644 --- a/source/blender/python/generic/mathutils_euler.c +++ b/source/blender/python/generic/mathutils_euler.c @@ -39,48 +39,26 @@ //makes a new euler for you to play with static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) { - PyObject *listObject = NULL; - int size, i; - float eul[3]; - PyObject *e; - short order= 0; // TODO, add order option - - size = PyTuple_GET_SIZE(args); - if (size == 1) { - listObject = PyTuple_GET_ITEM(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - } else { // Single argument was not a sequence - PyErr_SetString(PyExc_TypeError, "mathutils.Euler(): 3d numeric sequence expected\n"); - return NULL; - } - } else if (size == 0) { - //returns a new empty 3d euler - return newEulerObject(NULL, order, Py_NEW, NULL); - } else { - listObject = args; - } + PyObject *seq= NULL; + char *order_str= NULL; + + float eul[3]= {0.0f, 0.0f, 0.0f}; + short order= 0; - if (size != 3) { // Invalid euler size - PyErr_SetString(PyExc_AttributeError, "mathutils.Euler(): 3d numeric sequence expected\n"); + if(!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str)) return NULL; - } - for (i=0; i<size; i++) { - e = PySequence_GetItem(listObject, i); - if (e == NULL) { // Failed to read sequence - Py_DECREF(listObject); - PyErr_SetString(PyExc_RuntimeError, "mathutils.Euler(): 3d numeric sequence expected\n"); + switch(PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if((order=euler_order_from_string(order_str, "mathutils.Euler()")) == -1) return NULL; - } - - eul[i]= (float)PyFloat_AsDouble(e); - Py_DECREF(e); - - if(eul[i]==-1 && PyErr_Occurred()) { // parsed item is not a number - PyErr_SetString(PyExc_TypeError, "mathutils.Euler(): 3d numeric sequence expected\n"); + /* intentionally pass through */ + case 1: + if (mathutils_array_parse(eul, 3, 3, seq, "mathutils.Euler()") == -1) return NULL; - } + break; } return newEulerObject(eul, order, Py_NEW, NULL); } @@ -353,7 +331,7 @@ static PyObject *Euler_repr(EulerObject * self) tuple= Euler_ToTupleExt(self, -1); - ret= PyUnicode_FromFormat("Euler%R", tuple); + ret= PyUnicode_FromFormat("Euler(%R)", tuple); Py_DECREF(tuple); return ret; diff --git a/source/blender/python/generic/mathutils_quat.c b/source/blender/python/generic/mathutils_quat.c index 322dcf31092..b9754f674c4 100644 --- a/source/blender/python/generic/mathutils_quat.c +++ b/source/blender/python/generic/mathutils_quat.c @@ -381,7 +381,7 @@ static PyObject *Quaternion_repr(QuaternionObject * self) tuple= Quaternion_ToTupleExt(self, -1); - ret= PyUnicode_FromFormat("Quaternion%R", tuple); + ret= PyUnicode_FromFormat("Quaternion(%R)", tuple); Py_DECREF(tuple); return ret; @@ -743,94 +743,27 @@ static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type ) //----------------------------------mathutils.Quaternion() -------------- static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *listObject = NULL, *n, *q; - int size, i; - float quat[4]; + PyObject *seq= NULL; double angle = 0.0f; + float quat[4]= {0.0f, 0.0f, 0.0f, 0.0f}; - size = PyTuple_GET_SIZE(args); - if (size == 1 || size == 2) { //seq? - listObject = PyTuple_GET_ITEM(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - if ((size == 4 && PySequence_Length(args) !=1) || - (size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) { - // invalid args/size - PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - if(size == 3){ //get angle in axis/angle - n = PySequence_GetItem(args, 1); - if(n == NULL) { // parsed item not a number or getItem fail - PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - - angle = PyFloat_AsDouble(n); - Py_DECREF(n); - - if (angle==-1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } - }else{ - listObject = PyTuple_GET_ITEM(args, 1); - if (size>1 && PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - if (size != 3) { - // invalid args/size - PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - angle = PyFloat_AsDouble(PyTuple_GET_ITEM(args, 0)); - - if (angle==-1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } else { // argument was not a sequence - PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } - } else if (size == 0) { //returns a new empty quat - return newQuaternionObject(NULL, Py_NEW, NULL); - } else { - listObject = args; - } - - if (size == 3) { // invalid quat size - if(PySequence_Length(args) != 2){ - PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - }else{ - if(size != 4){ - PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } + if(!PyArg_ParseTuple(args, "|Of:mathutils.Quaternion", &seq, &angle)) + return NULL; - for (i=0; i<size; i++) { //parse - q = PySequence_GetItem(listObject, i); - if (q == NULL) { // Failed to read sequence - PyErr_SetString(PyExc_RuntimeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + switch(PyTuple_GET_SIZE(args)) { + case 0: + break; + case 1: + if (mathutils_array_parse(quat, 4, 4, seq, "mathutils.Quaternion()") == -1) return NULL; - } - - quat[i] = PyFloat_AsDouble(q); - Py_DECREF(q); - - if (quat[i]==-1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + break; + case 2: + if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1) return NULL; - } - } - - if(size == 3) //calculate the quat based on axis/angle axis_angle_to_quat(quat, quat, angle); - + break; + /* PyArg_ParseTuple assures no more then 2 */ + } return newQuaternionObject(quat, Py_NEW, NULL); } diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c index b825f3187cd..c9e151167de 100644 --- a/source/blender/python/generic/mathutils_vector.c +++ b/source/blender/python/generic/mathutils_vector.c @@ -47,48 +47,20 @@ static PyObject *Vector_ToTupleExt(VectorObject *self, int ndigits); // accepted. Mixed float and int values accepted. Ints are parsed to float static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *listObject = NULL; - int size, i; - float vec[4], f; - PyObject *v; - - size = PyTuple_GET_SIZE(args); /* we know its a tuple because its an arg */ - if (size == 1) { - listObject = PyTuple_GET_ITEM(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - } else { // Single argument was not a sequence - PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + 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; - } - } else if (size == 0) { - //returns a new empty 3d vector - return newVectorObject(NULL, 3, Py_NEW, type); - } else { - listObject = args; - } - - if (size<2 || size>4) { // Invalid vector size - PyErr_SetString(PyExc_AttributeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + break; + default: + PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): more then a single arg given"); return NULL; } - - for (i=0; i<size; i++) { - v=PySequence_GetItem(listObject, i); - if (v==NULL) { // Failed to read sequence - PyErr_SetString(PyExc_RuntimeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); - return NULL; - } - - if((f=PyFloat_AsDouble(v)) == -1 && PyErr_Occurred()) { // parsed item not a number - Py_DECREF(v); - PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); - return NULL; - } - - vec[i]= f; - Py_DECREF(v); - } return newVectorObject(vec, size, Py_NEW, type); } @@ -726,7 +698,7 @@ static PyObject *Vector_repr(VectorObject *self) return NULL; tuple= Vector_ToTupleExt(self, -1); - ret= PyUnicode_FromFormat("Vector%R", tuple); + ret= PyUnicode_FromFormat("Vector(%R)", tuple); Py_DECREF(tuple); return ret; } @@ -1488,8 +1460,8 @@ static int Vector_setLength(VectorObject *self, PyObject * value ) in Vector_createSwizzleGetSeter. */ static PyObject *Vector_getSwizzle(VectorObject *self, void *closure) { - size_t axisA; - size_t axisB; + size_t axis_to; + size_t axis_from; float vec[MAX_DIMENSIONS]; unsigned int swizzleClosure; @@ -1497,22 +1469,22 @@ static PyObject *Vector_getSwizzle(VectorObject *self, void *closure) return NULL; /* Unpack the axes from the closure into an array. */ - axisA = 0; + axis_to = 0; swizzleClosure = GET_INT_FROM_POINTER(closure); while (swizzleClosure & SWIZZLE_VALID_AXIS) { - axisB = swizzleClosure & SWIZZLE_AXIS; - if(axisB >= self->size) { + axis_from = swizzleClosure & SWIZZLE_AXIS; + if(axis_from >= self->size) { PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis."); return NULL; } - vec[axisA] = self->vec[axisB]; + vec[axis_to] = self->vec[axis_from]; swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; - axisA++; + axis_to++; } - return newVectorObject(vec, axisA, Py_NEW, Py_TYPE(self)); + return newVectorObject(vec, axis_to, Py_NEW, Py_TYPE(self)); } /* Set the items of this vector using a swizzle. @@ -1527,16 +1499,16 @@ static PyObject *Vector_getSwizzle(VectorObject *self, void *closure) unchanged. */ static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure) { - VectorObject *vecVal = NULL; - PyObject *item; - size_t listLen; + size_t size_from; float scalarVal; - size_t axisB; - size_t axisA; + size_t axis_from; + size_t axis_to; + unsigned int swizzleClosure; - float vecTemp[MAX_DIMENSIONS]; + float tvec[MAX_DIMENSIONS]; + float vec_assign[MAX_DIMENSIONS]; if(!BaseMath_ReadCallback(self)) return -1; @@ -1544,94 +1516,48 @@ static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure /* 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) { - axisA = swizzleClosure & SWIZZLE_AXIS; - if (axisA >= self->size) + axis_to = swizzleClosure & SWIZZLE_AXIS; + if (axis_to >= self->size) { PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n"); return -1; } swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; + axis_from++; } - - if (VectorObject_Check(value)) - { - /* Copy vector contents onto swizzled axes. */ - vecVal = (VectorObject*) value; - axisB = 0; - swizzleClosure = GET_INT_FROM_POINTER(closure); - 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; - } + if (((scalarVal=PyFloat_AsDouble(value)) == -1 && PyErr_Occurred())==0) { + int i; + for(i=0; i < MAX_DIMENSIONS; i++) + vec_assign[i]= scalarVal; - memcpy(self->vec, vecTemp, axisB * sizeof(float)); - /* continue with BaseMathObject_WriteCallback at the end */ + size_from= axis_from; + } + else if((size_from=mathutils_array_parse(vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) { + return -1; } - else if (PyList_Check(value)) - { - /* Copy list contents onto swizzled axes. */ - listLen = PyList_GET_SIZE(value); - swizzleClosure = GET_INT_FROM_POINTER(closure); - axisB = 0; - while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < listLen) - { - item = PyList_GET_ITEM(value, axisB); - - if((scalarVal=PyFloat_AsDouble(item))==-1.0 && PyErr_Occurred()) { - PyErr_SetString(PyExc_AttributeError, "Error: list item could not be used as a float.\n"); - return -1; - } - - - axisA= swizzleClosure & SWIZZLE_AXIS; - vecTemp[axisA] = scalarVal; - - 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 */ + if(axis_from != size_from) { + PyErr_SetString(PyExc_AttributeError, "Error: vector size does not match swizzle.\n"); + return -1; } - else if (((scalarVal=PyFloat_AsDouble(value)) == -1 && PyErr_Occurred())==0) + + /* Copy vector contents onto swizzled axes. */ + axis_from = 0; + swizzleClosure = GET_INT_FROM_POINTER(closure); + while (swizzleClosure & SWIZZLE_VALID_AXIS) { - /* Assign the same value to each axis. */ - swizzleClosure = GET_INT_FROM_POINTER(closure); - while (swizzleClosure & SWIZZLE_VALID_AXIS) - { - axisA = swizzleClosure & SWIZZLE_AXIS; - self->vec[axisA] = scalarVal; - - swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; - } - /* continue with BaseMathObject_WriteCallback at the end */ - } - else { - PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." ); - return -1; + 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)) return -1; |