[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60655] trunk/blender/source/blender: Weight Paint Tools: Add "Subset" option to "Normalize All"

Shinsuke Irie irieshinsuke at yahoo.co.jp
Thu Oct 10 08:33:23 CEST 2013


Revision: 60655
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60655
Author:   irie
Date:     2013-10-10 06:33:23 +0000 (Thu, 10 Oct 2013)
Log Message:
-----------
Weight Paint Tools: Add "Subset" option to "Normalize All"

This option is needed when vertex groups are used for both armature
deformation and the other purpose such as influence of mesh modifier.

Thanks to Campbell for code review!

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_deform.h
    trunk/blender/source/blender/blenkernel/intern/deform.c
    trunk/blender/source/blender/editors/object/object_vgroup.c

Modified: trunk/blender/source/blender/blenkernel/BKE_deform.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_deform.h	2013-10-10 03:35:32 UTC (rev 60654)
+++ trunk/blender/source/blender/blenkernel/BKE_deform.h	2013-10-10 06:33:23 UTC (rev 60655)
@@ -78,8 +78,12 @@
 void defvert_normalize(struct MDeformVert *dvert);
 void defvert_normalize_subset(struct MDeformVert *dvert,
                               const bool *vgroup_subset, const int vgroup_tot);
-void defvert_normalize_lock_single(struct MDeformVert *dvert, const int def_nr_lock);
-void defvert_normalize_lock_map(struct MDeformVert *dvert, const bool *lock_flags, const int defbase_tot);
+void defvert_normalize_lock_single(struct MDeformVert *dvert,
+                                   const bool *vgroup_subset, const int vgroup_tot,
+                                   const int def_nr_lock);
+void defvert_normalize_lock_map(struct MDeformVert *dvert,
+                                const bool *vgroup_subset, const int vgroup_tot,
+                                const bool *lock_flags, const int defbase_tot);
 
 /* utility function, note that MAX_VGROUP_NAME chars is the maximum string length since its only
  * used with defgroups currently */

Modified: trunk/blender/source/blender/blenkernel/intern/deform.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/deform.c	2013-10-10 03:35:32 UTC (rev 60654)
+++ trunk/blender/source/blender/blenkernel/intern/deform.c	2013-10-10 06:33:23 UTC (rev 60655)
@@ -217,32 +217,43 @@
 void defvert_normalize_subset(MDeformVert *dvert,
                               const bool *vgroup_subset, const int vgroup_tot)
 {
-	MDeformWeight *dw;
-	unsigned int i;
-	float tot_weight = 0.0f;
-
-	for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+	if (dvert->totweight == 0) {
+		/* nothing */
+	}
+	else if (dvert->totweight == 1) {
+		MDeformWeight *dw = dvert->dw;
 		if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
-			tot_weight += dw->weight;
+			dw->weight = 1.0f;
 		}
 	}
+	else {
+		MDeformWeight *dw;
+		unsigned int i;
+		float tot_weight = 0.0f;
 
-	if (tot_weight > 0.0f) {
-		float scalar = 1.0f / tot_weight;
 		for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
 			if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
-				dw->weight *= scalar;
-				
-				/* in case of division errors with very low weights */
-				CLAMP(dw->weight, 0.0f, 1.0f);
+				tot_weight += dw->weight;
 			}
 		}
+
+		if (tot_weight > 0.0f) {
+			float scalar = 1.0f / tot_weight;
+			for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+				if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+					dw->weight *= scalar;
+
+					/* in case of division errors with very low weights */
+					CLAMP(dw->weight, 0.0f, 1.0f);
+				}
+			}
+		}
 	}
 }
 
 void defvert_normalize(MDeformVert *dvert)
 {
-	if (dvert->totweight <= 0) {
+	if (dvert->totweight == 0) {
 		/* nothing */
 	}
 	else if (dvert->totweight == 1) {
@@ -269,14 +280,20 @@
 	}
 }
 
-void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
+/* Same as defvert_normalize() if the locked vgroup is not a member of the subset */
+void defvert_normalize_lock_single(MDeformVert *dvert,
+                                   const bool *vgroup_subset, const int vgroup_tot,
+                                   const int def_nr_lock)
 {
-	if (dvert->totweight <= 0) {
+	if (dvert->totweight == 0) {
 		/* nothing */
 	}
 	else if (dvert->totweight == 1) {
-		if (def_nr_lock != 0) {
-			dvert->dw[0].weight = 1.0f;
+		MDeformWeight *dw = dvert->dw;
+		if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+			if (def_nr_lock != 0) {
+				dw->weight = 1.0f;
+			}
 		}
 	}
 	else {
@@ -287,14 +304,16 @@
 		float lock_iweight = 1.0f;
 
 		for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
-			if (dw->def_nr != def_nr_lock) {
-				tot_weight += dw->weight;
+			if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+				if (dw->def_nr != def_nr_lock) {
+					tot_weight += dw->weight;
+				}
+				else {
+					dw_lock = dw;
+					lock_iweight = (1.0f - dw_lock->weight);
+					CLAMP(lock_iweight, 0.0f, 1.0f);
+				}
 			}
-			else {
-				dw_lock = dw;
-				lock_iweight = (1.0f - dw_lock->weight);
-				CLAMP(lock_iweight, 0.0f, 1.0f);
-			}
 		}
 
 		if (tot_weight > 0.0f) {
@@ -302,25 +321,33 @@
 
 			float scalar = (1.0f / tot_weight) * lock_iweight;
 			for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
-				if (dw != dw_lock) {
-					dw->weight *= scalar;
+				if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+					if (dw != dw_lock) {
+						dw->weight *= scalar;
 
-					/* in case of division errors with very low weights */
-					CLAMP(dw->weight, 0.0f, 1.0f);
+						/* in case of division errors with very low weights */
+						CLAMP(dw->weight, 0.0f, 1.0f);
+					}
 				}
 			}
 		}
 	}
 }
 
