- added a new math function double_round, useful for rounding a number to a number...
authorCampbell Barton <ideasman42@gmail.com>
Sun, 29 Nov 2009 22:42:33 +0000 (22:42 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 29 Nov 2009 22:42:33 +0000 (22:42 +0000)
- added Mathutils vector method, vec.asTuple(round), since this is tedious in python and fairly common task.

source/blender/blenlib/BLI_math_base.h
source/blender/blenlib/intern/math_base.c
source/blender/python/generic/vector.c

index 4e845ae35d9c997b6b13f29b03b9ae7adbd2cd41..af301386920b45e3d25ac20fa339ba33ca35258c 100644 (file)
@@ -148,6 +148,8 @@ float power_of_2(float f);
 
 float shell_angle_to_dist(float angle);
 
+double double_round(double x, int ndigits);
+
 #ifdef __cplusplus
 }
 #endif
index f3fe09c088fa2ca1c52e32f173f4e14ab2986c70..e1a53a09d403e43f46ab63c7c1390d6457ed1b0d 100644 (file)
@@ -109,3 +109,34 @@ float power_of_2(float val)
        return (float)pow(2, ceil(log(val) / log(2)));
 }
 
+/* from python 3.1 floatobject.c
+ * ndigits must be between 0 and 21 */
+double double_round(double x, int ndigits) {
+       double pow1, pow2, y, z;
+       if (ndigits >= 0) {
+               pow1 = pow(10.0, (double)ndigits);
+               pow2 = 1.0;
+               y = (x*pow1)*pow2;
+               /* if y overflows, then rounded value is exactly x */
+               if (!finite(y))
+                       return x;
+       }
+       else {
+               pow1 = pow(10.0, (double)-ndigits);
+               pow2 = 1.0; /* unused; silences a gcc compiler warning */
+               y = x / pow1;
+       }
+
+       z = round(y);
+       if (fabs(y-z) == 0.5)
+               /* halfway between two integers; use round-half-even */
+               z = 2.0*round(y/2.0);
+
+       if (ndigits >= 0)
+               z = (z / pow2) / pow1;
+       else
+               z *= pow1;
+
+       /* if computation resulted in overflow, raise OverflowError */
+       return z;
+}
index b3e54ac225005d8b1f05925e2af8ad7775b1ee7f..b8f2ca6f1dfc5369a58159e2ff75abd26d938f66 100644 (file)
@@ -48,6 +48,7 @@ static PyObject *Vector_Negate( VectorObject * self );
 static PyObject *Vector_Resize2D( VectorObject * self );
 static PyObject *Vector_Resize3D( VectorObject * self );
 static PyObject *Vector_Resize4D( VectorObject * self );
+static PyObject *Vector_ToTuple( VectorObject * self, PyObject *value );
 static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
 static PyObject *Vector_Reflect( VectorObject *self, VectorObject *value );
 static PyObject *Vector_Cross( VectorObject * self, VectorObject * value );
@@ -61,6 +62,7 @@ static struct PyMethodDef Vector_methods[] = {
        {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, NULL},
        {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, NULL},
        {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, NULL},
+       {"toTuple", (PyCFunction) Vector_ToTuple, METH_O, NULL},
        {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, NULL},
        {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, NULL},
        {"cross", ( PyCFunction ) Vector_Cross, METH_O, NULL},
@@ -236,6 +238,30 @@ static PyObject *Vector_Resize4D(VectorObject * self)
        Py_INCREF(self);
        return (PyObject*)self;
 }
+
+/*----------------------------Vector.resize4D() ------------------
+  resize the vector to x,y,z,w */
+static PyObject *Vector_ToTuple(VectorObject * self, PyObject *value)
+{
+       int ndigits= PyLong_AsSsize_t(value);
+       int x;
+
+       PyObject *ret;
+
+       if(ndigits > 22 || ndigits < 0) { /* accounts for non ints */
+               PyErr_SetString(PyExc_TypeError, "vector.key(ndigits): ndigits must be between 0 and 21");
+               return NULL;
+       }
+
+       ret= PyTuple_New(self->size);
+
+       for(x = 0; x < self->size; x++) {
+               PyTuple_SET_ITEM(ret, x, PyFloat_FromDouble(double_round((double)self->vec[x], ndigits)));
+       }
+
+       return ret;
+}
+
 /*----------------------------Vector.toTrackQuat(track, up) ----------------------
   extract a quaternion from the vector and the track and up axis */
 static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )