Softbody now uses the new pointcache code.
authorJanne Karhu <jhkarh@gmail.com>
Sun, 2 Aug 2009 19:39:33 +0000 (19:39 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Sun, 2 Aug 2009 19:39:33 +0000 (19:39 +0000)
Note: Rna access to softbody point cache is through softbody modifier although the point cache is in softbody settings. This is to make it similar to cloth.

Bugfix: Softbody rna was trying to get "ob->soft->softflag" instead of the correct "ob->softflag".

release/ui/buttons_physics_softbody.py
source/blender/blenkernel/BKE_softbody.h
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/softbody.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/physics/ed_pointcache.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_object_force.c

index 80e11f9..bff9b13 100644 (file)
@@ -51,7 +51,54 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel):
                        col.itemL(text="Simulation:")
                        col.itemR(softbody, "gravity")
                        col.itemR(softbody, "speed")
+                       
+class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
+       __label__ = "Soft Body Cache"
+       __default_closed__ = True
+
+       def poll(self, context):
+               return (context.soft_body)
+
+       def draw(self, context):
+               layout = self.layout
+
+               cache = context.soft_body.point_cache
+               
+               row = layout.row()
+               row.itemR(cache, "name")
+               
+               row = layout.row()
+               row.itemR(cache, "start_frame")
+               row.itemR(cache, "end_frame")
+               
+               row = layout.row()
+               
+               if cache.baked == True:
+                       row.itemO("ptcache.free_bake_softbody", text="Free Bake")
+               else:
+                       row.item_booleanO("ptcache.cache_softbody", "bake", True, text="Bake")
+               
+               sub = row.row()
+               sub.enabled = cache.frames_skipped or cache.outdated
+               sub.itemO("ptcache.cache_softbody", text="Calculate to Current Frame")
+                       
+               row = layout.row()
+               row.itemO("ptcache.bake_from_softbody_cache", text="Current Cache to Bake")
+               row.itemR(cache, "step");
        
+               row = layout.row()
+               row.itemR(cache, "quick_cache")
+               row.itemR(cache, "disk_cache")
+               
+               layout.itemL(text=cache.info)
+               
+               layout.itemS()
+               
+               row = layout.row()
+               row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+               row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+               layout.itemO("ptcache.bake_all", text="Update All Dynamics to current frame")
+               
 class PHYSICS_PT_softbody_goal(PhysicButtonsPanel):
        __label__ = "Soft Body Goal"
        
@@ -211,6 +258,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
                        layout.itemR(softbody, "diagnose")
        
 bpy.types.register(PHYSICS_PT_softbody)
+bpy.types.register(PHYSICS_PT_softbody_cache)
 bpy.types.register(PHYSICS_PT_softbody_goal)
 bpy.types.register(PHYSICS_PT_softbody_edge)
 bpy.types.register(PHYSICS_PT_softbody_collision)
index 971ac7a..0d9682c 100644 (file)
@@ -69,7 +69,7 @@ extern void                           sbObjectToSoftbody(struct Object *ob);
 extern void             sbSetInterruptCallBack(int (*f)(void));
 
 /* writing to cache for bake editing */
-extern void                    sbWriteCache(struct Object *ob, int framenr);
+extern void                    softbody_write_cache(struct Object *ob, struct SoftBody *soft, int cfra);
 
 #endif
 
