[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55005] trunk/blender/source/blender: fix [#34490] Copy and paste floating point number fields losses precision

Campbell Barton ideasman42 at gmail.com
Mon Mar 4 05:21:53 CET 2013


Revision: 55005
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55005
Author:   campbellbarton
Date:     2013-03-04 04:21:51 +0000 (Mon, 04 Mar 2013)
Log Message:
-----------
fix [#34490] Copy and paste floating point number fields losses precision
- copy now gets up to 6 decimal places
- copy and UI float button editing now strip zeros: 1.000 -> 1.0

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_string.h
    trunk/blender/source/blender/blenlib/intern/string.c
    trunk/blender/source/blender/editors/interface/interface.c
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_intern.h

Modified: trunk/blender/source/blender/blenlib/BLI_string.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_string.h	2013-03-04 01:57:29 UTC (rev 55004)
+++ trunk/blender/source/blender/blenlib/BLI_string.h	2013-03-04 04:21:51 UTC (rev 55005)
@@ -226,6 +226,11 @@
 __attribute__((nonnull))
 #endif
 ;
+int BLI_str_rstrip_float_zero(char *str, const char pad)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
 
 #ifdef __cplusplus
 }

Modified: trunk/blender/source/blender/blenlib/intern/string.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/string.c	2013-03-04 01:57:29 UTC (rev 55004)
+++ trunk/blender/source/blender/blenlib/intern/string.c	2013-03-04 04:21:51 UTC (rev 55005)
@@ -454,3 +454,31 @@
 		if (str[i] >= 'a' && str[i] <= 'z')
 			str[i] -= 'a' - 'A';
 }
+
+/**
+ * Strip trailing zeros from a float, eg:
+ *   0.0000 -> 0.0
+ *   2.0010 -> 2.001
+ *
+ * \param str
+ * \param len
+ * \return The number of zeto's stripped.
+ */
+int BLI_str_rstrip_float_zero(char *str, const char pad)
+{
+	char *p = strchr(str, '.');
+	int totstrip = 0;
+	if (p) {
+		char *end_p;
+		p++;  /* position at first decimal place */
+		end_p = p + (strlen(p) - 1);  /* position at last character */
+		if (end_p > p) {
+			while (end_p != p && *end_p == '0') {
+				*end_p = pad;
+				end_p--;
+			}
+		}
+	}
+
+	return totstrip;
+}

Modified: trunk/blender/source/blender/editors/interface/interface.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface.c	2013-03-04 01:57:29 UTC (rev 55004)
+++ trunk/blender/source/blender/editors/interface/interface.c	2013-03-04 04:21:51 UTC (rev 55005)
@@ -1674,18 +1674,28 @@
 	}
 }
 
-static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad)
+/**
+ * \param float_precision  Override the button precision.
+ */
+static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad, int float_precision)
 {
 	UnitSettings *unit = but->block->unit;
 	int do_split = unit->flag & USER_UNIT_OPT_SPLIT;
 	int unit_type = uiButGetUnitType(but);
-	int precision = but->a2;
+	int precision;
 
 	if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f;  // XXX do_versions
 
-	/* Sanity checks */
-	if (precision > PRECISION_FLOAT_MAX) precision = PRECISION_FLOAT_MAX;
-	else if (precision == 0) precision = 2;
+	/* Use precision override? */
+	if (float_precision == -1) {
+		/* Sanity checks */
+		precision = (int)but->a2;
+		if      (precision > PRECISION_FLOAT_MAX) precision = PRECISION_FLOAT_MAX;
+		else if (precision == 0)                  precision = 2;
+	}
+	else {
+		precision = float_precision;
+	}
 
 	bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision,
 	               unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type), do_split, pad);
@@ -1706,8 +1716,10 @@
 	}
 }
 
-
-void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
+/**
+ * \param float_precision  For number buttons the precission to use or -1 to fallback to the button default.
+ */
+void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
 {
 	if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
 		PropertyType type;
@@ -1779,10 +1791,10 @@
 
 		if (ui_is_but_float(but)) {
 			if (ui_is_but_unit(but)) {
-				ui_get_but_string_unit(but, str, maxlen, value, 0);
+				ui_get_but_string_unit(but, str, maxlen, value, 0, float_precision);
 			}
 			else {
-				const int prec = ui_but_float_precision(but, value);
+				const int prec = (float_precision == -1) ? ui_but_float_precision(but, value) : float_precision;
 				BLI_snprintf(str, maxlen, "%.*f", prec, value);
 			}
 		}
@@ -1790,6 +1802,10 @@
 			BLI_snprintf(str, maxlen, "%d", (int)value);
 	}
 }
+void ui_get_but_string(uiBut *but, char *str, const size_t maxlen)
+{
+	ui_get_but_string_ex(but, str, maxlen, -1);
+}
 
 #ifdef WITH_PYTHON
 
@@ -2345,7 +2361,7 @@
 				/* support length type buttons */
 				else if (ui_is_but_unit(but)) {
 					char new_str[sizeof(but->drawstr)];
-					ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE);
+					ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1);
 					BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
 				}
 				else {

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2013-03-04 01:57:29 UTC (rev 55004)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2013-03-04 04:21:51 UTC (rev 55005)
@@ -1402,7 +1402,11 @@
 			/* pass */
 		}
 		else if (mode == 'c') {
-			ui_get_but_string(but, buf, sizeof(buf));
+			/* Get many decimal places, then strip trailing zeros.
+			 * note: too high values start to give strange results (6 or so is ok) */
+			ui_get_but_string_ex(but, buf, sizeof(buf), 6);
+			BLI_str_rstrip_float_zero(buf, '\0');
+
 			WM_clipboard_text_set(buf, 0);
 		}
 		else {
@@ -1984,6 +1988,10 @@
 	data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
 	ui_get_but_string(but, data->str, data->maxlen);
 
+	if (ui_is_but_float(but) && !ui_is_but_unit(but)) {
+		BLI_str_rstrip_float_zero(data->str, '\0');
+	}
+
 	if (ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
 		ui_convert_to_unit_alt_name(but, data->str, data->maxlen);
 	}

Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h	2013-03-04 01:57:29 UTC (rev 55004)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h	2013-03-04 04:21:51 UTC (rev 55005)
@@ -394,7 +394,8 @@
 extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
                                        const float mx, const float my);
 
-extern void ui_get_but_string(uiBut *but, char *str, size_t maxlen);
+extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision);
+extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen);
 extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen);
 extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str);
 extern int ui_get_but_string_max_length(uiBut *but);




More information about the Bf-blender-cvs mailing list