diff options
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 66 | ||||
-rw-r--r-- | source/blender/editors/armature/meshlaplacian.c | 10 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 12 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshdeform.c | 92 |
5 files changed, 150 insertions, 33 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index ae6f1f5ed85..d6ab99d6534 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -321,5 +321,8 @@ struct LinkNode *modifiers_calcDataMasks(struct Scene *scene, int required_mode); struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob); +/* here for do_versions */ +void modifier_mdef_compact_influences(struct ModifierData *md); + #endif diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 32a07db1768..8b0861252fe 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3852,24 +3852,35 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) else if (md->type==eModifierType_MeshDeform) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; - mmd->bindweights= newdataadr(fd, mmd->bindweights); - mmd->bindcos= newdataadr(fd, mmd->bindcos); + mmd->bindinfluences= newdataadr(fd, mmd->bindinfluences); + mmd->bindoffsets= newdataadr(fd, mmd->bindoffsets); + mmd->bindcagecos= newdataadr(fd, mmd->bindcagecos); mmd->dyngrid= newdataadr(fd, mmd->dyngrid); mmd->dyninfluences= newdataadr(fd, mmd->dyninfluences); mmd->dynverts= newdataadr(fd, mmd->dynverts); + mmd->bindweights= newdataadr(fd, mmd->bindweights); + mmd->bindcos= newdataadr(fd, mmd->bindcos); + if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) { int a; + if(mmd->bindoffsets) + for(a=0; a<mmd->totvert+1; a++) + SWITCH_INT(mmd->bindoffsets[a]) + if(mmd->bindcagecos) + for(a=0; a<mmd->totcagevert*3; a++) + SWITCH_INT(mmd->bindcagecos[a]) + if(mmd->dynverts) + for(a=0; a<mmd->totvert; a++) + SWITCH_INT(mmd->dynverts[a]) + if(mmd->bindweights) for(a=0; a<mmd->totcagevert*mmd->totvert; a++) SWITCH_INT(mmd->bindweights[a]) if(mmd->bindcos) for(a=0; a<mmd->totcagevert*3; a++) SWITCH_INT(mmd->bindcos[a]) - if(mmd->dynverts) - for(a=0; a<mmd->totvert; a++) - SWITCH_INT(mmd->dynverts[a]) } } } @@ -5169,7 +5180,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) /*comma expressions, (e.g. expr1, expr2, expr3) evalutate each expression, from left to right. the right-most expression sets the result of the comma expression as a whole*/ - for(cl= sconsole->history.first; cl && (clnext=cl->next), cl; cl= clnext) { + for(cl= sconsole->history.first; cl && (clnext=cl->next); cl= clnext) { cl->line= newdataadr(fd, cl->line); if (!cl->line) { BLI_remlink(&sconsole->history, cl); @@ -6451,6 +6462,30 @@ static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype) } } +static void do_version_mdef_250(FileData *fd, Library *lib, Main *main) +{ + Object *ob; + ModifierData *md; + MeshDeformModifierData *mmd; + + for(ob= main->object.first; ob; ob=ob->id.next) { + for(md=ob->modifiers.first; md; md=md->next) { + if(md->type == eModifierType_MeshDeform) { + mmd= (MeshDeformModifierData*)md; + + if(mmd->bindcos) { + /* make bindcos NULL in order to trick older versions + into thinking that the mesh was not bound yet */ + mmd->bindcagecos= mmd->bindcos; + mmd->bindcos= NULL; + + modifier_mdef_compact_influences(md); + } + } + } + } +} + static void do_version_constraints_radians_degrees_250(ListBase *lb) { bConstraint *con; @@ -10780,7 +10815,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put 2.50 compatibility code here until next subversion bump */ { - + do_version_mdef_250(fd, lib, main); } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ @@ -12219,16 +12254,17 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) printf(" absolute lib: %s\n", mainptr->curlib->filename); printf(" relative lib: %s\n", mainptr->curlib->name); printf(" enter a new path:\n"); - scanf("%s", newlib_path); - strcpy(mainptr->curlib->name, newlib_path); - strcpy(mainptr->curlib->filename, newlib_path); - cleanup_path(G.sce, mainptr->curlib->filename); - - fd= blo_openblenderfile(mainptr->curlib->filename, basefd->reports); + if(scanf("%s", newlib_path) > 0) { + strcpy(mainptr->curlib->name, newlib_path); + strcpy(mainptr->curlib->filename, newlib_path); + cleanup_path(G.sce, mainptr->curlib->filename); + + fd= blo_openblenderfile(mainptr->curlib->filename, basefd->reports); - if(fd) { - printf("found: '%s', party on macuno!\n", mainptr->curlib->filename); + if(fd) { + printf("found: '%s', party on macuno!\n", mainptr->curlib->filename); + } } } } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 700f4573e3a..f0f7bc9eb88 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -44,6 +44,7 @@ #include "BLI_memarena.h" #include "BKE_DerivedMesh.h" +#include "BKE_modifier.h" #include "BKE_utildefines.h" #ifdef RIGID_DEFORM @@ -1991,19 +1992,22 @@ void mesh_deform_bind(Scene *scene, DerivedMesh *dm, MeshDeformModifierData *mmd #endif /* assign bind variables */ - mmd->bindcos= (float*)mdb.cagecos; + mmd->bindcagecos= (float*)mdb.cagecos; mmd->totvert= mdb.totvert; mmd->totcagevert= mdb.totcagevert; copy_m4_m4(mmd->bindmat, mmd->object->obmat); - /* transform bindcos to world space */ + /* transform bindcagecos to world space */ for(a=0; a<mdb.totcagevert; a++) - mul_m4_v3(mmd->object->obmat, mmd->bindcos+a*3); + mul_m4_v3(mmd->object->obmat, mmd->bindcagecos+a*3); /* free */ mdb.cagedm->release(mdb.cagedm); MEM_freeN(mdb.vertexcos); + /* compact weights */ + modifier_mdef_compact_influences((ModifierData*)mmd); + end_progress_bar(); waitcursor(0); } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index a52c1f83433..3117536a7dc 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -516,9 +516,13 @@ typedef struct MeshDeformModifierData { short gridsize, flag, mode, pad; - /* variables filled in when bound */ - float *bindweights, *bindcos; /* computed binding weights */ + /* result of static binding */ + MDefInfluence *bindinfluences; /* influences */ + int *bindoffsets; /* offsets into influences array */ + float *bindcagecos; /* coordinates that cage was bound with */ int totvert, totcagevert; /* total vertices in mesh and cage */ + + /* result of dynamic binding */ MDefCell *dyngrid; /* grid with dynamic binding cell points */ MDefInfluence *dyninfluences; /* dynamic binding vertex influences */ int *dynverts, *pad2; /* is this vertex bound or not? */ @@ -528,6 +532,10 @@ typedef struct MeshDeformModifierData { float dyncellwidth; /* width of dynamic bind cell */ float bindmat[4][4]; /* matrix of cage at binding time */ + /* deprecated storage */ + float *bindweights; /* deprecated inefficient storage */ + float *bindcos; /* deprecated storage of cage coords */ + /* runtime */ void (*bindfunc)(struct Scene *scene, struct DerivedMesh *dm, struct MeshDeformModifierData *mmd, diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index f10dbf94060..4b53ac910d1 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -58,8 +58,9 @@ static void freeData(ModifierData *md) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; - if(mmd->bindweights) MEM_freeN(mmd->bindweights); - if(mmd->bindcos) MEM_freeN(mmd->bindcos); + if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences); + if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets); + if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos); if(mmd->dyngrid) MEM_freeN(mmd->dyngrid); if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences); if(mmd->dynverts) MEM_freeN(mmd->dynverts); @@ -170,7 +171,7 @@ static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3 } static void meshdeformModifier_do( - ModifierData *md, Object *ob, DerivedMesh *dm, + ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; @@ -180,11 +181,13 @@ static void meshdeformModifier_do( MDeformVert *dvert = NULL; MDeformWeight *dw; MVert *cagemvert; + MDefInfluence *influences; + int *offsets; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; - float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3]; + float weight, totweight, fac, co[3], (*dco)[3], (*bindcagecos)[3]; int a, b, totvert, totcagevert, defgrp_index; - if(!mmd->object || (!mmd->bindcos && !mmd->bindfunc)) + if(!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) return; /* get cage derivedmesh */ @@ -216,7 +219,7 @@ static void meshdeformModifier_do( copy_m3_m4(icagemat, iobmat); /* bind weights if needed */ - if(!mmd->bindcos) { + if(!mmd->bindcagecos) { static int recursive = 0; /* progress bar redraw can make this recursive .. */ @@ -231,15 +234,16 @@ static void meshdeformModifier_do( totvert= numVerts; totcagevert= cagedm->getNumVerts(cagedm); - if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindcos) { + if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindcagecos) { cagedm->release(cagedm); return; } /* setup deformation data */ cagemvert= cagedm->getVertArray(cagedm); - weights= mmd->bindweights; - bindcos= (float(*)[3])mmd->bindcos; + influences= mmd->bindinfluences; + offsets= mmd->bindoffsets; + bindcagecos= (float(*)[3])mmd->bindcagecos; dco= MEM_callocN(sizeof(*dco)*totcagevert, "MDefDco"); for(a=0; a<totcagevert; a++) { @@ -249,7 +253,7 @@ static void meshdeformModifier_do( if(G.rt != 527) { mul_m4_v3(mmd->bindmat, co); /* compute difference with world space bind coord */ - sub_v3_v3v3(dco[a], co, bindcos[a]); + sub_v3_v3v3(dco[a], co, bindcagecos[a]); } else copy_v3_v3(dco[a], co); @@ -296,9 +300,9 @@ 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]; - madd_v3_v3fl(co, dco[a], weight); + for(a=offsets[b]; a<offsets[b+1]; a++) { + weight= influences[a].weight; + madd_v3_v3fl(co, dco[influences[a].vertex], weight); totweight += weight; } } @@ -352,6 +356,68 @@ static void deformVertsEM( dm->release(dm); } +#define MESHDEFORM_MIN_INFLUENCE 0.00001 + +void modifier_mdef_compact_influences(ModifierData *md) +{ + MeshDeformModifierData *mmd= (MeshDeformModifierData*)md; + float weight, *weights, totweight; + int totinfluence, totvert, totcagevert, a, b; + + weights= mmd->bindweights; + if(!weights) + return; + + totvert= mmd->totvert; + totcagevert= mmd->totcagevert; + + /* count number of influences above threshold */ + for(b=0; b<totvert; b++) { + for(a=0; a<totcagevert; a++) { + weight= weights[a + b*totcagevert]; + + if(weight > MESHDEFORM_MIN_INFLUENCE) + mmd->totinfluence++; + } + } + + /* allocate bind influences */ + mmd->bindinfluences= MEM_callocN(sizeof(MDefInfluence)*mmd->totinfluence, "MDefBindInfluence"); + mmd->bindoffsets= MEM_callocN(sizeof(int)*(totvert+1), "MDefBindOffset"); + + /* write influences */ + totinfluence= 0; + + for(b=0; b<totvert; b++) { + mmd->bindoffsets[b]= totinfluence; + totweight= 0.0f; + + /* sum total weight */ + for(a=0; a<totcagevert; a++) { + weight= weights[a + b*totcagevert]; + + if(weight > MESHDEFORM_MIN_INFLUENCE) + totweight += weight; + } + + /* assign weights normalized */ + for(a=0; a<totcagevert; a++) { + weight= weights[a + b*totcagevert]; + + if(weight > MESHDEFORM_MIN_INFLUENCE) { + mmd->bindinfluences[totinfluence].weight= weight/totweight; + mmd->bindinfluences[totinfluence].vertex= a; + totinfluence++; + } + } + } + + mmd->bindoffsets[b]= totinfluence; + + /* free */ + MEM_freeN(mmd->bindweights); + mmd->bindweights= NULL; +} ModifierTypeInfo modifierType_MeshDeform = { /* name */ "MeshDeform", |