Fix #32667: Curve softbodies doesn't render animation (cycles)
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 27 Sep 2012 14:37:20 +0000 (14:37 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 27 Sep 2012 14:37:20 +0000 (14:37 +0000)
Issue was caused by cycles being duplicated curve objects before converting
them to mesh. This duplication will loose pointcache which resulted in object
not being properly deformed.

source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/pointcache.c
source/blender/editors/object/object_edit.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/modifiers/intern/MOD_cloth.c

index 269d96d..ec07032 100644 (file)
@@ -54,7 +54,7 @@ void BKE_object_workob_clear(struct Object *workob);
 void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
 
 void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
-struct SoftBody *copy_softbody(struct SoftBody *sb);
+struct SoftBody *copy_softbody(struct SoftBody *sb, int copy_caches);
 struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb);
 void BKE_object_copy_particlesystems(struct Object *obn, struct Object *ob);
 void BKE_object_copy_softbody(struct Object *obn, struct Object *ob);
@@ -82,6 +82,7 @@ struct Object *BKE_object_add(struct Scene *scene, int type);
 void *BKE_object_obdata_add_from_type(int type);
 
 struct Object *BKE_object_copy(struct Object *ob);
+struct Object *BKE_object_copy_with_caches(struct Object *ob);
 void BKE_object_make_local(struct Object *ob);
 int  BKE_object_is_libdata(struct Object *ob);
 int  BKE_object_obdata_is_libdata(struct Object *ob);
index d6ab9a3..77b35e1 100644 (file)
@@ -303,7 +303,7 @@ struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches);
 void BKE_ptcache_free_mem(struct ListBase *mem_cache);
 void BKE_ptcache_free(struct PointCache *cache);
 void BKE_ptcache_free_list(struct ListBase *ptcaches);
-struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, struct ListBase *ptcaches_old);
+struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, struct ListBase *ptcaches_old, int copy_data);
 
 /********************** Baking *********************/
 
index e659441..ab261e7 100644 (file)
@@ -889,23 +889,44 @@ Object *BKE_object_add(struct Scene *scene, int type)
        return ob;
 }
 
-SoftBody *copy_softbody(SoftBody *sb)
+SoftBody *copy_softbody(SoftBody *sb, int copy_caches)
 {
        SoftBody *sbn;
        
        if (sb == NULL) return(NULL);
        
        sbn = MEM_dupallocN(sb);
-       sbn->totspring = sbn->totpoint = 0;
-       sbn->bpoint = NULL;
-       sbn->bspring = NULL;
+
+       if (copy_caches == FALSE) {
+               sbn->totspring = sbn->totpoint = 0;
+               sbn->bpoint = NULL;
+               sbn->bspring = NULL;
+       }
+       else {
+               sbn->totspring = sb->totspring;
+               sbn->totpoint = sb->totpoint;
+
+               if (sbn->bpoint) {
+                       int i;
+
+                       sbn->bpoint = MEM_dupallocN(sbn->bpoint);
+
+                       for (i = 0; i < sbn->totpoint; i++) {
+                               if (sbn->bpoint[i].springs)
+                                       sbn->bpoint[i].springs = MEM_dupallocN(sbn->bpoint[i].springs);
+                       }
+               }
+
+               if (sb->bspring)
+                       sbn->bspring = MEM_dupallocN(sb->bspring);
+       }
        
        sbn->keys = NULL;
        sbn->totkey = sbn->totpointkey = 0;
        
        sbn->scratch = NULL;
 
-       sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches);
+       sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, copy_caches);
 
        if (sb->effector_weights)
                sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
@@ -978,7 +999,7 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
        psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
        psysn->renderdata = NULL;
        
