- switch to using softbody modifier, controls enabling but does not have

variables, these are still in same place. enable button automatically
   makes/enables modifier.
 - changed hook to hook modifier conversion to happen on direct link,
   required to make sure we don't forget to free any memory for files
   saved with 2.38 that have hooks.
 - update modifier interface to enforce modifiers with the require-original-
   data flag to not move beyond deforming modifiers.
 - enforce only one softbody modifier allowed

NOTE: Once again, no modifier stack for lattice yet means softbody for
lattice does not work atm.
This commit is contained in:
Daniel Dunbar 2005-08-11 02:23:52 +00:00
parent 2f32c8451c
commit ac3ed0f92a
12 changed files with 156 additions and 222 deletions

View File

@ -34,7 +34,6 @@
#define BKE_MODIFIER_H
struct DerivedMesh;
struct ModifierData;
struct DagForest;
struct DagNode;
struct Object;
@ -94,19 +93,19 @@ typedef struct ModifierTypeInfo {
*
* This function is optional.
*/
void (*initData)(struct ModifierData *md);
void (*initData)(ModifierData *md);
/* Copy instance data for this modifier type. Should copy all user
* level settings to the target modifier.
*/
void (*copyData)(struct ModifierData *md, struct ModifierData *target);
void (*copyData)(ModifierData *md, ModifierData *target);
/* Free internal modifier data variables, this function should
* not free the _md_ variable itself.
*
* This function is optional.
*/
void (*freeData)(struct ModifierData *md);
void (*freeData)(ModifierData *md);
/* Return a boolean value indicating if this modifier is able to be calculated
* based on the modifier data. This is *not* regarding the md->flag, that is
@ -115,20 +114,20 @@ typedef struct ModifierTypeInfo {
*
* This function is optional (assumes never disabled if not present).
*/
int (*isDisabled)(struct ModifierData *md);
int (*isDisabled)(ModifierData *md);
/* Add the appropriate relations to the DEP graph depending on the modifier
* data.
*
* This function is optional.
*/
void (*updateDepgraph)(struct ModifierData *md, struct DagForest *forest, struct Object *ob, struct DagNode *obNode);
void (*updateDepgraph)(ModifierData *md, struct DagForest *forest, struct Object *ob, struct DagNode *obNode);
/* Should return true if the modifier needs to be recalculated on time changes.
*
* This function is optional (assumes false if not present).
*/
int (*dependsOnTime)(struct ModifierData *md);
int (*dependsOnTime)(ModifierData *md);
/* Should call the given _walk_ function on with a pointer to each Object pointer
* that the modifier data stores. This is used for linking on file load and for
@ -136,17 +135,17 @@ typedef struct ModifierTypeInfo {
*
* This function is optional.
*/
void (*foreachObjectLink)(struct ModifierData *md, struct Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData);
void (*foreachObjectLink)(ModifierData *md, struct Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData);
/* Only for deform types, should apply the deformation
* to the given vertex array. If the deformer requires information from
* the object it can obtain it from the _derivedData_ argument if non-NULL,
* and otherwise the _ob_ argument.
*/
void (*deformVerts)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts);
void (*deformVerts)(ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts);
/* Like deformVerts but called during editmode (for supporting modifiers) */
void (*deformVertsEM)(struct ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts);
void (*deformVertsEM)(ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts);
/* For non-deform types: apply the modifier and return a new derived
* data object (type is dependent on object type). If the _derivedData_
@ -170,7 +169,7 @@ typedef struct ModifierTypeInfo {
* The modifier *MAY NOT* reuse or release the _derivedData_ argument
* if non-NULL. The modifier *MAY NOT* share the _vertexCos_ argument.
*/
void *(*applyModifier)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc);
void *(*applyModifier)(ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc);
/* Like applyModifier but called during editmode (for supporting modifiers).
*
@ -178,7 +177,7 @@ typedef struct ModifierTypeInfo {
* from editmode objects. The same qualifications regarding _derivedData_ and _vertexCos_
* apply as for applyModifier.
*/
void *(*applyModifierEM)(struct ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]);
void *(*applyModifierEM)(ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]);
} ModifierTypeInfo;
ModifierTypeInfo* modifierType_getInfo (ModifierType type);
@ -186,19 +185,21 @@ ModifierTypeInfo* modifierType_getInfo (ModifierType type);
/* Modifier utility calls, do call through type pointer and return
* default values if pointer is optional.
*/
struct ModifierData* modifier_new (int type);
void modifier_free (struct ModifierData *md);
ModifierData* modifier_new (int type);
void modifier_free (ModifierData *md);
void modifier_copyData (struct ModifierData *md, struct ModifierData *target);
int modifier_dependsOnTime (struct ModifierData *md);
int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage (struct ModifierData *md);
void modifier_setError (struct ModifierData *md, char *format, ...);
void modifier_copyData (ModifierData *md, ModifierData *target);
int modifier_dependsOnTime (ModifierData *md);
int modifier_supportsMapping (ModifierData *md);
int modifier_couldBeCage (ModifierData *md);
void modifier_setError (ModifierData *md, char *format, ...);
void modifiers_foreachObjectLink (struct Object *ob, void (*walk)(void *userData, struct Object *ob, struct Object **obpoin), void *userData);
struct ModifierData* modifiers_findByType (struct Object *ob, ModifierType type);
void modifiers_clearErrors (struct Object *ob);
int modifiers_getCageIndex (struct Object *ob, int *lastPossibleCageIndex_r);
void modifiers_foreachObjectLink (struct Object *ob, void (*walk)(void *userData, struct Object *ob, struct Object **obpoin), void *userData);
ModifierData* modifiers_findByType (struct Object *ob, ModifierType type);
void modifiers_clearErrors (struct Object *ob);
int modifiers_getCageIndex (struct Object *ob, int *lastPossibleCageIndex_r);
int modifiers_isSoftbodyEnabled (struct Object *ob);
#endif