index 4bb571a..beb72c2 100644 (file)
@@ -310,7 +310,7 @@ int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot)
 static int ptcache_pid_elemsize(PTCacheID *pid)
 {
        if(pid->type==PTCACHE_TYPE_SOFTBODY)
-               return 0; // TODO
+               return 6 * sizeof(float);
        else if(pid->type==PTCACHE_TYPE_PARTICLES)
                return sizeof(ParticleKey);
        else if(pid->type==PTCACHE_TYPE_CLOTH)
@@ -320,8 +320,10 @@ static int ptcache_pid_elemsize(PTCacheID *pid)
 }
 static int ptcache_pid_totelem(PTCacheID *pid)
 {
-       if(pid->type==PTCACHE_TYPE_SOFTBODY)
-               return 0; // TODO
+       if(pid->type==PTCACHE_TYPE_SOFTBODY) {
+               SoftBody *soft = pid->data;
+               return soft->totpoint;
+       }
        else if(pid->type==PTCACHE_TYPE_PARTICLES) {
                ParticleSystem *psys = pid->data;
                return psys->totpart;
index fe63585..0a1963c 100644 (file)
@@ -3687,64 +3687,85 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts,
        }
 }
 
-void sbWriteCache(Object *ob, int framenr)
+static void softbody_write_state(int index, void *soft_v, float *data)
 {
-       SoftBody *sb= ob->soft;
-       BodyPoint *bp;
-       PTCacheID pid;
-       PTCacheFile *pf;
-       int a;
+       SoftBody *soft= soft_v;
+       BodyPoint *bp = soft->bpoint + index;
 
-       if(sb->totpoint == 0)
-               return;
+       memcpy(data, bp->pos, 3 * sizeof(float));
+       memcpy(data + 3, bp->vec, 3 * sizeof(float));
+}
+static void softbody_read_state(int index, void *soft_v, float *data)
+{
+       SoftBody *soft= soft_v;
+       BodyPoint *bp = soft->bpoint + index;
+       
+       memcpy(bp->pos, data, 3 * sizeof(float));
+       memcpy(bp->vec, data + 3, 3 * sizeof(float));
+}
+static void softbody_cache_interpolate(int index, void *soft_v, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
+{
+       SoftBody *soft= soft_v;
+       BodyPoint *bp = soft->bpoint + index;
+       ParticleKey keys[4];
+       float dfra;
 
-       BKE_ptcache_id_from_softbody(&pid, ob, sb);
-       pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
-       if(!pf)
+       if(cfra1 == cfra2) {
+               softbody_read_state(index, soft, data1);
                return;
-       
-       for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
-               BKE_ptcache_file_write_floats(pf, bp->pos, 3);
+       }
 
-       for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
-               BKE_ptcache_file_write_floats(pf, bp->vec, 3);
+       memcpy(keys[1].co, data1, 3 * sizeof(float));
+       memcpy(keys[1].vel, data1 + 3, 3 * sizeof(float));
 
-       BKE_ptcache_file_close(pf);
-}
+       memcpy(keys[2].co, data2, 3 * sizeof(float));
+       memcpy(keys[2].vel, data2 + 3, 3 * sizeof(float));
+
+       dfra = cfra2 - cfra1;
+
+       VecMulf(keys[1].vel, dfra);
+       VecMulf(keys[2].vel, dfra);
+
+       psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1);
 
-static int softbody_read_cache(Object *ob, float framenr)
+       VecMulf(keys->vel, 1.0f / dfra);
+
+       memcpy(bp->pos, keys->co, 3 * sizeof(float));
+       memcpy(bp->vec, keys->vel, 3 * sizeof(float));
+}
+void softbody_write_cache(Object *ob, SoftBody *soft, int cfra)
 {
-       SoftBody *sb= ob->soft;
-       BodyPoint *bp;
+       PTCacheWriter writer;
        PTCacheID pid;
-       PTCacheFile *pf;
-       int a;
-
-       if(sb->totpoint == 0)
-               return 0;
-       
-       BKE_ptcache_id_from_softbody(&pid, ob, sb);
-       pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
-       if(!pf)
-               return 0;
 
-       for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) {
-               if(!BKE_ptcache_file_read_floats(pf, bp->pos, 3)) {
-                       BKE_ptcache_file_close(pf);
-                       return 0;
-               }
-       }
+       BKE_ptcache_id_from_softbody(&pid, ob, soft);
 
