diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-11-30 01:42:33 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-11-30 01:42:33 +0300 |
commit | d98093a91ac7ce96ab6b1e14168493f9f69f379d (patch) | |
tree | a89141e41ab7dfaa81b05b5f3cf97dd7baa8469e /source/blender | |
parent | cd154da9732962870339952898499ed1b1c32d93 (diff) |
- added a new math function double_round, useful for rounding a number to a number of decimal places.
- added Mathutils vector method, vec.asTuple(round), since this is tedious in python and fairly common task.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/BLI_math_base.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_base.c | 31 | ||||
-rw-r--r-- | source/blender/python/generic/vector.c | 26 |
3 files changed, 59 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 4e845ae35d9..af301386920 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -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 diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c index f3fe09c088f..e1a53a09d40 100644 --- a/source/blender/blenlib/intern/math_base.c +++ b/source/blender/blenlib/intern/math_base.c @@ -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; +} diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index b3e54ac2250..b8f2ca6f1df 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -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 ) |