View File

@ -163,11 +163,6 @@ void mesh_modifier(Object *ob, float (**vertexCos_r)[3])
do_mesh_key(me);
if((ob->softflag & OB_SB_ENABLE) && !(ob->softflag & OB_SB_POSTDEF)) {
if (!vertexCos) vertexCos = mesh_getVertexCos(me, NULL);
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
}
if (ob->parent && me->totvert) {
if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
if (!vertexCos) vertexCos = mesh_getVertexCos(me, NULL);
@ -183,11 +178,6 @@ void mesh_modifier(Object *ob, float (**vertexCos_r)[3])
}
}
if((ob->softflag & OB_SB_ENABLE) && (ob->softflag & OB_SB_POSTDEF)) {
if (!vertexCos) vertexCos = mesh_getVertexCos(me, NULL);
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
}
*vertexCos_r = vertexCos;
}
@ -229,31 +219,10 @@ int curve_modifier(Object *ob, char mode)
int lattice_modifier(Object *ob, char mode)
{
static BPoint *bpoint;
Lattice *lt= ob->data;
int done= 0;
Lattice *lt = ob->data;
do_latt_key(lt);
/* conditions if it's needed */
if(ob->parent && ob->partype==PARSKEL);
else if((ob->softflag & OB_SB_ENABLE));
else return 0;
if(mode=='s') { // "start"
/* copy */
bpoint= MEM_dupallocN(lt->def);
if((ob->softflag & OB_SB_ENABLE)) {
sbObjectStep(ob, (float)G.scene->r.cfra, NULL);
}
}
else { // end
MEM_freeN(lt->def);
lt->def= bpoint;
bpoint= NULL;
}
return done;
return 0;
}

View File