-void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, const int defbase_tot)
+/* Same as defvert_normalize() if no locked vgroup is a member of the subset */
+void defvert_normalize_lock_map(MDeformVert *dvert,
+				const bool *vgroup_subset, const int vgroup_tot,
+				const bool *lock_flags, const int defbase_tot)
 {
-	if (dvert->totweight <= 0) {
+	if (dvert->totweight == 0) {
 		/* nothing */
 	}
 	else if (dvert->totweight == 1) {
-		if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
-			dvert->dw[0].weight = 1.0f;
+		MDeformWeight *dw = dvert->dw;
+		if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+			if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
+				dw->weight = 1.0f;
+			}
 		}
 	}
 	else {
@@ -330,13 +357,15 @@
 		float lock_iweight = 0.0f;
 
 		for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
-			if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
-				tot_weight += dw->weight;
+			if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+				if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+					tot_weight += dw->weight;
+				}
+				else {
+					/* invert after */
+					lock_iweight += dw->weight;
+				}
 			}
-			else {
-				/* invert after */
-				lock_iweight += dw->weight;
-			}
 		}
 
 		lock_iweight = max_ff(0.0f, 1.0f - lock_iweight);
@@ -346,11 +375,13 @@
 
 			float scalar = (1.0f / tot_weight) * lock_iweight;
 			for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
-				if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
-					dw->weight *= scalar;
+				if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+					if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+						dw->weight *= scalar;
 
-					/* in case of division errors with very low weights */
-					CLAMP(dw->weight, 0.0f, 1.0f);
+						/* in case of division errors with very low weights */
+						CLAMP(dw->weight, 0.0f, 1.0f);
+					}
 				}
 			}
 		}

Modified: trunk/blender/source/blender/editors/object/object_vgroup.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_vgroup.c	2013-10-10 03:35:32 UTC (rev 60654)
+++ trunk/blender/source/blender/editors/object/object_vgroup.c	2013-10-10 06:33:23 UTC (rev 60655)
@@ -2001,7 +2001,11 @@
 	}
 }
 
-static void vgroup_normalize_all(Object *ob, const bool lock_active)
+static void vgroup_normalize_all(Object *ob,
+                                 const bool *vgroup_validmap,
+                                 const int vgroup_tot,
+                                 const int subset_count,
+                                 const bool lock_active)
 {
 	MDeformVert *dv, **dvert_array = NULL;
 	int i, dvert_tot = 0;
@@ -2009,7 +2013,7 @@
 
 	const int use_vert_sel = vertex_group_use_vert_sel(ob);
 
-	if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) {
+	if ((lock_active && !BLI_findlink(&ob->defbase, def_nr)) || subset_count == 0) {
 		return;
 	}
 
@@ -2030,13 +2034,15 @@
 			/* in case its not selected */
 			if ((dv = dvert_array[i])) {
 				if (lock_flags) {
-					defvert_normalize_lock_map(dv, lock_flags, defbase_tot);
+					defvert_normalize_lock_map(dv, vgroup_validmap, vgroup_tot,
+					                           lock_flags, defbase_tot);
 				}
 				else if (lock_active) {
-					defvert_normalize_lock_single(dv, def_nr);
+					defvert_normalize_lock_single(dv, vgroup_validmap, vgroup_tot,
+					                              def_nr);
 				}
 				else {
-					defvert_normalize(dv);
+					defvert_normalize_subset(dv, vgroup_validmap, vgroup_tot);
 				}
 			}
 		}
@@ -3474,9 +3480,14 @@
 {
 	Object *ob = ED_object_context(C);
 	bool lock_active = RNA_boolean_get(op->ptr, "lock_active");
+	eVGroupSelect subset_type  = RNA_enum_get(op->ptr, "group_select_mode");
 
-	vgroup_normalize_all(ob, lock_active);
+	int subset_count, vgroup_tot;
 
+	const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+	vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active);
+	MEM_freeN((void *)vgroup_validmap);
+
 	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
 	WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
@@ -3499,6 +3510,7 @@
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
+	vgroup_operator_subset_select_props(ot, false);
 	RNA_def_boolean(ot->srna, "lock_active", true, "Lock Active",
 	                "Keep the values of the active group while normalizing others");
 }




More information about the Bf-blender-cvs mailing list