[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50409] trunk/blender/source/blender: fix [#29431] "Normalize All" from Weight Tools don't work correctly

Campbell Barton ideasman42 at gmail.com
Wed Sep 5 06:16:10 CEST 2012


Revision: 50409
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50409
Author:   campbellbarton
Date:     2012-09-05 04:16:09 +0000 (Wed, 05 Sep 2012)
Log Message:
-----------
fix [#29431] "Normalize All" from Weight Tools don't work correctly

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	2012-09-05 03:45:32 UTC (rev 50408)
+++ trunk/blender/source/blender/blenkernel/BKE_deform.h	2012-09-05 04:16:09 UTC (rev 50409)
@@ -67,7 +67,8 @@
 void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
 void defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
 void defvert_normalize(struct MDeformVert *dvert);
-void defvert_normalize_lock(struct MDeformVert *dvert, const int def_nr_lock);
+void defvert_normalize_lock_single(struct MDeformVert *dvert, const int def_nr_lock);
+void defvert_normalize_lock_map(struct MDeformVert *dvert, const char *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	2012-09-05 03:45:32 UTC (rev 50408)
+++ trunk/blender/source/blender/blenkernel/intern/deform.c	2012-09-05 04:16:09 UTC (rev 50409)
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <math.h>
 #include <ctype.h>
+#include <stdlib.h>
 
 #include "MEM_guardedalloc.h"
 
@@ -41,7 +42,10 @@
 
 #include "BKE_deform.h"
 
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
 #include "BLI_utildefines.h"
 
 
@@ -204,7 +208,7 @@
 	}
 }
 
-void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
+void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
 {
 	if (dvert->totweight <= 0) {
 		/* nothing */
@@ -248,6 +252,50 @@
 	}
 }
 
+void defvert_normalize_lock_map(MDeformVert *dvert, const char *lock_flags, const int defbase_tot)
+{
+	if (dvert->totweight <= 0) {
+		/* nothing */
+	}
+	else if (dvert->totweight == 1) {
+		if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
+			dvert->dw[0].weight = 1.0f;
+		}
+	}
+	else {
+		MDeformWeight *dw;
+		unsigned int i;
+		float tot_weight = 0.0f;
+		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;
+			}
+			else {
+				/* invert after */
+				lock_iweight += dw->weight;
+			}
+		}
+
+		lock_iweight = maxf(0.0f, 1.0f - lock_iweight);
+
+		if (tot_weight > 0.0f) {
+			/* paranoid, should be 1.0 but in case of float error clamp anyway */
+
+			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;
+
+					/* in case of division errors with very low weights */
+					CLAMP(dw->weight, 0.0f, 1.0f);
+				}
+			}
+		}
+	}
+}
+
 void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
 {
 	MDeformWeight *dw;

Modified: trunk/blender/source/blender/editors/object/object_vgroup.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_vgroup.c	2012-09-05 03:45:32 UTC (rev 50408)
+++ trunk/blender/source/blender/editors/object/object_vgroup.c	2012-09-05 04:16:09 UTC (rev 50409)
@@ -62,6 +62,7 @@
 #include "BKE_tessmesh.h"
 #include "BKE_report.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_object_deform.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -1136,7 +1137,6 @@
 	}
 }
 
-/* TODO - select between groups */
 static void vgroup_normalize_all(Object *ob, int lock_active)
 {
 	MDeformVert *dv, **dvert_array = NULL;
@@ -1152,29 +1152,35 @@
 	ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
 
 	if (dvert_array) {
-		if (lock_active) {
+		const int defbase_tot = BLI_countlist(&ob->defbase);
+		char *lock_flags = BKE_objdef_lock_flags_get(ob, defbase_tot);
 
-			for (i = 0; i < dvert_tot; i++) {
-				/* in case its not selected */
-				if (!(dv = dvert_array[i])) {
-					continue;
-				}
-
-				defvert_normalize_lock(dv, def_nr);
-			}
+		if ((lock_active == TRUE) &&
+		    (lock_flags != NULL) &&
+		    (def_nr < defbase_tot))
+		{
+			lock_flags[def_nr] = TRUE;
 		}
-		else {
-			for (i = 0; i < dvert_tot; i++) {
 
-				/* in case its not selected */
-				if (!(dv = dvert_array[i])) {
-					continue;
+		for (i = 0; i < dvert_tot; i++) {
+			/* in case its not selected */
+			if ((dv = dvert_array[i])) {
+				if (lock_flags) {
+					defvert_normalize_lock_map(dv, lock_flags, defbase_tot);
 				}
-
-				defvert_normalize(dv);
+				else if (lock_active) {
+					defvert_normalize_lock_single(dv, def_nr);
+				}
+				else {
+					defvert_normalize(dv);
+				}
 			}
 		}
 
+		if (lock_flags) {
+			MEM_freeN(lock_flags);
+		}
+
 		MEM_freeN(dvert_array);
 	}
 }




More information about the Bf-blender-cvs mailing list