@ -1426,7 +1426,7 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay)
if(ob->action) ob->recalc |= OB_RECALC_DATA;
else if(ob->nlastrips.first) ob->recalc |= OB_RECALC_DATA;
else if(ob->softflag & OB_SB_ENABLE) ob->recalc |= OB_RECALC_DATA;
else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
else {
Mesh *me;

View File

@ -12,6 +12,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_effect_types.h"
#include "DNA_scene_types.h"
#include "BLI_editVert.h"
@ -26,6 +27,7 @@
#include "BKE_subsurf.h"
#include "BKE_object.h"
#include "BKE_mesh.h"
#include "BKE_softbody.h"
#include "depsgraph_private.h"
#include "LOD_DependKludge.h"
@ -1138,10 +1140,10 @@ static void hookModifier_deformVerts(ModifierData *md, Object *ob, void *derived
for (i=0; i<hmd->totindex; i++) {
int index = hmd->indexar[i];
/* These should always be true and I don't generally like
/* 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.
* not correct them on exit editmode. - zr
*/
if (index<numVerts) {
float *co = vertexCos[index];
@ -1174,14 +1176,7 @@ static void softbodyModifier_deformVerts(ModifierData *md, Object *ob, void *der
{
SoftbodyModifierData *hmd = (SoftbodyModifierData*) md;
// sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
}
static void softbodyModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
{
SoftbodyModifierData *hmd = (SoftbodyModifierData*) md;
// sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
}
/***/
@ -1299,9 +1294,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti = INIT_TYPE(Softbody);
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode;
mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_RequiresOriginalData;
mti->deformVerts = softbodyModifier_deformVerts;
mti->deformVertsEM = softbodyModifier_deformVertsEM;
typeArrInit = 0;
#undef INIT_TYPE
@ -1460,3 +1454,17 @@ int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r)
return cageIndex;
}
int modifiers_isSoftbodyEnabled(Object *ob)
{
ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
/* Softbody not allowed in this situation, enforce! */
if (md && ob->pd && ob->pd->deflect) {
md->mode &= ~(eModifierMode_Realtime|eModifierMode_Render|eModifierMode_Editmode);
md = NULL;
}
return (md && md->mode&(eModifierMode_Realtime|eModifierMode_Render));
}

View File

@ -929,7 +929,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
{
BPoint *bp, *bpu;
int u, v, w, dv, dw, uxt, vxt, wxt, bpc, bpuc;
int debugspringcounter = 0;
int debugspringcounter = 0;
bp= lt->def;
bpc =0;

View File

@ -2318,7 +2318,6 @@ static void direct_link_object(FileData *fd, Object *ob)
bSensor *sens;
bController *cont;
bActuator *act;
ObHook *hook;
int a;
ob->disp.first=ob->disp.last= NULL;
@ -2439,8 +2438,13 @@ static void direct_link_object(FileData *fd, Object *ob)
act= act->next;
}
direct_link_modifiers(fd, &ob->modifiers);
link_list(fd, &ob->hooks);
for(hook= ob->hooks.first; hook; hook= hook->next) {
while (ob->hooks.first) {
ObHook *hook = ob->hooks.first;
HookModifierData *hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
hook->indexar= newdataadr(fd, hook->indexar);
if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
int a;
@ -2448,9 +2452,24 @@ static void direct_link_object(FileData *fd, Object *ob)
SWITCH_INT(hook->indexar[a]);
}
}
}
direct_link_modifiers(fd, &ob->modifiers);
/* Do conversion here because if we have loaded
* a hook we need to make sure it gets converted
* and free'd, regardless of version.
*/
VECCOPY(hmd->cent, hook->cent);
hmd->falloff = hook->falloff;
hmd->force = hook->force;
hmd->indexar = hook->indexar;
hmd->object = hook->parent;
memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
hmd->totindex = hook->totindex;
BLI_addhead(&ob->modifiers, hmd);
BLI_remlink(&ob->hooks, hook);
MEM_freeN(hook);
}
ob->bb= NULL;
ob->derivedDeform= NULL;
@ -4782,22 +4801,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
where_is_armature(arm);
}
for(ob= main->object.first; ob; ob= ob->id.next) {
while (ob->hooks.first) {
ObHook *hook = ob->hooks.first;
HookModifierData *hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
if (ob->softflag&OB_SB_ENABLE) {
if (ob->softflag&OB_SB_POSTDEF) {
ModifierData *md = ob->modifiers.first;
VECCOPY(hmd->cent, hook->cent);
hmd->falloff = hook->falloff;
hmd->force = hook->force;
hmd->indexar = hook->indexar;
hmd->object = hook->parent;
memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
hmd->totindex = hook->totindex;
while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
md = md->next;
}
BLI_addtail(&ob->modifiers, hmd);
BLI_remlink(&ob->hooks, hook);
MEM_freeN(hook);
BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(eModifierType_Softbody));
} else {
BLI_addhead(&ob->modifiers, modifier_new(eModifierType_Softbody));
}
}
// btw. armature_rebuild_pose is further only called on leave editmode

