diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_deform.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 23 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 34 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 18 |
4 files changed, 59 insertions, 20 deletions
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index a45893b00fa..e716a7bc8fe 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -68,6 +68,10 @@ void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *s float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup); float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup); +float BKE_defvert_multipaint_collective_weight( + const struct MDeformVert *dv, int defbase_tot, + const bool *defbase_sel, int defbase_tot_sel, bool do_autonormalize); + void defvert_copy(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src); void defvert_copy_subset(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const bool *vgroup_subset, const int vgroup_tot); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 1577a818180..dc7ef3055ee 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1373,30 +1373,13 @@ static void calc_weightpaint_vert_color( if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { /* Multi-Paint feature */ - bool was_a_nonzero = false; - unsigned int i; - - const MDeformWeight *dw = dv->dw; - for (i = dv->totweight; i != 0; i--, dw++) { - /* in multipaint, get the average if auto normalize is inactive - * get the sum if it is active */ - if (dw->def_nr < defbase_tot) { - if (defbase_sel[dw->def_nr]) { - if (dw->weight) { - input += dw->weight; - was_a_nonzero = true; - } - } - } - } + input = BKE_defvert_multipaint_collective_weight( + dv, defbase_tot, defbase_sel, defbase_sel_tot, (draw_flag & CALC_WP_AUTO_NORMALIZE) != 0); /* make it black if the selected groups have no weight on a vertex */ - if (was_a_nonzero == false) { + if (input == 0.0f) { show_alert_color = true; } - else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == false) { - input /= defbase_sel_tot; /* get the average */ - } } else { /* default, non tricky behavior */ diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index b09a0e92edb..135bf3e02ac 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -919,6 +919,40 @@ bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_ return true; } + +/** + * \return The representative weight of a multipaint group, used for + * viewport colors and actual painting. + * + * Result equal to sum of weights with auto normalize, and average otherwise. + * Value is not clamped, since painting relies on multiplication being always + * commutative with the collective weight function. + */ +float BKE_defvert_multipaint_collective_weight( + const struct MDeformVert *dv, int defbase_tot, + const bool *defbase_sel, int defbase_tot_sel, bool do_autonormalize) +{ + int i; + float total = 0.0f; + const MDeformWeight *dw = dv->dw; + + for (i = dv->totweight; i != 0; i--, dw++) { + /* in multipaint, get the average if auto normalize is inactive + * get the sum if it is active */ + if (dw->def_nr < defbase_tot) { + if (defbase_sel[dw->def_nr]) { + total += dw->weight; + } + } + } + + if (do_autonormalize == false) { + total /= defbase_tot_sel; + } + + return total; +} + /* -------------------------------------------------------------------- */ /* Defvert Array functions */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 140c86a206a..572d19dc55c 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1014,6 +1014,24 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even Brush *brush = BKE_paint_brush(&ts->wpaint->paint); const int vgroup_active = vc.obact->actdef - 1; float vgroup_weight = defvert_find_weight(&me->dvert[v_idx_best], vgroup_active); + + /* use combined weight in multipaint mode, since that's what is displayed to the user in the colors */ + if (ts->multipaint) { + int defbase_tot_sel; + const int defbase_tot = BLI_listbase_count(&vc.obact->defbase); + bool *defbase_sel = BKE_object_defgroup_selected_get(vc.obact, defbase_tot, &defbase_tot_sel); + + if (defbase_tot_sel > 1) { + vgroup_weight = BKE_defvert_multipaint_collective_weight( + &me->dvert[v_idx_best], defbase_tot, defbase_sel, defbase_tot_sel, ts->auto_normalize); + + /* if autonormalize is enabled, but weights are not normalized, the value can exceed 1 */ + CLAMP(vgroup_weight, 0.0f, 1.0f); + } + + MEM_freeN(defbase_sel); + } + BKE_brush_weight_set(vc.scene, brush, vgroup_weight); changed = true; } |