diff options
-rw-r--r-- | source/blender/blenkernel/BKE_deform.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_simple_deform.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 28 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 38 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/shrinkwrap.c | 20 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/simple_deform.c | 58 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 20 |
8 files changed, 107 insertions, 64 deletions
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index a1975dd4265..b0570e8bd45 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -46,5 +46,8 @@ int get_defgroup_num (struct Object *ob, struct bDeformGroup *dg); int get_named_vertexgroup_num (Object *ob, char *name); void unique_vertexgroup_name (struct bDeformGroup *dg, struct Object *ob); +float deformvert_get_weight(struct MDeformVert *dvert, int group_num); +float vertexgroup_get_vertex_weight(struct MDeformVert *dvert, int index, int group_num); + #endif diff --git a/source/blender/blenkernel/BKE_simple_deform.h b/source/blender/blenkernel/BKE_simple_deform.h index dd4f3786e62..161871a64bc 100644 --- a/source/blender/blenkernel/BKE_simple_deform.h +++ b/source/blender/blenkernel/BKE_simple_deform.h @@ -33,7 +33,7 @@ struct Object; struct DerivedMesh; struct SimpleDeformModifierData; -void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, float (*vertexCos)[3], int numVerts); +void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts); #endif diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index ab53571b62d..888432005d0 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -220,3 +220,31 @@ void unique_vertexgroup_name (bDeformGroup *dg, Object *ob) } } } + +float deformvert_get_weight(struct MDeformVert *dvert, int group_num) +{ + if(dvert) + { + MDeformWeight *dw = dvert->dw; + int i; + + for(i=dvert->totweight; i>0; i--, dw++) + if(dw->def_nr == group_num) + return dw->weight; + } + + /* Not found */ + return 0.0; +} + +float vertexgroup_get_vertex_weight(struct MDeformVert *dvert, int index, int group_num) +{ + if(group_num == -1) + return 1.0; + + if(dvert == 0) + return 0.0; + + return deformvert_get_weight(dvert+index, group_num); +} + diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index d3cc451c6fc..6779b18154f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -3,7 +3,7 @@ * * ***** BEGIN GPL LICENSE BLOCK ***** * -* This program is free software; you can redistribute it and/or +* This program is free software; you can redistribute it and/orw * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. @@ -100,6 +100,7 @@ #include "BKE_utildefines.h" #include "depsgraph_private.h" #include "BKE_bmesh.h" +#include "BKE_deform.h" #include "BKE_shrinkwrap.h" #include "BKE_simple_deform.h" @@ -6088,22 +6089,6 @@ CustomDataMask explodeModifier_requiredDataMask(ModifierData *md) return dataMask; } -/* this should really be put somewhere permanently */ -static float vert_weight(MDeformVert *dvert, int group) -{ - MDeformWeight *dw; - int i; - - if(dvert) { - dw= dvert->dw; - for(i= dvert->totweight; i>0; i--, dw++) { - if(dw->def_nr == group) return dw->weight; - if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/ - } - } - return 0.0; -} - static void explodeModifier_createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Object *ob, DerivedMesh *dm) @@ -6147,7 +6132,7 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd, for(i=0; i<totvert; i++){ val = BLI_frand(); val = (1.0f-emd->protect)*val + emd->protect*0.5f; - if(val < vert_weight(dvert+i,emd->vgroup-1)) + if(val < deformvert_get_weight(dvert+i,emd->vgroup-1)) vertpa[i] = -1; } } @@ -7304,12 +7289,24 @@ static void simpledeformModifier_copyData(ModifierData *md, ModifierData *target static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, vertexCos, numVerts); + SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, derivedData, vertexCos, numVerts); } static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, vertexCos, numVerts); + SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, derivedData, vertexCos, numVerts); +} + +static CustomDataMask simpledeformModifier_requiredDataMask(ModifierData *md) +{ + SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(smd->vgroup_name[0]) + dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; } static void simpledeformModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData) @@ -7669,6 +7666,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) | eModifierTypeFlag_EnableInEditmode; mti->initData = simpledeformModifier_initData; mti->copyData = simpledeformModifier_copyData; + mti->requiredDataMask = simpledeformModifier_requiredDataMask; mti->deformVerts = simpledeformModifier_deformVerts; mti->deformVertsEM = simpledeformModifier_deformVertsEM; mti->foreachObjectLink = simpledeformModifier_foreachObjectLink; diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 4ae2ad8f4a9..4409594f1e2 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -96,18 +96,6 @@ static void normal_short2float(const short *ns, float *nf) nf[2] = ns[2] / 32767.0f; } -static float vertexgroup_get_weight(MDeformVert *dvert, int index, int vgroup) -{ - if(dvert && vgroup >= 0) - { - int j; - for(j = 0; j < dvert[index].totweight; j++) - if(dvert[index].dw[j].def_nr == vgroup) - return dvert[index].dw[j].weight; - } - return 1.0; -} - /* * BVH tree from mesh vertices */ @@ -722,7 +710,7 @@ static void shrinkwrap_calc_foreach_vertex(ShrinkwrapCalcData *calc, Shrinkwrap_ //Shrink (calculate each vertex final position) for(i = 0; i<numVerts; i++) { - float weight = vertexgroup_get_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); float orig[3], final[3]; //Coords relative to target float normal[3]; @@ -1093,7 +1081,7 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) for(i=0; i<numVerts; i++) { int index; - float weight = vertexgroup_get_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); if(weight == 0.0f) continue; VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co); @@ -1157,7 +1145,7 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) for(i=0; i<numVerts; i++) { float dist = FLT_MAX; - float weight = vertexgroup_get_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); float face_normal[3]; if(weight == 0.0f) continue; @@ -1260,7 +1248,7 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) for(i=0; i<numVerts; i++) { int index; - float weight = vertexgroup_get_weight(dvert, i, vgroup); + float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); if(weight == 0.0f) continue; VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co); diff --git a/source/blender/blenkernel/intern/simple_deform.c b/source/blender/blenkernel/intern/simple_deform.c index 548c53be8ba..0c58543a58d 100644 --- a/source/blender/blenkernel/intern/simple_deform.c +++ b/source/blender/blenkernel/intern/simple_deform.c @@ -32,6 +32,8 @@ #include "BKE_simple_deform.h" #include "BKE_DerivedMesh.h" +#include "BKE_deform.h" +#include "BKE_utildefines.h" #include "BLI_arithb.h" #include <string.h> @@ -173,66 +175,84 @@ static void simpleDeform_bend(const float factor, const float dcut[3], float *co /* simple deform modifier */ -void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, float (*vertexCos)[3], int numVerts) +void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { + int i; float (*ob2mod)[4] = NULL, (*mod2ob)[4] = NULL; - float tmp[2][4][4], dcut[3]; + float tmp_matrix[2][4][4]; + int vgroup = get_named_vertexgroup_num(ob, smd->vgroup_name); + + MDeformVert *dvert = NULL; + + //Calculate matrixs do convert between coordinate spaces if(smd->origin) { //inverse is outdated Mat4Invert(smd->origin->imat, smd->origin->obmat); Mat4Invert(ob->imat, ob->obmat); - ob2mod = tmp[0]; - mod2ob = tmp[1]; + ob2mod = tmp_matrix[0]; + mod2ob = tmp_matrix[1]; Mat4MulSerie(ob2mod, smd->origin->imat, ob->obmat, 0, 0, 0, 0, 0, 0); Mat4Invert(mod2ob, ob2mod); } - for(; numVerts; numVerts--, vertexCos++) + if(dm) + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + + for(i=0; i<numVerts; i++) { + float co[3], dcut[3]; + float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup); + + if(weight == 0) continue; + if(ob2mod) - Mat4MulVecfl(ob2mod, *vertexCos); + Mat4MulVecfl(ob2mod, vertexCos[i]); dcut[0] = dcut[1] = dcut[2] = 0.0f; + VECCOPY(co, vertexCos[i]); switch(smd->mode) { case MOD_SIMPLEDEFORM_MODE_TWIST: - axis_limit(2, smd->factor+1, *vertexCos, dcut); - simpleDeform_twist (smd->factor[0], dcut, *vertexCos); + axis_limit(2, smd->factor+1, co, dcut); + simpleDeform_twist (smd->factor[0], dcut, co); break; case MOD_SIMPLEDEFORM_MODE_BEND: - axis_limit(0, smd->factor+1, *vertexCos, dcut); - simpleDeform_bend (smd->factor[0], dcut, *vertexCos); + axis_limit(0, smd->factor+1, co, dcut); + simpleDeform_bend (smd->factor[0], dcut, co); break; case MOD_SIMPLEDEFORM_MODE_TAPER_X: - axis_limit(2, smd->factor+1, *vertexCos, dcut); - simpleDeform_tapperX (smd->factor[0], dcut, *vertexCos); + axis_limit(2, smd->factor+1, co, dcut); + simpleDeform_tapperX (smd->factor[0], dcut, co); break; case MOD_SIMPLEDEFORM_MODE_TAPER_XY: - axis_limit(2, smd->factor+1, *vertexCos, dcut); - simpleDeform_tapperXY(smd->factor[0], dcut, *vertexCos); + axis_limit(2, smd->factor+1, co, dcut); + simpleDeform_tapperXY(smd->factor[0], dcut, co); break; case MOD_SIMPLEDEFORM_MODE_STRECH: - axis_limit(2, smd->factor+1, *vertexCos, dcut); - simpleDeform_strech(smd->factor[0], dcut, *vertexCos); + axis_limit(2, smd->factor+1, co, dcut); + simpleDeform_strech(smd->factor[0], dcut, co); break; case MOD_SIMPLEDEFORM_MODE_SQUASH: - axis_limit(2, smd->factor+1, *vertexCos, dcut); - simpleDeform_squash(smd->factor[0], dcut, *vertexCos); + axis_limit(2, smd->factor+1, co, dcut); + simpleDeform_squash(smd->factor[0], dcut, co); break; } + //linear interpolation + VecLerpf(vertexCos[i], vertexCos[i], co, weight); + if(mod2ob) - Mat4MulVecfl(mod2ob, *vertexCos); + Mat4MulVecfl(mod2ob, vertexCos[i]); } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 74308579cf1..9e1a6ede9f9 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -523,7 +523,9 @@ typedef struct SimpleDeformModifierData { ModifierData modifier; struct Object *origin; /* object to control the origin of modifier space coordinates */ + char vgroup_name[32]; /* optional vertexgroup name */ float factor[4]; /* factors to control simple deforms */ + char mode; char pad[7]; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 5985d473a5d..36ab0961150 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -971,22 +971,23 @@ static void do_modifiers_select_simpledeform_typemenu(void *ob_v, int event) object_add_modifier((Object*) ob_v, (ModifierData*)smd); BIF_undo_push("Add modifier"); + do_modifier_panels(B_MODIFIER_RECALC); } static uiBlock *modifiers_select_simpledeform_typemenu(void *ob_v) { uiBlock *block; - short yco = 20, menuwidth = 160; + short yco = 20, menuwidth = 120; block= uiNewBlock(&curarea->uiblocks, "modifiers_select_simpledeform_typemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); uiBlockSetButmFunc(block, do_modifiers_select_simpledeform_typemenu, ob_v); - uiDefBut(block, BUTM, 1, "Twist", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_TWIST, ""); - uiDefBut(block, BUTM, 1, "Bend", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_BEND, ""); - uiDefBut(block, BUTM, 1, "Tapper X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_TAPER_X, ""); - uiDefBut(block, BUTM, 1, "Tapper XY", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_TAPER_XY, ""); - uiDefBut(block, BUTM, 1, "Strech", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_STRECH, ""); - uiDefBut(block, BUTM, 1, "Squash", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_SQUASH, ""); + uiDefBut(block, BUTM, B_MODIFIER_RECALC, "Twist", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_TWIST, ""); + uiDefBut(block, BUTM, B_MODIFIER_RECALC, "Bend", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_BEND, ""); + uiDefBut(block, BUTM, B_MODIFIER_RECALC, "Tapper X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_TAPER_X, ""); + uiDefBut(block, BUTM, B_MODIFIER_RECALC, "Tapper XY", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_TAPER_XY, ""); + uiDefBut(block, BUTM, B_MODIFIER_RECALC, "Strech", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_STRECH, ""); + uiDefBut(block, BUTM, B_MODIFIER_RECALC, "Squash", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, MOD_SIMPLEDEFORM_MODE_SQUASH, ""); uiBlockSetDirection(block, UI_RIGHT); uiTextBoundsBlock(block, 50); @@ -1906,7 +1907,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco if (smd->shrinkType == MOD_SHRINKWRAP_NORMAL) height += 19*5; } else if (md->type==eModifierType_SimpleDeform) { - height += 19*4; + height += 19*5; } /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */ uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, ""); @@ -2561,6 +2562,9 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiDefButC(block, MENU, B_MODIFIER_RECALC, simpledeform_typemenu, lx,(cy-=19),buttonWidth,19, &smd->mode, 0, 0, 0, 0, "Selects type of deform"); */ + but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name"); + uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth-17,19, &smd->origin, "Origin of modifier space coordinates"); if(smd->origin) |