Fix T41590: When scene scale is not 1.0, and units are "None," Blender assumes transl...
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 26 Aug 2014 10:04:24 +0000 (12:04 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 26 Aug 2014 10:31:08 +0000 (12:31 +0200)
Turned out there were several issues in handling of scale parameter by numinput.
Fixed that by factorizing more some code in common with 'usual' numbuttons eval code
(new `bUnit_getScaleUnit()` helper will return valid scaled value, depending on
given system and type).

Now, numinput behaves as expected - using default unit amended by scale in case no unit is given
(i.e. entering '20' with a scale of 0.01 will give you 20cm, and '20cm' as well!).

source/blender/blenkernel/BKE_unit.h
source/blender/blenkernel/intern/unit.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/include/ED_numinput.h
source/blender/editors/interface/interface.c
source/blender/editors/mesh/editmesh_bevel.c
source/blender/editors/mesh/editmesh_inset.c
source/blender/editors/mesh/editmesh_loopcut.c
source/blender/editors/transform/transform.c
source/blender/editors/util/numinput.c

index b351bc6fe3e28da8aaba26ba50affe19144ad7c2..c7847947d33f50164365f4808e2c6839d6c167f6 100644 (file)
@@ -31,6 +31,8 @@
 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) */
@@ -39,6 +41,11 @@ size_t  bUnit_AsString(char *str, int len_max, double value, int prec, int syste
 /* 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);
 
+/* Apply the needed correction factor to value, based on unit_type (only length-related are affected currently)
+ * and unit->scale_length.
+ */
+double bUnit_getScaleUnit(struct UnitSettings *unit, const int unit_type, double value);
+
 /* make string keyboard-friendly: 10µm --> 10um */
 void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type);
 
index 98b16b022cd7fc1fb96e454d5404639bc75d17bd..cdaf72aa1911c77b32ef49a9eaed2bf3b07c59a8 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "BKE_unit.h"  /* own include */
 
+#include "DNA_scene_types.h"
+
 #ifdef WIN32
 #  include "BLI_winstuff.h"
 #endif
@@ -789,6 +791,29 @@ double bUnit_BaseScalar(int system, int type)
        return unit_default(usys)->scalar;
 }
 
+double bUnit_getScaleUnit(UnitSettings *unit, const int unit_type, double value)
+{
+       if (unit->system == USER_UNIT_NONE) {
+               /* Never apply scale_length when not using a unit setting! */
+               return value;
+       }
+
+       switch (unit_type) {
+               case B_UNIT_LENGTH:
+                       return value * (double)unit->scale_length;
+               case B_UNIT_CAMERA:
+                       return value * (double)unit->scale_length;
+               case B_UNIT_AREA:
+                       return value * pow(unit->scale_length, 2);
+               case B_UNIT_VOLUME:
+                       return value * pow(unit->scale_length, 3);
+               case B_UNIT_MASS:
+                       return value * pow(unit->scale_length, 3);
+               default:
+                       return value;
+       }
+}
+
 /* external access */
 bool bUnit_IsValid(int system, int type)
 {
index 3313b7038e871425e95deea1ad3b3ab774595c4c..7cd47fab83a5e323cd7b321f6ec6b9725267d6ed 100644 (file)
@@ -637,7 +637,7 @@ static void ed_marker_move_update_header(bContext *C, wmOperator *op)
        }
 
        if (hasNumInput(&mm->num)) {
-               outputNumInput(&mm->num, str_offs, scene->unit.scale_length);
+               outputNumInput(&mm->num, str_offs, &scene->unit);
        }
        else if (use_time) {
                BLI_snprintf(str_offs, sizeof(str_offs), "%.2f", FRA2TIME(offs));
index 4e96ed0c7e7ce0704022547356b968f00aa3719d..f9a22429fc237b53c91407585d2ce87e5692f992 100644 (file)
@@ -64,6 +64,8 @@ enum {
        /* (1 << 9) and above are reserved for internal flags! */
 };
 
+struct UnitSettings;
+
 /*********************** NumInput ********************************/
 
 /* There are important things to note here for code using numinput:
@@ -76,7 +78,7 @@ enum {
  */
 
 void initNumInput(NumInput *n);
-void outputNumInput(NumInput *n, char *str, const float scale_length);
+void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings);
 bool hasNumInput(const NumInput *n);
 bool applyNumInput(NumInput *n, float *vec);
 bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event);
index b4c2a431570e48291c28860283012794b82448fa..698d3f0a585f614f3f891efdb6f53b4b0e333f3b 100644 (file)
@@ -1942,27 +1942,13 @@ static double ui_get_but_scale_unit(uiBut *but, double value)
        UnitSettings *unit = but->block->unit;
        int unit_type = uiButGetUnitType(but);
 
