diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 2e65f8d1c39..8409608bb54 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -90,8 +90,6 @@ extern int get_defgroup_num (Object *ob, bDeformGroup *dg); float SoftHeunTol = 1.0f; // humm .. this should be calculated from sb parameters and sizes /* local prototypes */ -//static void softbody_scale_time(float steptime); -static int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target); static void free_softbody_intern(SoftBody *sb); @@ -321,7 +319,7 @@ static int sb_deflect_particle(Object *ob,float *actpos, float *futurepos,float } - +#if 0 static int sb_deflect_test(float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce) { @@ -465,7 +463,7 @@ static int sb_deflect_test(float *actpos, float *futurepos,float *collisionpos, return 0; } - +#endif @@ -728,7 +726,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * if(bp->goal < SOFTGOALSNAP){ /* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/ - /* the ( ... )' operator denotes derivate respective time + /* the ( ... )' operator denotes derivate respective time */ /* the euler step for velocity then becomes */ /* v(t + dt) = v(t) + a(t) * dt */ bp->force[0]*= timeovermass; /* individual mass of node here */ @@ -1018,37 +1016,29 @@ static void mesh_update_softbody(Object *ob) } -static int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target) +static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex, float *target) /* result 0 on success, else indicates error number -- kind of *inverse* result defintion, -- but this way we can signal error condition to caller -- and yes this function must not be here but in a *vertex group module* */ { - bDeformGroup *locGroup = NULL; MDeformVert *dv; - int i, groupindex; + int i; - locGroup = get_named_vertexgroup(ob,name); - if(locGroup){ - /* retrieve index for that group */ - groupindex = get_defgroup_num(ob,locGroup); - /* spot the vert in deform vert list at mesh */ - /* todo (coder paranoya) what if ob->data is not a mesh .. */ - /* hrms.. would like to have the same for lattices anyhoo */ + /* spot the vert in deform vert list at mesh */ + if(ob->type==OB_MESH) { if (((Mesh *)ob->data)->dvert) { dv = ((Mesh*)ob->data)->dvert + vertID; /* Lets see if this vert is in the weight group */ for (i=0; itotweight; i++){ if (dv->dw[i].def_nr == groupindex){ *target= dv->dw[i].weight; /* got it ! */ - return 0; + break; } } } - return 2; - }/*if(locGroup)*/ - return 1; + } } /* makes totally fresh start situation */ @@ -1078,38 +1068,26 @@ static void mesh_to_softbody(Object *ob) set_body_point(ob, bp, mvert->co); - if (1) { /* switch to vg scalars*/ - /* get scalar values needed *per vertex* from vertex group functions, - so we can *paint* them nicly .. - they are normalized [0.0..1.0] so may be we need amplitude for scale - which can be done by caller - but still .. i'd like it to go this way - */ - int error; - char name[32] = "SOFTGOAL"; - float temp; + /* get scalar values needed *per vertex* from vertex group functions, + so we can *paint* them nicly .. + they are normalized [0.0..1.0] so may be we need amplitude for scale + which can be done by caller but still .. i'd like it to go this way + */ + + if(sb->vertgroup) { + get_scalar_from_vertexgroup(ob, me->totvert - a, sb->vertgroup-1, &bp->goal); + // do this always, regardless successfull read from vertex group + bp->goal= sb->mingoal + bp->goal*goalfac; + } + /* a little ad hoc changing the goal control to be less *sharp* */ + bp->goal = (float)pow(bp->goal, 4.0f); - error = get_scalar_from_named_vertexgroup(ob, name, me->totvert - a, &temp); - if (!error) { - bp->goal = temp; - - /* works assuming goal is <0.0, 1.0> */ - bp->goal= sb->mingoal + bp->goal*goalfac; - - } - /* a little ad hoc changing the goal control to be less *sharp* */ - bp->goal = (float)pow(bp->goal, 4.0f); - - /* to proove the concept - this would enable per vertex *mass painting* - strcpy(name,"SOFTMASS"); - error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp); - if (!error) bp->mass = temp * ob->rangeofmass; - */ - - - - } /* switch to vg scalars */ + /* to proove the concept + this would enable per vertex *mass painting* + strcpy(name,"SOFTMASS"); + error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp); + if (!error) bp->mass = temp * ob->rangeofmass; + */ } /* but we only optionally add body edge springs */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b2fce9edfe6..0d04fff7343 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -110,6 +110,7 @@ #include "BKE_action.h" #include "BKE_constraint.h" #include "BKE_curve.h" +#include "BKE_deform.h" #include "BKE_effect.h" // for give_parteff #include "BKE_global.h" // for G #include "BKE_property.h" // for get_property @@ -4681,6 +4682,13 @@ static void do_versions(Main *main) ob->softflag |= OB_SB_GOAL|OB_SB_EDGES; } + if(ob->soft && ob->soft->vertgroup==0) { + bDeformGroup *locGroup = get_named_vertexgroup(ob, "SOFTGOAL"); + if(locGroup){ + /* retrieve index for that group */ + ob->soft->vertgroup = 1 + get_defgroup_num(ob, locGroup); + } + } } } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 1b6d20f1b16..4b5f5a67258 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -35,6 +35,7 @@ /* all internal calls and event codes for buttons space */ struct Base; +struct Object; struct ID; @@ -76,6 +77,7 @@ extern void do_fontbuts(unsigned short event); extern void do_mballbuts(unsigned short event); extern void do_latticebuts(unsigned short event); extern void do_fpaintbuts(unsigned short event); +extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons /* shading */ extern void material_panels(void); @@ -219,6 +221,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_CURVECHECK 1416 #define B_SOFTBODY_CHANGE 1420 +#define B_SOFTBODY_DEL_VG 1421 /* this has MAX_EFFECT settings! Next free define is 1450... */ #define B_SELEFFECT 1430 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 1e1c0760889..35260805d05 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -121,6 +121,8 @@ typedef struct SoftBody { float goalfrict; /* softbody goal springs friction */ float mingoal; /* quick limits for goal */ float maxgoal; + short vertgroup; /* index starting at 1 */ + short pad1, pad2, pad3; float inspring; /* softbody inner springs */ float infrict; /* softbody inner springs friction */ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 4312e413de7..d81c5f46e61 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2165,6 +2165,49 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me) } +char *get_vertexgroup_menustr(Object *ob) +{ + bDeformGroup *dg; + int defCount, min, index; + char (*qsort_ptr)[32] = NULL; + char *s, *menustr; + + defCount=BLI_countlist(&ob->defbase); + + if (!defCount) min=0; + else min=1; + + if (defCount > 0) { + /* + * This will hold the group names temporarily + * so we can sort them + */ + qsort_ptr = MEM_callocN (defCount * sizeof (qsort_ptr[0]), + "qsort_ptr"); + for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next) { + snprintf (qsort_ptr[index - 1], sizeof (qsort_ptr[0]), + "%s%%x%d|", dg->name, index); + } + + qsort (qsort_ptr, defCount, sizeof (qsort_ptr[0]), + ( int (*)(const void *, const void *) ) strcmp); + } + + s= menustr = MEM_callocN((32 * defCount)+30, "menustr"); // plus 30 for when defCount==0 + if(defCount) { + for (index = 0; index < defCount; index++) { + int cnt= sprintf (s, "%s", qsort_ptr[index]); + if (cnt>0) s+= cnt; + } + } + else strcpy(menustr, "No Vertex Groups in Object"); + + if (qsort_ptr) + MEM_freeN (qsort_ptr); + + return menustr; +} + static void editing_panel_links(Object *ob) { uiBlock *block; @@ -2264,52 +2307,20 @@ static void editing_panel_links(Object *ob) uiBut *but; int defCount; bDeformGroup *defGroup; - char *s, *menustr; - bDeformGroup *dg; - int min, index; - char (*qsort_ptr)[32] = NULL; - + uiDefBut(block, LABEL,0,"Vertex Groups", 143,153,130,20, 0, 0, 0, 0, 0, ""); defCount=BLI_countlist(&ob->defbase); - if (!defCount) min=0; - else min=1; - - if (defCount > 0) { - /* - * This will hold the group names temporarily - * so we can sort them - */ - qsort_ptr = MEM_callocN (defCount * sizeof (qsort_ptr[0]), - "qsort_ptr"); - for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next) { - snprintf (qsort_ptr[index - 1], sizeof (qsort_ptr[0]), - "%s%%x%d|", dg->name, index); - } - - qsort (qsort_ptr, defCount, sizeof (qsort_ptr[0]), - ( int (*)(const void *, const void *) ) strcmp); - } - - s= menustr = MEM_callocN((32 * defCount)+20, "menustr"); - for (index = 0; index < defCount; index++) { - int cnt= sprintf (s, "%s", qsort_ptr[index]); - if (cnt>0) s+= cnt; - } - - if (qsort_ptr) - MEM_freeN (qsort_ptr); - uiBlockBeginAlign(block); - if (defCount) - uiDefButS(block, MENU, REDRAWBUTSEDIT, menustr, - 143, 132,18,21, &ob->actdef, min, defCount, 0, 0, - "Browses available vertex groups"); - - MEM_freeN (menustr); - + if (defCount) { + char *menustr= get_vertexgroup_menustr(ob); + + uiDefButS(block, MENU, REDRAWBUTSEDIT, menustr, 143, 132,18,21, &ob->actdef, 1, defCount, 0, 0, "Browses available vertex groups"); + MEM_freeN (menustr); + } + if (ob->actdef){ defGroup = BLI_findlink(&ob->defbase, ob->actdef-1); but= uiDefBut(block, TEX,REDRAWBUTSEDIT,"", 161,132,140-18,21, defGroup->name, 0, 32, 0, 0, "Displays current vertex group name. Click to change. (Match bone name for deformation.)"); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 2fe7b758eb6..0fd762837b1 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1192,8 +1192,20 @@ void do_object_panels(unsigned short event) case B_SOFTBODY_CHANGE: ob= OBACT; - if(ob) ob->softflag |= OB_SB_REDO; - allqueue(REDRAWVIEW3D, 0); + if(ob) { + ob->softflag |= OB_SB_REDO; + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + break; + case B_SOFTBODY_DEL_VG: + ob= OBACT; + if(ob && ob->soft) { + ob->soft->vertgroup= 0; + ob->softflag |= OB_SB_REDO; + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } break; default: @@ -1469,6 +1481,8 @@ static void object_softbodies(Object *ob) if(ob->softflag & OB_SB_ENABLE) { SoftBody *sb= ob->soft; + int defCount; + char *menustr; if(sb==NULL) { sb= ob->soft= sbNew(); @@ -1491,8 +1505,26 @@ static void object_softbodies(Object *ob) /* GOAL STUFF */ uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, OB_SB_GOAL, B_DIFF, "Use Goal", 10,100,150,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Goal:", 160,100,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButBitS(block, TOG, OB_SB_GOAL, B_DIFF, "Use Goal", 10,100,130,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + + menustr= get_vertexgroup_menustr(ob); + defCount=BLI_countlist(&ob->defbase); + if(defCount==0) sb->vertgroup= 0; + uiDefButS(block, MENU, B_SOFTBODY_CHANGE, menustr, 140,100,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups"); + + if(sb->vertgroup) { + bDeformGroup *defGroup = BLI_findlink(&ob->defbase, sb->vertgroup-1); + if(defGroup) + uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group"); + else + uiDefBut(block, BUT, B_DIFF, "(no group)", 160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore"); + uiDefIconBut(block, BUT, B_SOFTBODY_DEL_VG, ICON_X, 290,100,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group"); + } + else { + uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Goal:", 160,100,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + } + MEM_freeN (menustr); + uiDefButF(block, NUM, B_DIFF, "GSpring:", 10,80,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) Spring Constant"); uiDefButF(block, NUM, B_DIFF, "GFrict:", 160,80,150,20, &sb->goalfrict , 0.0, 10.0, 10, 0, "Goal (vertex target position) Friction Constant"); uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "GMin:", 10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Min Goal bound");