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.
This commit is contained in:
@@ -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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
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);
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user