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:
-rw-r--r--source/blender/blenkernel/intern/modifier.c78
-rw-r--r--source/blender/include/BDR_editobject.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h4
-rw-r--r--source/blender/src/buttons_editing.c23
-rw-r--r--source/blender/src/editobject.c72
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 */