when units are enabled use them for 3d viewport grid drawing, display the dimension for the smallest grid cell.

still need to make this work with grid snapping.
This commit is contained in:
Campbell Barton 2009-08-12 14:11:53 +00:00
parent fcf883ecf9
commit 45ba3d31c0
4 changed files with 201 additions and 80 deletions

@ -37,7 +37,26 @@ void bUnit_AsString(char *str, double value, int prec, int system, int type, int
int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double scale_pref, int system, int type); int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double scale_pref, int system, int type);
/* the size of the unit used for this value (used for calculating the ckickstep) */ /* the size of the unit used for this value (used for calculating the ckickstep) */
double bUnit_Size(double value, int system, int type); double bUnit_ClosestScalar(double value, int system, int type);
/* loop over scales, coudl add names later */
//double bUnit_Iter(void **unit, char **name, int system, int type);
void bUnit_GetSystem(void **usys_pt, int *len, int system, int type);
char* bUnit_GetName(void *usys_pt, int index);
char* bUnit_GetNamePlural(void *usys_pt, int index);
double bUnit_GetScaler(void *usys_pt, int index);
/* aligned with PropertyUnit */
#define B_UNIT_NONE 0
#define B_UNIT_LENGTH 1
#define B_UNIT_AREA 2
#define B_UNIT_VOLUME 3
#define B_UNIT_MASS 4
#define B_UNIT_ROTATION 5
#define B_UNIT_TIME 6
#define B_UNIT_VELOCITY 7
#define B_UNIT_ACCELERATION 8
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -30,19 +30,24 @@
/* define a single unit */ /* define a single unit */
typedef struct bUnitDef { typedef struct bUnitDef {
char *name; char *name;
char *name_plural; /* can be NULL */ char *name_plural; /* abused a bit for the display name */
char *name_short; /* this is used for display*/ char *name_short; /* this is used for display*/
char *name_alt; /* can be NULL */ char *name_alt; /* can be NULL */
double mul; double scalar;
double bias; /* not used yet, needed for converting temperature */ double bias; /* not used yet, needed for converting temperature */
int flag;
} bUnitDef; } bUnitDef;
#define B_UNIT_DEF_NONE 0
#define B_UNIT_DEF_SUPPRESS 1 /* Use for units that are not used enough to be translated into for common use */
/* define a single unit */ /* define a single unit */
typedef struct bUnitCollection { typedef struct bUnitCollection {
struct bUnitDef *units; struct bUnitDef *units;
int base_unit; /* use for 0.0, or none given */ int base_unit; /* use for 0.0, or none given */
int flag; /* options for this system */ int flag; /* options for this system */
int length; /* to quickly find the last item */
} bUnitCollection; } bUnitCollection;
/* Dummy */ /* Dummy */
@ -50,45 +55,49 @@ static struct bUnitDef buDummyDef[] = {
{"", NULL, "", NULL, 1.0, 0.0}, {"", NULL, "", NULL, 1.0, 0.0},
{NULL, NULL, NULL, NULL, 0.0, 0.0} {NULL, NULL, NULL, NULL, 0.0, 0.0}
}; };
static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0}; static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0, sizeof(buDummyDef)};
/* Lengths */ /* Lengths */
static struct bUnitDef buMetricLenDef[] = { static struct bUnitDef buMetricLenDef[] = {
{"kilometer", "kilometers", "km", NULL, 1000.0, 0.0}, {"kilometer", "Kilometers", "km", NULL, 1000.0, 0.0, B_UNIT_DEF_NONE},
{"meter", "meters", "m", NULL, 1.0, 0.0}, /* base unit */ {"hectometer", "100 Meters", "hm", NULL, 100.0, 0.0, B_UNIT_DEF_SUPPRESS},
{"centimeter", "centimeters", "cm", NULL, 0.01, 0.0}, {"dekameter", "10 Meters", "dkm",NULL, 10.0, 0.0, B_UNIT_DEF_SUPPRESS},
{"millimeter", "millimeters", "mm", NULL, 0.001, 0.0}, {"meter", "Meters", "m", NULL, 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"micrometer", "micrometers", "um", "µm", 0.000001, 0.0}, // micron too? {"decimetre", "10 Centimeters", "dm", NULL, 0.1, 0.0, B_UNIT_DEF_SUPPRESS},
{"nanometer", "nanometers", "nm", NULL, 0.000000001, 0.0}, {"centimeter", "Centimeters", "cm", NULL, 0.01, 0.0, B_UNIT_DEF_NONE},
{"picometer", "picometers", "pm", NULL, 0.000000000001, 0.0}, {"millimeter", "Millimeters", "mm", NULL, 0.001, 0.0, B_UNIT_DEF_NONE},
{"micrometer", "Micrometers", "um", "µm", 0.000001, 0.0, B_UNIT_DEF_NONE}, // micron too?
{"nanometer", "Nanometers", "nm", NULL, 0.000000001, 0.0, B_UNIT_DEF_NONE},
{"picometer", "Picometers", "pm", NULL, 0.000000000001, 0.0,B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, 0.0, 0.0} {NULL, NULL, NULL, NULL, 0.0, 0.0}
}; };
static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 1, 0}; static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 1, 0, sizeof(buMetricLenDef)/sizeof(bUnitDef)};
static struct bUnitDef buImperialLenDef[] = { static struct bUnitDef buImperialLenDef[] = {
{"mile", "miles", "mi", "m", 1609.344, 0.0}, {"mile", "Miles", "mi", "m", 1609.344, 0.0, B_UNIT_DEF_NONE},
{"yard", "yards", "yd", NULL, 0.9144, 0.0}, {"furlong", "Furlongs", "fur", NULL,201.168, 0.0, B_UNIT_DEF_SUPPRESS},
{"foot", "feet", "'", "ft", 0.3048, 0.0}, {"yard", "Yards", "yd", NULL, 0.9144, 0.0, B_UNIT_DEF_NONE},
{"inch", "inches", "\"", "in", 0.0254, 0.0}, /* base unit */ {"foot", "Feet", "'", "ft", 0.3048, 0.0, B_UNIT_DEF_NONE},
{"thou", "thous", "mil", NULL,0.0000254, 0.0}, {"inch", "Inches", "\"", "in", 0.0254, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"thou", "Thous", "mil", NULL,0.0000254, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, 0.0, 0.0} {NULL, NULL, NULL, NULL, 0.0, 0.0}
}; };
static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 2, 0}; static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 2, 0, sizeof(buImperialLenDef)/sizeof(bUnitDef)};
/* Time */ /* Time */
static struct bUnitDef buNaturalTimeDef[] = { static struct bUnitDef buNaturalTimeDef[] = {
/* weeks? - probably not needed for blender */ /* weeks? - probably not needed for blender */
{"day", "days", "d", NULL, 90000.0, 0.0}, {"day", "Days", "d", NULL, 90000.0, 0.0, B_UNIT_DEF_NONE},
{"hour", "hours", "hr", "h", 3600.0, 0.0}, {"hour", "Hours", "hr", "h", 3600.0, 0.0, B_UNIT_DEF_NONE},
{"minute", "minutes", "min", "m", 60.0, 0.0}, {"minute", "Minutes", "min", "m", 60.0, 0.0, B_UNIT_DEF_NONE},
{"second", "seconds", "sec", "s", 1.0, 0.0}, /* base unit */ {"second", "Seconds", "sec", "s", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"millisecond", "milliseconds", "ms", NULL, 0.001, 0.0}, {"millisecond", "Milliseconds", "ms", NULL, 0.001, 0.0 , B_UNIT_DEF_NONE},
{"microsecond", "microseconds", "us", NULL, 0.000001, 0.0}, {"microsecond", "Microseconds", "us", NULL, 0.000001, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, 0.0, 0.0} {NULL, NULL, NULL, NULL, 0.0, 0.0}
}; };
static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0}; static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef)/sizeof(bUnitDef)};
#define UNIT_SYSTEM_MAX 3 #define UNIT_SYSTEM_MAX 3
static struct bUnitCollection *bUnitSystems[][8] = { static struct bUnitCollection *bUnitSystems[][8] = {
@ -109,14 +118,19 @@ static bUnitDef *unit_default(bUnitCollection *usys)
return &usys->units[usys->base_unit]; return &usys->units[usys->base_unit];
} }
static bUnitDef *unit_best_fit(double value, bUnitCollection *usys, bUnitDef *unit_start) static bUnitDef *unit_best_fit(double value, bUnitCollection *usys, bUnitDef *unit_start, int suppress)
{ {
bUnitDef *unit; bUnitDef *unit;
double value_abs= value>0.0?value:-value; double value_abs= value>0.0?value:-value;
for(unit= unit_start ? unit_start:usys->units; unit->name; unit++) for(unit= unit_start ? unit_start:usys->units; unit->name; unit++) {
if (value_abs >= unit->mul*0.9999) /* scale down mul so 1cm doesnt convert to 10mm because of float error */
if(suppress && (unit->flag & B_UNIT_DEF_SUPPRESS))
continue;
if (value_abs >= unit->scalar*0.9999) /* scale down scalar so 1cm doesnt convert to 10mm because of float error */
return unit; return unit;
}
return unit_default(usys); return unit_default(usys);
} }
@ -127,13 +141,13 @@ static bUnitDef *unit_best_fit(double value, bUnitCollection *usys, bUnitDef *un
static void unit_dual_convert(double value, bUnitCollection *usys, static void unit_dual_convert(double value, bUnitCollection *usys,
bUnitDef **unit_a, bUnitDef **unit_b, double *value_a, double *value_b) bUnitDef **unit_a, bUnitDef **unit_b, double *value_a, double *value_b)
{ {
bUnitDef *unit= unit_best_fit(value, usys, NULL); bUnitDef *unit= unit_best_fit(value, usys, NULL, 1);
*value_a= floor(value/unit->mul) * unit->mul; *value_a= floor(value/unit->scalar) * unit->scalar;
*value_b= value - (*value_a); *value_b= value - (*value_a);
*unit_a= unit; *unit_a= unit;
*unit_b= unit_best_fit(*value_b, usys, *unit_a); *unit_b= unit_best_fit(*value_b, usys, *unit_a, 1);
} }
static int unit_as_string(char *str, double value, int prec, bUnitCollection *usys, static int unit_as_string(char *str, double value, int prec, bUnitCollection *usys,
@ -151,10 +165,10 @@ static int unit_as_string(char *str, double value, int prec, bUnitCollection *us
unit= unit_default(usys); unit= unit_default(usys);
} }
else { else {
unit= unit_best_fit(value, usys, NULL); unit= unit_best_fit(value, usys, NULL, 1);
} }
value_conv= value/unit->mul; value_conv= value/unit->scalar;
/* Convert to a string */ /* Convert to a string */
{ {
@ -252,7 +266,7 @@ static int unit_scale_str(char *str, char *str_tmp, double scale_pref, bUnitDef
/* next char cannot be alphanum */ /* next char cannot be alphanum */
if (!isalpha(*(str_found+len_name))) { if (!isalpha(*(str_found+len_name))) {
int len= strlen(str); int len= strlen(str);
int len_num= sprintf(str_tmp, "*%g", unit->mul/scale_pref); int len_num= sprintf(str_tmp, "*%g", unit->scalar/scale_pref);
memmove(str_found+len_num, str_found+len_name, (len+1)-(int)((str_found+len_name)-str)); /* may grow or shrink the string, 1+ to copy the string terminator */ memmove(str_found+len_num, str_found+len_name, (len+1)-(int)((str_found+len_name)-str)); /* may grow or shrink the string, 1+ to copy the string terminator */
memcpy(str_found, str_tmp, len_num); /* without the string terminator */ memcpy(str_found, str_tmp, len_num); /* without the string terminator */
change= 1; change= 1;
@ -299,6 +313,10 @@ int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double scale_
} }
for(unit= usys->units; unit->name; unit++) { for(unit= usys->units; unit->name; unit++) {
if(unit->flag & B_UNIT_DEF_SUPPRESS)
continue;
/* incase there are multiple instances */ /* incase there are multiple instances */
while(unit_replace(str, str_tmp, scale_pref, unit)) while(unit_replace(str, str_tmp, scale_pref, unit))
change= 1; change= 1;
@ -314,6 +332,10 @@ int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double scale_
if (system_iter != system) { if (system_iter != system) {
usys_iter= unit_get_system(system_iter, type); usys_iter= unit_get_system(system_iter, type);
for(unit= usys_iter->units; unit->name; unit++) { for(unit= usys_iter->units; unit->name; unit++) {
if(unit->flag & B_UNIT_DEF_SUPPRESS)
continue;
/* incase there are multiple instances */ /* incase there are multiple instances */
while(unit_replace(str, str_tmp, scale_pref, unit)) while(unit_replace(str, str_tmp, scale_pref, unit))
change= 1; change= 1;
@ -329,6 +351,10 @@ int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double scale_
/* see which units the original value had */ /* see which units the original value had */
strcpy(str, str_prev); /* temp overwrite */ strcpy(str, str_prev); /* temp overwrite */
for(unit= usys->units; unit->name; unit++) { for(unit= usys->units; unit->name; unit++) {
if(unit->flag & B_UNIT_DEF_SUPPRESS)
continue;
if (unit_replace(str, str_tmp, scale_pref, unit)) if (unit_replace(str, str_tmp, scale_pref, unit))
break; break;
} }
@ -349,7 +375,7 @@ int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double scale_
} }
double bUnit_Size(double value, int system, int type) double bUnit_ClosestScalar(double value, int system, int type)
{ {
bUnitCollection *usys = unit_get_system(system, type); bUnitCollection *usys = unit_get_system(system, type);
bUnitDef *unit; bUnitDef *unit;
@ -357,9 +383,37 @@ double bUnit_Size(double value, int system, int type)
if(usys==NULL) if(usys==NULL)
return -1; return -1;
unit= unit_best_fit(value, usys, NULL); unit= unit_best_fit(value, usys, NULL, 1);
if(unit==NULL) if(unit==NULL)
return -1; return -1;
return unit->mul; return unit->scalar;
}
/* external access */
void bUnit_GetSystem(void **usys_pt, int *len, int system, int type)
{
bUnitCollection *usys = unit_get_system(system, type);
*usys_pt= usys;
if(usys==NULL) {
*len= 0;
return;
}
*len= usys->length;
}
char *bUnit_GetName(void *usys_pt, int index)
{
return ((bUnitCollection *)usys_pt)->units[index].name;
}
char *bUnit_GetNamePlural(void *usys_pt, int index)
{
return ((bUnitCollection *)usys_pt)->units[index].name_plural;
}
double bUnit_GetScaler(void *usys_pt, int index)
{
return ((bUnitCollection *)usys_pt)->units[index].scalar;
} }

@ -1356,7 +1356,7 @@ static float ui_get_but_step_unit(uiBut *but, double value, float step_default)
int unit_type= RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop)); int unit_type= RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop));
float step; float step;
step = bUnit_Size(ui_get_but_scale_unit(but, value), U.unit_system, unit_type); step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, value), U.unit_system, unit_type);
if(step > 0.0) { /* -1 is an error value */ if(step > 0.0) { /* -1 is an error value */
return (step/ui_get_but_scale_unit(but, 1.0))*100; return (step/ui_get_but_scale_unit(but, 1.0))*100;

@ -62,6 +62,7 @@
#include "BKE_scene.h" #include "BKE_scene.h"
#include "BKE_screen.h" #include "BKE_screen.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_unit.h"
#include "RE_pipeline.h" // make_stars #include "RE_pipeline.h" // make_stars
@ -234,7 +235,9 @@ static void drawgrid_draw(ARegion *ar, float wx, float wy, float x, float y, flo
} }
static void drawgrid(ARegion *ar, View3D *v3d) #define GRID_MIN_PX 6.0f
static void drawgrid(ARegion *ar, View3D *v3d, char **grid_unit)
{ {
/* extern short bgpicmode; */ /* extern short bgpicmode; */
RegionView3D *rv3d= ar->regiondata; RegionView3D *rv3d= ar->regiondata;
@ -243,6 +246,8 @@ static void drawgrid(ARegion *ar, View3D *v3d)
char col[3], col2[3]; char col[3], col2[3];
short sublines = v3d->gridsubdiv; short sublines = v3d->gridsubdiv;
*grid_unit= NULL;
vec4[0]=vec4[1]=vec4[2]=0.0; vec4[0]=vec4[1]=vec4[2]=0.0;
vec4[3]= 1.0; vec4[3]= 1.0;
Mat4MulVec4fl(rv3d->persmat, vec4); Mat4MulVec4fl(rv3d->persmat, vec4);
@ -272,72 +277,110 @@ static void drawgrid(ARegion *ar, View3D *v3d)
/* check zoom out */ /* check zoom out */
UI_ThemeColor(TH_GRID); UI_ThemeColor(TH_GRID);
if(dx<6.0) { if(U.unit_system) {
v3d->gridview*= sublines; void *usys;
dx*= sublines; int len, i;
double scalar;
float dx_scalar;
float blend_fac;
if(dx<6.0) { bUnit_GetSystem(&usys, &len, U.unit_system, B_UNIT_LENGTH);
if(usys) {
i= len;
while(i--) {
scalar= bUnit_GetScaler(usys, i);
dx_scalar = dx * scalar * U.unit_scale_length;
if (dx_scalar < GRID_MIN_PX)
continue;
/* Store the smallest drawn grid size units name so users know how bit each grid cell is */
if(*grid_unit==NULL)
*grid_unit= bUnit_GetNamePlural(usys, i);
blend_fac= 1-(GRID_MIN_PX/dx_scalar);
/* tweak to have the fade a bit nicer */
blend_fac= (blend_fac * blend_fac) * 2.0f;
CLAMP(blend_fac, 0.3f, 1.0f);
UI_ThemeColorBlend(TH_BACK, TH_GRID, blend_fac);
drawgrid_draw(ar, wx, wy, x, y, dx_scalar);
}
}
}
else {
if(dx<GRID_MIN_PX) {
v3d->gridview*= sublines; v3d->gridview*= sublines;
dx*= sublines; dx*= sublines;
if(dx<6.0) { if(dx<GRID_MIN_PX) {
v3d->gridview*= sublines; v3d->gridview*= sublines;
dx*=sublines; dx*= sublines;
if(dx<6.0);
else { if(dx<GRID_MIN_PX) {
UI_ThemeColor(TH_GRID); v3d->gridview*= sublines;
dx*=sublines;
if(dx<GRID_MIN_PX);
else {
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx);
}
}
else { // start blending out
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/(GRID_MIN_PX*10));
drawgrid_draw(ar, wx, wy, x, y, dx); drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, sublines*dx);
} }
} }
else { // start blending out else { // start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10))
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/(GRID_MIN_PX*10));
drawgrid_draw(ar, wx, wy, x, y, dx); drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID); UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, sublines*dx); drawgrid_draw(ar, wx, wy, x, y, sublines*dx);
} }
} }
else { // start blending out (6 < dx < 60) else {
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); if(dx>(GRID_MIN_PX*10)) { // start blending in
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, sublines*dx);
}
}
else {
if(dx>60.0) { // start blending in
v3d->gridview/= sublines;
dx/= sublines;
if(dx>60.0) { // start blending in
v3d->gridview/= sublines; v3d->gridview/= sublines;
dx/= sublines; dx/= sublines;
if(dx>60.0) { if(dx>(GRID_MIN_PX*10)) { // start blending in
UI_ThemeColor(TH_GRID); v3d->gridview/= sublines;
drawgrid_draw(ar, wx, wy, x, y, dx); dx/= sublines;
if(dx>(GRID_MIN_PX*10)) {
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx);
}
else {
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/(GRID_MIN_PX*10));
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx*sublines);
}
} }
else { else {
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/(GRID_MIN_PX*10));
drawgrid_draw(ar, wx, wy, x, y, dx); drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID); UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx*sublines); drawgrid_draw(ar, wx, wy, x, y, dx*sublines);
} }
} }
else { else {
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0); UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/(GRID_MIN_PX*10));
drawgrid_draw(ar, wx, wy, x, y, dx); drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID); UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx*sublines); drawgrid_draw(ar, wx, wy, x, y, dx*sublines);
} }
} }
else {
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0);
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx*sublines);
}
} }
x+= (wx); x+= (wx);
y+= (wy); y+= (wy);
UI_GetThemeColor3ubv(TH_GRID, col); UI_GetThemeColor3ubv(TH_GRID, col);
@ -361,7 +404,7 @@ static void drawgrid(ARegion *ar, View3D *v3d)
glDepthMask(1); // enable write in zbuffer glDepthMask(1); // enable write in zbuffer
} }
#undef GRID_MIN_PX
static void drawfloor(Scene *scene, View3D *v3d) static void drawfloor(Scene *scene, View3D *v3d)
{ {
@ -1855,6 +1898,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
Object *ob; Object *ob;
int retopo= 0, sculptparticle= 0; int retopo= 0, sculptparticle= 0;
Object *obact = OBACT; Object *obact = OBACT;
char *grid_unit= NULL;
/* from now on all object derived meshes check this */ /* from now on all object derived meshes check this */
v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C)); v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C));
@ -1929,7 +1973,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
} }
else { else {
ED_region_pixelspace(ar); ED_region_pixelspace(ar);
drawgrid(ar, v3d); drawgrid(ar, v3d, &grid_unit);
/* XXX make function? replaces persp(1) */ /* XXX make function? replaces persp(1) */
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
wmLoadMatrix(rv3d->winmat); wmLoadMatrix(rv3d->winmat);
@ -2060,6 +2104,10 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
if(U.uiflag & USER_SHOW_VIEWPORTNAME) { if(U.uiflag & USER_SHOW_VIEWPORTNAME) {
draw_viewport_name(ar, v3d); draw_viewport_name(ar, v3d);
} }
if (grid_unit) { /* draw below the viewport name */
UI_ThemeColor(TH_TEXT_HI);
BLF_draw_default(10, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, grid_unit);
}
ob= OBACT; ob= OBACT;
if(U.uiflag & USER_DRAWVIEWINFO) if(U.uiflag & USER_DRAWVIEWINFO)