Cloth simulation: share point cache between CoW copies of objects

This commit is contained in:
Sybren A. Stüvel 2018-07-04 12:46:03 +02:00
parent 60b9d413db
commit 175fe29e58
2 changed files with 24 additions and 5 deletions

View File

@ -119,6 +119,8 @@ typedef struct ModifierData {
typedef enum {
/* This modifier has been inserted in local override, and hence can be fully edited. */
eModifierFlag_StaticOverride_Local = (1 << 0),
/* This modifier does not own its caches, but instead shares them with another modifier. */
eModifierFlag_SharedCaches = (1 << 1),
} ModifierFlag;
typedef enum {
@ -608,8 +610,12 @@ typedef struct ClothModifierData {
struct Cloth *clothObject; /* The internal data structure for cloth. */
struct ClothSimSettings *sim_parms; /* definition is in DNA_cloth_types.h */
struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
/* PointCache can be shared with other instances of ClothModifierData.
* Inspect (modifier.flag & eModifierFlag_SharedCaches) to find out. */
struct PointCache *point_cache; /* definition is in DNA_object_force_types.h */
struct ListBase ptcaches;
/* XXX nasty hack, remove once hair can be separated from cloth modifier data */
struct ClothHairData *hairdata;
/* grid geometry values of hair continuum */

View File

@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BKE_cloth.h"
@ -155,7 +156,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
static void copyData(const ModifierData *md, ModifierData *target, const int UNUSED(flag))
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
const ClothModifierData *clmd = (const ClothModifierData *) md;
ClothModifierData *tclmd = (ClothModifierData *) target;
@ -170,14 +171,21 @@ static void copyData(const ModifierData *md, ModifierData *target, const int UNU
MEM_freeN(tclmd->coll_parms);
BKE_ptcache_free_list(&tclmd->ptcaches);
tclmd->point_cache = NULL;
if (flag & LIB_ID_CREATE_NO_MAIN) {
/* Share the cache with the original object's modifier. */
tclmd->modifier.flag |= eModifierFlag_SharedCaches;
tclmd->ptcaches = clmd->ptcaches;
tclmd->point_cache = clmd->point_cache;
}
else {
tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
tclmd->point_cache->step = 1;
}
tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
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_add(&tclmd->ptcaches);
tclmd->point_cache->step = 1;
tclmd->clothObject = NULL;
tclmd->hairdata = NULL;
tclmd->solver_result = NULL;
@ -206,7 +214,12 @@ static void freeData(ModifierData *md)
if (clmd->coll_parms)
MEM_freeN(clmd->coll_parms);
BKE_ptcache_free_list(&clmd->ptcaches);
if (md->flag & eModifierFlag_SharedCaches) {
BLI_listbase_clear(&clmd->ptcaches);
}
else {
BKE_ptcache_free_list(&clmd->ptcaches);
}
clmd->point_cache = NULL;
if (clmd->hairdata)