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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to