-       for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) {
-               if(!BKE_ptcache_file_read_floats(pf, bp->vec, 3)) {
-                       BKE_ptcache_file_close(pf);
-                       return 0;
-               }
-       }
+       writer.calldata = soft;
+       writer.cfra = cfra;
+       writer.set_elem = softbody_write_state;
+       writer.pid = &pid;
+       writer.totelem = soft->totpoint;
 
-       BKE_ptcache_file_close(pf);
+       BKE_ptcache_write_cache(&writer);
+}
 
-       return 1;
+int softbody_read_cache(Scene *scene, Object *ob, SoftBody *soft, float cfra, int *old_framenr)
+{
+       PTCacheReader reader;
+       PTCacheID pid;
+       
+       BKE_ptcache_id_from_softbody(&pid, ob, soft);
+
+       reader.calldata = soft;
+       reader.cfra = cfra;
+       reader.interpolate_elem = softbody_cache_interpolate;
+       reader.old_frame = old_framenr;
+       reader.pid = &pid;
+       reader.scene = scene;
+       reader.set_elem = softbody_read_state;
+       reader.totelem = soft->totpoint;
+
+       return BKE_ptcache_read_cache(&reader);
 }
 
 /* +++ ************ maintaining scratch *************** */
@@ -4114,6 +4135,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
        PTCacheID pid;
        float dtime, timescale;
        int framedelta, framenr, startframe, endframe;
+       int cache_result, old_framenr;
 
        cache= sb->pointcache;
 
@@ -4128,7 +4150,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
        if(sb->bpoint && numVerts != sb->totpoint) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
-
+               cache->last_exact= 0;
                return;
        }
 
@@ -4136,6 +4158,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
        if(framenr < startframe) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
 
                return;
        }
@@ -4198,26 +4221,36 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
        }
 
        /* try to read from cache */
-       if(softbody_read_cache(ob, framenr)) {
-               if(sb->particles==0)
-                       softbody_to_object(ob, vertexCos, numVerts, sb->local);
+       cache_result = softbody_read_cache(scene, ob, sb, framenr, &old_framenr);
 
+       if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
                cache->flag |= PTCACHE_SIMULATION_VALID;
                cache->simframe= framenr;
 
+               if(sb->particles==0)
+                       softbody_to_object(ob, vertexCos, numVerts, sb->local);
+
                return;
        }
+       else if(cache_result==PTCACHE_READ_OLD) {
+               BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
+               cache->flag |= PTCACHE_SIMULATION_VALID;
+               cache->simframe= old_framenr;
+       }
        else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
                /* if baked and nothing in cache, do nothing */
-               if(cache->flag & PTCACHE_SIMULATION_VALID) {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-               }
-
+               cache->flag &= ~PTCACHE_SIMULATION_VALID;
+               cache->simframe= 0;
+               cache->last_exact= 0;
                return;
        }
 
        if(framenr == startframe) {
+               if(cache->flag & PTCACHE_REDO_NEEDED) {
+                       softbody_update_positions(ob, sb, vertexCos, numVerts);
+                       softbody_reset(ob, sb, vertexCos, numVerts);
+                       cache->flag &= ~PTCACHE_REDO_NEEDED;
+               }
                /* first frame, no simulation to do, just set the positions */
                softbody_update_positions(ob, sb, vertexCos, numVerts);
 
@@ -4227,10 +4260,10 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
                /* don't write cache on first frame, but on second frame write
                 * cache for frame 1 and 2 */
        }
-       else if(framedelta == 1) {
+       else {
                /* if on second frame, write cache for first frame */
-               if(framenr == startframe+1)
-                       sbWriteCache(ob, startframe);
+               if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
+                       softbody_write_cache(ob, sb, startframe);
 
                softbody_update_positions(ob, sb, vertexCos, numVerts);
 
@@ -4246,14 +4279,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
                if(sb->particles==0)
                        softbody_to_object(ob, vertexCos, numVerts, 0);
 
-               sbWriteCache(ob, framenr);
-       }
-       else {
-               /* time step backwards or too large forward - do nothing */
-               if(cache->flag & PTCACHE_SIMULATION_VALID) {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-               }
+               softbody_write_cache(ob, sb, framenr);
        }
 }
 
