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:
authorBastien Montagne <montagne29@wanadoo.fr>2018-04-04 15:56:32 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-04-04 15:58:52 +0300
commitd59c2d12b1226afa3789b0ef142f8f6cc9356ead (patch)
treedfd6f50ab327b3b77994a661a449fa5ec09bbbb3 /source/blender/blenkernel
parent0c7ec5896638480c8ed0a67d80026b83e4d12526 (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')
-rw-r--r--source/blender/blenkernel/BKE_modifier.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c24
-rw-r--r--source/blender/blenkernel/intern/object.c9
5 files changed, 31 insertions, 7 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b0917e4f6cd..18cde156f5e 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -346,6 +346,7 @@ const ModifierTypeInfo *modifierType_getInfo(ModifierType type);
* default values if pointer is optional.
*/
struct ModifierData *modifier_new(int type);
+void modifier_free_ex(struct ModifierData *md, const int flag);
void modifier_free(struct ModifierData *md);
bool modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 5578290c41a..3fea26e7359 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -73,7 +73,7 @@ void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *
bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src);
-void BKE_object_free_modifiers(struct Object *ob);
+void BKE_object_free_modifiers(struct Object *ob, const int flag);
void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index c8b44511edd..6a45432e863 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2429,7 +2429,7 @@ Mesh *BKE_mesh_new_from_object(
/* if getting the original caged mesh, delete object modifiers */
if (cage)
- BKE_object_free_modifiers(tmpobj);
+ BKE_object_free_modifiers(tmpobj, 0);
/* copies the data */
copycu = tmpobj->data = BKE_curve_copy(bmain, (Curve *) ob->data);
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) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index acc652fb1be..751cd733ae1 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -201,12 +201,12 @@ void BKE_object_free_curve_cache(Object *ob)
}
}
-void BKE_object_free_modifiers(Object *ob)
+void BKE_object_free_modifiers(Object *ob, const int flag)
{
ModifierData *md;
while ((md = BLI_pophead(&ob->modifiers))) {
- modifier_free(md);
+ modifier_free_ex(md, flag);
}
/* particle modifiers were freed, so free the particlesystems as well */
@@ -268,7 +268,7 @@ bool BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src)
{
ModifierData *md;
- BKE_object_free_modifiers(ob_dst);
+ BKE_object_free_modifiers(ob_dst, 0);
if (!ELEM(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
/* only objects listed above can have modifiers and linking them to objects
@@ -410,7 +410,8 @@ void BKE_object_free(Object *ob)
{
BKE_animdata_free((ID *)ob, false);
- BKE_object_free_modifiers(ob);
+ /* BKE_<id>_free shall never touch to ID->us. Never ever. */
+ BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
MEM_SAFE_FREE(ob->mat);
MEM_SAFE_FREE(ob->matbits);