diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2012-03-02 14:30:11 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2012-03-02 14:30:11 +0400 |
commit | 47a1c7e5aab44ce24814f0c421315a50ab7a6147 (patch) | |
tree | 5cc949c4d8f98a44bb68b07c004fa851289bc88e /source/blender | |
parent | 979a80e74398dd68f013b8ca1f18b2653a4f6338 (diff) |
Fix [#30419] Median wrongly setting lattice vertex weights.
In fact, the same bug affected curves' weights too. Now using the same method as for setting mesh edges' crease and bevel weights. Also factorized/simplified that part of code by defining a new utility func computing the scale factor.
Also greatly simplified UI code in same v3d_editvertex_buts() function, was really over-complicated (this fixes btw a few minor UI bugs in the transform editmode panel, like missing tips, etc.).
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_buttons.c | 299 |
1 files changed, 148 insertions, 151 deletions
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 3c4e3b6009c..6ac400b3e43 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -131,6 +131,36 @@ typedef struct { float *defweightp; } TransformProperties; +/* Helper function to compute a median changed value, + * when the value should be clamped in [0.0, 1.0]. + * Returns either 0.0, 1.0 (both can be applied directly), a positive scale factor + * for scale down, or a negative one for scale up. + */ +static float compute_scale_factor(const float ve_median, const float median) +{ + if (ve_median <= 0.0f) + return 0.0f; + else if (ve_median >= 1.0f) + return 1.0f; + else { + /* Scale value to target median. */ + float median_new = ve_median; + float median_orig = ve_median - median; /* Previous median value. */ + + /* In case of floating point error. */ + CLAMP(median_orig, 0.0f, 1.0f); + CLAMP(median_new, 0.0f, 1.0f); + + if (median_new <= median_orig) { + /* Scale down. */ + return median_new / median_orig; + } + else { + /* Scale up, negative to indicate it... */ + return -(1.0f - median_new) / (1.0f - median_orig); + } + } +} /* is used for both read and write... */ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) @@ -312,78 +342,45 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float uiBut *but; memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); - + uiBlockBeginAlign(block); if (tot==1) { uiDefBut(block, LABEL, 0, "Vertex:", 0, 150, 200, 20, NULL, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - - but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 130, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 110, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 90, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - - if (totw==1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 70, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); - uiBlockEndAlign(block); - if (totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, ""); - if (totradius) { - if (totradius==1) uiDefButR(block, NUM, 0, "Radius", 0, 20, 200, 20, &radius_ptr, "radius", 0, 0.0, 100.0, 10, 3, NULL); - else uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); - } - } - else { - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); - uiBlockEndAlign(block); - if (totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); - if (totradius) { - if (totradius==1) uiDefButR(block, NUM, 0, "Radius", 0, 40, 200, 20, &radius_ptr, "radius", 0, 0.0, 100.0, 10, 3, NULL); - else uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 40, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); - } - } } else { uiDefBut(block, LABEL, 0, "Median:", 0, 150, 200, 20, NULL, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 130, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 110, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 90, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); - uiButSetUnitType(but, PROP_UNIT_LENGTH); - if (totw==tot) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 70, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); - uiBlockEndAlign(block); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); - uiBlockEndAlign(block); - if (totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal"); - if (totradius) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); - uiBlockEndAlign(block); - } - else { - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); - uiBlockEndAlign(block); - if (totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "Weight is used for SoftBody Goal"); - if (totradius) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); - uiBlockEndAlign(block); - } + } + + uiBlockBeginAlign(block); + + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 130, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 110, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 90, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); + uiButSetUnitType(but, PROP_UNIT_LENGTH); + + if (totw==tot) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 70, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); + } + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); + uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); + uiBlockEndAlign(block); + + if (totweight == 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "Weight is used for SoftBody Goal"); + } + else if (totweight > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Weight:", 0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "Weight is used for SoftBody Goal"); + } + + if (totradius == 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); + } + else if (totradius > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); } if (totedge==1) { @@ -395,6 +392,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Bevel Weight:", 0, 20, 200, 20, &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, ""); } + uiBlockEndAlign(block); + uiBlockEndAlign(block); + } else { // apply memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median)); @@ -430,56 +430,37 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (median[3] != 0.0f) { BMEdge *eed; - const float fixed_crease= (ve_median[3] <= 0.0f ? 0.0f : (ve_median[3] >= 1.0f ? 1.0f : FLT_MAX)); - - if (fixed_crease != FLT_MAX) { - /* simple case */ + const float sca = compute_scale_factor(ve_median[3], median[3]); + if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (!crease) break; - - *crease= fixed_crease; + if (!crease) + break; + *crease = sca; } } } - else { - /* scale crease to target median */ - float median_new= ve_median[3]; - float median_orig= ve_median[3] - median[3]; /* previous median value */ - - /* incase of floating point error */ - CLAMP(median_orig, 0.0f, 1.0f); - CLAMP(median_new, 0.0f, 1.0f); - - if (median_new < median_orig) { - /* scale down */ - const float sca= median_new / median_orig; - - BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - - if (!crease) break; - - *crease *= sca; - CLAMP(*crease, 0.0f, 1.0f); - } + else if (sca > 0.0f) { + BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); + if (!crease) + break; + *crease *= sca; + CLAMP(*crease, 0.0f, 1.0f); } } - else { - /* scale up */ - const float sca= (1.0f - median_new) / (1.0f - median_orig); - - BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (!crease) break; - - *crease = 1.0f - ((1.0f - *crease) * sca); - CLAMP(*crease, 0.0f, 1.0f); - } + } + else { + BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); + if (!crease) + break; + *crease = 1.0f + ((1.0f - *crease) * sca); + CLAMP(*crease, 0.0f, 1.0f); } } } @@ -487,55 +468,37 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (median[6] != 0.0f) { BMEdge *eed; - const float fixed_bweight = (ve_median[6] <= 0.0f ? 0.0f : (ve_median[6] >= 1.0f ? 1.0f : FLT_MAX)); - - if (fixed_bweight != FLT_MAX) { - /* simple case */ + const float sca = compute_scale_factor(ve_median[6], median[6]); + if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (!bweight) break; - - *bweight = fixed_bweight; + if (!bweight) + break; + *bweight = sca; } } } - else { - /* scale crease to target median */ - float median_new = ve_median[6]; - float median_orig = ve_median[6] - median[6]; /* previous median value */ - - /* incase of floating point error */ - CLAMP(median_orig, 0.0f, 1.0f); - CLAMP(median_new, 0.0f, 1.0f); - - if (median_new < median_orig) { - /* scale down */ - const float sca = median_new / median_orig; - - BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (!bweight) break; - - *bweight *= sca; - CLAMP(*bweight, 0.0f, 1.0f); - } + else if (sca > 0.0f) { + BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); + if (!bweight) + break; + *bweight *= sca; + CLAMP(*bweight, 0.0f, 1.0f); } } - else { - /* scale up */ - const float sca = (1.0f - median_new) / (1.0f - median_orig); - - BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (!bweight) break; - - *bweight = 1.0f - ((1.0f - *bweight) * sca); - CLAMP(*bweight, 0.0f, 1.0f); - } + } + else { + BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); + if (!bweight) + break; + *bweight = 1.0f + ((1.0f - *bweight) * sca); + CLAMP(*bweight, 0.0f, 1.0f); } } } @@ -549,6 +512,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BezTriple *bezt; int a; ListBase *nurbs= curve_editnurbs(cu); + const float scale_w = compute_scale_factor(ve_median[4], median[4]); nu= nurbs->first; while (nu) { @@ -560,7 +524,18 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float add_v3_v3(bezt->vec[0], median); add_v3_v3(bezt->vec[1], median); add_v3_v3(bezt->vec[2], median); - bezt->weight+= median[4]; + + if (median[4] != 0.0f) { + if (ELEM(scale_w, 0.0f, 1.0f)) { + bezt->weight = scale_w; + } + else { + bezt->weight = scale_w > 0.0f ? bezt->weight * scale_w : + 1.0f + ((1.0f - bezt->weight) * scale_w); + CLAMP(bezt->weight, 0.0f, 1.0f); + } + } + bezt->radius+= median[5]; } else { @@ -581,7 +556,18 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (bp->f1 & SELECT) { add_v3_v3(bp->vec, median); bp->vec[3]+= median[3]; - bp->weight+= median[4]; + + if (median[4] != 0.0f) { + if (ELEM(scale_w, 0.0f, 1.0f)) { + bp->weight = scale_w; + } + else { + bp->weight = scale_w > 0.0f ? bp->weight * scale_w : + 1.0f + ((1.0f - bp->weight) * scale_w); + CLAMP(bp->weight, 0.0f, 1.0f); + } + } + bp->radius+= median[5]; } bp++; @@ -597,13 +583,24 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Lattice *lt= ob->data; BPoint *bp; int a; - + const float scale_w = compute_scale_factor(ve_median[4], median[4]); + a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; bp= lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { add_v3_v3(bp->vec, median); - bp->weight+= median[4]; + + if (median[4] != 0.0f) { + if (ELEM(scale_w, 0.0f, 1.0f)) { + bp->weight = scale_w; + } + else { + bp->weight = scale_w > 0.0f ? bp->weight * scale_w : + 1.0f + ((1.0f - bp->weight) * scale_w); + CLAMP(bp->weight, 0.0f, 1.0f); + } + } } bp++; } |