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

Brecht Van Lommel brechtvanlommel at pandora.be
Sun Nov 11 23:54:14 CET 2007


Revision: 12559
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12559
Author:   blendix
Date:     2007-11-11 23:54:14 +0100 (Sun, 11 Nov 2007)

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

Mesh Deform Modifier
====================

Dynamic binding support. This means that the mesh can move _within_
the cage and still deform correct. If the mesh goes out of the cage,
don't expect correct result. Must be enabled with the 'Dynamic'
option, because it is slower and consumes more memory.

This is useful to use e.g. the cage mesh for main deformations and
still have shape keys for facial deformation working.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_modifier_types.h
    trunk/blender/source/blender/src/buttons_editing.c
    trunk/blender/source/blender/src/meshlaplacian.c

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2007-11-11 21:14:44 UTC (rev 12558)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2007-11-11 22:54:14 UTC (rev 12559)
@@ -4935,8 +4935,11 @@
 {
 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
 
-	if (mmd->bindweights) MEM_freeN(mmd->bindweights);
-	if (mmd->bindcos) MEM_freeN(mmd->bindcos);
+	if(mmd->bindweights) MEM_freeN(mmd->bindweights);
+	if(mmd->bindcos) MEM_freeN(mmd->bindcos);
+	if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
+	if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
+	if(mmd->dynverts) MEM_freeN(mmd->dynverts);
 }
 
 static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
@@ -4990,12 +4993,64 @@
 	}
 }
 
+static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float *vec)
+{
+	MDefCell *cell;
+	MDefInfluence *inf;
+	float gridvec[3], dvec[3], ivec[3], co[3], wx, wy, wz;
+	float weight, cageweight, totweight, *cageco;
+	int i, j, a, x, y, z, size;
+
+	co[0]= co[1]= co[2]= 0.0f;
+	totweight= 0.0f;
+	size= mmd->dyngridsize;
+
+	for(i=0; i<3; i++) {
+		gridvec[i]= (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth*0.5f)/mmd->dyncellwidth;
+		ivec[i]= (int)gridvec[i];
+		dvec[i]= gridvec[i] - ivec[i];
+	}
+
+	for(i=0; i<8; i++) {
+		if(i & 1) { x= ivec[0]+1; wx= dvec[0]; }
+		else { x= ivec[0]; wx= 1.0f-dvec[0]; } 
+
+		if(i & 2) { y= ivec[1]+1; wy= dvec[1]; }
+		else { y= ivec[1]; wy= 1.0f-dvec[1]; } 
+
+		if(i & 4) { z= ivec[2]+1; wz= dvec[2]; }
+		else { z= ivec[2]; wz= 1.0f-dvec[2]; } 
+
+		CLAMP(x, 0, size-1);
+		CLAMP(y, 0, size-1);
+		CLAMP(z, 0, size-1);
+
+		a= x + y*size + z*size*size;
+		weight= wx*wy*wz;
+
+		cell= &mmd->dyngrid[a];
+		inf= mmd->dyninfluences + cell->offset;
+		for(j=0; j<cell->totinfluence; j++, inf++) {
+			cageco= dco[inf->vertex];
+			cageweight= weight*inf->weight;
+			co[0] += cageweight*cageco[0];
+			co[1] += cageweight*cageco[1];
+			co[2] += cageweight*cageco[2];
+			totweight += cageweight;
+		}
+	}
+
+	VECCOPY(vec, co);
+
+	return totweight;
+}
+
 static void meshdeformModifier_do(
                 ModifierData *md, Object *ob, DerivedMesh *dm,
                 float (*vertexCos)[3], int numVerts)
 {
 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-	float imat[4][4], cagemat[4][4], icagemat[4][4], icmat[3][3];
+	float imat[4][4], cagemat[4][4], icagemat[4][4], iobmat[3][3];
 	float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
 	int a, b, totvert, totcagevert, defgrp_index;
 	DerivedMesh *tmpdm, *cagedm;
@@ -5003,7 +5058,7 @@
 	MDeformWeight *dw;
 	MVert *cagemvert;
 
-	if(!mmd->object || (!mmd->bindweights && !mmd->needbind))
+	if(!mmd->object || (!mmd->bindcos && !mmd->needbind))
 		return;
 	
 	/* get cage derivedmesh */
@@ -5020,20 +5075,21 @@
 		return;
 
  	/* compute matrices to go in and out of cage object space */
-	Mat4Invert(imat, mmd->object->obmat);
+	Mat4Invert(imat, (mmd->bindcos)? mmd->bindmat: mmd->object->obmat);
 	Mat4MulMat4(cagemat, ob->obmat, imat);
 	Mat4Invert(icagemat, cagemat);
-	Mat3CpyMat4(icmat, icagemat);
+	Mat4Invert(imat, ob->obmat);
+	Mat3CpyMat4(iobmat, imat);
 
 	/* bind weights if needed */
-	if(!mmd->bindweights)
+	if(!mmd->bindcos)
 		harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
 
 	/* verify we have compatible weights */
 	totvert= numVerts;
 	totcagevert= cagedm->getNumVerts(cagedm);
 
-	if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindweights) {
+	if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindcos) {
 		cagedm->release(cagedm);
 		return;
 	}