View File

@ -1,6 +1,6 @@
/**
*
* $Id:
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*

View File

@ -259,10 +259,6 @@ static PyObject *Object_getSBInnerSpringFriction( BPy_Object * self );
static PyObject *Object_setSBInnerSpringFriction( BPy_Object * self, PyObject * args );
static PyObject *Object_getSBDefaultGoal( BPy_Object * self );
static PyObject *Object_setSBDefaultGoal( BPy_Object * self, PyObject * args );
static PyObject *Object_getSBEnable( BPy_Object * self );
static PyObject *Object_setSBEnable( BPy_Object * self, PyObject * args );
static PyObject *Object_getSBPostDef( BPy_Object * self );
static PyObject *Object_setSBPostDef( BPy_Object * self, PyObject * args );
static PyObject *Object_getSBUseGoal( BPy_Object * self );
static PyObject *Object_setSBUseGoal( BPy_Object * self, PyObject * args );
static PyObject *Object_getSBUseEdges( BPy_Object * self );
@ -422,14 +418,6 @@ automatic when the script finishes."},
"Returns SB DefaultGoal"},
{"setSBDefaultGoal", ( PyCFunction ) Object_setSBDefaultGoal, METH_VARARGS,
"Sets SB DefaultGoal"},
{"getSBEnable", ( PyCFunction ) Object_getSBEnable, METH_NOARGS,
"Returns SB Enable"},
{"setSBEnable", ( PyCFunction ) Object_setSBEnable, METH_VARARGS,
"Sets SB Enable"},
{"getSBPostDef", ( PyCFunction ) Object_getSBPostDef, METH_NOARGS,
"Returns SB PostDef"},
{"setSBPostDef", ( PyCFunction ) Object_setSBPostDef, METH_VARARGS,
"Sets SB PostDef"},
{"getSBUseGoal", ( PyCFunction ) Object_getSBUseGoal, METH_NOARGS,
"Returns SB UseGoal"},
{"setSBUseGoal", ( PyCFunction ) Object_setSBUseGoal, METH_VARARGS,
@ -3924,97 +3912,6 @@ PyObject *Object_setSBDefaultGoal( BPy_Object * self, PyObject * args )
return EXPP_incr_ret( Py_None );
}
PyObject *Object_getSBEnable( BPy_Object * self )
{
/*short flag = self->object->softflag;*/
PyObject *attr = NULL;
if(!self->object->soft){
if(!setupSB(self->object))
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"softbody could not be accessed (null pointer)" ) );
}
if(self->object->softflag & OB_SB_ENABLE){
attr = PyInt_FromLong(1);
}
else{ attr = PyInt_FromLong(0); }
if( attr )
return attr;
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't get Object->softflag attribute" ) );
}
PyObject *Object_setSBEnable( BPy_Object * self, PyObject * args )
{
short value;
if(!self->object->soft){
if(!setupSB(self->object))
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"softbody could not be accessed (null pointer)" ) );
}
if( !PyArg_ParseTuple( args, "h", &value ) )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected integer argument" ) );
if(value > 0){
self->object->softflag |= OB_SB_ENABLE;
}
else{
self->object->softflag &= ~OB_SB_ENABLE;
}
return EXPP_incr_ret( Py_None );
}
PyObject *Object_getSBPostDef( BPy_Object * self )
{
/*short flag = self->object->softflag;*/
PyObject *attr = NULL;
if(!self->object->soft){
if(!setupSB(self->object))
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"softbody could not be accessed (null pointer)" ) );
}
if(self->object->softflag & OB_SB_POSTDEF){
attr = PyInt_FromLong(1);
}
else{ attr = PyInt_FromLong(0); }
if( attr )
return attr;
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't get Object->softflag attribute" ) );
}
PyObject *Object_setSBPostDef( BPy_Object * self, PyObject * args )
{
short value;
if(!self->object->soft){
if(!setupSB(self->object))
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"softbody could not be accessed (null pointer)" ) );
}
if( !PyArg_ParseTuple( args, "h", &value ) )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected integer argument" ) );
if(value){ self->object->softflag |= OB_SB_POSTDEF; }
else{ self->object->softflag &= ~OB_SB_POSTDEF; }
return EXPP_incr_ret( Py_None );
}
PyObject *Object_getSBUseGoal( BPy_Object * self )
{
/*short flag = self->object->softflag;*/

View File

@ -526,8 +526,19 @@ void do_modifier_panels(unsigned short event)
static void modifiers_add(void *ob_v, int type)
{
Object *ob = ob_v;
ModifierTypeInfo *mti = modifierType_getInfo(type);
if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
ModifierData *md = ob->modifiers.first;
BLI_addtail(&ob->modifiers, modifier_new(type));
while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
md = md->next;
}
BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
} else {
BLI_addtail(&ob->modifiers, modifier_new(type));
}
}
static uiBlock *modifiers_add_menu(void *ob_v)
@ -542,6 +553,9 @@ static uiBlock *modifiers_add_menu(void *ob_v)
for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
ModifierTypeInfo *mti = modifierType_getInfo(i);
if (i==eModifierType_Softbody && modifiers_findByType(ob, eModifierType_Softbody))
continue;
if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
uiDefBut(block, BUTM, B_MODIFIER_RECALC, mti->name, 0, yco-=20, 160, 19, NULL, 0, 0, 1, i, "");
@ -581,6 +595,17 @@ static void modifiers_moveUp(void *ob_v, void *md_v)
ModifierData *md = md_v;
if (md->prev) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (mti->type!=eModifierTypeType_OnlyDeform) {
ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
if (nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
error("Cannot move above a modifier requiring original data.");
return;
}
}
BLI_remlink(&ob->modifiers, md);
BLI_insertlink(&ob->modifiers, md->prev->prev, md);
}
@ -782,10 +807,14 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
BIF_ThemeColor(color);
uiBlockBeginAlign(block);
uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, width-120-60-10, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name");
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+width-120-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+width-120-60+20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+width-120-60+40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
/* Softbody not allowed in this situation, enforce! */
if (md->type!=eModifierType_Softbody || !(ob->pd && ob->pd->deflect)) {
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+width-120-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+width-120-60+20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+width-120-60+40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
}
}
uiBlockEndAlign(block);
@ -856,7 +885,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
} else if (md->type==eModifierType_Hook) {
height = 86;
} else if (md->type==eModifierType_Softbody) {
height = 46;
height = 26;
}
BIF_ThemeColor(color);
@ -866,8 +895,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiBlockBeginAlign(block);
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
uiButSetFunc(but, modifiers_applyModifier, ob, md);
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
uiButSetFunc(but, modifiers_copyModifier, ob, md);
if (md->type!=eModifierType_Softbody) {
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
uiButSetFunc(but, modifiers_copyModifier, ob, md);
}
uiBlockEndAlign(block);
// uiDefButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, "Render", lx,(cy-=19),60,19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");