-       if (unit_type == PROP_UNIT_LENGTH) {
-               return value * (double)unit->scale_length;
-       }
-       else if (unit_type == PROP_UNIT_CAMERA) {
-               return value * (double)unit->scale_length;
-       }
-       else if (unit_type == PROP_UNIT_AREA) {
-               return value * pow(unit->scale_length, 2);
-       }
-       else if (unit_type == PROP_UNIT_VOLUME) {
-               return value * pow(unit->scale_length, 3);
-       }
-       else if (unit_type == PROP_UNIT_MASS) {
-               return value * pow(unit->scale_length, 3);
-       }
-       else if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */
+       /* Time unit is a bit special, not handled by bUnit_getScaleUnit() for now. */
+       if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */
                Scene *scene = CTX_data_scene(but->block->evil_C);
                return FRA2TIME(value);
        }
        else {
-               return value;
+               return bUnit_getScaleUnit(unit, RNA_SUBTYPE_UNIT_VALUE(unit_type), value);
        }
 }
 
index 545ecbaebe4c2a13c3033a8d60191f387794b6ec..48d5113a279789c253960b46139d112ced5ae2f5 100644 (file)
@@ -88,7 +88,7 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
                PropertyRNA *prop = RNA_struct_find_property(op->ptr, "offset_type");
 
                if (hasNumInput(&opdata->num_input)) {
-                       outputNumInput(&opdata->num_input, offset_str, sce->unit.scale_length);
+                       outputNumInput(&opdata->num_input, offset_str, &sce->unit);
                }
                else {
                        BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
index 4a552d0fbd329efe73dddaf0643b3aa620234071..a4942d016710699abadff09903fceed7a7d86fef 100644 (file)
@@ -90,7 +90,7 @@ static void edbm_inset_update_header(wmOperator *op, bContext *C)
        if (sa) {
                char flts_str[NUM_STR_REP_LEN * 2];
                if (hasNumInput(&opdata->num_input))
-                       outputNumInput(&opdata->num_input, flts_str, sce->unit.scale_length);
+                       outputNumInput(&opdata->num_input, flts_str, &sce->unit);
                else {
                        BLI_snprintf(flts_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "thickness"));
                        BLI_snprintf(flts_str + NUM_STR_REP_LEN, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "depth"));
index 3329d25d0f04a279b415577e04ae365b46deb8d9..59fbe739d030be2f2b03ffe4c550aefa81d92e8c 100644 (file)
@@ -686,7 +686,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
                char buf[64 + NUM_STR_REP_LEN * 2];
                char str_rep[NUM_STR_REP_LEN * 2];
                if (hasNumInput(&lcd->num)) {
-                       outputNumInput(&lcd->num, str_rep, sce->unit.scale_length);
+                       outputNumInput(&lcd->num, str_rep, &sce->unit);
                }
                else {
                        BLI_snprintf(str_rep, NUM_STR_REP_LEN, "%d", cuts);
index 58dee620a6114a9c4e320fabb96b3eaa410038af..a85801a621bfacc917d8edd0f37656f3ee46a5c6 100644 (file)
@@ -2872,7 +2872,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN * 2];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bend Angle: %s Radius: %s Alt, Clamp %s"),
                             &c[0], &c[NUM_STR_REP_LEN],
@@ -3040,7 +3040,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
                
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shear: %s %s"), c, t->proptext);
        }
@@ -3141,7 +3141,7 @@ static void headerResize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
        char tvec[NUM_STR_REP_LEN * 3];
        size_t ofs = 0;
        if (hasNumInput(&t->num)) {
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
        }
        else {
                BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
@@ -3555,7 +3555,7 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
                
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("To Sphere: %s %s"), c, t->proptext);
        }
@@ -3919,7 +3919,7 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
                
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                
                ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
        }
@@ -4023,7 +4023,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN * 2];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %s %s %s"),
                                    &c[0], &c[NUM_STR_REP_LEN], t->proptext);
@@ -4125,7 +4125,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]
        float dist;
 
        if (hasNumInput(&t->num)) {
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
                dist = len_v3(t->num.val);
        }
        else {
@@ -4373,7 +4373,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
        ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Shrink/Fatten:"), MAX_INFO_LEN - ofs);
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %s", c);
        }
        else {
@@ -4468,7 +4468,7 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
 
@@ -4546,7 +4546,7 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %s"), c);
        }
        else {
@@ -4624,7 +4624,7 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Feather Shrink/Fatten: %s"), c);
        }
        else {
@@ -4717,7 +4717,7 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
        }