@@ -5070,6 +5126,10 @@
 	fac= 1.0f;
 
 	for(b=0; b<totvert; b++) {
+		if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
+			if(!mmd->dynverts[b])
+				continue;
+
 		if(dvert) {
 			for(dw=NULL, a=0; a<dvert[b].totweight; a++) {
 				if(dvert[b].dw[a].def_nr == defgrp_index) {
@@ -5089,20 +5149,27 @@
 			}
 		}
 
-		totweight= 0.0f;
-		co[0]= co[1]= co[2]= 0.0f;
+		if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
+			VECCOPY(co, vertexCos[b]);
+			Mat4MulVecfl(cagemat, co);
+			totweight= meshdeform_dynamic_bind(mmd, dco, co);
+		}
+		else {
+			totweight= 0.0f;
+			co[0]= co[1]= co[2]= 0.0f;
 
-		for(a=0; a<totcagevert; a++) {
-			weight= weights[a + b*totcagevert];
-			co[0]+= weight*dco[a][0];
-			co[1]+= weight*dco[a][1];
-			co[2]+= weight*dco[a][2];
-			totweight += weight;
+			for(a=0; a<totcagevert; a++) {
+				weight= weights[a + b*totcagevert];
+				co[0]+= weight*dco[a][0];
+				co[1]+= weight*dco[a][1];
+				co[2]+= weight*dco[a][2];
+				totweight += weight;
+			}
 		}
 
 		if(totweight > 0.0f) {
 			VecMulf(co, fac/totweight);
-			Mat3MulVecfl(icmat, co);
+			Mat3MulVecfl(iobmat, co);
 			VECADD(vertexCos[b], vertexCos[b], co);
 		}
 	}

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2007-11-11 21:14:44 UTC (rev 12558)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2007-11-11 22:54:14 UTC (rev 12559)
@@ -2894,6 +2894,9 @@
 
 			mmd->bindweights= newdataadr(fd, mmd->bindweights);
 			mmd->bindcos= newdataadr(fd, mmd->bindcos);
+			mmd->dyngrid= newdataadr(fd, mmd->dyngrid);
+			mmd->dyninfluences= newdataadr(fd, mmd->dyninfluences);
+			mmd->dynverts= newdataadr(fd, mmd->dynverts);
 
 			if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
 				int a;
@@ -2902,6 +2905,8 @@
 					SWITCH_INT(mmd->bindweights[a])
 				for(a=0; a<mmd->totcagevert*3; a++)
 					SWITCH_INT(mmd->bindcos[a])
+				for(a=0; a<mmd->totvert; a++)
+					SWITCH_INT(mmd->dynverts[a])
 			}
 		}
 	}

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c	2007-11-11 21:14:44 UTC (rev 12558)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c	2007-11-11 22:54:14 UTC (rev 12559)
@@ -787,11 +787,16 @@
 		}
 		else if (md->type==eModifierType_MeshDeform) {
 			MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+			int size = mmd->dyngridsize;
 
 			writedata(wd, DATA, sizeof(float)*mmd->totvert*mmd->totcagevert,
 				mmd->bindweights);
 			writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert,
 				mmd->bindcos);
