[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25009] trunk/blender/source/blender: - added a new math function double_round, useful for rounding a number to a number of decimal places.

Campbell Barton ideasman42 at gmail.com
Sun Nov 29 23:42:34 CET 2009


Revision: 25009
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25009
Author:   campbellbarton
Date:     2009-11-29 23:42:33 +0100 (Sun, 29 Nov 2009)

Log Message:
-----------
- 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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_math_base.h
    trunk/blender/source/blender/blenlib/intern/math_base.c
    trunk/blender/source/blender/python/generic/vector.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_base.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_base.h	2009-11-29 22:16:29 UTC (rev 25008)
+++ trunk/blender/source/blender/blenlib/BLI_math_base.h	2009-11-29 22:42:33 UTC (rev 25009)
@@ -148,6 +148,8 @@
 
 float shell_angle_to_dist(float angle);
 
+double double_round(double x, int ndigits);
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/blender/source/blender/blenlib/intern/math_base.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_base.c	2009-11-29 22:16:29 UTC (rev 25008)
+++ trunk/blender/source/blender/blenlib/intern/math_base.c	2009-11-29 22:42:33 UTC (rev 25009)
@@ -109,3 +109,34 @@
 	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;
+}

Modified: trunk/blender/source/blender/python/generic/vector.c
===================================================================
--- trunk/blender/source/blender/python/generic/vector.c	2009-11-29 22:16:29 UTC (rev 25008)
+++ trunk/blender/source/blender/python/generic/vector.c	2009-11-29 22:42:33 UTC (rev 25009)
@@ -48,6 +48,7 @@
 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 @@
 	{"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 @@
 	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 )





More information about the Bf-blender-cvs mailing list