diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index e2838622494..574f7b313b4 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -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 diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index a1f04eaa048..e2cb842e16d 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -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; } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 323c6793c7d..bf0bab5403f 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -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; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 5e6be926caa..f306986a8ef 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -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; itotindex; 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 (indexr.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)); +} diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index b4da0f1097c..5e23e00bb19 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -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; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a166b070d67..cfecaa5e9f6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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 diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 77ceb52788f..334d4b44aa6 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -1,6 +1,6 @@ /** * - * $Id: + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index f79faac690c..9cec69b2d1c 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -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;*/ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 354f204087f..63303defd44 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -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; iflags&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"); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 9ce1ecb099f..5fbd80e6027 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -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 */ diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 82851ee82d2..687e0f09f66 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -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; iflags&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)); + } } } } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 3926783c4e3..93479e45be3 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -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)){