diff options
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 78 | ||||
-rw-r--r-- | source/blender/include/BDR_editobject.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 4 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 23 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 72 |
5 files changed, 136 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f8769dd6ece..bb21343e039 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1077,29 +1077,67 @@ static void hookModifier_deformVerts(ModifierData *md, Object *ob, void *derived Mat4Invert(ob->imat, ob->obmat); Mat4MulSerie(mat, ob->imat, hmd->object->obmat, hmd->parentinv, NULL, NULL, NULL, NULL, NULL); - for (i=0; i<hmd->totindex; i++) { - int index = hmd->indexar[i]; - - /* This should always be true and I don't generally like - * "paranoid" style code like this, but old files can have - * indices that are out of range because old blender did - * not correct them on exit editmode. - zr - */ - if (index<numVerts) { - float *co = vertexCos[index]; - float fac = hmd->force; - - if(hmd->falloff!=0.0) { - float len= VecLenf(co, hmd->cent); - if(len > hmd->falloff) fac = 0.0; - else if(len>0.0) fac *= sqrt(1.0 - len/hmd->falloff); - } + /* vertex indices? */ + if(hmd->indexar) { + for (i=0; i<hmd->totindex; i++) { + int index = hmd->indexar[i]; + + /* This should always be true and I don't generally like + * "paranoid" style code like this, but old files can have + * indices that are out of range because old blender did + * not correct them on exit editmode. - zr + */ + if (index<numVerts) { + float *co = vertexCos[index]; + float fac = hmd->force; + + if(hmd->falloff!=0.0) { + float len= VecLenf(co, hmd->cent); + if(len > hmd->falloff) fac = 0.0; + else if(len>0.0) fac *= sqrt(1.0 - len/hmd->falloff); + } - if(fac!=0.0) { - VecMat4MulVecfl(vec, mat, co); - VecLerpf(co, co, vec, fac); + if(fac!=0.0) { + VecMat4MulVecfl(vec, mat, co); + VecLerpf(co, co, vec, fac); + } + } + } + } + else { /* vertex group hook */ + bDeformGroup *curdef; + Mesh *me= ob->data; + int index=0; + + /* find the group (weak loop-in-loop) */ + for (curdef = ob->defbase.first; curdef; curdef=curdef->next, index++) + if (!strcmp(curdef->name, hmd->name)) + break; + + if(curdef && me->dvert) { + MDeformVert *dvert= me->dvert; + int i, j; + + for (i=0; i < me->totvert; i++, dvert++) { + for(j=0; j<dvert->totweight; j++) { + if (dvert->dw[j].def_nr == index) { + float fac = hmd->force*dvert->dw[j].weight; + float *co = vertexCos[i]; + + if(hmd->falloff!=0.0) { + float len= VecLenf(co, hmd->cent); + if(len > hmd->falloff) fac = 0.0; + else if(len>0.0) fac *= sqrt(1.0 - len/hmd->falloff); + } + + VecMat4MulVecfl(vec, mat, co); + VecLerpf(co, co, vec, fac); + + } + } } } + } } diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index 2ac7bfa8910..99c9655a763 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -107,7 +107,7 @@ void mirrormenu(void); void add_hook(void); void hook_select(struct HookModifierData *hmd); -int hook_getIndexArray(int **indexar, float *cent_r); +int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r); #endif /* BDR_EDITOBJECT_H */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index e858fa5aa96..065af972dd4 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -49,6 +49,7 @@ typedef enum { eSubsurfModifierFlag_DebugIncr = (1<<1), eSubsurfModifierFlag_ControlEdges = (1<<2) } SubsurfModifierFlag; + typedef struct SubsurfModifierData { ModifierData modifier; @@ -115,9 +116,10 @@ typedef struct HookModifierData { float cent[3]; /* visualization of hook */ float falloff; /* if not zero, falloff is distance where influence zero */ - int *indexar; + int *indexar; /* if NULL, it's using vertexgroup */ int totindex; float force; + char name[32]; /* optional vertexgroup name */ } HookModifierData; typedef struct SoftbodyModifierData { diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index fba3e570681..3faf76c9e32 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1050,10 +1050,13 @@ static void modifiers_reassignHook(void *ob_v, void *md_v) ModifierData *md = md_v; HookModifierData *hmd = (HookModifierData*) md; float cent[3]; - int *indexar, tot = hook_getIndexArray(&indexar, cent); + int *indexar, tot, ok; + char name[32]; + + ok= hook_getIndexArray(&tot, &indexar, name, cent); - if (!tot) { - error("Requires selected vertices"); + if (!ok) { + error("Requires selected vertices or active Vertex Group"); } else { if (hmd->indexar) { MEM_freeN(hmd->indexar); @@ -1187,9 +1190,12 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco } else if (md->type==eModifierType_Armature) { height = 46; } else if (md->type==eModifierType_Hook) { + HookModifierData *hmd = (HookModifierData*) md; height = 86; if (editing) height += 20; + if(hmd->indexar==NULL) + height += 20; } else if (md->type==eModifierType_Softbody) { height = 26; } else if (md->type==eModifierType_Boolean) { @@ -1276,11 +1282,14 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff: ", lx, (cy-=19), buttonWidth,19, &hmd->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends"); - uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Force: ", lx, (cy-=19), buttonWidth,19, &hmd->force, 0.0, 1.0, 100, 0, "Set relative force of hook"); - uiDefIDPoinBut(block, test_obpoin_but, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &hmd->object, "Parent Object for hook, also recalculates and clears offset"); - but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Reset", lx, (cy-=19), 80,19, NULL, 0.0, 0.0, 0, 0, "Recalculate and clear offset (transform) of hook"); + uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Force: ", lx, (cy-=19), buttonWidth,19, &hmd->force, 0.0, 1.0, 100, 0, "Set relative force of hook"); + uiDefIDPoinBut(block, test_obpoin_but, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &hmd->object, "Parent Object for hook, also recalculates and clears offset"); + if(hmd->indexar==NULL) + uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name"); + uiBlockBeginAlign(block); + but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Reset", lx, (cy-=19), 80,19, NULL, 0.0, 0.0, 0, 0, "Recalculate and clear offset (transform) of hook"); uiButSetFunc(but, modifiers_clearHookOffset, ob, md); - but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Recenter", lx+80, cy, buttonWidth-80,19, NULL, 0.0, 0.0, 0, 0, "Sets hook center to cursor position"); + but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Recenter", lx+80, cy, buttonWidth-80,19, NULL, 0.0, 0.0, 0, 0, "Sets hook center to cursor position"); uiButSetFunc(but, modifiers_cursorHookCenter, ob, md); if (editing) { diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 6beeda7636b..8893b152f76 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -277,7 +277,7 @@ void delete_obj(int ok) BIF_undo_push("Delete object(s)"); } -static int return_editmesh_indexar(int **indexar, float *cent) +static int return_editmesh_indexar(int *tot, int **indexar, float *cent) { EditMesh *em = G.editMesh; EditVert *eve; @@ -289,6 +289,7 @@ static int return_editmesh_indexar(int **indexar, float *cent) if(totvert==0) return 0; *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); + *tot= totvert; nr= 0; cent[0]= cent[1]= cent[2]= 0.0; @@ -305,6 +306,36 @@ static int return_editmesh_indexar(int **indexar, float *cent) return totvert; } +static int return_editmesh_vgroup(char *name, float *cent) +{ + EditMesh *em = G.editMesh; + EditVert *eve; + int i, totvert=0; + + cent[0]= cent[1]= cent[2]= 0.0; + + if (G.obedit->actdef) { + + /* find the vertices */ + for(eve= em->verts.first; eve; eve= eve->next) { + for (i=0; i<eve->totweight; i++){ + if(eve->dw[i].def_nr == (G.obedit->actdef-1)) { + totvert++; + VecAddf(cent, cent, eve->co); + } + } + } + if(totvert) { + bDeformGroup *defGroup = BLI_findlink(&G.obedit->defbase, G.obedit->actdef-1); + strcpy(name, defGroup->name); + VecMulf(cent, 1.0f/(float)totvert); + return 1; + } + } + + return 0; +} + static void select_editmesh_hook(HookModifierData *hmd) { EditMesh *em = G.editMesh; @@ -320,7 +351,7 @@ static void select_editmesh_hook(HookModifierData *hmd) EM_select_flush(); } -static int return_editlattice_indexar(int **indexar, float *cent) +static int return_editlattice_indexar(int *tot, int **indexar, float *cent) { BPoint *bp; int *index, nr, totvert=0, a; @@ -338,6 +369,7 @@ static int return_editlattice_indexar(int **indexar, float *cent) if(totvert==0) return 0; *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); + *tot= totvert; nr= 0; cent[0]= cent[1]= cent[2]= 0.0; @@ -377,7 +409,7 @@ static void select_editlattice_hook(HookModifierData *hmd) } } -static int return_editcurve_indexar(int **indexar, float *cent) +static int return_editcurve_indexar(int *tot, int **indexar, float *cent) { extern ListBase editNurb; Nurb *nu; @@ -408,6 +440,7 @@ static int return_editcurve_indexar(int **indexar, float *cent) if(totvert==0) return 0; *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); + *tot= totvert; nr= 0; cent[0]= cent[1]= cent[2]= 0.0; @@ -507,16 +540,23 @@ void hook_select(HookModifierData *hmd) else if(G.obedit->type==OB_CURVE) select_editcurve_hook(hmd); else if(G.obedit->type==OB_SURF) select_editcurve_hook(hmd); } -int hook_getIndexArray(int **indexar, float *cent_r) + +int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r) { + *indexar= NULL; + *tot= 0; + name[0]= 0; + switch(G.obedit->type) { - case OB_MESH: - return return_editmesh_indexar(indexar, cent_r); + case OB_MESH: + /* check selected vertices first */ + if( return_editmesh_indexar(tot, indexar, cent_r)) return 1; + else return return_editmesh_vgroup(name, cent_r); case OB_CURVE: case OB_SURF: - return return_editcurve_indexar(indexar, cent_r); + return return_editcurve_indexar(tot, indexar, cent_r); case OB_LATTICE: - return return_editlattice_indexar(indexar, cent_r); + return return_editlattice_indexar(tot, indexar, cent_r); default: return 0; } @@ -527,13 +567,12 @@ void add_hook(void) ModifierData *md = NULL; HookModifierData *hmd = NULL; Object *ob=NULL; - float cent[3]; - int tot=0, *indexar, mode; + int mode; if(G.obedit==NULL) return; if(modifiers_findByType(G.obedit, eModifierType_Hook)) - mode= pupmenu("Hooks %t|Add Hook, To New Empty %x1|Add Hook, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6"); + mode= pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6"); else mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2"); @@ -604,10 +643,14 @@ void add_hook(void) /* do it, new hooks or reassign */ if(mode==1 || mode==2 || mode==4) { - tot = hook_getIndexArray(&indexar, cent); + float cent[3]; + int tot, ok, *indexar; + char name[32]; + + ok = hook_getIndexArray(&tot, &indexar, name, cent); - if(tot==0) { - error("Requires selected vertices"); + if(ok==0) { + error("Requires selected vertices or active Vertex Group"); } else { @@ -646,6 +689,7 @@ void add_hook(void) hmd->indexar= indexar; VECCOPY(hmd->cent, cent); hmd->totindex= tot; + BLI_strncpy(hmd->name, name, 32); if(mode==1 || mode==2) { /* matrix calculus */ |