View File

@ -1417,13 +1417,12 @@ static void object_panel_deflectors(Object *ob)
uiDefButF(block, NUM, REDRAWVIEW3D, "MaxDist: ", 10,40,140,20, &pd->maxdist, 0, 1000.0, 100, 0, "Maximum distance for the field to work");
uiBlockEndAlign(block);
if(ob->softflag & OB_SB_ENABLE) {
if(modifiers_isSoftbodyEnabled(ob)) {
uiDefBut(block, LABEL, 0, "Object is Softbody,", 160,160,150,20, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "no Deflection possible", 160,140,150,20, NULL, 0.0, 0, 0, 0, "");
pd->deflect= 0;
}
else {
uiDefBut(block, LABEL, 0, "Deflection", 160,180,140,20, NULL, 0.0, 0, 0, 0, "");
/* only meshes collide now */
@ -1452,6 +1451,20 @@ static void object_panel_deflectors(Object *ob)
/* Panel for softbodies */
static void object_softbodies__enable(void *ob_v, void *arg2)
{
Object *ob = ob_v;
ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
if (!md) {
md = modifier_new(eModifierType_Softbody);
BLI_addhead(&ob->modifiers, md);
}
md->mode |= eModifierMode_Render|eModifierMode_Realtime;
allqueue(REDRAWBUTSEDIT, 0);
}
static void object_softbodies(Object *ob)
{
@ -1462,22 +1475,18 @@ static void object_softbodies(Object *ob)
if(uiNewPanel(curarea, block, "Softbody", "Object", 640, 0, 318, 204)==0) return;
/* do not allow to combine with force fields */
if(ob->pd) {
PartDeflect *pd= ob->pd;
if(pd->deflect) {
uiDefBut(block, LABEL, 0, "Object has Deflection,", 10,160,300,20, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "no Softbody possible", 10,140,300,20, NULL, 0.0, 0, 0, 0, "");
ob->softflag &= ~OB_SB_ENABLE;
return;
if(ob->pd && ob->pd->deflect) {
uiDefBut(block, LABEL, 0, "Object has Deflection,", 10,160,300,20, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "no Softbody possible", 10,140,300,20, NULL, 0.0, 0, 0, 0, "");
} else {
if (!modifiers_isSoftbodyEnabled(ob)) {
uiBut *but = uiDefButS(block, BUT, REDRAWBUTSOBJECT, "Enable Soft Body", 10,200,150,20, &ob->softflag, 0, 0, 0, 0, "Sets object to become soft body");
uiButSetFunc(but, object_softbodies__enable, ob, NULL);
uiDefBut(block, LABEL, 0, "", 160, 200,150,20, NULL, 0.0, 0.0, 0, 0, ""); // alignment reason
}
}
uiDefButBitS(block, TOG, OB_SB_ENABLE, REDRAWBUTSOBJECT, "Enable Soft Body", 10,200,150,20, &ob->softflag, 0, 0, 0, 0, "Sets object to become soft body");
uiDefBut(block, LABEL, 0, "", 160, 200,150,20, NULL, 0.0, 0.0, 0, 0, ""); // alignment reason
if(ob->softflag & OB_SB_ENABLE) {
if(modifiers_isSoftbodyEnabled(ob)) {
SoftBody *sb= ob->soft;
int defCount;
char *menustr;
@ -1522,7 +1531,6 @@ static void object_softbodies(Object *ob)
uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_DIFF, "Speed:", 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
uiDefButF(block, NUM, B_DIFF, "Error Limit:", 10,130,150,20, &sb->rklimit , 0.01, 1.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision");
uiDefButBitS(block, TOG, OB_SB_POSTDEF, B_DIFF, "Apply Deform First", 160,130,150,20, &ob->softflag, 0, 0, 0, 0, "Softbody is calculated AFTER Deformation");
uiBlockEndAlign(block);
/* GOAL STUFF */

View File

@ -1511,7 +1511,7 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un
if(freedata) G.obedit= NULL;
/* total remake of softbody data */
if(ob->softflag & OB_SB_ENABLE) {
if(modifiers_isSoftbodyEnabled(ob)) {
SoftBody *sb= ob->soft;
if(sb->keys) {
@ -2473,7 +2473,7 @@ static void copymenu_modifiers(Object *ob)
for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
ModifierTypeInfo *mti = modifierType_getInfo(i);
if (i==eModifierType_Hook) continue;
if (ELEM(i, eModifierType_Hook, eModifierType_Softbody)) continue;
if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@ -2774,6 +2774,10 @@ void copy_attr(short event)
if(base->object->soft) sbFree(base->object->soft);
base->object->soft= copy_softbody(ob->soft);
if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
}
}
}
}

View File

@ -55,6 +55,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
@ -80,11 +81,11 @@
#include "BKE_ipo.h"
#include "BKE_lattice.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
#include "BIF_editaction.h"
#include "BIF_editview.h"
#include "BIF_editlattice.h"
@ -1411,8 +1412,8 @@ void special_aftertrans_update(short cancelled)
if(base->flag & BA_DO_IPO) redrawipo= 1;
ob= base->object;
/* reset soft body object */
if(ob->softflag & OB_SB_ENABLE) sbObjectReset(ob, NULL);
if(modifiers_isSoftbodyEnabled(ob)) sbObjectReset(ob, NULL);
/* Set autokey if necessary */
if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){