[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22383] branches/blender2.5/blender: user interface units, off by default.

Campbell Barton ideasman42 at gmail.com
Tue Aug 11 20:53:02 CEST 2009


Revision: 22383
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22383
Author:   campbellbarton
Date:     2009-08-11 20:53:01 +0200 (Tue, 11 Aug 2009)

Log Message:
-----------
user interface units, off by default.

- currently only distances work.
- user preferences, edit section to set the units and scale.
- option to display pairs (nicer for imperial display?)
- support for evaluating multiple comma separated values eg: 2',11" ..or.. 5ft, 4mil
- comma separated expressions/values accumulate 1+1,2**3,4cm/3
- attempted fast conversion from a value to a string so button drawing isn't too slow.

* imperial long/short *
- mile, mi
- yard, yd
- foot, '
- inch, "
- thou, mil

* metric long/short *
kilometer, km
meter, m
centimeter, cm
millimeter, mm
micrometer, um
nanometer, nm
picometer, pm

Modified Paths:
--------------
    branches/blender2.5/blender/release/ui/bpy_ops.py
    branches/blender2.5/blender/release/ui/space_info.py
    branches/blender2.5/blender/source/blender/editors/interface/interface.c
    branches/blender2.5/blender/source/blender/makesdna/DNA_scene_types.h
    branches/blender2.5/blender/source/blender/makesdna/DNA_userdef_types.h
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_lamp.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_material.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_meta.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_object.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_scene.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_space.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_userdef.c
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_world.c
    branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c

Added Paths:
-----------
    branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h
    branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c

Modified: branches/blender2.5/blender/release/ui/bpy_ops.py
===================================================================
--- branches/blender2.5/blender/release/ui/bpy_ops.py	2009-08-11 18:43:55 UTC (rev 22382)
+++ branches/blender2.5/blender/release/ui/bpy_ops.py	2009-08-11 18:53:01 UTC (rev 22383)
@@ -111,48 +111,3 @@
 
 import bpy
 bpy.ops = bpy_ops()
-
-
-
-
-# A bit out of place but add button conversion code here
-module_type = type(__builtins__)
-import types
-mod = types.ModuleType('button_convert')
-
-import sys
-sys.modules['button_convert'] = mod
-
-def convert(expr):
-	
-	def replace(string, unit, scaler):
-		# in need of regex
-		change = True
-		while change:
-			change = False
-			i = string.find(unit)
-			if i != -1:
-				if i>0 and not string[i-1].isalpha():
-					i_end = i+len(unit)
-					if i_end+1 >= len(string) or (not string[i_end+1].isalpha()):
-						string = string.replace(unit, scaler)
-						change = True
-		# print(string)
-		return string
-	
-	#imperial
-	expr = replace(expr, 'mi', '*1609.344')
-	expr = replace(expr, 'yd', '*0.9144')
-	expr = replace(expr, 'ft', '*0.3048')
-	expr = replace(expr, 'in', '*0.0254')
-	
-	# metric
-	expr = replace(expr, 'km', '*1000')
-	expr = replace(expr, 'm', '')
-	expr = replace(expr, 'cm', '*0.01')
-	expr = replace(expr, 'mm', '*0.001')
-	
-	return expr
-
-mod.convert = convert
-

Modified: branches/blender2.5/blender/release/ui/space_info.py
===================================================================
--- branches/blender2.5/blender/release/ui/space_info.py	2009-08-11 18:43:55 UTC (rev 22382)
+++ branches/blender2.5/blender/release/ui/space_info.py	2009-08-11 18:53:01 UTC (rev 22383)
@@ -320,7 +320,18 @@
 		sub1.itemS()
 		sub1.itemL(text="Transform:")
 		sub1.itemR(edit, "drag_immediately")
+		sub1.itemS()
+		sub1.itemS()
+		sub1.itemS()
 		
+		sub1.itemL(text="Units:")
+		sub1.itemR(edit, "unit_type")
+		
+		sub2 = sub1.column()
+		sub2.active = (edit.unit_type != 'NONE')
+		sub2.itemR(edit, "unit_scale_length")
+		sub2.itemR(edit, "use_unit_split")
+
 		col = split.column()
 		sub = col.split(percentage=0.85)
 		

