diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-04-04 15:56:32 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-04-04 15:58:52 +0300 |
commit | d59c2d12b1226afa3789b0ef142f8f6cc9356ead (patch) | |
tree | dfd6f50ab327b3b77994a661a449fa5ec09bbbb3 /source/blender/blenkernel/intern/modifier.c | |
parent | 0c7ec5896638480c8ed0a67d80026b83e4d12526 (diff) |
Fix modifier freeing code re. ID refcounting.
Free code should not handle ID refcounting at all. This has to be done
at higher level, since in some case we want to free (temp) data that
actually did not refcount at all its IDs.
This change seems to be working OK, but as usual in that area, only
lots of testing in real-case situation will say whether there are some
hidden bugs or not.
Diffstat (limited to 'source/blender/blenkernel/intern/modifier.c')
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index d7a24f90dbe..ce04f3c31e2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -136,16 +136,38 @@ ModifierData *modifier_new(int type) return md; } -void modifier_free(ModifierData *md) +static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag) +{ + ID *id = *idpoin; + if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) { + id_us_min(id); + } +} + +void modifier_free_ex(ModifierData *md, const int flag) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + if (mti->foreachIDLink) { + mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL); + } + else if (mti->foreachObjectLink) { + mti->foreachObjectLink(md, NULL, (ObjectWalkFunc)modifier_free_data_id_us_cb, NULL); + } + } + if (mti->freeData) mti->freeData(md); if (md->error) MEM_freeN(md->error); MEM_freeN(md); } +void modifier_free(ModifierData *md) +{ + modifier_free_ex(md, 0); +} + bool modifier_unique_name(ListBase *modifiers, ModifierData *md) { if (modifiers && md) { |