@@ -4810,7 +4810,7 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                if (weight >= 0.0f)
                        BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
@@ -4888,7 +4888,7 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                if (crease >= 0.0f)
                        BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: +%s %s"), c, t->proptext);
@@ -4958,7 +4958,7 @@ static void headerBoneSize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
 {
        char tvec[NUM_STR_REP_LEN * 3];
        if (hasNumInput(&t->num)) {
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
        }
        else {
                BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
@@ -5095,7 +5095,7 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
                
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Envelope: %s"), c);
        }
        else {
@@ -6270,7 +6270,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                if (is_proportional) {
                        BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s"),
@@ -6793,7 +6793,7 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
        ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Vert Slide: "), MAX_INFO_LEN - ofs);
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
                ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs);
        }
        else {
@@ -6860,7 +6860,7 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %s"), &c[0]);
        }
@@ -6934,7 +6934,7 @@ static void applyBakeTime(TransInfo *t, const int mval[2])
        if (hasNumInput(&t->num)) {
                char c[NUM_STR_REP_LEN];
 
-               outputNumInput(&(t->num), c, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), c, &t->scene->unit);
 
                if (time >= 0.0f)
                        BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: +%s %s"), c, t->proptext);
@@ -7145,7 +7145,7 @@ static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN])
        size_t ofs = 0;
 
        if (hasNumInput(&t->num)) {
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
        }
        else {
                BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.0f, %.0f", val[0], val[1]);
@@ -7371,7 +7371,7 @@ static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
 
        /* if numeric input is active, use results from that, otherwise apply snapping to result */
        if (hasNumInput(&t->num)) {
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
        }
        else {
                const Scene *scene = t->scene;
@@ -7535,7 +7535,7 @@ static void headerTimeSlide(TransInfo *t, float sval, char str[MAX_INFO_LEN])
        char tvec[NUM_STR_REP_LEN * 3];
 
        if (hasNumInput(&t->num)) {
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
        }
        else {
                float minx = *((float *)(t->customData));
@@ -7683,7 +7683,7 @@ static void headerTimeScale(TransInfo *t, char str[MAX_INFO_LEN])
        char tvec[NUM_STR_REP_LEN * 3];
 
        if (hasNumInput(&t->num))
-               outputNumInput(&(t->num), tvec, t->scene->unit.scale_length);
+               outputNumInput(&(t->num), tvec, &t->scene->unit);
        else
                BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", t->values[0]);
 
index aade6d7b7e86ed62d5440c9ef18981c1eb77431d..4e8f6df66e1bdd4b4358652a8bb21f17490ec890 100644 (file)
@@ -87,7 +87,7 @@ void initNumInput(NumInput *n)
 }
 
 /* str must be NUM_STR_REP_LEN * (idx_max + 1) length. */
-void outputNumInput(NumInput *n, char *str, const float scale_length)
+void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings)
 {
        short j;
        const int ln = NUM_STR_REP_LEN;
@@ -98,7 +98,7 @@ void outputNumInput(NumInput *n, char *str, const float scale_length)
                const short i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j;
 
                /* Use scale_length if needed! */
-               const float fac = ELEM(n->unit_type[j], B_UNIT_LENGTH, B_UNIT_AREA, B_UNIT_VOLUME) ? scale_length : 1.0f;
+               const float fac = (float)bUnit_getScaleUnit(unit_settings, n->unit_type[j], 1.0);
 
                if (n->val_flag[i] & NUM_EDITED) {
                        /* Get the best precision, allows us to draw '10.0001' as '10' instead! */
@@ -478,26 +478,24 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
 #ifdef WITH_PYTHON
                Scene *sce = CTX_data_scene(C);
                double val;
-               float fac = 1.0f;
                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)bUnit_getScaleUnit(&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";
 
-               /* Use scale_length if needed! */
-               if (ELEM(n->unit_type[idx], B_UNIT_LENGTH, B_UNIT_AREA, B_UNIT_VOLUME))
-                       fac /= sce->unit.scale_length;
-
                BLI_strncpy(str_unit_convert, n->str, sizeof(str_unit_convert));
 
-               bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), default_unit, 1.0,
+               bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), default_unit, fac,
                                    n->unit_sys, n->unit_type[idx]);
 
                /* Note: with angles, we always get values as radians here... */
                if (BPY_button_exec(C, str_unit_convert, &val, false) != -1) {
-                       n->val[idx] = (float)val * fac;
+                       n->val[idx] = (float)val;
                        n->val_flag[idx] &= ~NUM_INVALID;
                }
                else {