diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2016-01-21 00:03:15 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-01-21 00:03:47 +0300 |
commit | 5ef2ed23e1238e88db899f9d96a9463e6f725e35 (patch) | |
tree | be650ab88c4acc28416b091b23b2b4a77fa1986c /source | |
parent | 3c74968aa461ec986190d3197cb3517851ac98be (diff) |
Weight Paint: Make multi-paint & mirror work as if bone selection was symmetric
The simplest way of handling mirroring in multi-paint is creating a
uniform symmetric selection and relying on existing symmetric weights
to direct changes to the appropriate vertex groups. This already works
if mirror bones are selected manually, and can be made easier to use
by doing it implicitly.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_object_deform.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_deform.c | 24 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 5 |
4 files changed, 44 insertions, 5 deletions
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h index e956815d6f7..a0a885c2a04 100644 --- a/source/blender/blenkernel/BKE_object_deform.h +++ b/source/blender/blenkernel/BKE_object_deform.h @@ -68,6 +68,10 @@ bool *BKE_object_defgroup_lock_flags_get(struct Object *ob, const int defbase_to bool *BKE_object_defgroup_validmap_get(struct Object *ob, const int defbase_tot); bool *BKE_object_defgroup_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot); +void BKE_object_defgroup_mirror_selection( + struct Object *ob, int defbase_tot, const bool *selection, + bool *dg_flags_sel, int *r_dg_flags_sel_tot); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index dc7ef3055ee..656c403e542 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1322,7 +1322,8 @@ enum { CALC_WP_GROUP_USER_ALL = (1 << 2), CALC_WP_MULTIPAINT = (1 << 3), - CALC_WP_AUTO_NORMALIZE = (1 << 4) + CALC_WP_AUTO_NORMALIZE = (1 << 4), + CALC_WP_MIRROR_X = (1 << 5), }; typedef struct DMWeightColorInfo { @@ -1331,12 +1332,13 @@ typedef struct DMWeightColorInfo { } DMWeightColorInfo; -static int dm_drawflag_calc(const ToolSettings *ts) +static int dm_drawflag_calc(const ToolSettings *ts, const Mesh *me) { return ((ts->multipaint ? CALC_WP_MULTIPAINT : 0) | /* CALC_WP_GROUP_USER_ACTIVE or CALC_WP_GROUP_USER_ALL*/ (1 << ts->weightuser) | - (ts->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); + (ts->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0) | + ((me->editflag & ME_EDIT_MIRROR_X) ? CALC_WP_MIRROR_X : 0)); } static void weightpaint_color(unsigned char r_col[4], DMWeightColorInfo *dm_wcinfo, const float input) @@ -1442,6 +1444,10 @@ static void calc_weightpaint_vert_array( if (draw_flag & CALC_WP_MULTIPAINT) { defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot); + + if (defbase_sel_tot > 1 && (draw_flag & CALC_WP_MIRROR_X)) { + BKE_object_defgroup_mirror_selection(ob, defbase_tot, defbase_sel, defbase_sel, &defbase_sel_tot); + } } for (i = numVerts; i != 0; i--, wc++, dv++) { @@ -1716,7 +1722,7 @@ static void mesh_calc_modifiers( bool multires_applied = false; const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams; const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams; - const int draw_flag = dm_drawflag_calc(scene->toolsettings); + const int draw_flag = dm_drawflag_calc(scene->toolsettings, me); /* Generic preview only in object mode! */ const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT); @@ -2257,7 +2263,7 @@ static void editbmesh_calc_modifiers( int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); CDMaskLink *datamasks, *curr; const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; - int draw_flag = dm_drawflag_calc(scene->toolsettings); + int draw_flag = dm_drawflag_calc(scene->toolsettings, ob->data); // const bool do_mod_mcol = true; // (ob->mode == OB_MODE_OBJECT); #if 0 /* XXX Will re-enable this when we have global mod stack options. */ diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index e823f87468d..38391c84d29 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -596,6 +596,30 @@ bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_fl return dg_selection; } +/* Marks mirror vgroups in output and counts them. Output and counter assumed to be already initialized. + * Designed to be usable after BKE_object_defgroup_selected_get to extend selection to mirror. + */ +void BKE_object_defgroup_mirror_selection( + struct Object *ob, int defbase_tot, const bool *dg_selection, + bool *dg_flags_sel, int *r_dg_flags_sel_tot) +{ + bDeformGroup *defgroup; + unsigned int i, i_mirr; + + for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) { + if (dg_selection[i]) { + char name_flip[MAXBONENAME]; + + BKE_deform_flip_side_name(name_flip, defgroup->name, false); + i_mirr = STREQ(name_flip, defgroup->name) ? i : defgroup_name_index(ob, name_flip); + + if ((i_mirr >= 0 && i_mirr < defbase_tot) && (dg_flags_sel[i_mirr] == false)) { + dg_flags_sel[i_mirr] = true; + (*r_dg_flags_sel_tot) += 1; + } + } + } +} /** * Return the subset type of the Vertex Group Selection diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 5296b8b0034..878c8274255 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1017,6 +1017,11 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even bool *defbase_sel = BKE_object_defgroup_selected_get(vc.obact, defbase_tot, &defbase_tot_sel); if (defbase_tot_sel > 1) { + if (me->editflag & ME_EDIT_MIRROR_X) { + BKE_object_defgroup_mirror_selection( + vc.obact, defbase_tot, defbase_sel, defbase_sel, &defbase_tot_sel); + } + vgroup_weight = BKE_defvert_multipaint_collective_weight( &me->dvert[v_idx_best], defbase_tot, defbase_sel, defbase_tot_sel, ts->auto_normalize); |