[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12697] trunk/blender/source/blender:

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Nov 27 22:16:47 CET 2007


Revision: 12697
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12697
Author:   blendix
Date:     2007-11-27 22:16:47 +0100 (Tue, 27 Nov 2007)

Log Message:
-----------

Heat Weighting
==============

Now takes b-bones into account, solving as if each bone segment was
an individual bone, and then adding the weights together.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BIF_editdeform.h
    trunk/blender/source/blender/src/editarmature.c
    trunk/blender/source/blender/src/editdeform.c
    trunk/blender/source/blender/src/meshlaplacian.c

Modified: trunk/blender/source/blender/include/BIF_editdeform.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editdeform.h	2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/include/BIF_editdeform.h	2007-11-27 21:16:47 UTC (rev 12697)
@@ -61,6 +61,8 @@
 						   int assignmode);
 void remove_vert_defgroup (struct Object *ob, struct bDeformGroup  *dg, 
 						   int vertnum);
+float get_vert_defgroup	(struct Object *ob, struct bDeformGroup  *dg,
+                         int vertnum);
 void create_dverts(ID *id);
 
 void vertexgroup_select_by_name(struct Object *ob, char *name);

Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c	2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/src/editarmature.c	2007-11-27 21:16:47 UTC (rev 12697)
@@ -2552,7 +2552,7 @@
 }
 
 
-static int bone_skinnable(Object *ob, Bone *bone, void *data)
+static int bone_skinnable(Object *ob, Bone *bone, void *datap)
 {
     /* Bones that are deforming
      * are regarded to be "skinnable" and are eligible for
@@ -2576,16 +2576,26 @@
      *      pointers to bones that point to all
      *      skinnable bones.
      */
-    Bone ***hbone;
+	Bone ***hbone;
+	int a, segments;
+	struct { Object *armob; void *list; int heat; } *data = datap;
 
 	if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
 		if (!(bone->flag & BONE_NO_DEFORM)) {
-			if (data != NULL) {
-				hbone = (Bone ***) data;
-				**hbone = bone;
-				++*hbone;
+			if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+				segments = bone->segments;
+			else
+				segments = 1;
+
+			if (data->list != NULL) {
+				hbone = (Bone ***) &data->list;
+				
+				for(a=0; a<segments; a++) {
+					**hbone = bone;
+					++*hbone;
+				}
 			}
-			return 1;
+			return segments;
 		}
 	}
     return 0;
@@ -2606,7 +2616,7 @@
     return 0;
 }
 
