From 76d2f0da9eb690da863c715c0681fbc894a27cb1 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 11 Aug 2005 06:44:32 +0000 Subject: [PATCH] - couldn't help myself, got distracted working on something else and wondered what these silly data pointers in MDeformVert were for. Turns out they aren't even need! Just taking up extra memory and space and confusing the armature deform algorithm. Naturally I had to clean things up. Sorry Ton. Deform weights are still stored in a pretty expensive and unnecessary way, probably use about twice as much memory as needed, and do way too many memory allocs. - moved armature_deform_verts into armature.c - some python code accessed the MDeformWeight data pointers, but did so in a completely wrong way, I am positive this code could never have worked (or maybe things changed during tons refactor), regardless it wouldn't work now... will test later. --- source/blender/blenkernel/intern/armature.c | 152 +++++++++++-------- source/blender/blenkernel/intern/lattice.c | 11 -- source/blender/makesdna/DNA_meshdata_types.h | 1 - source/blender/makesdna/DNA_object_types.h | 1 - source/blender/python/api2_2x/NMesh.c | 22 +-- 5 files changed, 99 insertions(+), 88 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b545cbedb56..74260dca4ba 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -71,8 +71,6 @@ /* ugly Globals */ static float g_premat[4][4]; static float g_postmat[4][4]; -static MDeformVert *g_dverts; -static ListBase *g_defbase; static Object *g_deform; /* **************** Generic Functions, data level *************** */ @@ -390,17 +388,12 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan) void init_armature_deform(Object *parent, Object *ob) { bArmature *arm; - bDeformGroup *dg; - MDeformVert *dvert; - int totverts; - float obinv[4][4]; - int i, j; + float obinv[4][4]; arm = get_armature(parent); if (!arm) return; - g_defbase = &ob->defbase; g_deform = parent; Mat4Invert(obinv, ob->obmat); @@ -409,37 +402,7 @@ void init_armature_deform(Object *parent, Object *ob) Mat4Invert (g_premat, g_postmat); - /* Store the deformation verts */ - if (ob->type==OB_MESH){ - g_dverts = ((Mesh*)ob->data)->dvert; - totverts = ((Mesh*)ob->data)->totvert; - } - else{ - g_dverts=NULL; - totverts=0; - } - /* bone defmats are already in the channels, chan_mat */ - - /* Validate channel data in bDeformGroups */ - - for (dg=g_defbase->first; dg; dg=dg->next) - dg->data = (void*)get_pose_channel(parent->pose, dg->name); - - if (g_dverts){ - for (j=0; jtotweight; i++){ - bDeformGroup *fg; - fg = BLI_findlink (g_defbase, dvert->dw[i].def_nr); - - if (fg) - dvert->dw[i].data = fg->data; - else - dvert->dw[i].data = NULL; - } - } - } } float dist_to_bone (float vec[3], float b1[3], float b2[3]) @@ -504,7 +467,7 @@ static float calc_armature_deform_bone(Bone *bone, bPoseChannel *pchan, float *v return contrib; } -void calc_bone_deform (bPoseChannel *pchan, float weight, float *vec, float *co, float *contrib) +static void calc_bone_deform(bPoseChannel *pchan, float weight, float *vec, float *co, float *contrib) { float cop[3]; @@ -525,35 +488,21 @@ void calc_bone_deform (bPoseChannel *pchan, float weight, float *vec, float *co, void calc_armature_deform (Object *ob, float *co, int index) { bPoseChannel *pchan; - MDeformVert *dvert = g_dverts+index; float vec[3]; float contrib=0.0; - int i; vec[0]=vec[1]=vec[2]=0; /* Apply the object's matrix */ Mat4MulVecfl(g_premat, co); - /* using deform vertex groups */ - if (g_dverts){ - - for (i=0; itotweight; i++){ - pchan = (bPoseChannel *)dvert->dw[i].data; - if (pchan) calc_bone_deform (pchan, dvert->dw[i].weight, vec, co, &contrib); + for(pchan= g_deform->pose->chanbase.first; pchan; pchan= pchan->next) { + Bone *bone= pchan->bone; + if(bone) { + contrib+= calc_armature_deform_bone(bone, pchan, vec, co); } } - else { /* or use bone distances */ - Bone *bone; - - for(pchan= g_deform->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; - if(bone) { - contrib+= calc_armature_deform_bone(bone, pchan, vec, co); - } - } - } if (contrib>0.0){ vec[0]/=contrib; vec[1]/=contrib; @@ -564,6 +513,77 @@ void calc_armature_deform (Object *ob, float *co, int index) Mat4MulVecfl(g_postmat, co); } +void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts) +{ + bArmature *arm = armOb->data; + bPoseChannel **defnrToPC = NULL; + MDeformVert *dverts; + float obinv[4][4], premat[4][4], postmat[4][4]; + int i; + + Mat4Invert(obinv, target->obmat); + Mat4CpyMat4(premat, target->obmat); + Mat4MulMat4(postmat, armOb->obmat, obinv); + + Mat4Invert(premat, postmat); + + /* bone defmats are already in the channels, chan_mat */ + + if (target->type==OB_MESH){ + int numGroups = BLI_countlist(&target->defbase); + bDeformGroup *dg; + + dverts = ((Mesh*)target->data)->dvert; + + defnrToPC = MEM_callocN(sizeof(*defnrToPC)*numGroups, "defnrToBone"); + for (i=0,dg=target->defbase.first; dg; i++,dg=dg->next) { + defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); + } + } + else { + dverts = NULL; + } + + for(i=0; itotweight; j++){ + pchan = defnrToPC[dvert->dw[j].def_nr]; + if (pchan) calc_bone_deform(pchan, dvert->dw[j].weight, vec, co, &contrib); + } + } + else { + for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next) { + Bone *bone= pchan->bone; + if(bone) contrib+= calc_armature_deform_bone(bone, pchan, vec, co); + } + } + + if (contrib>0.0){ + vec[0]/=contrib; + vec[1]/=contrib; + vec[2]/=contrib; + } + + VecAddf(co, vec, co); + Mat4MulVecfl(postmat, co); + } + + if (defnrToPC) MEM_freeN(defnrToPC); +} + /* ************ END Armature Deform ******************* */ void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed) @@ -1168,7 +1188,7 @@ void GB_build_mats (float parmat[][4], float obmat[][4], float premat[][4], floa void GB_init_armature_deform(ListBase *defbase, float premat[][4], float postmat[][4]) { - g_defbase = defbase; +// g_defbase = defbase; Mat4CpyMat4 (g_premat, premat); Mat4CpyMat4 (g_postmat, postmat); @@ -1177,14 +1197,14 @@ void GB_init_armature_deform(ListBase *defbase, float premat[][4], float postmat void GB_validate_defgroups (Mesh *mesh, ListBase *defbase) { /* Should only be called when the mesh or armature changes */ - int j, i; - MDeformVert *dvert; +// int j, i; +// MDeformVert *dvert; - for (j=0; jtotvert; j++){ - dvert = mesh->dvert+j; - for (i=0; itotweight; i++) - dvert->dw[i].data = ((bDeformGroup*)BLI_findlink (defbase, dvert->dw[i].def_nr))->data; - } +// for (j=0; jtotvert; j++){ +// dvert = mesh->dvert+j; +// for (i=0; itotweight; i++) +// dvert->dw[i].data = ((bDeformGroup*)BLI_findlink (defbase, dvert->dw[i].def_nr))->data; +// } } void GB_calc_armature_deform (float *co, MDeformVert *dvert) @@ -1198,7 +1218,7 @@ void GB_calc_armature_deform (float *co, MDeformVert *dvert) for (i=0; itotweight; i++){ // pchan = (bPoseChannel *)dvert->dw[i].data; -// if (pchan) calc_bone_deform (pchan, dvert->dw[i].weight, vec, co, &contrib); +// if (pchan) calc_bone_deform(pchan, dvert->dw[i].weight, vec, co, &contrib); } if (contrib){ diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 1949915b2aa..c7d11559db7 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -556,17 +556,6 @@ void lattice_deform_verts(Object *laOb, Object *target, float (*vertexCos)[3], i end_latt_deform(); } -void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts) -{ - int a; - - init_armature_deform(armOb, target); - - for(a=0; advert[index].dw; for( i = 0; i < totinfluences; i++ ) { - /*Add the weight and the name of the bone, which is used to identify it */ - if( sweight->data ) + /* Disabled this code, it couldn't be correct! + * sweight->data was being set to a posechannel not a bone + * for one thing, and it is not always set for another. + * The only thing safe here is to return the defgroup number. -zr + */ +// if( sweight->data ) /* valid bone: return its name */ /* PyList_SetItem(influence_list, i, Py_BuildValue("[sf]", sweight->data->name, sweight->weight)); else // NULL bone: return Py_None instead PyList_SetItem(influence_list, i, Py_BuildValue("[Of]", Py_None, sweight->weight)); */ - PyList_Append( influence_list, - Py_BuildValue( "[sf]", - sweight-> - data-> - name, - sweight-> - weight ) ); +// PyList_Append( influence_list, +// Py_BuildValue( "[sf]", +// sweight-> +// data-> +// name, +// sweight-> +// weight ) ); /* Next weight */ sweight++;