Softbody:
authorTon Roosendaal <ton@blender.org>
Sat, 16 Apr 2005 14:01:49 +0000 (14:01 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 16 Apr 2005 14:01:49 +0000 (14:01 +0000)
- Added browsing for vertex group for "Goal" in SoftBody buttons.
- Means the default name "SOFTGOAL" isn't needed anymore
- temporally, on file read, the "SOFTGOAL" vertex group is set, if exists
- removing vertex group possible too
- changed softbody.c code to use this

source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_object_types.h
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c

index 2e65f8d1c392ac2b0de64a3ea916dcff29b582ad..8409608bb5459350949f35f88f6044291705767b 100644 (file)
@@ -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;
-       
-       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 */
+       int i;
+       
+       /* 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; i<dv->totweight; 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;
-                       
-                       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);
+               /* 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);
                        
-                       /* 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 */
index b2fce9edfe6c2f43b8c3e82844ca5e2924169cc9..0d04fff7343d3ddb865f2281bc0e015be6fd21cb 100644 (file)
 #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); 
+                               }
+                       }
                }
        }
        
index 1b6d20f1b168f9db680776e6e66549002b971b7c..4b5f5a672589026b37cfe9c1932b5bff352ae56c 100644 (file)
@@ -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    
index 1e1c0760889e2a7badbacd7774703869fa536ec9..35260805d05554ed0a2fe5eabc6d6a793c9e52f1 100644 (file)
@@ -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 */
index 4312e413de7e4c3343baaf8374209d8a741b5019..d81c5f46e61a3e5b80e8eb7c584b3ec522388b37 100644 (file)
@@ -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.)");
index 2fe7b758eb6600c46510792f367492a89204a90e..0fd762837b1e2d21c321c5b4f88e47b7fcbf378b 100644 (file)
@@ -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");