[Bf-blender-cvs] [7c2d5eaacb7] master: Change weigth paint accumulate mechanics to fix problems with mirroring.

Alexander Gavrilov noreply at git.blender.org
Tue Oct 3 11:43:48 CEST 2017


Commit: 7c2d5eaacb70420b447107da29b114c9a62b294f
Author: Alexander Gavrilov
Date:   Tue Oct 3 12:28:07 2017 +0300
Branches: master
https://developer.blender.org/rB7c2d5eaacb70420b447107da29b114c9a62b294f

Change weigth paint accumulate mechanics to fix problems with mirroring.

Restoring weights is problematic when the stroke overlaps its mirror.
It's better to simply compute the new weight based on the saved data
rather than restoring things, and check that the change is monotonic.

This way is also closer to how things worked before the merge.

===================================================================

M	source/blender/editors/sculpt_paint/paint_vertex.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 9ab4e816010..98732e0bb9e 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -148,7 +148,7 @@ static bool vwpaint_use_normal(const VPaint *vp)
 }
 
 
-static void defweight_prev_restore_or_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index)
+static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index)
 {
 	MDeformVert *dv_curr = &dvert_curr[index];
 	MDeformVert *dv_prev = &dvert_prev[index];
@@ -156,9 +156,7 @@ static void defweight_prev_restore_or_init(MDeformVert *dvert_prev, MDeformVert
 		dv_prev->flag = 0;
 		defvert_copy(dv_prev, dv_curr);
 	}
-	else {
-		defvert_copy(dv_curr, dv_prev);
-	}
+	return dv_prev;
 }
 
 /* check if we can do partial updates and have them draw realtime
@@ -412,6 +410,16 @@ static float wpaint_blend(
 	return weight;
 }
 
+static float wpaint_clamp_monotonic(float oldval, float curval, float newval)
+{
+	if (newval < oldval)
+		return MIN2(newval, curval);
+	else if (newval > oldval)
+		return MAX2(newval, curval);
+	else
+		return newval;
+}
+
 /* ----------------------------------------------------- */
 
 static void do_weight_paint_normalize_all(MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap)
@@ -706,6 +714,7 @@ static void do_weight_paint_vertex_single(
 	bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
 
 	MDeformWeight *dw;
+	float weight_prev;
 
 	/* mirror vars */
 	int index_mirr;
@@ -729,14 +738,6 @@ static void do_weight_paint_vertex_single(
 		index_mirr = vgroup_mirr = -1;
 	}
 
-	if ((wp->paint.brush->flag & BRUSH_ACCUMULATE) == 0) {
-		struct MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
-		defweight_prev_restore_or_init(dvert_prev, me->dvert, index);
-		if (index_mirr != -1) {
-			defweight_prev_restore_or_init(dvert_prev, me->dvert, index_mirr);
-		}
-	}
-
 	if (wp->flag & VP_FLAG_VGROUP_RESTRICT) {
 		dw = defvert_find_index(dv, wpi->active.index);
 	}
@@ -781,14 +782,29 @@ static void do_weight_paint_vertex_single(
 		dw_mirr = NULL;
 	}
 
+	if ((wp->paint.brush->flag & BRUSH_ACCUMULATE) == 0) {
+		MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
+		MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index);
+		if (index_mirr != -1) {
+			defweight_prev_init(dvert_prev, me->dvert, index_mirr);
+		}
+
+		weight_prev = defvert_find_weight(dv_prev, wpi->active.index);
+	}
+	else {
+		weight_prev = dw->weight;
+	}
+
 	/* If there are no normalize-locks or multipaint,
 	 * then there is no need to run the more complicated checks */
 
 	{
-		dw->weight = wpaint_blend(
-		        wp, dw->weight, alpha, paintweight,
+		float new_weight = wpaint_blend(
+		        wp, weight_prev, alpha, paintweight,
 		        wpi->brush_alpha_value, wpi->do_flip);
 
+		dw->weight = wpaint_clamp_monotonic(weight_prev, dw->weight, new_weight);
+
 		/* WATCH IT: take care of the ordering of applying mirror -> normalize,
 		 * can give wrong results [#26193], least confusing if normalize is done last */
 
@@ -859,7 +875,7 @@ static void do_weight_paint_vertex_multi(
 	MDeformVert *dv_mirr = NULL;
 
 	/* weights */
-	float curw, neww, change, curw_mirr, change_mirr;
+	float curw, oldw, neww, change, curw_mirr, change_mirr;
 
 	/* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */
 	if (me->editflag & ME_EDIT_MIRROR_X) {
@@ -873,14 +889,6 @@ static void do_weight_paint_vertex_multi(
 		}
 	}
 
-	if ((wp->paint.brush->flag & BRUSH_ACCUMULATE) == 0) {
-		struct MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
-		defweight_prev_restore_or_init(dvert_prev, me->dvert, index);
-		if (index_mirr != -1) {
-			defweight_prev_restore_or_init(dvert_prev, me->dvert, index_mirr);
-		}
-	}
-
 	/* compute weight change by applying the brush to average or sum of group weights */
 	curw = BKE_defvert_multipaint_collective_weight(
 	        dv, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->do_auto_normalize);
@@ -890,7 +898,22 @@ static void do_weight_paint_vertex_multi(
 		return;
 	}
 
-	neww = wpaint_blend(wp, curw, alpha, paintweight, wpi->brush_alpha_value, wpi->do_flip);
+	if ((wp->paint.brush->flag & BRUSH_ACCUMULATE) == 0) {
+		MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
+		MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index);
+		if (index_mirr != -1) {
+			defweight_prev_init(dvert_prev, me->dvert, index_mirr);
+		}
+
+		oldw = BKE_defvert_multipaint_collective_weight(
+			dv_prev, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->do_auto_normalize);
+	}
+	else {
+		oldw = curw;
+	}
+
+	neww = wpaint_blend(wp, oldw, alpha, paintweight, wpi->brush_alpha_value, wpi->do_flip);
+	neww = wpaint_clamp_monotonic(oldw, curw, neww);
 
 	change = neww / curw;



More information about the Bf-blender-cvs mailing list