index 6c66ae4..e32dd0e 100644 (file)
@@ -1160,7 +1160,7 @@ void load_editMesh(Scene *scene, Object *ob)
                if(pid.type == PTCACHE_TYPE_CLOTH)
                        cloth_write_cache(ob, pid.data, pid.cache->editframe);
                else if(pid.type == PTCACHE_TYPE_SOFTBODY)
-                       sbWriteCache(ob, pid.cache->editframe);
+                       softbody_write_cache(ob, pid.data, pid.cache->editframe);
        }
 
        /* the edges */
index 4bf6612..5d0a6d2 100644 (file)
@@ -146,6 +146,113 @@ void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/**************************** softbody **********************************/
+static int ptcache_bake_softbody_poll(bContext *C)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       SoftBody *sb = ob->soft;
+
+       if(!scene || !ob || ob->id.lib || !sb)
+               return 0;
+       
+       return 1;
+}
+
+static int ptcache_bake_softbody_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       SoftBody *sb = ob->soft;
+       PTCacheID pid;
+       PTCacheBaker baker;
+
+       BKE_ptcache_id_from_softbody(&pid, ob, sb);
+
+       baker.scene = scene;
+       baker.pid = &pid;
+       baker.bake = RNA_boolean_get(op->ptr, "bake");
+       baker.render = 0;
+       baker.anim_init = 0;
+       baker.quick_step = 1;
+       baker.break_test = cache_break_test;
+       baker.break_data = NULL;
+       baker.progressbar = (void (*)(void *, int))WM_timecursor;
+       baker.progresscontext = CTX_wm_window(C);
+
+       BKE_ptcache_make_cache(&baker);
+
+       WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+       return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_softbody_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       SoftBody *sb = ob->soft;
+       PTCacheID pid;
+
+       BKE_ptcache_id_from_softbody(&pid, ob, sb);
+       pid.cache->flag &= ~PTCACHE_BAKED;
+
+       WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+       return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_softbody(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bake Softbody";
+       ot->idname= "PTCACHE_OT_cache_softbody";
+       
+       /* api callbacks */
+       ot->exec= ptcache_bake_softbody_exec;
+       ot->poll= ptcache_bake_softbody_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_softbody(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Free SoftBody Bake";
+       ot->idname= "PTCACHE_OT_free_bake_softbody";
+       
+       /* api callbacks */
+       ot->exec= ptcache_free_bake_softbody_exec;
+       ot->poll= ptcache_bake_softbody_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_softbody_cache_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_active_object(C);
+       SoftBody *sb = ob->soft;
+       PTCacheID pid;
+
+       BKE_ptcache_id_from_softbody(&pid, ob, sb);
+       pid.cache->flag |= PTCACHE_BAKED;
+
+       return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_softbody_cache(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bake From Cache";
+       ot->idname= "PTCACHE_OT_bake_from_softbody_cache";
+       
+       /* api callbacks */
+       ot->exec= ptcache_bake_from_softbody_cache_exec;
+       ot->poll= ptcache_bake_softbody_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /**************************** cloth **********************************/
 static int ptcache_bake_cloth_poll(bContext *C)
 {
@@ -371,6 +478,9 @@ void ED_operatortypes_pointcache(void)
        WM_operatortype_append(PTCACHE_OT_cache_cloth);
        WM_operatortype_append(PTCACHE_OT_free_bake_cloth);
        WM_operatortype_append(PTCACHE_OT_bake_from_cloth_cache);
+       WM_operatortype_append(PTCACHE_OT_cache_softbody);
+       WM_operatortype_append(PTCACHE_OT_free_bake_softbody);
+       WM_operatortype_append(PTCACHE_OT_bake_from_softbody_cache);
 }
 
 //void ED_keymap_pointcache(wmWindowManager *wm)
index 5192e2d..80bc46b 100644 (file)
@@ -34,6 +34,7 @@
 #include "DNA_armature_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
+#include "DNA_object_force.h"
 #include "DNA_scene_types.h"
 
 #include "BKE_bmesh.h" /* For BevelModifierData */
@@ -383,6 +384,12 @@ static PointerRNA rna_SoftBodyModifier_settings_get(PointerRNA *ptr)
        return rna_pointer_inherit_refine(ptr, &RNA_SoftBodySettings, ob->soft);
 }
 
+static PointerRNA rna_SoftBodyModifier_point_cache_get(PointerRNA *ptr)
+{
+       Object *ob= (Object*)ptr->id.data;
+       return rna_pointer_inherit_refine(ptr, &RNA_PointCache, ob->soft->pointcache);
+}
+
 static PointerRNA rna_CollisionModifier_settings_get(PointerRNA *ptr)
 {
        Object *ob= (Object*)ptr->id.data;
@@ -883,6 +890,11 @@ static void rna_def_modifier_softbody(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "SoftBodySettings");
        RNA_def_property_pointer_funcs(prop, "rna_SoftBodyModifier_settings_get", NULL, NULL);
        RNA_def_property_ui_text(prop, "Soft Body Settings", "");
+
+       prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
+       RNA_def_property_struct_type(prop, "PointCache");
+       RNA_def_property_pointer_funcs(prop, "rna_SoftBodyModifier_point_cache_get", NULL, NULL);
+       RNA_def_property_ui_text(prop, "Soft Body Point Cache", "");
 }
 
 static void rna_def_modifier_boolean(BlenderRNA *brna)
index 215a1e7..e229afe 100644 (file)
@@ -171,91 +171,91 @@ static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr)
 
 static int rna_SoftBodySettings_use_edges_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_EDGES) != 0);
 }
 
 static void rna_SoftBodySettings_use_edges_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_EDGES;
        else data->softflag &= ~OB_SB_EDGES;
 }
 
 static int rna_SoftBodySettings_use_goal_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_GOAL) != 0);
 }
 
 static void rna_SoftBodySettings_use_goal_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_GOAL;
        else data->softflag &= ~OB_SB_GOAL;
 }
 
 static int rna_SoftBodySettings_stiff_quads_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_QUADS) != 0);
 }
 
 static void rna_SoftBodySettings_stiff_quads_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_QUADS;
        else data->softflag &= ~OB_SB_QUADS;
 }
 
 static int rna_SoftBodySettings_self_collision_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_SELF) != 0);
 }
 
 static void rna_SoftBodySettings_self_collision_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_SELF;
        else data->softflag &= ~OB_SB_SELF;
 }
 
 static int rna_SoftBodySettings_new_aero_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_AERO_ANGLE) != 0);
 }
 
 static void rna_SoftBodySettings_new_aero_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_AERO_ANGLE;
        else data->softflag &= ~OB_SB_AERO_ANGLE;
 }
 
 static int rna_SoftBodySettings_face_collision_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_FACECOLL) != 0);
 }
 
 static void rna_SoftBodySettings_face_collision_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_FACECOLL;
        else data->softflag &= ~OB_SB_FACECOLL;
 }
 
 static int rna_SoftBodySettings_edge_collision_get(PointerRNA *ptr)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        return (((data->softflag) & OB_SB_EDGECOLL) != 0);
 }
 
 static void rna_SoftBodySettings_edge_collision_set(PointerRNA *ptr, int value)
 {
-       Object *data= (Object*)(ptr->data);
+       Object *data= (Object*)(ptr->id.data);
        if(value) data->softflag |= OB_SB_EDGECOLL;
        else data->softflag &= ~OB_SB_EDGECOLL;
 }