+			writedata(wd, DATA, sizeof(MDefCell)*size*size*size, mmd->dyngrid);
+			writedata(wd, DATA, sizeof(MDefInfluence)*mmd->totinfluence,
+				mmd->dyninfluences);
+			writedata(wd, DATA, sizeof(int)*mmd->totvert, mmd->dynverts);
 		}
 	}
 }

Modified: trunk/blender/source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2007-11-11 21:14:44 UTC (rev 12558)
+++ trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2007-11-11 22:54:14 UTC (rev 12559)
@@ -349,18 +349,38 @@
 } BooleanModifierData;
 
 #define MOD_MDEF_INVERT_VGROUP (1<<0)
+#define MOD_MDEF_DYNAMIC_BIND  (1<<1)
 
+typedef struct MDefInfluence {
+	int vertex;
+	float weight;
+} MDefInfluence;
+
+typedef struct MDefCell {
+	int offset;
+	int totinfluence;
+} MDefCell;
+
 typedef struct MeshDeformModifierData {
 	ModifierData modifier;
 
 	struct Object *object;			/* mesh object */
 	char defgrp_name[32];			/* optional vertexgroup name */
 
-	float *bindweights, *bindcos;	/* computed binding weights */
 	short gridsize, needbind;
 	short flag, pad;
 
-	int totvert, totcagevert;
+	/* variables filled in when bound */
+	float *bindweights, *bindcos;	/* computed binding weights */
+	int totvert, totcagevert;		/* total vertices in mesh and cage */
+	MDefCell *dyngrid;				/* grid with dynamic binding cell points */
+	MDefInfluence *dyninfluences;	/* dynamic binding vertex influences */
+	int *dynverts, *pad2;			/* is this vertex bound or not? */
+	int dyngridsize;				/* size of the dynamic bind grid */
+	int totinfluence;				/* total number of vertex influences */
+	float dyncellmin[3];			/* offset of the dynamic bind grid */
+	float dyncellwidth;				/* width of dynamic bind cell */
+	float bindmat[4][4];			/* matrix of cage at binding time */
 } MeshDeformModifierData;
 
 #endif

Modified: trunk/blender/source/blender/src/buttons_editing.c
===================================================================
--- trunk/blender/source/blender/src/buttons_editing.c	2007-11-11 21:14:44 UTC (rev 12558)
+++ trunk/blender/source/blender/src/buttons_editing.c	2007-11-11 22:54:14 UTC (rev 12559)
@@ -1470,13 +1470,20 @@
 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
 	Object *ob = (Object*)ob_v;
 
-	if(mmd->bindweights) {
-		MEM_freeN(mmd->bindweights);
-		MEM_freeN(mmd->bindcos);
+	if(mmd->bindcos) {
+		if(mmd->bindweights) MEM_freeN(mmd->bindweights);
+		if(mmd->bindcos) MEM_freeN(mmd->bindcos);
+		if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
+		if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
+		if(mmd->dynverts) MEM_freeN(mmd->dynverts);
 		mmd->bindweights= NULL;
 		mmd->bindcos= NULL;
+		mmd->dyngrid= NULL;
+		mmd->dyninfluences= NULL;
+		mmd->dynverts= NULL;
 		mmd->totvert= 0;
 		mmd->totcagevert= 0;
+		mmd->totinfluence= 0;
 	}
 	else {
 		DerivedMesh *dm;
@@ -1640,7 +1647,8 @@
 		} else if (md->type==eModifierType_Array) {
 			height = 211;
 		} else if (md->type==eModifierType_MeshDeform) {
-			height = 73;
+			MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
+			height = (mmd->bindcos)? 73: 93;
 		} 
 		
 							/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
@@ -2130,14 +2138,15 @@
 			uiDefButBitS(block, TOG, MOD_MDEF_INVERT_VGROUP, B_MODIFIER_RECALC, "Inv", lx+buttonWidth-40, (cy-=19), 40,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
 
 			uiBlockBeginAlign(block);
-			if(mmd->bindweights) {
-				but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
+			if(mmd->bindcos) {
+				but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
 				uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
 			}
 			else {
-				but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-24), buttonWidth/2,19, 0, 0, 0, 0, 0, "Bind mesh to cage");

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list