Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2018-07-04 12:22:15 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2018-07-04 12:33:27 +0300
commit769c57b38a707397ac7fdda15b1deb561194b66c (patch)
treec618131eb63627c5a353c8ba1437c359b72ddbad /source/blender/blenkernel
parent9e4d667c2cfd4a81f9a69628b69facd8fd4e0a01 (diff)
SoftBody: share point cache between CoW copies
This is the same approach as 98a0bcd4252e952fa5438e9d1b69b0204f8a8746 applied to soft body simulation. In short, CoW copies share the point cache, and treat it as read-only except when the depsgraph is active.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/bpath.c2
-rw-r--r--source/blender/blenkernel/intern/object.c6
-rw-r--r--source/blender/blenkernel/intern/pointcache.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c23
4 files changed, 25 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 7c9e57b039e..34f54704f75 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -513,7 +513,7 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
}
if (ob->soft) {
- BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches);
+ BPATH_TRAVERSE_POINTCACHE(ob->soft->shared->ptcaches);
}
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 3f5464156c5..61d38a4e937 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -834,6 +834,7 @@ void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src
{
SoftBody *sb = ob_src->soft;
SoftBody *sbn;
+ bool tagged_no_main = ob_dst->id.tag & LIB_TAG_NO_MAIN;
ob_dst->softflag = ob_src->softflag;
if (sb == NULL) {
@@ -872,7 +873,10 @@ void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src
sbn->scratch = NULL;
- sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, flag);
+ if (tagged_no_main == 0) {
+ sbn->shared = MEM_dupallocN(sb->shared);
+ sbn->shared->pointcache = BKE_ptcache_copy_list(&sbn->shared->ptcaches, &sb->shared->ptcaches, flag);
+ }
if (sb->effector_weights)
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index a8c6091124a..17e90d688a2 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1389,9 +1389,9 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
pid->ob= ob;
pid->calldata= sb;
pid->type= PTCACHE_TYPE_SOFTBODY;
- pid->cache= sb->pointcache;
- pid->cache_ptr= &sb->pointcache;
- pid->ptcaches= &sb->ptcaches;
+ pid->cache= sb->shared->pointcache;
+ pid->cache_ptr= &sb->shared->pointcache;
+ pid->ptcaches= &sb->shared->ptcaches;
pid->totpoint= pid->totwrite= ptcache_softbody_totpoint;
pid->error = ptcache_softbody_error;
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 4960714b47c..d3429622573 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3276,7 +3276,8 @@ SoftBody *sbNew(Scene *scene)
sb->shearstiff = 1.0f;
sb->solverflags |= SBSO_OLDERR;
- sb->pointcache = BKE_ptcache_add(&sb->ptcaches);
+ sb->shared = MEM_callocN(sizeof(*sb->shared), "SoftBody_Shared");
+ sb->shared->pointcache = BKE_ptcache_add(&sb->shared->ptcaches);
if (!sb->effector_weights)
sb->effector_weights = BKE_add_effector_weights(NULL);
@@ -3295,8 +3296,13 @@ void sbFree(Object *ob)
}
free_softbody_intern(sb);
- BKE_ptcache_free_list(&sb->ptcaches);
- sb->pointcache = NULL;
+
+ if ((ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
+ /* Only free shared data on non-CoW copies */
+ BKE_ptcache_free_list(&sb->shared->ptcaches);
+ sb->shared->pointcache = NULL;
+ MEM_freeN(sb->shared);
+ }
if (sb->effector_weights)
MEM_freeN(sb->effector_weights);
MEM_freeN(sb);
@@ -3608,7 +3614,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
float dtime, timescale;
int framedelta, framenr, startframe, endframe;
int cache_result;
- cache= sb->pointcache;
+ cache= sb->shared->pointcache;
framenr= (int)cfra;
framedelta= framenr - cache->simframe;
@@ -3676,7 +3682,8 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
}
/* try to read from cache */
- bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED);
+ bool can_write_cache = DEG_is_active(depsgraph);
+ bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED) && can_write_cache;
cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, can_simulate);
@@ -3687,7 +3694,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
BKE_ptcache_validate(cache, framenr);
- if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+ if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED && can_write_cache)
BKE_ptcache_write(&pid, framenr);
sb->last_frame = framenr;
@@ -3699,7 +3706,9 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c
}
else if (/*ob->id.lib || */(cache->flag & PTCACHE_BAKED)) { /* "library linking & pointcaches" has to be solved properly at some point */
/* if baked and nothing in cache, do nothing */
- BKE_ptcache_invalidate(cache);
+ if (can_write_cache) {
+ BKE_ptcache_invalidate(cache);
+ }
return;
}