Added: branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h	                        (rev 0)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h	2009-08-11 18:53:01 UTC (rev 22383)
@@ -0,0 +1,43 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_UNIT_H
+#define BKE_UNIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* in all cases the value is assumed to be scaled by the user preference */
+
+/* humanly readable representation of a value in units (used for button drawing) */
+void	bUnit_AsString(char *str, double value, int prec, int system, int type, int split, int pad);
+
+/* replace units with values, used before python button evaluation */
+int		bUnit_ReplaceString(char *str, char *str_orig, double scale_pref, int system, int type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BKE_UNIT_H */


Property changes on: branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c	                        (rev 0)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c	2009-08-11 18:53:01 UTC (rev 22383)
@@ -0,0 +1,267 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+
+/* define a single unit */
+typedef struct bUnitDef {
+	char *name;
+
+	/* optional, can be null */
+	char *name_plural;
+	char *name_short;	/* this is used for display*/
+	char *name_alt;		/* alternative name */
+	
+	double mul;
+	double bias;
+} bUnitDef;
+
+/* define a single unit */
+typedef struct bUnitCollection {
+	struct bUnitDef *units;
+	int def;					/* default unit, use for 0.0, or none given */
+	int flag;					/* options for this system */
+} bUnitCollection;
+
+static struct bUnitDef buMetricLenDef[] = {
+	{"kilometer", "kilometers",		"km", NULL,	1000.0, 0.0},
+	{"meter", "meters",				"m",  NULL,	1.0, 0.0},
+	{"centimeter", "centimeters",	"cm", NULL,	0.01, 0.0},
+	{"millimeter", "millimeters",	"mm", NULL,	0.001, 0.0},
+	{"micrometer", "micrometers",	"um", "µm",	0.000001, 0.0}, // micron too?
+	{"nanometer", "nanometers",		"nm", NULL,	0.000000001, 0.0},
+	{"picometer", "picometers",		"pm", NULL,	0.000000000001, 0.0},
+	{NULL, NULL, NULL,	NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 1, 0};
+
+#define IMPERIAL_DEFAULT 3 /* inch */
+static struct bUnitDef buImperialLenDef[] = {
+	{"mile", "miles",				"mi", "m",	1609.344, 0.0},
+	{"yard", "yards",				"yd", NULL,	0.9144, 0.0},
+	{"foot", "feet",				"'", "ft",	0.3048, 0.0},
+	{"inch", "inches",				"\"", "in",	0.0254, 0.0},
+	{"thou", "thous",				"mil", NULL,0.0000254, 0.0},
+	{NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 2, 0};
+
+static struct bUnitCollection *bUnitSystems[][8] = {
+	{0,&buMetricLenCollecton, 0,0,0,0,0,0}, /* metric */
+	{0,&buImperialLenCollecton, 0,0,0,0,0,0}, /* imperial */
+	{0,0,0,0,0,0,0,0}
+};
+
+/* internal, has some option not exposed */
+static bUnitCollection *unit_get_system(int system, int type)
+{
+	return bUnitSystems[system-1][type];
+}
+
+static bUnitDef *unit_best_fit(double value, bUnitCollection *usys, bUnitDef *unit_start)
+{
+	bUnitDef *unit;
+	double value_abs= value>0.0?value:-value;
+
+	for(unit= unit_start ? unit_start:usys->units; unit->name; unit++)
+		if (value_abs >= unit->mul)
+			return unit;
+
+	return &usys->units[usys->def];
+}
+
+/* convert into 2 units and 2 values for "2ft, 3inch" syntax */
+static void unit_dual_convert(double value, bUnitCollection *usys,
+		bUnitDef **unit_a, bUnitDef **unit_b, double *value_a, double *value_b)
+{
+	bUnitDef *unit= unit_best_fit(value, usys, NULL);
+
+	*value_a= floor(value/unit->mul) * unit->mul;
+	*value_b= value - (*value_a);
+
+	*unit_a=	unit;
+	*unit_b=	unit_best_fit(*value_b, usys, *unit_a);
+}
+
+static int unit_as_string(char *str, double value, int prec, bUnitCollection *usys,
+		/* non exposed options */
+		bUnitDef *unit, char pad)
+{
+	double value_conv;
+	int len, i;
+	
+	if(unit) {
+		/* use unit without finding the best one */
+	}
+	else if(value == 0.0) {
+		/* use the default units since there is no way to convert */
+		unit= &usys->units[usys->def];
+	}
+	else {
+		unit= unit_best_fit(value, usys, NULL);
+	}
+
+	value_conv= value/unit->mul;
+
+	/* Convert to a string */
+	{
+		char conv_str[5] = {'%', '.', '0'+prec, 'f', '\0'}; /* "%.2f" when prec is 2, must be under 10 */
+		len= sprintf(str, conv_str, (float)value_conv);
+	}
+	
+	
+	/* Add unit prefix and strip zeros */
+	{
+		/* replace trailing zero's with spaces 
+		 * so the number is less complicated but allignment in a button wont
+		 * jump about while dragging */
+		int j;
+		i= len-1;
+
+	
+		while(i>0 && str[i]=='0') { /* 4.300 -> 4.3 */
+			str[i--]= pad;
+		}
+		
+		if(i>0 && str[i]=='.') { /* 10. -> 10 */
+			str[i--]= pad;
+		}
+		
+		/* Now add the suffix */
+		i++;
+		j=0;
+		while(unit->name_short[j]) {
+			str[i++]= unit->name_short[j++];
+		}
+
+		if(pad) {
+			/* this loop only runs if so many zeros were removed that
+			 * the unit name only used padded chars,
+			 * In that case add padding for the name. */
+
+			while(i<=len+j) {
+				str[i++]= pad;
+			}
+		}
+		
+		/* terminate no matter whats done with padding above */
+		str[i] = '\0';
+	}
+
+	return i;
+}
+
+/* Used for drawing number buttons, try keep fast */
+void bUnit_AsString(char *str, double value, int prec, int system, int type, int split, int pad)
+{
+	bUnitCollection *usys = unit_get_system(system, type);
+
+	if(split) {
+		int i;
+		bUnitDef *unit_a, *unit_b;
+		double value_a, value_b;
+
+		unit_dual_convert(value, usys,		&unit_a, &unit_b, &value_a, &value_b);
+
+		/* check the 2 is a smaller unit */
+		if(unit_b > unit_a) {
+			i= unit_as_string(str, value_a, prec, usys,    unit_a, '\0');
+			i= strlen(str);
+			str[i++]= ',';
+			str[i++]= ' ';
+
+			/* use low precision since this is a smaller unit */
+			unit_as_string(str+i, value_b, prec?1:0, usys, unit_b, '\0');
+			return;
+		}
+	}
+
+	unit_as_string(str, value, prec, usys,    NULL, pad?' ':'\0');
+}
+
+
+static int unit_scale_str(char *str, char *str_tmp, double scale_pref, bUnitDef *unit, char *replace_str)
+{
+	char *str_found;
+	int change= 0;
+
+	if(replace_str && (str_found= strstr(str, replace_str))) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list