diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_vertex.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 9e9e0f441f7..f45c244f675 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -415,7 +415,12 @@ static float wpaint_undo_lock_relative( /* In auto-normalize mode, or when there is no unlocked weight, * compute based on locked weight. */ if (auto_normalize || free_weight <= 0.0f) { - weight *= (1.0f - locked_weight); + if (locked_weight < 1.0f - VERTEX_WEIGHT_LOCK_EPSILON) { + weight *= (1.0f - locked_weight); + } + else { + weight = 0; + } } else { /* When dealing with full unlocked weight, don't paint, as it is always displayed as 1. */ @@ -518,7 +523,7 @@ static bool do_weight_paint_normalize_all_locked(MDeformVert *dvert, return false; } - if (lock_weight >= 1.0f) { + if (lock_weight >= 1.0f - VERTEX_WEIGHT_LOCK_EPSILON) { /* locked groups make it impossible to fully normalize, * zero out what we can and return false */ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { @@ -779,7 +784,25 @@ static void do_weight_paint_vertex_single( index_mirr = vgroup_mirr = -1; } - if (wp->flag & VP_FLAG_VGROUP_RESTRICT) { + /* Check if painting should create new deform weight entries. */ + bool restrict_to_existing = (wp->flag & VP_FLAG_VGROUP_RESTRICT) != 0; + + if (wpi->do_lock_relative || wpi->do_auto_normalize) { + /* Without do_lock_relative only dw_rel_locked is reliable, while dw_rel_free may be fake 0. */ + dw_rel_free = BKE_defvert_total_selected_weight(dv, wpi->defbase_tot, wpi->vgroup_unlocked); + dw_rel_locked = BKE_defvert_total_selected_weight(dv, wpi->defbase_tot, wpi->vgroup_locked); + CLAMP(dw_rel_locked, 0.0f, 1.0f); + + /* Do not create entries if there is not enough free weight to paint. + * This logic is the same as in wpaint_undo_lock_relative and auto-normalize. */ + if (wpi->do_auto_normalize || dw_rel_free <= 0.0f) { + if (dw_rel_locked >= 1.0f - VERTEX_WEIGHT_LOCK_EPSILON) { + restrict_to_existing = true; + } + } + } + + if (restrict_to_existing) { dw = BKE_defvert_find_index(dv, wpi->active.index); } else { @@ -827,10 +850,6 @@ static void do_weight_paint_vertex_single( /* Handle weight caught up in locked defgroups for Lock Relative. */ if (wpi->do_lock_relative) { - dw_rel_free = BKE_defvert_total_selected_weight(dv, wpi->defbase_tot, wpi->vgroup_unlocked); - dw_rel_locked = BKE_defvert_total_selected_weight(dv, wpi->defbase_tot, wpi->vgroup_locked); - CLAMP(dw_rel_locked, 0.0f, 1.0f); - weight_cur = BKE_defvert_calc_lock_relative_weight(weight_cur, dw_rel_locked, dw_rel_free); } @@ -1658,6 +1677,10 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo wpd->lock_flags, wpd->vgroup_validmap, wpd->active.index) && (!wpd->do_multipaint || BKE_object_defgroup_check_lock_relative_multi( defbase_tot, wpd->lock_flags, defbase_sel, defbase_tot_sel))) { + wpd->do_lock_relative = true; + } + + if (wpd->do_lock_relative || (ts->auto_normalize && wpd->lock_flags && !wpd->do_multipaint)) { bool *unlocked = MEM_dupallocN(wpd->vgroup_validmap); if (wpd->lock_flags) { @@ -1668,7 +1691,6 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo } wpd->vgroup_unlocked = unlocked; - wpd->do_lock_relative = true; } if (wpd->do_multipaint && ts->auto_normalize) { @@ -2383,7 +2405,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P wpi.vgroup_unlocked = wpd->vgroup_unlocked; wpi.do_flip = RNA_boolean_get(itemptr, "pen_flip"); wpi.do_multipaint = wpd->do_multipaint; - wpi.do_auto_normalize = ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL)); + wpi.do_auto_normalize = ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL) && + (wpi.do_multipaint || wpi.vgroup_validmap[wpi.active.index])); wpi.do_lock_relative = wpd->do_lock_relative; wpi.is_normalized = wpi.do_auto_normalize || wpi.do_lock_relative; wpi.brush_alpha_value = brush_alpha_value; |