diff options
author | Gaia Clary <gaia.clary@machinimatrix.org> | 2013-06-15 14:18:16 +0400 |
---|---|---|
committer | Gaia Clary <gaia.clary@machinimatrix.org> | 2013-06-15 14:18:16 +0400 |
commit | 6a60bf2f03fa2b78b8ae6e6a7501d0a20d58dbdf (patch) | |
tree | 8d08a5270812118f274abfc83e635a8e231f8465 /source/blender/editors/space_view3d/view3d_buttons.c | |
parent | 790e8b6eda0c3478fe52853c381fca46bd264dff (diff) |
Added support for Vertex Weight panel in weight Paint Mode
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_buttons.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_buttons.c | 285 |
1 files changed, 194 insertions, 91 deletions
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index f7edb2949bc..9420ed8d659 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -776,9 +776,22 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float #define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */ #define B_VGRP_PNL_COPY_SINGLE 16384 /* or greater */ -static void act_vert_def(Object *ob, BMVert **r_eve, MDeformVert **r_dvert) +static MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index) { - if (ob && ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) { + Mesh *me = ob->data; + int index = BKE_mesh_mselect_active_get(me, ME_VSEL); + if (r_index) *r_index = index; + if (index == -1 || me->dvert == NULL) { + return NULL; + } + else { + return me->dvert + index; + } +} + +static MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve) +{ + if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); @@ -789,44 +802,80 @@ static void act_vert_def(Object *ob, BMVert **r_eve, MDeformVert **r_dvert) if (ese && ese->htype == BM_VERT) { BMVert *eve = (BMVert *)ese->ele; if (r_eve) *r_eve = eve; - *r_dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - return; + return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); } } } if (r_eve) *r_eve = NULL; - *r_dvert = NULL; + return NULL; } -static void editvert_mirror_update(Object *ob, BMVert *eve, int def_nr, int index, - const int cd_dvert_offset) +static MDeformVert *ED_mesh_active_dvert_get_only(Object *ob) +{ + if (ob->type == OB_MESH) { + if (ob->mode & OB_MODE_EDIT) { + return ED_mesh_active_dvert_get_em(ob, NULL); + } + else { + return ED_mesh_active_dvert_get_ob(ob, NULL); + } + } + else { + return NULL; + } +} + +/* TODO, cache flip data to speedup calls within a loop. */ +static void mesh_defvert_mirror_update_internal(Object *ob, + MDeformVert *dvert_dst, MDeformVert *dvert_src, + const int def_nr) +{ + if (def_nr == -1) { + /* all vgroups, add groups where neded */ + int flip_map_len; + int *flip_map = defgroup_flip_map(ob, &flip_map_len, true); + defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true); + MEM_freeN(flip_map); + } + else { + /* single vgroup */ + MDeformWeight *dw = defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1)); + if (dw) { + dw->weight = defvert_find_weight(dvert_src, def_nr); + } + } +} + +static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx, + const int cd_dvert_offset) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMVert *eve_mirr; - eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, index); + eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, vidx); if (eve_mirr && eve_mirr != eve) { MDeformVert *dvert_src = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); MDeformVert *dvert_dst = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset); - if (dvert_dst) { - if (def_nr == -1) { - /* all vgroups, add groups where neded */ - int flip_map_len; - int *flip_map = defgroup_flip_map(ob, &flip_map_len, true); - defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true); - MEM_freeN(flip_map); - } - else { - /* single vgroup */ - MDeformWeight *dw = defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1)); - if (dw) { - dw->weight = defvert_find_weight(dvert_src, def_nr); - } - } - } + mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr); + } +} + +static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx) +{ + int vidx_mirr; + Mesh *me = ob->data; + if (vidx == -1) + return; + + vidx_mirr = mesh_get_x_mirror_vert(ob, vidx); + + if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) { + MDeformVert *dvert_src = &me->dvert[vidx]; + MDeformVert *dvert_dst = &me->dvert[vidx_mirr]; + mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr); } } @@ -834,100 +883,138 @@ static void vgroup_adjust_active(Object *ob, int def_nr) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; - const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - BMVert *eve_act; MDeformVert *dvert_act; - act_vert_def(ob, &eve_act, &dvert_act); - - if (dvert_act) { - if (me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve_act, def_nr, -1, cd_dvert_offset); + if (me->editflag & ME_EDIT_MIRROR_X) { + if (em) { + BMVert *eve_act; + dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act); + if (dvert_act) { + const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); + ED_mesh_defvert_mirror_update_em(ob, eve_act, def_nr, -1, cd_dvert_offset); + } + } + else { + int v_act; + dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); + if (dvert_act) { + ED_mesh_defvert_mirror_update_ob(ob, def_nr, v_act); + } + } } } static void vgroup_copy_active_to_sel(Object *ob) { - BMVert *eve_act; + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; MDeformVert *dvert_act; + int i; - act_vert_def(ob, &eve_act, &dvert_act); - - if (dvert_act == NULL) { - return; - } - else { - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; + if (em) { + BMIter iter; + BMVert *eve, *eve_act; const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - BMIter iter; - BMVert *eve; - MDeformVert *dvert; - int index = 0; + dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act); + if (dvert_act == NULL) { + return; + } - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve != eve_act) { - dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - if (dvert) { - defvert_copy(dvert, dvert_act); + MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + defvert_copy(dv, dvert_act); + if (me->editflag & ME_EDIT_MIRROR_X) { + ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset); + } + } + } + } + else { + MDeformVert *dv; + int v_act; - if (me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve, -1, index, cd_dvert_offset); + dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); + if (dvert_act == NULL) { + return; + } + dv = me->dvert; + for (i = 0; i < me->totvert; i++, dv++) { + if ((me->mvert[i].flag & SELECT) && dv != dvert_act) { + defvert_copy(dv, dvert_act); + if (me->editflag & ME_EDIT_MIRROR_X) { + ED_mesh_defvert_mirror_update_ob(ob, -1, i); } } - - index++; } } } static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) { - BMVert *eve_act; - MDeformVert *dv_act; + MDeformVert *dvert_act; - act_vert_def(ob, &eve_act, &dv_act); + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + float weight_act; + int i; - if (dv_act == NULL) { - return; - } - else { - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; + if (em) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); BMIter iter; - BMVert *eve; - MDeformVert *dv; - MDeformWeight *dw; - float weight_act; - int index = 0; + BMVert *eve, *eve_act; - dw = defvert_find_index(dv_act, def_nr); - - if (dw == NULL) + dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act); + if (dvert_act == NULL) { return; + } + weight_act = defvert_find_weight(dvert_act, def_nr); - weight_act = dw->weight; - - eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - for (index = 0; eve; eve = BM_iter_step(&iter), index++) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve != eve_act) { - dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - dw = defvert_find_index(dv, def_nr); + BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && (eve != eve_act)) { + MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + MDeformWeight *dw = defvert_find_index(dv, def_nr); if (dw) { dw->weight = weight_act; if (me->editflag & ME_EDIT_MIRROR_X) { - editvert_mirror_update(ob, eve, -1, index, cd_dvert_offset); + ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset); + } + } + } + } + + if (me->editflag & ME_EDIT_MIRROR_X) { + ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset); + } + } + else { + MDeformVert *dv; + int v_act; + + dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); + if (dvert_act == NULL) { + return; + } + weight_act = defvert_find_weight(dvert_act, def_nr); + + dv = me->dvert; + for (i = 0; i < me->totvert; i++, dv++) { + if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + if (dw) { + dw->weight = weight_act; + if (me->editflag & ME_EDIT_MIRROR_X) { + ED_mesh_defvert_mirror_update_ob(ob, -1, i); } } } } if (me->editflag & ME_EDIT_MIRROR_X) { - editvert_mirror_update(ob, eve_act, -1, -1, cd_dvert_offset); + ED_mesh_defvert_mirror_update_ob(ob, -1, v_act); } } } @@ -936,20 +1023,33 @@ static void vgroup_normalize_active(Object *ob) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; - const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - BMVert *eve_act; + int v_act; MDeformVert *dvert_act; - act_vert_def(ob, &eve_act, &dvert_act); + if (em) { + dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act); + } + else { + dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); + } - if (dvert_act == NULL) + if (dvert_act == NULL) { return; + } defvert_normalize(dvert_act); - if (me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve_act, -1, -1, cd_dvert_offset); + if (me->editflag & ME_EDIT_MIRROR_X) { + if (em) { + const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); + ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset); + } + else { + int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL); + ED_mesh_defvert_mirror_update_ob(ob, -1, v_act); + } + } } static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event) @@ -985,11 +1085,14 @@ static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt)) { Scene *scene = CTX_data_scene(C); Object *ob = OBACT; - MDeformVert *dvert_act; - - act_vert_def(ob, NULL, &dvert_act); + if ((ob->mode & OB_MODE_EDIT) || (ob->mode & OB_MODE_WEIGHT_PAINT)) { + MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob); + if (dvert_act) { + return (dvert_act->totweight != 0); + } + } - return dvert_act ? dvert_act->totweight : 0; + return false; } @@ -1001,7 +1104,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) MDeformVert *dv; - act_vert_def(ob, NULL, &dv); + dv = ED_mesh_active_dvert_get_only(ob); if (dv && dv->totweight) { uiLayout *col; @@ -1025,9 +1128,9 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) MDeformWeight *dw = defvert_find_index(dv, i); if (dw) { uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, dg->name, 0, yco, 180, 20, - &dw->weight, 0.0, 1.0, 1, 3, ""); + &dw->weight, 0.0, 1.0, 1, 3, ""); uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, "C", 180, yco, 20, 20, - NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts")); + NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts")); yco -= 20; } } |