Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2007-11-12 01:54:14 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2007-11-12 01:54:14 +0300
commit7f2e43968a917e4512117164a8645756893c93da (patch)
treecfd391353933b5e3c98aa7a5ba62bc65c6ef67e0 /source/blender
parent828eba48420c69bf25752b2ed0a2d47badbc0f67 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/modifier.c103
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/blenloader/intern/writefile.c5
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h24
-rw-r--r--source/blender/src/buttons_editing.c25
-rw-r--r--source/blender/src/meshlaplacian.c119
6 files changed, 224 insertions, 57 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 743926ed91b..9c4280166ec 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -4935,8 +4935,11 @@ static void meshdeformModifier_freeData(ModifierData *md)
{
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 void meshdeformModifier_updateDepgraph(
}
}
+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 @@ static void meshdeformModifier_do(
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 @@ static void meshdeformModifier_do(
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 @@ static void meshdeformModifier_do(
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 @@ static void meshdeformModifier_do(
}
}
- 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;
+ 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;
+ }
}
if(totweight > 0.0f) {
VecMulf(co, fac/totweight);
- Mat3MulVecfl(icmat, co);
+ Mat3MulVecfl(iobmat, co);
VECADD(vertexCos[b], vertexCos[b], co);
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 384a6d93480..615d1759f66 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2894,6 +2894,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
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 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
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])
}
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 43907a30ac2..1aa47960bad 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -787,11 +787,16 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
}
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);
}
}
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 42016ad1c16..80011c233a8 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -349,6 +349,17 @@ typedef struct BooleanModifierData {
} 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;
@@ -356,11 +367,20 @@ typedef struct MeshDeformModifierData {
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
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index abd2fa015c3..c5720ac47af 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1470,13 +1470,20 @@ static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
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 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
} 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 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
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");
+ but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
- uiDefButS(block, NUM, B_NOP, "Precision:", lx+(buttonWidth+1)/2,(cy-=24), buttonWidth/2,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding");
+ uiDefButS(block, NUM, B_NOP, "Precision:", lx,(cy-19), buttonWidth/2 + 20,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding");
+ uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
}
uiBlockEndAlign(block);
}
diff --git a/source/blender/src/meshlaplacian.c b/source/blender/src/meshlaplacian.c
index c27694ae51e..c689306e848 100644
--- a/source/blender/src/meshlaplacian.c
+++ b/source/blender/src/meshlaplacian.c
@@ -805,11 +805,8 @@ void rigid_deform_iteration()
laplacian_begin_solve(sys, i);
for(a=0; a<sys->totvert; a++)
- if(!sys->vpinned[a]) {
- /*if (i==0)
- printf("rhs %f\n", sys->rigid.rhs[a][0]);*/
+ if(!sys->vpinned[a])
laplacian_add_right_hand_side(sys, a, sys->rigid.rhs[a][i]);
- }
if(laplacian_system_solve(sys)) {
for(a=0, eve=em->verts.first; eve; eve=eve->next, a++)
@@ -823,8 +820,6 @@ void rigid_deform_iteration()
break;
}
}
-
- /*printf("\n--------------------------------------------\n\n");*/
}
static void rigid_laplacian_create(LaplacianSystem *sys)
@@ -926,6 +921,8 @@ void rigid_deform_end(int cancel)
#define MESHDEFORM_LEN_THRESHOLD 1e-6
+#define MESHDEFORM_MIN_INFLUENCE 0.005
+
static int MESHDEFORM_OFFSET[7][3] =
{{0,0,0}, {1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}};
@@ -935,6 +932,12 @@ typedef struct MDefBoundIsect {
float len;
} MDefBoundIsect;
+typedef struct MDefBindInfluence {
+ struct MDefBindInfluence *next;
+ float weight;
+ int vertex;
+} MDefBindInfluence;
+
typedef struct MeshDeformBind {
/* grid dimensions */
float min[3], max[3];
@@ -957,6 +960,7 @@ typedef struct MeshDeformBind {
/* mesh stuff */
int *inside;
float *weights;
+ MDefBindInfluence **dyngrid;
float cagemat[4][4];
/* direct solver */
@@ -1594,16 +1598,32 @@ static void meshdeform_matrix_solve(MeshDeformBind *mdb)
mdb->totalphi[b] += mdb->phi[b];
}
- /* compute weights for each vertex */
- for(b=0; b<mdb->totvert; b++) {
- if(mdb->inside[b]) {
- VECCOPY(vec, mdb->vertexcos[b]);
- Mat4MulVecfl(mdb->cagemat, vec);
- gridvec[0]= (vec[0] - mdb->min[0] - mdb->halfwidth[0])/mdb->width[0];
- gridvec[1]= (vec[1] - mdb->min[1] - mdb->halfwidth[1])/mdb->width[1];
- gridvec[2]= (vec[2] - mdb->min[2] - mdb->halfwidth[2])/mdb->width[2];
-
- mdb->weights[b*mdb->totcagevert + a]= meshdeform_interp_w(mdb, gridvec, vec, a);
+ if(mdb->weights) {
+ /* static bind : compute weights for each vertex */
+ for(b=0; b<mdb->totvert; b++) {
+ if(mdb->inside[b]) {
+ VECCOPY(vec, mdb->vertexcos[b]);
+ Mat4MulVecfl(mdb->cagemat, vec);
+ gridvec[0]= (vec[0] - mdb->min[0] - mdb->halfwidth[0])/mdb->width[0];
+ gridvec[1]= (vec[1] - mdb->min[1] - mdb->halfwidth[1])/mdb->width[1];
+ gridvec[2]= (vec[2] - mdb->min[2] - mdb->halfwidth[2])/mdb->width[2];
+
+ mdb->weights[b*mdb->totcagevert + a]= meshdeform_interp_w(mdb, gridvec, vec, a);
+ }
+ }
+ }
+ else {
+ MDefBindInfluence *inf;
+
+ /* dynamic bind */
+ for(b=0; b<mdb->size3; b++) {
+ if(mdb->phi[b] >= 0.0f) { //MESHDEFORM_MIN_INFLUENCE) {
+ inf= BLI_memarena_alloc(mdb->memarena, sizeof(*inf));
+ inf->vertex= a;
+ inf->weight= mdb->phi[b];
+ inf->next= mdb->dyngrid[b];
+ mdb->dyngrid[b]= inf;
+ }
}
}
}
@@ -1634,21 +1654,16 @@ static void meshdeform_matrix_solve(MeshDeformBind *mdb)
void harmonic_coordinates_bind(MeshDeformModifierData *mmd, float (*vertexcos)[3], int totvert, float cagemat[][4])
{
MeshDeformBind mdb;
+ MDefBindInfluence *inf;
+ MDefInfluence *mdinf;
+ MDefCell *cell;
MVert *mvert;
- float center[3], vec[3], maxwidth;
- int a, x, y, z, totinside;
+ float center[3], vec[3], maxwidth, totweight;
+ int a, b, x, y, z, totinside, offset;
waitcursor(1);
start_progress_bar();
- /* free exisiting weights */
- if(mmd->bindweights) {
- MEM_freeN(mmd->bindweights);
- MEM_freeN(mmd->bindcos);
- mmd->bindweights= NULL;
- mmd->bindcos= NULL;
- }
-
memset(&mdb, 0, sizeof(MeshDeformBind));
/* get mesh and cage mesh */
@@ -1679,9 +1694,13 @@ void harmonic_coordinates_bind(MeshDeformModifierData *mmd, float (*vertexcos)[3
mdb.boundisect= MEM_callocN(sizeof(*mdb.boundisect)*mdb.size3, "MDefBoundIsect");
mdb.semibound= MEM_callocN(sizeof(int)*mdb.size3, "MDefSemiBound");
- mdb.weights= MEM_callocN(sizeof(float)*mdb.totvert*mdb.totcagevert, "MDefWeights");
mdb.inside= MEM_callocN(sizeof(int)*mdb.totvert, "MDefInside");
+ if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
+ mdb.dyngrid= MEM_callocN(sizeof(MDefBindInfluence*)*mdb.size3, "MDefDynGrid");
+ else
+ mdb.weights= MEM_callocN(sizeof(float)*mdb.totvert*mdb.totcagevert, "MDefWeights");
+
mdb.memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
BLI_memarena_use_calloc(mdb.memarena);
@@ -1752,10 +1771,53 @@ void harmonic_coordinates_bind(MeshDeformModifierData *mmd, float (*vertexcos)[3
meshdeform_matrix_solve(&mdb);
/* assign results */
- mmd->bindweights= mdb.weights;
mmd->bindcos= (float*)mdb.cagecos;
mmd->totvert= mdb.totvert;
mmd->totcagevert= mdb.totcagevert;
+ Mat4CpyMat4(mmd->bindmat, mmd->object->obmat);
+
+ if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
+ mmd->totinfluence= 0;
+ for(a=0; a<mdb.size3; a++)
+ for(inf=mdb.dyngrid[a]; inf; inf=inf->next)
+ mmd->totinfluence++;
+
+ /* convert MDefBindInfluences to smaller MDefInfluences */
+ mmd->dyngrid= MEM_callocN(sizeof(MDefCell)*mdb.size3, "MDefDynGrid");
+ mmd->dyninfluences= MEM_callocN(sizeof(MDefInfluence)*mmd->totinfluence, "MDefInfluence");
+ offset= 0;
+ for(a=0; a<mdb.size3; a++) {
+ cell= &mmd->dyngrid[a];
+ cell->offset= offset;
+
+ totweight= 0.0f;
+ mdinf= mmd->dyninfluences + cell->offset;
+ for(inf=mdb.dyngrid[a]; inf; inf=inf->next, mdinf++) {
+ mdinf->weight= inf->weight;
+ mdinf->vertex= inf->vertex;
+ totweight += mdinf->weight;
+ cell->totinfluence++;
+ }
+
+ if(totweight > 0.0f) {
+ mdinf= mmd->dyninfluences + cell->offset;
+ for(b=0; b<cell->totinfluence; b++, mdinf++)
+ mdinf->weight /= totweight;
+ }
+
+ offset += cell->totinfluence;
+ }
+
+ mmd->dynverts= mdb.inside;
+ mmd->dyngridsize= mdb.size;
+ VECCOPY(mmd->dyncellmin, mdb.min);
+ mmd->dyncellwidth= mdb.width[0];
+ MEM_freeN(mdb.dyngrid);
+ }
+ else {
+ mmd->bindweights= mdb.weights;
+ MEM_freeN(mdb.inside);
+ }
/* transform bindcos to world space */
for(a=0; a<mdb.totcagevert; a++)
@@ -1768,7 +1830,6 @@ void harmonic_coordinates_bind(MeshDeformModifierData *mmd, float (*vertexcos)[3
MEM_freeN(mdb.totalphi);
MEM_freeN(mdb.boundisect);
MEM_freeN(mdb.semibound);
- MEM_freeN(mdb.inside);
BLI_memarena_free(mdb.memarena);
end_progress_bar();