-static int dgroup_skinnable(Object *ob, Bone *bone, void *data) 
+static int dgroup_skinnable(Object *ob, Bone *bone, void *datap) 
 {
     /* Bones that are deforming
      * are regarded to be "skinnable" and are eligible for
@@ -2632,19 +2642,28 @@
      *      of skinnable bones.
      */
     bDeformGroup ***hgroup, *defgroup;
+	int a, segments;
+	struct { Object *armob; void *list; int heat; } *data= datap;
 
 	if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
 	   if (!(bone->flag & BONE_NO_DEFORM)) {
-			if ( !(defgroup = get_named_vertexgroup(ob, bone->name)) ) {
+			if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+				segments = bone->segments;
+			else
+				segments = 1;
+
+			if(!(defgroup = get_named_vertexgroup(ob, bone->name)))
 				defgroup = add_defgroup_name(ob, bone->name);
-			}
 
-			if (data != NULL) {
-				hgroup = (bDeformGroup ***) data;
-				**hgroup = defgroup;
-				++*hgroup;
+			if (data->list != NULL) {
+				hgroup = (bDeformGroup ***) &data->list;
+
+				for(a=0; a<segments; a++) {
+					**hgroup = defgroup;
+					++*hgroup;
+				}
 			}
-			return 1;
+			return segments;
 		}
 	}
     return 0;
@@ -2682,7 +2701,7 @@
 			/* store the distance-factor from the vertex to the bone */
 			distance = distfactor_to_bone (verts[i], root[j], tip[j],
 				bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale);
-
+			
 			/* add the vert to the deform group if weight!=0.0 */
 			if (distance!=0.0)
 				add_vert_to_defgroup (ob, dgroup, i, distance, WEIGHT_REPLACE);
@@ -2713,59 +2732,95 @@
 	 * The mesh vertex positions used are either the final deformed coords
 	 * from the derivedmesh in weightpaint mode, the final subsurf coords
 	 * when parenting, or simply the original mesh coords.
-     */
+	 */
 
-    bArmature *arm;
-    Bone **bonelist, **bonehandle, *bone;
-    bDeformGroup **dgrouplist, **dgroupflip, **dgrouphandle;
+	bArmature *arm;
+	Bone **bonelist, *bone;
+	bDeformGroup **dgrouplist, **dgroupflip;
 	bDeformGroup *dgroup, *curdg;
-    Mesh *mesh;
-    float (*root)[3], (*tip)[3], (*verts)[3];
+	bPoseChannel *pchan;
+	Mesh *mesh;
+	Mat4 *bbone = NULL;
+	float (*root)[3], (*tip)[3], (*verts)[3];
 	int *selected;
-    int numbones, vertsfilled = 0, i, j;
+	int numbones, vertsfilled = 0, i, j, segments = 0;
 	int wpmode = (G.f & G_WEIGHTPAINT);
+	struct { Object *armob; void *list; int heat; } looper_data;
 
-    /* If the parent object is not an armature exit */
-    arm = get_armature(par);
-    if (!arm)
-        return;
+	/* If the parent object is not an armature exit */
+	arm = get_armature(par);
+	if (!arm)
+		return;
+	
+	looper_data.armob = par;
+	looper_data.heat= heat;
+	looper_data.list= NULL;
 
-    /* count the number of skinnable bones */
-    numbones = bone_looper(ob, arm->bonebase.first, NULL, bone_skinnable);
+	/* count the number of skinnable bones */
+	numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable);
 	
 	if (numbones == 0)
 		return;
 	
-    /* create an array of pointer to bones that are skinnable
-     * and fill it with all of the skinnable bones */
-    bonelist = MEM_callocN(numbones*sizeof(Bone *), "bonelist");
-    bonehandle = bonelist;
-    bone_looper(ob, arm->bonebase.first, &bonehandle, bone_skinnable);
+	/* create an array of pointer to bones that are skinnable
+	 * and fill it with all of the skinnable bones */
+	bonelist = MEM_callocN(numbones*sizeof(Bone *), "bonelist");
+	looper_data.list= bonelist;
+	bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable);
 
-    /* create an array of pointers to the deform groups that
-     * coorespond to the skinnable bones (creating them
-     * as necessary. */
-    dgrouplist = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
-    dgroupflip = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgroupflip");
+	/* create an array of pointers to the deform groups that
+	 * coorespond to the skinnable bones (creating them
+	 * as necessary. */
+	dgrouplist = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
+	dgroupflip = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgroupflip");
 
-    dgrouphandle = dgrouplist;
-    bone_looper(ob, arm->bonebase.first, &dgrouphandle, dgroup_skinnable);
+	looper_data.list= dgrouplist;
+	bone_looper(ob, arm->bonebase.first, &looper_data, dgroup_skinnable);
 
-    /* create an array of root and tip positions transformed into
+	/* create an array of root and tip positions transformed into
 	 * global coords */
