[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37487] branches/soc-2011-radish/source/ blender/editors/sculpt_paint/paint_vertex.c: Made Multi-Paint support vertices containing locked groups

Jason Hays jason_hays22 at mymail.eku.edu
Tue Jun 14 21:11:01 CEST 2011


Revision: 37487
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37487
Author:   jason_hays22
Date:     2011-06-14 19:11:01 +0000 (Tue, 14 Jun 2011)
Log Message:
-----------
Made Multi-Paint support vertices containing locked groups
Changed locking system to check the amount of space in unlocked groups ahead of time.

Modified Paths:
--------------
    branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c

Modified: branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c
===================================================================
--- branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c	2011-06-14 19:00:52 UTC (rev 37486)
+++ branches/soc-2011-radish/source/blender/editors/sculpt_paint/paint_vertex.c	2011-06-14 19:11:01 UTC (rev 37487)
@@ -1098,17 +1098,54 @@
 	return NULL;
 }
 /* Jason was here */
+static int has_locked_group_selected(int defcnt, char *selection, char *flags) {
+	int i;
+	for(i = 0; i < defcnt; i++) {
+		if(selection[i] && flags[i]) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+/* Jason was here */
+static float get_change_allowed_from_unlocked_bone_groups(MDeformVert *dvert, int def_nr, int defcnt, char *selection, int pos, char *flags, char *bone_groups) {
+	int i;
+	float allowed_totchange = 0.0f;
+	for(i = 0; i < defcnt; i++) {
+		if(def_nr != i && bone_groups[i] && !selection[i] && !flags[i]) {
+			// positive change
+			if(pos == 1) {
+				allowed_totchange -= 1-defvert_verify_index(dvert, i)->weight;
+			} else {//negative change
+				allowed_totchange -= defvert_verify_index(dvert, i)->weight;
+			}
+		}
+	}
+	return allowed_totchange;
+}
+/* Jason was here */
+static int has_unselected_unlocked_bone_group(int defcnt, char *selection, int selected, char *flags, char *bone_groups) {
+	int i;
+	if(defcnt == selected) {
+		return FALSE;
+	}
+	for(i = 0; i < defcnt; i++) {
+		if(bone_groups[i] && !selection[i] && !flags[i]) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
 /*
-The idea behind this function is to get the difference in weight for pnt_dw,
+The idea behind this function is to get the difference in weight,
 and to redistribute that weight to the unlocked groups
 (if it has to, then it will put some/all of the change
 back onto the original group)
 */
-static void redistribute_weight_change(Object *ob, MDeformVert *dvert, int index, MDeformWeight *pnt_dw, float oldw, char* flags, int defcnt, char *map)
+static void redistribute_weight_change(Object *ob, MDeformVert *dvert, int index, int def_nr, int multipaint, char *selection, int selected, float change_left, char* flags, int defcnt, char *map)
 {
 	int i;
 	float old_change_left;
-	float change_left = oldw - pnt_dw->weight;
 	// make sure the redistribution the same per loop.
 	float change;
 	char was_a_change;
@@ -1116,7 +1153,7 @@
 	char* change_status = MEM_mallocN(defcnt*sizeof(char), "defflags");
 	MDeformWeight *dw;
 	for(i = 0; i < defcnt; i++) {
-		if(pnt_dw->def_nr == i || !map[i]) {
+		if(def_nr == i || (multipaint && selection[i]) || !map[i]) {
 			change_status[i] = FALSE;
 		} else {
 			change_status[i] = !flags[i];
@@ -1135,19 +1172,19 @@
 		do {
 			was_a_change = FALSE;
 			for(i = 0; i < dvert->totweight; i++) {
-				dw = (dvert->dw+i);
+				dw = defvert_verify_index(dvert, i);
 				if(!change_status[dw->def_nr]) {
 					continue;
 				}
 
-				dw->weight += change;
 				old_change_left = change_left;
 				change_left -= change;
 				// sign change?
 				if(change_left!=0 && change_left/fabs(change_left) != old_change_left/fabs(old_change_left)) {
-					dw->weight -= change;
 					change_left = old_change_left;
 					break;
+				} else {
+					dw->weight += change;
 				}
 				if(dw->weight >= 1.0f) {
 
@@ -1163,53 +1200,57 @@
 					groups_left_that_can_change--;
 					change_status[dw->def_nr] = FALSE;
 				}
-				was_a_change = TRUE;
 				/* if it was too small, don't get stuck in an infinite loop! */
-				if(old_change_left == change_left) {
-					change *= 2;
+				if(old_change_left != change_left) {
+					was_a_change = TRUE;
 				}
 			}
 		} while(groups_left_that_can_change > 0 && change_left != 0.0f && was_a_change);
 	}
+	// now it should never have any left, unless there are precision problems
 	// add any remaining change back to the original weight
-	pnt_dw->weight += change_left;
+	if(change_left > 0) {
+		if(multipaint) {
+			for(i = 0; i < defcnt; i++) {
+				if(selection[i]) {
+					defvert_find_index(dvert, i)->weight += change_left/selected;
+				}
+			}
+		} else {
+			defvert_find_index(dvert, def_nr)->weight += change_left;
+		}
+	}
 	MEM_freeN(change_status);
 }
 /* Jason */
 /* get the change that is needed to get a valid multipaint (if it can)*/
-static float get_valid_multipaint_change(MDeformVert *dvert, MDeformWeight *dw, float oldw, char* validmap, char* bone_groups, char* selection, int defcnt) {
+static float get_valid_multipaint_change(MDeformVert *dvert, float neww, float oldw, float allowed_totchange, char* validmap, char* bone_groups, char* selection, int defcnt) {
 	int i;
 	float change;
+	float tchange;
 	MDeformWeight *w;
 	float val;
 	// see if you need to do anything (if it is normalized)
 	float sumw = 0.0f;
-	if(oldw == 0 || !selection) {
+	if(allowed_totchange == 0 || oldw == 0 || !selection) {
 		return FALSE;
 	}
-	change = dw->weight/oldw;
+	change = neww/oldw;
 	if(change == 1 || !change) {
 		return FALSE;
 	}
-	dw->weight = oldw;
-	// make sure all selected dverts exist
+	// see if all changes are valid before doing any
 	for(i = 0; i < defcnt; i++) {
-		if(selection[i]){
-			defvert_verify_index(dvert, i);
-		}
-	}
-	// see if all changes are valid before doing any
-	for(i = 0; i < dvert->totweight; i++) {
-		w = (dvert->dw+i);
-		if(!selection[w->def_nr] || !bone_groups[w->def_nr]) {
+		if(!selection[i] || !bone_groups[i]) {
 			continue;
 		}
+		w = defvert_verify_index(dvert, i);
 		// already reached the cap
 		if(change > 1 && w->weight==1) {
 			return FALSE;
 		}
 		if(w->weight == 0) {
-			if(selection[w->def_nr]) {
+			if(selection[i]) {
 				return FALSE;
 			}
 			continue;
@@ -1230,44 +1271,80 @@
 	if(validmap && sumw == 1.0f) {
 		return FALSE;
 	}
+	if(allowed_totchange>0) {
+		for(i = 0; i < defcnt; i++) {
+			w = defvert_find_index(dvert, i);
+			if(w && selection[i] && bone_groups[i]) {
+				tchange += w->weight*change;
+			}
+		}
+		tchange = tchange/allowed_totchange;
+		if(tchange < change) {
+			change = tchange;
+		}
+	}
 	return change;
 }
-static void multipaint_vgroups(MDeformVert *dvert, float change, char* bone_groups, char* selection) {
+static float multipaint_vgroups(MDeformVert *dvert, float change, char* bone_groups, char* selection) {
 	int i;
+	float totchange = 0.0f;
+	float old;
 	MDeformWeight *w;
 	for(i = 0; i < dvert->totweight; i++) {
 		w = (dvert->dw+i);
 		if(!bone_groups[w->def_nr] || !selection[w->def_nr] || w->weight == 0) {
 			continue;
 		}
+		old = w->weight;
 		w->weight *= change;
+		totchange += w->weight - old;
 	}
+	return totchange;
 }
 /* Jason */
 static void check_locks_and_normalize(Object *ob, Mesh *me, int index, int vgroup, MDeformWeight *dw, float oldw, char *validmap, char *flags, int defcnt, char *bone_groups, char *selection, int selected, int multipaint)
 {
 	float change=0.0f;
-	if(flags && has_locked_group(me->dvert+index, flags)) {
-		if(flags[dw->def_nr] || multipaint) {
+	float totchange=0.0f;
+	float allowed_totchange;
+	int def_nr = dw->def_nr;
+	float orig_change = oldw-dw->weight;
+	float neww = dw->weight;
+	dw->weight = oldw;
+	if(flags && (has_locked_group(me->dvert+index, flags) || flags[dw->def_nr])) {
+		if(flags[dw->def_nr] || (multipaint && has_locked_group_selected(defcnt, selection, flags)) || !has_unselected_unlocked_bone_group(defcnt, selection, selected, flags, bone_groups)) {
 			// cannot change locked groups!
-			dw->weight = oldw;
-		} else if(bone_groups[dw->def_nr]) {
-			redistribute_weight_change(ob, me->dvert+index, index, dw, oldw, flags, defcnt, bone_groups);
-			do_weight_paint_auto_normalize_change_act_group(me->dvert+index, validmap);//do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
+		} else if((allowed_totchange = get_change_allowed_from_unlocked_bone_groups(me->dvert+index, def_nr, defcnt, selection, (int)(fabs(orig_change)/orig_change), flags, bone_groups)) != 0) {
+			dw = defvert_find_index(me->dvert+index, def_nr);
+			if (multipaint && selected > 1) {
+				if(selection[dw->def_nr] && (change = get_valid_multipaint_change(me->dvert+index, neww, oldw, allowed_totchange, validmap, bone_groups, selection, defcnt))) {
+					totchange = multipaint_vgroups(me->dvert+index, change, bone_groups, selection);
+					if(totchange !=0){
+						redistribute_weight_change(ob, me->dvert+index, index, def_nr, multipaint, selection, selected, totchange, flags, defcnt, bone_groups);
+					}
+				}
+			} else if(bone_groups[dw->def_nr]) {
+				totchange = oldw - neww;
+				if(fabs(totchange) > fabs(allowed_totchange)) {
+					totchange = allowed_totchange;
+				}
+				if(totchange !=0){
+					redistribute_weight_change(ob, me->dvert+index, index, def_nr, FALSE, selection, selected, totchange, flags, defcnt, bone_groups);
+					dw->weight -= totchange;
+				}
+			}
 		}
-	} else if(bone_groups[dw->def_nr]) {// disable auto normalize if the active group is not a bone group
+	} else if(bone_groups[dw->def_nr]) {
 		if(multipaint && selected > 1) {
 			// try to alter the other bone groups in the dvert with the changed dw if possible, if it isn't, change it back
-			if(selection[dw->def_nr] && (change = get_valid_multipaint_change(me->dvert+index, dw, oldw, validmap, bone_groups, selection, defcnt)) > 0) {
+			if(selection[dw->def_nr] && (change = get_valid_multipaint_change(me->dvert+index, neww, oldw, -1, validmap, bone_groups, selection, defcnt))) {
 				multipaint_vgroups(me->dvert+index, change, bone_groups, selection);
-				do_weight_paint_auto_normalize_change_act_group(me->dvert+index, validmap);
-			}else {
-				// multi-paint failed
-				dw->weight = oldw;
 			}
+		}else {
+			dw->weight = neww;
 		}
-		do_weight_paint_auto_normalize_change_act_group(me->dvert+index, validmap);
 	}
+	do_weight_paint_auto_normalize_change_act_group(me->dvert+index, validmap);
 }
 /* Jason was here duplicate function I used in DerivedMesh.c*/
 static char* get_selected_defgroups(Object *ob, int defcnt) {
@@ -1343,10 +1420,15 @@
 	flags = gen_lck_flags(ob, defcnt = BLI_countlist(&ob->defbase), bone_groups);
 	selection = get_selected_defgroups(ob, defcnt);
 	selected = count_true(selection, defcnt);
+	if(!selected && ob->actdef) {
+		selected = 1;
+	}
 	oldw = dw->weight;
 	wpaint_blend(wp, dw, uw, alpha, paintweight, flip);
 	/* Jason was here */
 	check_locks_and_normalize(ob, me, index, vgroup, dw, oldw, validmap, flags, defcnt, bone_groups, selection, selected, multipaint);
+	// dvert may have been altered greatly

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list