- 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
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);
}
-
+#if 0
static int sb_deflect_test(float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce)
{
return 0;
}
-
+#endif
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 */
}
-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 */
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 */
#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
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);
+ }
+ }
}
}
/* all internal calls and event codes for buttons space */
struct Base;
+struct Object;
struct ID;
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);
#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
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 */
}
+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;
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.)");
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:
if(ob->softflag & OB_SB_ENABLE) {
SoftBody *sb= ob->soft;
+ int defCount;
+ char *menustr;
if(sb==NULL) {
sb= ob->soft= sbNew();
/* 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");