diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_unit.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/unit.c | 224 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 12 | ||||
-rw-r--r-- | source/blender/draw/modes/edit_mesh_mode_text.c | 11 | ||||
-rw-r--r-- | source/blender/editors/include/ED_numinput.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 26 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_eyedropper_depth.c | 9 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_gizmo_ruler.c | 14 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ruler.c | 13 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 12 | ||||
-rw-r--r-- | source/blender/editors/util/numinput.c | 54 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 89 |
14 files changed, 360 insertions, 129 deletions
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h index 82a4659eec7..bb7fb006038 100644 --- a/source/blender/blenkernel/BKE_unit.h +++ b/source/blender/blenkernel/BKE_unit.h @@ -31,14 +31,23 @@ extern "C" { #endif +struct UnitSettings; + /* 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) */ -size_t bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad); +size_t bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad); +size_t bUnit_AsString2(char *str, int len_max, double value, int prec, int type, const struct UnitSettings *settings, bool pad); /* replace units with values, used before python button evaluation */ bool bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type); +/* return true if the string contains any valid unit for the given type */ +bool bUnit_ContainsUnit(const char *str, int system, int type); + +/* if user does not specify a unit, multiply with this value */ +double bUnit_PreferredUnitScalar(const struct UnitSettings *settings, int type); + /* make string keyboard-friendly: 10µm --> 10um */ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type); @@ -56,9 +65,11 @@ bool bUnit_IsValid(int system, int type); void bUnit_GetSystem(int system, int type, void const **r_usys_pt, int *r_len); int bUnit_GetBaseUnit(const void *usys_pt); +int bUnit_GetBaseUnitOfType(int system, int type); const char *bUnit_GetName(const void *usys_pt, int index); const char *bUnit_GetNameDisplay(const void *usys_pt, int index); double bUnit_GetScaler(const void *usys_pt, int index); +bool bUnit_IsSuppressed(const void *usys_pt, int index); /* aligned with PropertyUnit */ enum { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 8c2f226eb8b..44406714771 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -703,6 +703,9 @@ void BKE_scene_init(Scene *sce) sce->unit.system = USER_UNIT_METRIC; sce->unit.scale_length = 1.0f; + sce->unit.length_unit = bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_LENGTH); + sce->unit.mass_unit = bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_MASS); + sce->unit.time_unit = bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_TIME); pset = &sce->toolsettings->particle; pset->flag = PE_KEEP_LENGTHS | PE_LOCK_FIRST | PE_DEFLECT_EMITTER | PE_AUTO_VELOCITY; diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 3a903eb31c1..c132053a82b 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -35,6 +35,8 @@ #include "BLI_string.h" #include "BLI_string_utf8.h" +#include "DNA_scene_types.h" + #include "BKE_unit.h" /* own include */ #ifdef WIN32 @@ -108,6 +110,8 @@ typedef struct bUnitCollection { int length; /* to quickly find the last item */ } bUnitCollection; +#define UNIT_COLLECTION_LENGTH(def) (sizeof(def) / sizeof(bUnitDef) - 1) + /* Dummy */ static struct bUnitDef buDummyDef[] = { {"", NULL, "", NULL, NULL, 1.0, 0.0}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}}; static struct bUnitCollection buDummyCollection = {buDummyDef, 0, 0, sizeof(buDummyDef)}; @@ -121,7 +125,7 @@ static const struct bUnitDef buMetricLenDef[] = { {"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_CM, 0.0, B_UNIT_DEF_NONE}, {"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH}, - {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, + {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, /* These get displayed because of float precision problems in the transform header, * could work around, but for now probably people wont use these */ @@ -131,7 +135,7 @@ static const struct bUnitDef buMetricLenDef[] = { #endif {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static const struct bUnitCollection buMetricLenCollection = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef) / sizeof(bUnitDef)}; +static const struct bUnitCollection buMetricLenCollection = {buMetricLenDef, 3, 0, UNIT_COLLECTION_LENGTH(buMetricLenDef)}; static struct bUnitDef buImperialLenDef[] = { {"mile", "miles", "mi", "m", "Miles", UN_SC_MI, 0.0, B_UNIT_DEF_NONE}, @@ -143,7 +147,7 @@ static struct bUnitDef buImperialLenDef[] = { {"thou", "thou", "thou", "mil", "Thou", UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, /* plural for thou has no 's' */ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buImperialLenCollection = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buImperialLenCollection = {buImperialLenDef, 4, 0, UNIT_COLLECTION_LENGTH(buImperialLenDef)}; /* Areas */ static struct bUnitDef buMetricAreaDef[] = { @@ -157,7 +161,7 @@ static struct bUnitDef buMetricAreaDef[] = { {"square micrometer", "square micrometers", "µm²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, UNIT_COLLECTION_LENGTH(buMetricAreaDef)}; static struct bUnitDef buImperialAreaDef[] = { {"square mile", "square miles", "sq mi", "sq m", "Square Miles", UN_SC_MI * UN_SC_MI, 0.0, B_UNIT_DEF_NONE}, @@ -169,7 +173,7 @@ static struct bUnitDef buImperialAreaDef[] = { {"square thou", "square thous", "sq mil", NULL, "Square Thous", UN_SC_MIL * UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buImperialAreaCollection = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buImperialAreaCollection = {buImperialAreaDef, 4, 0, UNIT_COLLECTION_LENGTH(buImperialAreaDef)}; /* Volumes */ static struct bUnitDef buMetricVolDef[] = { @@ -183,7 +187,7 @@ static struct bUnitDef buMetricVolDef[] = { {"cubic micrometer", "cubic micrometers", "µm³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, UNIT_COLLECTION_LENGTH(buMetricVolDef)}; static struct bUnitDef buImperialVolDef[] = { {"cubic mile", "cubic miles", "cu mi", "cu m", "Cubic Miles", UN_SC_MI * UN_SC_MI * UN_SC_MI, 0.0, B_UNIT_DEF_NONE}, @@ -195,7 +199,7 @@ static struct bUnitDef buImperialVolDef[] = { {"cubic thou", "cubic thous", "cu mil", NULL, "Cubic Thous", UN_SC_MIL * UN_SC_MIL * UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buImperialVolCollection = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buImperialVolCollection = {buImperialVolDef, 4, 0, UNIT_COLLECTION_LENGTH(buImperialVolDef)}; /* Mass */ static struct bUnitDef buMetricMassDef[] = { @@ -208,7 +212,7 @@ static struct bUnitDef buMetricMassDef[] = { {"milligram", "milligrams", "mg", NULL, "Milligrams", UN_SC_MG, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buMetricMassCollection = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buMetricMassCollection = {buMetricMassDef, 2, 0, UNIT_COLLECTION_LENGTH(buMetricMassDef)}; static struct bUnitDef buImperialMassDef[] = { {"ton", "tonnes", "ton", "t", "Tonnes", UN_SC_ITON, 0.0, B_UNIT_DEF_NONE}, @@ -218,7 +222,7 @@ static struct bUnitDef buImperialMassDef[] = { {"ounce", "ounces", "oz", NULL, "Ounces", UN_SC_OZ, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buImperialMassCollection = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buImperialMassCollection = {buImperialMassDef, 3, 0, UNIT_COLLECTION_LENGTH(buImperialMassDef)}; /* Even if user scales the system to a point where km^3 is used, velocity and * acceleration aren't scaled: that's why we have so few units for them */ @@ -229,27 +233,27 @@ static struct bUnitDef buMetricVelDef[] = { {"kilometer per hour", "kilometers per hour", "km/h", NULL, "Kilometers per hour", UN_SC_KM / 3600.0f, 0.0, B_UNIT_DEF_SUPPRESS}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buMetricVelCollection = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buMetricVelCollection = {buMetricVelDef, 0, 0, UNIT_COLLECTION_LENGTH(buMetricVelDef)}; static struct bUnitDef buImperialVelDef[] = { {"foot per second", "feet per second", "ft/s", "fps", "Feet per second", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"mile per hour", "miles per hour", "mph", NULL, "Miles per hour", UN_SC_MI / 3600.0f, 0.0, B_UNIT_DEF_SUPPRESS}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buImperialVelCollection = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buImperialVelCollection = {buImperialVelDef, 0, 0, UNIT_COLLECTION_LENGTH(buImperialVelDef)}; /* Acceleration */ static struct bUnitDef buMetricAclDef[] = { {"meter per second squared", "meters per second squared", "m/s²", "m/s2", "Meters per second squared", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buMetricAclCollection = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buMetricAclCollection = {buMetricAclDef, 0, 0, UNIT_COLLECTION_LENGTH(buMetricAclDef)}; static struct bUnitDef buImperialAclDef[] = { {"foot per second squared", "feet per second squared", "ft/s²", "ft/s2", "Feet per second squared", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buImperialAclCollection = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buImperialAclCollection = {buImperialAclDef, 0, 0, UNIT_COLLECTION_LENGTH(buImperialAclDef)}; /* Time */ static struct bUnitDef buNaturalTimeDef[] = { @@ -262,7 +266,7 @@ static struct bUnitDef buNaturalTimeDef[] = { {"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, UNIT_COLLECTION_LENGTH(buNaturalTimeDef)}; static struct bUnitDef buNaturalRotDef[] = { @@ -274,7 +278,7 @@ static struct bUnitDef buNaturalRotDef[] = { // {"turn", "turns", "t", NULL, "Turns", 1.0 / (M_PI * 2.0), 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, UNIT_COLLECTION_LENGTH(buNaturalRotDef)}; /* Camera Lengths */ static struct bUnitDef buCameraLenDef[] = { @@ -285,7 +289,7 @@ static struct bUnitDef buCameraLenDef[] = { {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; -static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, sizeof(buCameraLenDef) / sizeof(bUnitDef)}; +static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, UNIT_COLLECTION_LENGTH(buCameraLenDef)}; #define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / B_UNIT_TYPE_TOT) / sizeof(void *)) - 1) @@ -341,9 +345,12 @@ static const bUnitDef *unit_best_fit( static void unit_dual_convert( double value, const bUnitCollection *usys, bUnitDef const **r_unit_a, bUnitDef const **r_unit_b, - double *r_value_a, double *r_value_b) + double *r_value_a, double *r_value_b, + const bUnitDef *main_unit) { - const bUnitDef *unit = unit_best_fit(value, usys, NULL, 1); + const bUnitDef *unit; + if (main_unit) unit = main_unit; + else unit = unit_best_fit(value, usys, NULL, 1); *r_value_a = (value < 0.0 ? ceil : floor)(value / unit->scalar) * unit->scalar; *r_value_b = value - (*r_value_a); @@ -426,43 +433,136 @@ static size_t unit_as_string(char *str, int len_max, double value, int prec, con return i; } -/* Used for drawing number buttons, try keep fast. - * Return the length of the generated string. - */ -size_t bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad) +static bool unit_should_be_split(int type) { - const bUnitCollection *usys = unit_get_system(system, type); + return ELEM(type, B_UNIT_LENGTH, B_UNIT_MASS, B_UNIT_TIME, B_UNIT_CAMERA); +} - if (usys == NULL || usys->units[0].name == NULL) - usys = &buDummyCollection; +typedef struct { + int system; + int rotation; + /* USER_UNIT_ADAPTIVE means none, otherwise the value is the index in the collection */ + int length; + int mass; + int time; +} PreferredUnits; - /* split output makes sense only for length, mass and time */ - if (split && (type == B_UNIT_LENGTH || type == B_UNIT_MASS || type == B_UNIT_TIME || type == B_UNIT_CAMERA)) { - const bUnitDef *unit_a, *unit_b; - double value_a, value_b; +static PreferredUnits preferred_units_from_UnitSettings(const UnitSettings *settings) +{ + PreferredUnits units = { 0 }; + units.system = settings->system; + units.rotation = settings->system_rotation; + units.length = settings->length_unit; + units.mass = settings->mass_unit; + units.time = settings->time_unit; + return units; +} - unit_dual_convert(value, usys, &unit_a, &unit_b, &value_a, &value_b); +static size_t unit_as_string_splitted( + char *str, int len_max, double value, int prec, + const bUnitCollection *usys, const bUnitDef *main_unit) +{ + const bUnitDef *unit_a, *unit_b; + double value_a, value_b; - /* check the 2 is a smaller unit */ - if (unit_b > unit_a) { - size_t i; - i = unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0'); + unit_dual_convert(value, usys, &unit_a, &unit_b, &value_a, &value_b, main_unit); - prec -= integer_digits_d(value_a / unit_b->scalar) - integer_digits_d(value_b / unit_b->scalar); - prec = max_ii(prec, 0); + /* check the 2 is a smaller unit */ + if (unit_b > unit_a) { + size_t i; + i = unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0'); - /* is there enough space for at least 1 char of the next unit? */ - if (i + 2 < len_max) { - str[i++] = ' '; + prec -= integer_digits_d(value_a / unit_b->scalar) - integer_digits_d(value_b / unit_b->scalar); + prec = max_ii(prec, 0); - /* use low precision since this is a smaller unit */ - i += unit_as_string(str + i, len_max - i, value_b, prec, usys, unit_b, '\0'); - } - return i; + /* is there enough space for at least 1 char of the next unit? */ + if (i + 2 < len_max) { + str[i++] = ' '; + + /* use low precision since this is a smaller unit */ + i += unit_as_string(str + i, len_max - i, value_b, prec, usys, unit_b, '\0'); } + return i; + } + + return -1; +} + +static bool is_valid_unit_collection(const bUnitCollection *usys) +{ + return usys != NULL && usys->units[0].name != NULL; +} + +static const bUnitDef *get_preferred_unit_if_used(int type, PreferredUnits units) +{ + const bUnitCollection *usys = unit_get_system(units.system, type); + if (!is_valid_unit_collection(usys)) return NULL; + + int max_offset = usys->length - 1; + + switch (type) + { + case B_UNIT_LENGTH: + case B_UNIT_AREA: + case B_UNIT_VOLUME: + if (units.length == USER_UNIT_ADAPTIVE) return NULL; + return usys->units + MIN2(units.length, max_offset); + case B_UNIT_MASS: + if (units.mass == USER_UNIT_ADAPTIVE) return NULL; + return usys->units + MIN2(units.mass, max_offset); + case B_UNIT_TIME: + if (units.time == USER_UNIT_ADAPTIVE) return NULL; + return usys->units + MIN2(units.time, max_offset); + case B_UNIT_ROTATION: + if (units.rotation == 0) return usys->units + 0; + else if (units.rotation == USER_UNIT_ROT_RADIANS) return usys->units + 3; + break; + default: + break; + } + return NULL; +} + +/* Return the length of the generated string. */ +static size_t unit_as_string_main( + char *str, int len_max, double value, int prec, + int type, bool split, bool pad, PreferredUnits units) +{ + const bUnitCollection *usys = unit_get_system(units.system, type); + const bUnitDef *main_unit = NULL; + + if (!is_valid_unit_collection(usys)) { + usys = &buDummyCollection; } + else { + main_unit = get_preferred_unit_if_used(type, units); + } + + if (split && unit_should_be_split(type)) { + int length = unit_as_string_splitted(str, len_max, value, prec, usys, main_unit); + /* failed when length is negative, fallback to no split */ + if (length >= 0) return length; + } + + return unit_as_string(str, len_max, value, prec, usys, main_unit, pad ? ' ' : '\0'); +} + +size_t bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad) +{ + PreferredUnits units; + units.system = system; + units.rotation = 0; + units.length = USER_UNIT_ADAPTIVE; + units.mass = USER_UNIT_ADAPTIVE; + units.time = USER_UNIT_ADAPTIVE; + return unit_as_string_main(str, len_max, value, prec, type, split, pad, units); +} - return unit_as_string(str, len_max, value, prec, usys, NULL, pad ? ' ' : '\0'); +size_t bUnit_AsString2(char *str, int len_max, double value, int prec, int type, const UnitSettings *settings, bool pad) +{ + bool do_split = (settings->flag & USER_UNIT_OPT_SPLIT) != 0; + PreferredUnits units = preferred_units_from_UnitSettings(settings); + return unit_as_string_main(str, len_max, value, prec, type, do_split, pad, units); } BLI_INLINE bool isalpha_or_utf8(const int ch) @@ -631,6 +731,27 @@ static const bUnitDef *unit_detect_from_str(const bUnitCollection *usys, const c return unit; } +bool bUnit_ContainsUnit(const char *str, int system, int type) +{ + const bUnitCollection *usys = unit_get_system(system, type); + if (!is_valid_unit_collection(usys)) return false; + + for (int i = 0; i < usys->length; i++) { + if (unit_find(str, usys->units + i)) { + return true; + } + } + return false; +} + +double bUnit_PreferredUnitScalar(const struct UnitSettings *settings, int type) +{ + PreferredUnits units = preferred_units_from_UnitSettings(settings); + const bUnitDef *unit = get_preferred_unit_if_used(type, units); + if (unit == NULL) return 1.0; + else return unit->scalar; +} + /* make a copy of the string that replaces the units with numbers * this is used before parsing * This is only used when evaluating user input and can afford to be a bit slower @@ -649,16 +770,13 @@ static const bUnitDef *unit_detect_from_str(const bUnitCollection *usys, const c bool bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type) { const bUnitCollection *usys = unit_get_system(system, type); + if (!is_valid_unit_collection(usys)) return false; const bUnitDef *unit = NULL, *default_unit; double scale_pref_base = scale_pref; char str_tmp[TEMP_STR_SIZE]; bool changed = false; - if (usys == NULL || usys->units[0].name == NULL) { - return changed; - } - /* make lowercase */ BLI_str_tolower_ascii(str, len_max); @@ -824,6 +942,11 @@ int bUnit_GetBaseUnit(const void *usys_pt) return ((bUnitCollection *)usys_pt)->base_unit; } +int bUnit_GetBaseUnitOfType(int system, int type) +{ + return unit_get_system(system, type)->base_unit; +} + const char *bUnit_GetName(const void *usys_pt, int index) { return ((bUnitCollection *)usys_pt)->units[index].name; @@ -837,3 +960,8 @@ double bUnit_GetScaler(const void *usys_pt, int index) { return ((bUnitCollection *)usys_pt)->units[index].scalar; } + +bool bUnit_IsSuppressed(const void *usys_pt, int index) +{ + return (((bUnitCollection *)usys_pt)->units[index].flag & B_UNIT_DEF_SUPPRESS) != 0; +}
\ No newline at end of file diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index c32cfa433bd..7d059d6f996 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -85,6 +85,7 @@ #include "BKE_object.h" #include "BKE_cloth.h" #include "BKE_key.h" +#include "BKE_unit.h" #include "BLT_translation.h" @@ -2132,4 +2133,15 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + if (!MAIN_VERSION_ATLEAST(bmain, 280, 25)) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + UnitSettings *unit = &scene->unit; + if (unit->system != USER_UNIT_NONE) { + unit->length_unit = bUnit_GetBaseUnitOfType(scene->unit.system, B_UNIT_LENGTH); + unit->mass_unit = bUnit_GetBaseUnitOfType(scene->unit.system, B_UNIT_MASS); + } + unit->time_unit = bUnit_GetBaseUnitOfType(USER_UNIT_NONE, B_UNIT_TIME); + } + } } diff --git a/source/blender/draw/modes/edit_mesh_mode_text.c b/source/blender/draw/modes/edit_mesh_mode_text.c index e81f181d636..d2bfc75a2bf 100644 --- a/source/blender/draw/modes/edit_mesh_mode_text.c +++ b/source/blender/draw/modes/edit_mesh_mode_text.c @@ -66,7 +66,6 @@ void DRW_edit_mesh_mode_text_measure_stats( uchar col[4] = {0, 0, 0, 255}; /* color of the text to draw */ float area; /* area of the face */ float grid = unit->system ? unit->scale_length : v3d->grid; - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0; const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0; /* when 2 edge-info options are enabled, space apart */ @@ -118,9 +117,9 @@ void DRW_edit_mesh_mode_text_measure_stats( } if (unit->system) { - numstr_len = bUnit_AsString( - numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3, - unit->system, B_UNIT_LENGTH, do_split, false); + numstr_len = bUnit_AsString2( + numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3, + B_UNIT_LENGTH, unit, false); } else { numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); @@ -231,10 +230,10 @@ void DRW_edit_mesh_mode_text_measure_stats( mul_m4_v3(ob->obmat, vmid); if (unit->system) { - numstr_len = bUnit_AsString( + numstr_len = bUnit_AsString2( numstr, sizeof(numstr), (double)(area * unit->scale_length * unit->scale_length), - 3, unit->system, B_UNIT_AREA, do_split, false); + 3, B_UNIT_AREA, unit, false); } else { numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area); diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h index 00558a3a787..f674a0d87f9 100644 --- a/source/blender/editors/include/ED_numinput.h +++ b/source/blender/editors/include/ED_numinput.h @@ -88,4 +88,6 @@ bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event #define NUM_MODAL_INCREMENT_UP 18 #define NUM_MODAL_INCREMENT_DOWN 19 +bool user_string_to_number(bContext *C, const char *str, const struct UnitSettings *unit, int type, double *r_value); + #endif /* __ED_NUMINPUT_H__ */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 312d41b796d..dcd09f0d4b0 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -80,6 +80,7 @@ #include "BPY_extern.h" #include "ED_screen.h" +#include "ED_numinput.h" #include "IMB_colormanagement.h" @@ -2177,7 +2178,6 @@ void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, bool pad, int float_precision) { UnitSettings *unit = but->block->unit; - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; int unit_type = UI_but_unit_type_get(but); int precision; @@ -2194,9 +2194,9 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va precision = float_precision; } - bUnit_AsString( + bUnit_AsString2( str, len_max, ui_get_but_scale_unit(but, value), precision, - unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type), do_split, pad); + RNA_SUBTYPE_UNIT_VALUE(unit_type), unit, pad); } static float ui_get_but_step_unit(uiBut *but, float step_default) @@ -2406,27 +2406,13 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size) return str; } -#ifdef WITH_PYTHON - static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *r_value) { - char str_unit_convert[256]; - const int unit_type = UI_but_unit_type_get(but); - - BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); - - /* ugly, use the draw string to get the value, - * this could cause problems if it includes some text which resolves to a unit */ - bUnit_ReplaceString( - str_unit_convert, sizeof(str_unit_convert), but->drawstr, - ui_get_but_scale_unit(but, 1.0), but->block->unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); - - return BPY_execute_string_as_number(C, NULL, str_unit_convert, true, r_value); + const UnitSettings *unit = but->block->unit; + int type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); + return user_string_to_number(C, str, unit, type, r_value); } -#endif /* WITH_PYTHON */ - - bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value) { bool ok = false; diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c index fb125a3845b..1dae076f930 100644 --- a/source/blender/editors/interface/interface_eyedropper_depth.c +++ b/source/blender/editors/interface/interface_eyedropper_depth.c @@ -158,9 +158,6 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my); Scene *scene = CTX_data_scene(C); - UnitSettings *unit = &scene->unit; - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; - ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); @@ -199,9 +196,9 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, *r_depth = len_v3v3(view_co, co_align); - bUnit_AsString(ddr->name, sizeof(ddr->name), - (double)*r_depth, - 4, unit->system, B_UNIT_LENGTH, do_split, false); + bUnit_AsString2( + ddr->name, sizeof(ddr->name), (double)*r_depth, + 4, B_UNIT_LENGTH, &scene->unit, false); } else { BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name)); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 62f66334516..a3bd1b26a01 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -164,8 +164,6 @@ static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *rul static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, char *numstr, size_t numstr_size, int prec) { - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; - if (ruler_item->flag & RULERITEM_USE_ANGLE) { const float ruler_angle = angle_v3v3v3(ruler_item->co[0], ruler_item->co[1], @@ -175,9 +173,9 @@ static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle)); } else { - bUnit_AsString(numstr, numstr_size, - (double)ruler_angle, - prec, unit->system, B_UNIT_ROTATION, do_split, false); + bUnit_AsString2( + numstr, numstr_size, (double)ruler_angle, + prec, B_UNIT_ROTATION, unit, false); } } else { @@ -188,9 +186,9 @@ static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len); } else { - bUnit_AsString(numstr, numstr_size, - (double)(ruler_len * unit->scale_length), - prec, unit->system, B_UNIT_LENGTH, do_split, false); + bUnit_AsString2( + numstr, numstr_size, (double)(ruler_len * unit->scale_length), + prec, B_UNIT_LENGTH, unit, false); } } } diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index d6637c2209e..ae57700653a 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -159,7 +159,6 @@ static void ruler_item_active_set(RulerInfo *ruler_info, RulerItem *ruler_item) static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, char *numstr, size_t numstr_size, int prec) { - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; if (ruler_item->flag & RULERITEM_USE_ANGLE) { const float ruler_angle = angle_v3v3v3(ruler_item->co[0], @@ -170,9 +169,9 @@ static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle)); } else { - bUnit_AsString(numstr, numstr_size, - (double)ruler_angle, - prec, unit->system, B_UNIT_ROTATION, do_split, false); + bUnit_AsString2( + numstr, numstr_size, (double)ruler_angle, + prec, B_UNIT_ROTATION, unit, false); } } else { @@ -183,9 +182,9 @@ static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len); } else { - bUnit_AsString(numstr, numstr_size, - (double)(ruler_len * unit->scale_length), - prec, unit->system, B_UNIT_LENGTH, do_split, false); + bUnit_AsString2( + numstr, numstr_size, (double)(ruler_len * unit->scale_length), + prec, B_UNIT_LENGTH, unit, false); } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 55fa1fb78c6..61a80e900e1 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4671,12 +4671,12 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ dist = len_v3(vec); if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) { - const bool do_split = (t->scene->unit.flag & USER_UNIT_OPT_SPLIT) != 0; int i; for (i = 0; i < 3; i++) { - bUnit_AsString(&tvec[NUM_STR_REP_LEN * i], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length, - 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, true); + bUnit_AsString2( + &tvec[NUM_STR_REP_LEN * i], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length, + 4, B_UNIT_LENGTH, &t->scene->unit, true); } } else { @@ -4687,9 +4687,9 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ } if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) { - const bool do_split = (t->scene->unit.flag & USER_UNIT_OPT_SPLIT) != 0; - bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system, - B_UNIT_LENGTH, do_split, false); + bUnit_AsString2( + distvec, sizeof(distvec), dist * t->scene->unit.scale_length, + 4, B_UNIT_LENGTH, &t->scene->unit, false); } else if (dist > 1e10f || dist < -1e10f) { /* prevent string buffer overflow */ diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 98e7e5ba897..887c85300d1 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -254,6 +254,32 @@ static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf return true; } +bool user_string_to_number(bContext *C, const char *str, const UnitSettings *unit, int type, double *r_value) +{ +#ifdef WITH_PYTHON + double unit_scale = BKE_scene_unit_scale(unit, type, 1.0); + if (!bUnit_ContainsUnit(str, unit->system, type)) { + int success = BPY_execute_string_as_number(C, NULL, str, true, r_value); + *r_value *= bUnit_PreferredUnitScalar(unit, type); + *r_value /= unit_scale; + return success; + } + else { + char str_unit_convert[256]; + BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); + bUnit_ReplaceString( + str_unit_convert, sizeof(str_unit_convert), str, + unit_scale, unit->system, type); + + return BPY_execute_string_as_number(C, NULL, str_unit_convert, true, r_value); + } +#else + *r_value = atof(str); + return true; +#endif +} + + static bool editstr_is_simple_numinput(const char ascii) { if (ascii >= '0' && ascii <= '9') { @@ -519,38 +545,18 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) /* At this point, our value has changed, try to interpret it with python (if str is not empty!). */ if (n->str[0]) { const float val_prev = n->val[idx]; - double val; -#ifdef WITH_PYTHON Scene *sce = CTX_data_scene(C); - char str_unit_convert[NUM_STR_REP_LEN * 6]; /* Should be more than enough! */ - const char *default_unit = NULL; - /* Use scale_length if needed! */ - const float fac = (float)BKE_scene_unit_scale(&sce->unit, n->unit_type[idx], 1.0); - - /* Make radian default unit when needed. */ - if (n->unit_use_radians && n->unit_type[idx] == B_UNIT_ROTATION) { - default_unit = "r"; - } - - BLI_strncpy(str_unit_convert, n->str, sizeof(str_unit_convert)); - - bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), default_unit, fac, - n->unit_sys, n->unit_type[idx]); + double val; + int success = user_string_to_number(C, n->str, &sce->unit, n->unit_type[idx], &val); - /* Note: with angles, we always get values as radians here... */ - if (BPY_execute_string_as_number(C, NULL, str_unit_convert, false, &val)) { + if (success) { n->val[idx] = (float)val; n->val_flag[idx] &= ~NUM_INVALID; } else { n->val_flag[idx] |= NUM_INVALID; - } -#else /* Very unlikely, but does not harm... */ - val = atof(n->str); - n->val[idx] = (float)val; - UNUSED_VARS(C); -#endif /* WITH_PYTHON */ + } #ifdef USE_FAKE_EDIT diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 0bc0fb28d2f..15e8f950686 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1387,6 +1387,12 @@ typedef struct UnitSettings { char system; /* imperial, metric etc */ char system_rotation; /* not implemented as a proper unit system yet */ short flag; + + char length_unit; + char mass_unit; + char time_unit; + + char pad[5]; } UnitSettings; /* ------------------------------------------- */ @@ -2156,6 +2162,7 @@ typedef enum eGPencil_Selectmode_types { /* UnitSettings */ +#define USER_UNIT_ADAPTIVE 0xFF /* UnitSettings.system */ #define USER_UNIT_NONE 0 #define USER_UNIT_METRIC 1 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 81e144925be..11d56206d6e 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -515,6 +515,7 @@ const EnumPropertyItem rna_enum_transform_orientation_items[] = { #include "BKE_animsys.h" #include "BKE_freestyle.h" #include "BKE_gpencil.h" +#include "BKE_unit.h" #include "ED_info.h" #include "ED_node.h" @@ -2015,6 +2016,68 @@ const EnumPropertyItem *rna_TransformOrientation_itemf( return item; } +static const EnumPropertyItem *get_unit_enum_items(int system, int type, bool *r_free) +{ + const void *usys; + int len; + bUnit_GetSystem(system, type, &usys, &len); + + EnumPropertyItem *items = NULL; + int totitem = 0; + + EnumPropertyItem adaptive = { 0 }; + adaptive.identifier = "ADAPTIVE"; + adaptive.name = "Adaptive"; + adaptive.value = USER_UNIT_ADAPTIVE; + RNA_enum_item_add(&items, &totitem, &adaptive); + + for (int i = 0; i < len; i++) { + if (!bUnit_IsSuppressed(usys, i)) { + EnumPropertyItem tmp = { 0 }; + tmp.identifier = bUnit_GetName(usys, i); + tmp.name = bUnit_GetNameDisplay(usys, i); + tmp.value = i; + RNA_enum_item_add(&items, &totitem, &tmp); + } + } + + *r_free = true; + return items; +} + +const EnumPropertyItem *rna_get_length_unit_items( + bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) +{ + UnitSettings *units = ptr->data; + return get_unit_enum_items(units->system, B_UNIT_LENGTH, r_free); +} + +const EnumPropertyItem *rna_get_mass_unit_items( + bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) +{ + UnitSettings *units = ptr->data; + return get_unit_enum_items(units->system, B_UNIT_MASS, r_free); +} + +const EnumPropertyItem *rna_get_time_unit_items( + bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) +{ + UnitSettings *units = ptr->data; + return get_unit_enum_items(units->system, B_UNIT_TIME, r_free); +} + +static void rna_unit_system_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) +{ + UnitSettings *unit = &scene->unit; + if (unit->system == USER_UNIT_NONE) { + unit->length_unit = USER_UNIT_ADAPTIVE; + unit->mass_unit = USER_UNIT_ADAPTIVE; + } + else { + unit->length_unit = bUnit_GetBaseUnitOfType(unit->system, B_UNIT_LENGTH); + unit->mass_unit = bUnit_GetBaseUnitOfType(unit->system, B_UNIT_MASS); + } +} #else @@ -2915,7 +2978,7 @@ static void rna_def_statvis(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_EditMesh_update"); } -static void rna_def_unit_settings(BlenderRNA *brna) +static void rna_def_unit_settings(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -2940,7 +3003,7 @@ static void rna_def_unit_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "system", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, unit_systems); RNA_def_property_ui_text(prop, "Unit System", "The unit system to use for button display"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_WINDOW, "rna_unit_system_update"); prop = RNA_def_property(srna, "system_rotation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rotation_units); @@ -2948,7 +3011,9 @@ static void rna_def_unit_settings(BlenderRNA *brna) RNA_def_property_update(prop, NC_WINDOW, NULL); prop = RNA_def_property(srna, "scale_length", PROP_FLOAT, PROP_UNSIGNED); - RNA_def_property_ui_text(prop, "Unit Scale", "Scale to use when converting between blender units and dimensions"); + RNA_def_property_ui_text(prop, "Unit Scale", "Scale to use when converting between blender units and dimensions." + " When working at microscopic or astronomical scale, a small or large unit scale" + " respectively can be used to avoid numerical precision problems"); RNA_def_property_range(prop, 0.00001, 100000.0); RNA_def_property_ui_range(prop, 0.001, 100.0, 0.1, 6); RNA_def_property_update(prop, NC_WINDOW, NULL); @@ -2957,6 +3022,24 @@ static void rna_def_unit_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_UNIT_OPT_SPLIT); RNA_def_property_ui_text(prop, "Separate Units", "Display units in pairs (e.g. 1m 0cm)"); RNA_def_property_update(prop, NC_WINDOW, NULL); + + prop = RNA_def_property(srna, "length_unit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_get_length_unit_items"); + RNA_def_property_ui_text(prop, "Length Unit", "Unit that will be used to display length values"); + RNA_def_property_update(prop, NC_WINDOW, NULL); + + prop = RNA_def_property(srna, "mass_unit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_get_mass_unit_items"); + RNA_def_property_ui_text(prop, "Mass Unit", "Unit that will be used to display mass values"); + RNA_def_property_update(prop, NC_WINDOW, NULL); + + prop = RNA_def_property(srna, "time_unit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_get_time_unit_items"); + RNA_def_property_ui_text(prop, "Time Unit", "Unit that will be used to display time values"); + RNA_def_property_update(prop, NC_WINDOW, NULL); } void rna_def_view_layer_common(StructRNA *srna, int scene) |