-    root = MEM_callocN(numbones*sizeof(float)*3, "root");
-    tip = MEM_callocN(numbones*sizeof(float)*3, "tip");
+	root = MEM_callocN(numbones*sizeof(float)*3, "root");
+	tip = MEM_callocN(numbones*sizeof(float)*3, "tip");
 	selected = MEM_callocN(numbones*sizeof(int), "selected");
 
 	for (j=0; j < numbones; ++j) {
    		bone = bonelist[j];
 		dgroup = dgrouplist[j];
 
+		/* handle bbone */
+		if(heat) {
+			if(segments == 0) {
+				segments = 1;
+				bbone = NULL;
+
+				if(par->pose && (pchan=get_pose_channel(par->pose, bone->name))) {
+					if(bone->segments > 1) {
+						segments = bone->segments;
+						bbone = b_bone_spline_setup(pchan, 1);
+					}
+				}
+			}
+
+			segments--;
+		}
+
 		/* compute root and tip */
-		VECCOPY(root[j], bone->arm_head);
+		if(bbone) {
+			VECCOPY(root[j], bbone[segments].mat[3]);
+			Mat4MulVecfl(bone->arm_mat, root[j]);
+			if(segments+1 < bone->segments) {
+				VECCOPY(tip[j], bbone[segments+1].mat[3])
+				Mat4MulVecfl(bone->arm_mat, tip[j]);
+			}
+			else
+				VECCOPY(tip[j], bone->arm_tail)
+		}
+		else {
+			VECCOPY(root[j], bone->arm_head);
+			VECCOPY(tip[j], bone->arm_tail);
+		}
+
 		Mat4MulVecfl(par->obmat, root[j]);
-
-		VECCOPY(tip[j], bone->arm_tail);
 		Mat4MulVecfl(par->obmat, tip[j]);
 
 		/* set selected */

Modified: trunk/blender/source/blender/src/editdeform.c
===================================================================
--- trunk/blender/source/blender/src/editdeform.c	2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/src/editdeform.c	2007-11-27 21:16:47 UTC (rev 12697)
@@ -704,6 +704,53 @@
 	remove_vert_def_nr (ob, def_nr, vertnum);
 }
 
+/* for mesh in object mode lattice can be in editmode */
+static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
+{
+	MDeformVert *dvert= NULL;
+	int i;
+
+	/* get the deform vertices corresponding to the
+	 * vertnum
+	 */
+	if(ob->type==OB_MESH) {
+		if( ((Mesh*)ob->data)->dvert )
+			dvert = ((Mesh*)ob->data)->dvert + vertnum;
+	}
+	else if(ob->type==OB_LATTICE) {
+		Lattice *lt= ob->data;
+		
+		if(ob==G.obedit)
+			lt= editLatt;
+		
+		if(lt->dvert)
+			dvert = lt->dvert + vertnum;
+	}
+	
+	if(dvert==NULL)
+		return 0.0f;
+	
+	for(i=dvert->totweight-1 ; i>=0 ; i--)
+		if(dvert->dw[i].def_nr == def_nr)
+			return dvert->dw[i].weight;
+
+	return 0.0f;
+}
+
+/* mesh object mode, lattice can be in editmode */
+float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
+{
+	int def_nr;
+
+	if(!ob)
+		return 0.0f;
+
+	def_nr = get_defgroup_num(ob, dg);
+	if(def_nr < 0) return 0.0f;
+
+	return get_vert_def_nr (ob, def_nr, vertnum);
+}
+
 /* Only available in editmode */
 /* removes from active defgroup, if allverts==0 only selected vertices */
 void remove_verts_defgroup (int allverts)

Modified: trunk/blender/source/blender/src/meshlaplacian.c
===================================================================
--- trunk/blender/source/blender/src/meshlaplacian.c	2007-11-27 19:23:26 UTC (rev 12696)
+++ trunk/blender/source/blender/src/meshlaplacian.c	2007-11-27 21:16:47 UTC (rev 12697)
@@ -407,7 +407,7 @@
 
 	if(v4) CalcNormFloat4(v1, v2, v3, v4, nor);
 	else CalcNormFloat(v1, v2, v3, nor);
-	
+
 	return (INPR(nor, is->vec) < 0);
 }
 
@@ -605,8 +605,9 @@
 {
 	LaplacianSystem *sys;
 	MFace *mface;
-	float solution;
-	int a, aflip, totface, j, thrownerror = 0;
+	float solution, weight;
+	int *vertsflipped = NULL;
+	int a, totface, j, bbone, firstsegment, lastsegment, thrownerror = 0;
 
 	/* count triangles */
 	for(totface=0, a=0, mface=me->mface; a<me->totface; a++, mface++) {
@@ -628,11 +629,31 @@
 
 	laplacian_system_construct_end(sys);
 
+	if(dgroupflip) {
+		vertsflipped = MEM_callocN(sizeof(int)*me->totvert, "vertsflipped");
+		for(a=0; a<me->totvert; a++)
+			vertsflipped[a] = mesh_get_x_mirror_vert(ob, a);
+	}
+
 	/* compute weights per bone */
 	for(j=0; j<numbones; j++) {
 		if(!selected[j])
 			continue;
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list