-       psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches);
+       psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, FALSE);
 
        /* XXX - from reading existing code this seems correct but intended usage of
         * pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -1039,7 +1060,7 @@ void BKE_object_copy_particlesystems(Object *obn, Object *ob)
 void BKE_object_copy_softbody(Object *obn, Object *ob)
 {
        if (ob->soft)
-               obn->soft = copy_softbody(ob->soft);
+               obn->soft = copy_softbody(ob->soft, FALSE);
 }
 
 static void copy_object_pose(Object *obn, Object *ob)
@@ -1120,7 +1141,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
        copy_v3_v3(ob_tar->size, ob_src->size);
 }
 
-Object *BKE_object_copy(Object *ob)
+static Object *object_copy_do(Object *ob, int copy_caches)
 {
        Object *obn;
        ModifierData *md;
@@ -1181,7 +1202,7 @@ Object *BKE_object_copy(Object *ob)
                if (obn->pd->rng)
                        obn->pd->rng = MEM_dupallocN(ob->pd->rng);
        }
-       obn->soft = copy_softbody(ob->soft);
+       obn->soft = copy_softbody(ob->soft, copy_caches);
        obn->bsoft = copy_bulletsoftbody(ob->bsoft);
 
        BKE_object_copy_particlesystems(obn, ob);
@@ -1197,6 +1218,18 @@ Object *BKE_object_copy(Object *ob)
        return obn;
 }
 
+/* copy objects, will re-initialize cached simulation data */
+Object *BKE_object_copy(Object *ob)
+{
+       return object_copy_do(ob, FALSE);
+}
+
+/* copy objects, will duplicate cached simulation data */
+Object *BKE_object_copy_with_caches(Object *ob)
+{
+       return object_copy_do(ob, TRUE);
+}
+
 static void extern_local_object(Object *ob)
 {
        ParticleSystem *psys;
index 780528f..0d01bb3 100644 (file)
@@ -2663,32 +2663,59 @@ void BKE_ptcache_free_list(ListBase *ptcaches)
        }
 }
 
-static PointCache *ptcache_copy(PointCache *cache)
+static PointCache *ptcache_copy(PointCache *cache, int copy_data)
 {
        PointCache *ncache;
 
        ncache= MEM_dupallocN(cache);
 
-       /* hmm, should these be copied over instead? */
        ncache->mem_cache.first = NULL;
        ncache->mem_cache.last = NULL;
-       ncache->cached_frames = NULL;
-       ncache->edit = NULL;
 
-       ncache->flag= 0;
-       ncache->simframe= 0;
+       if (copy_data == FALSE) {
+               ncache->mem_cache.first = NULL;
+               ncache->mem_cache.last = NULL;
+               ncache->cached_frames = NULL;
+
+               ncache->flag= 0;
+               ncache->simframe= 0;
+       }
+       else {
+               PTCacheMem *pm;
+
+               for (pm = cache->mem_cache.first; pm; pm = pm->next) {
+                       PTCacheMem *pmn = MEM_dupallocN(pm);
+                       int i;
+
+                       for (i = 0; i < BPHYS_TOT_DATA; i++) {
+                               if (pmn->data[i])
+                                       pmn->data[i] = MEM_dupallocN(pm->data[i]);
+                       }
+
+                       BKE_ptcache_mem_pointers_init(pm);
+
+                       BLI_addtail(&ncache->mem_cache, pmn);
+               }
+
+               if (ncache->cached_frames)
+                       ncache->cached_frames = MEM_dupallocN(cache->cached_frames);
+       }
+
+       /* hmm, should these be copied over instead? */
+       ncache->edit = NULL;
 
        return ncache;
 }
+
 /* returns first point cache */
-PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old)
+PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old, int copy_data)
 {
        PointCache *cache = ptcaches_old->first;
 
        ptcaches_new->first = ptcaches_new->last = NULL;
 
        for (; cache; cache=cache->next)
-               BLI_addtail(ptcaches_new, ptcache_copy(cache));
+               BLI_addtail(ptcaches_new, ptcache_copy(cache, copy_data));
 
        return ptcaches_new->first;
 }
index f95a186..bdc7699 100644 (file)
@@ -957,7 +957,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
                                        base->object->softflag = ob->softflag;
                                        if (base->object->soft) sbFree(base->object->soft);
                                        
-                                       base->object->soft = copy_softbody(ob->soft);
+                                       base->object->soft = copy_softbody(ob->soft, FALSE);
 
                                        if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
                                                BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
index 1263e77..a6f49d8 100644 (file)
@@ -96,7 +96,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_
                        float (*orco)[3] = NULL;
 
                        /* copies object and modifiers (but not the data) */
-                       tmpobj = BKE_object_copy(ob);
+                       tmpobj = BKE_object_copy_with_caches(ob);
                        tmpcu = (Curve *)tmpobj->data;
                        tmpcu->id.us--;
 
index dc6fef9..8eb47f4 100644 (file)
@@ -155,7 +155,7 @@ static void copyData(ModifierData *md, ModifierData *target)
        if (clmd->sim_parms->effector_weights)
                tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
        tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
-       tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
+       tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches, FALSE);
        tclmd->clothObject = NULL;
 }