Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/unit.c246
1 files changed, 113 insertions, 133 deletions
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index ce4ed05b10e..5af24152972 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -101,7 +101,7 @@ typedef struct bUnitDef {
const char *identifier;
double scalar;
- /** not used yet, needed for converting temperature */
+ /** Not used yet, needed for converting temperature. */
double bias;
int flag;
} bUnitDef;
@@ -139,7 +139,7 @@ typedef struct bUnitCollection {
static struct bUnitDef buDummyDef[] = { {"", NULL, "", NULL, NULL, NULL, 1.0, 0.0}, NULL_UNIT};
static struct bUnitCollection buDummyCollection = {buDummyDef, 0, 0, sizeof(buDummyDef)};
-/* Lengths */
+/* Lengths. */
static struct bUnitDef buMetricLenDef[] = {
{"kilometer", "kilometers", "km", NULL, "Kilometers", "KILOMETERS", UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
{"hectometer", "hectometers", "hm", NULL, "100 Meters", "HECTOMETERS", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
@@ -226,7 +226,7 @@ static struct bUnitCollection buImperialVolCollection = {buImperialVolDef, 4, 0,
/* Mass. */
static struct bUnitDef buMetricMassDef[] = {
- {"ton", "tonnes", "ton", "t", "Tonnes", "TONNES", UN_SC_MTON, 0.0, B_UNIT_DEF_NONE},
+ {"ton", "tonnes", "ton", "t", "Tonnes", "TONNES", UN_SC_MTON, 0.0, B_UNIT_DEF_NONE},
{"quintal", "quintals", "ql", "q", "100 Kilograms", "QUINTALS", UN_SC_QL, 0.0, B_UNIT_DEF_SUPPRESS},
{"kilogram", "kilograms", "kg", NULL, "Kilograms", "KILOGRAMS", UN_SC_KG, 0.0, B_UNIT_DEF_NONE}, /* Base unit. */
{"hectogram", "hectograms", "hg", NULL, "Hectograms", "HECTOGRAMS", UN_SC_HG, 0.0, B_UNIT_DEF_SUPPRESS},
@@ -372,11 +372,10 @@ static const struct bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = {
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
};
-/* internal, has some option not exposed */
static const bUnitCollection *unit_get_system(int system, int type)
{
assert((system > -1) && (system < UNIT_SYSTEM_TOT) && (type > -1) && (type < B_UNIT_TYPE_TOT));
- return bUnitSystems[system][type]; /* select system to use, metric/imperial/other? */
+ return bUnitSystems[system][type]; /* Select system to use: metric/imperial/other? */
}
static const bUnitDef *unit_default(const bUnitCollection *usys)
@@ -389,10 +388,9 @@ static const bUnitDef *unit_best_fit(double value,
const bUnitDef *unit_start,
int suppress)
{
- const bUnitDef *unit;
double value_abs = value > 0.0 ? value : -value;
- for (unit = unit_start ? unit_start : usys->units; unit->name; unit++) {
+ for (const bUnitDef *unit = unit_start ? unit_start : usys->units; unit->name; unit++) {
if (suppress && (unit->flag & B_UNIT_DEF_SUPPRESS)) {
continue;
@@ -423,13 +421,7 @@ static void unit_dual_convert(double value,
double *r_value_b,
const bUnitDef *main_unit)
{
- const bUnitDef *unit;
- if (main_unit) {
- unit = main_unit;
- }
- else {
- unit = unit_best_fit(value, usys, NULL, 1);
- }
+ const bUnitDef *unit = (main_unit) ? main_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);
@@ -447,21 +439,17 @@ static size_t unit_as_string(char *str,
const bUnitDef *unit,
char pad)
{
- double value_conv;
- size_t 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 = unit_default(usys);
- }
- else {
- unit = unit_best_fit(value, usys, NULL, 1);
+ if (unit == NULL) {
+ if (value == 0.0) {
+ /* Use the default units since there is no way to convert. */
+ unit = unit_default(usys);
+ }
+ else {
+ unit = unit_best_fit(value, usys, NULL, 1);
+ }
}
- value_conv = value / unit->scalar;
+ double value_conv = value / unit->scalar;
/* Adjust precision to expected number of significant digits.
* Note that here, we shall not have to worry about very big/small numbers, units are expected
@@ -470,14 +458,14 @@ static size_t unit_as_string(char *str,
CLAMP(prec, 0, 6);
/* Convert to a string. */
- len = BLI_snprintf_rlen(str, len_max, "%.*f", prec, value_conv);
+ size_t len = BLI_snprintf_rlen(str, len_max, "%.*f", prec, value_conv);
/* Add unit prefix and strip zeros. */
/* Replace trailing zero's with spaces so the number
* is less complicated but alignment in a button won't
* jump about while dragging. */
- i = len - 1;
+ size_t i = len - 1;
if (prec > 0) {
while (i > 0 && str[i] == '0') { /* 4.300 -> 4.3 */
@@ -546,13 +534,11 @@ static size_t unit_as_string_split_pair(char *str,
{
const bUnitDef *unit_a, *unit_b;
double value_a, value_b;
-
unit_dual_convert(value, usys, &unit_a, &unit_b, &value_a, &value_b, main_unit);
/* 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');
+ size_t i = unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0');
prec -= integer_digits_d(value_a / unit_b->scalar) -
integer_digits_d(value_b / unit_b->scalar);
@@ -680,41 +666,44 @@ BLI_INLINE bool isalpha_or_utf8(const int ch)
static const char *unit_find_str(const char *str, const char *substr, bool case_sensitive)
{
- if (substr && substr[0] != '\0') {
- while (true) {
- /* Unit detection is case insensitive. */
- const char *str_found;
- if (case_sensitive) {
- str_found = strstr(str, substr);
- }
- else {
- str_found = BLI_strcasestr(str, substr);
- }
+ if (substr == NULL || substr[0] == '\0') {
+ return NULL;
+ }
- if (str_found) {
- /* Previous char cannot be a letter. */
- if (str_found == str ||
- /* Weak unicode support!, so "µm" won't match up be replaced by "m"
- * since non ascii utf8 values will NEVER return true */
- isalpha_or_utf8(*BLI_str_prev_char_utf8(str_found)) == 0) {
- /* Next char cannot be alphanum. */
- int len_name = strlen(substr);
-
- if (!isalpha_or_utf8(*(str_found + len_name))) {
- return str_found;
- }
- }
- /* If str_found is not a valid unit, we have to check further in the string... */
- for (str_found++; isalpha_or_utf8(*str_found); str_found++) {
- /* Pass. */
+ while (true) {
+ /* Unit detection is case insensitive. */
+ const char *str_found;
+ if (case_sensitive) {
+ str_found = strstr(str, substr);
+ }
+ else {
+ str_found = BLI_strcasestr(str, substr);
+ }
+
+ if (str_found) {
+ /* Previous char cannot be a letter. */
+ if (str_found == str ||
+ /* Weak unicode support!, so "µm" won't match up be replaced by "m"
+ * since non ascii utf8 values will NEVER return true */
+ isalpha_or_utf8(*BLI_str_prev_char_utf8(str_found)) == 0) {
+ /* Next char cannot be alphanum. */
+ int len_name = strlen(substr);
+
+ if (!isalpha_or_utf8(*(str_found + len_name))) {
+ return str_found;
}
- str = str_found;
}
- else {
- break;
+ /* If str_found is not a valid unit, we have to check further in the string... */
+ for (str_found++; isalpha_or_utf8(*str_found); str_found++) {
+ /* Pass. */
}
+ str = str_found;
+ }
+ else {
+ break;
}
}
+
return NULL;
}
@@ -863,54 +852,56 @@ static int unit_scale_str(char *str,
const char *replace_str,
bool case_sensitive)
{
- char *str_found;
-
- if ((len_max > 0) && (str_found = (char *)unit_find_str(str, replace_str, case_sensitive))) {
- /* XXX - investigate, does not respect len_max properly. */
+ if (len_max < 0) {
+ return 0;
+ }
- int len, len_num, len_name, len_move, found_ofs;
+ /* XXX - investigate, does not respect len_max properly. */
+ char *str_found = (char *)unit_find_str(str, replace_str, case_sensitive);
- found_ofs = (int)(str_found - str);
+ if (str_found == NULL) {
+ return 0;
+ }
- len = strlen(str);
+ int found_ofs = (int)(str_found - str);
- len_name = strlen(replace_str);
- len_move = (len - (found_ofs + len_name)) + 1; /* 1+ to copy the string terminator. */
+ int len = strlen(str);
- /* "#" Removed later */
- len_num = BLI_snprintf(str_tmp, TEMP_STR_SIZE, "*%.9g" SEP_STR, unit->scalar / scale_pref);
+ int len_name = strlen(replace_str);
+ int len_move = (len - (found_ofs + len_name)) + 1; /* 1+ to copy the string terminator. */
- if (len_num > len_max) {
- len_num = len_max;
- }
+ /* "#" Removed later */
+ int len_num = BLI_snprintf(str_tmp, TEMP_STR_SIZE, "*%.9g" SEP_STR, unit->scalar / scale_pref);
- if (found_ofs + len_num + len_move > len_max) {
- /* Can't move the whole string, move just as much as will fit. */
- len_move -= (found_ofs + len_num + len_move) - len_max;
- }
+ if (len_num > len_max) {
+ len_num = len_max;
+ }
- if (len_move > 0) {
- /* Resize the last part of the string.
- * May grow or shrink the string. */
- memmove(str_found + len_num, str_found + len_name, len_move);
- }
+ if (found_ofs + len_num + len_move > len_max) {
+ /* Can't move the whole string, move just as much as will fit. */
+ len_move -= (found_ofs + len_num + len_move) - len_max;
+ }
- if (found_ofs + len_num > len_max) {
- /* Not even the number will fit into the string, only copy part of it. */
- len_num -= (found_ofs + len_num) - len_max;
- }
+ if (len_move > 0) {
+ /* Resize the last part of the string.
+ * May grow or shrink the string. */
+ memmove(str_found + len_num, str_found + len_name, len_move);
+ }
- if (len_num > 0) {
- /* It's possible none of the number could be copied in. */
- memcpy(str_found, str_tmp, len_num); /* Without the string terminator. */
- }
+ if (found_ofs + len_num > len_max) {
+ /* Not even the number will fit into the string, only copy part of it. */
+ len_num -= (found_ofs + len_num) - len_max;
+ }
- /* Since the null terminator wont be moved if the stringlen_max
- * was not long enough to fit everything in it. */
- str[len_max - 1] = '\0';
- return found_ofs + len_num;
+ if (len_num > 0) {
+ /* It's possible none of the number could be copied in. */
+ memcpy(str_found, str_tmp, len_num); /* Without the string terminator. */
}
- return 0;
+
+ /* Since the null terminator wont be moved if the stringlen_max
+ * was not long enough to fit everything in it. */
+ str[len_max - 1] = '\0';
+ return found_ofs + len_num;
}
static int unit_replace(
@@ -947,17 +938,19 @@ static bool unit_find(const char *str, const bUnitDef *unit)
return false;
}
+/**
+ * Try to find a default unit from current or previous string.
+ * This allows us to handle cases like 2 + 2mm, people would expect to get 4mm, not 2.002m!
+ * \note This does not handle corner cases like 2 + 2cm + 1 + 2.5mm... We can't support
+ * everything.
+ */
static const bUnitDef *unit_detect_from_str(const bUnitCollection *usys,
const char *str,
const char *str_prev)
{
- /* Try to find a default unit from current or previous string.
- * This allows us to handle cases like 2 + 2mm, people would expect to get 4mm, not 2.002m!
- * Note this does not handle corner cases like 2 + 2cm + 1 + 2.5mm... We can't support
- * everything. */
const bUnitDef *unit = NULL;
- /* see which units the new value has. */
+ /* See which units the new value has. */
for (unit = usys->units; unit->name; unit++) {
if (unit_find(str, unit)) {
break;
@@ -1032,7 +1025,6 @@ bool bUnit_ReplaceString(
return false;
}
- const bUnitDef *unit = NULL, *default_unit;
double scale_pref_base = scale_pref;
char str_tmp[TEMP_STR_SIZE];
bool changed = false;
@@ -1041,7 +1033,7 @@ bool bUnit_ReplaceString(
changed |= unit_distribute_negatives(str, len_max);
/* Try to find a default unit from current or previous string. */
- default_unit = unit_detect_from_str(usys, str, str_prev);
+ const bUnitDef *default_unit = unit_detect_from_str(usys, str, str_prev);
/* We apply the default unit to the whole expression (default unit is now the reference
* '1.0' one). */
@@ -1059,40 +1051,32 @@ bool bUnit_ReplaceString(
return changed;
}
- for (unit = usys->units; unit->name; unit++) {
+ for (const bUnitDef *unit = usys->units; unit->name; unit++) {
/* In case there are multiple instances. */
while (unit_replace(str, len_max, str_tmp, scale_pref_base, unit)) {
changed = true;
}
}
- unit = NULL;
- {
- /* Try other unit systems now, so we can evaluate imperial when metric is set for eg. */
- /* Note that checking other systems at that point means we do not support their units as
- * 'default' one. In other words, when in metrics, typing '2+2in' will give 2 meters 2 inches,
- * not 4 inches. I do think this is the desired behavior!
- */
- const bUnitCollection *usys_iter;
- int system_iter;
-
- for (system_iter = 0; system_iter < UNIT_SYSTEM_TOT; system_iter++) {
- if (system_iter != system) {
- usys_iter = unit_get_system(system_iter, type);
- if (usys_iter) {
- for (unit = usys_iter->units; unit->name; unit++) {
- int ofs = 0;
- /* In case there are multiple instances. */
- while (
- (ofs = unit_replace(str + ofs, len_max - ofs, str_tmp, scale_pref_base, unit))) {
- changed = true;
- }
+ /* Try other unit systems now, so we can evaluate imperial when metric is set for eg. */
+ /* Note that checking other systems at that point means we do not support their units as
+ * 'default' one. In other words, when in metrics, typing '2+2in' will give 2 meters 2 inches,
+ * not 4 inches. I do think this is the desired behavior!
+ */
+ for (int system_iter = 0; system_iter < UNIT_SYSTEM_TOT; system_iter++) {
+ if (system_iter != system) {
+ const bUnitCollection *usys_iter = unit_get_system(system_iter, type);
+ if (usys_iter) {
+ for (const bUnitDef *unit = usys_iter->units; unit->name; unit++) {
+ int ofs = 0;
+ /* In case there are multiple instances. */
+ while ((ofs = unit_replace(str + ofs, len_max - ofs, str_tmp, scale_pref_base, unit))) {
+ changed = true;
}
}
}
}
}
- unit = NULL;
/* Replace # with add sign when there is no operator between it and the next number.
*
@@ -1128,10 +1112,8 @@ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int syste
{
const bUnitCollection *usys = unit_get_system(system, type);
- const bUnitDef *unit;
-
/* Find and substitute all units. */
- for (unit = usys->units; unit->name; unit++) {
+ for (const bUnitDef *unit = usys->units; unit->name; unit++) {
if (len_max > 0 && unit->name_alt) {
const bool case_sensitive = (unit->flag & B_UNIT_DEF_CASE_SENSITIVE) != 0;
const char *found = unit_find_str(orig_str, unit->name_short, case_sensitive);
@@ -1169,13 +1151,12 @@ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int syste
double bUnit_ClosestScalar(double value, int system, int type)
{
const bUnitCollection *usys = unit_get_system(system, type);
- const bUnitDef *unit;
if (usys == NULL) {
return -1;
}
- unit = unit_best_fit(value, usys, NULL, 1);
+ const bUnitDef *unit = unit_best_fit(value, usys, NULL, 1);
if (unit == NULL) {
return -1;
}
@@ -1193,7 +1174,6 @@ double bUnit_BaseScalar(int system, int type)
return 1.0;
}
-/* External access. */
bool bUnit_IsValid(int system, int type)
{
return !(system < 0 || system > UNIT_SYSTEM_TOT || type < 0 || type > B_UNIT_TYPE_TOT);