Fix for freeing node trees that are part of other data blocks (material, world, lamp...
authorLukas Toenne <lukas.toenne@googlemail.com>
Sun, 28 Oct 2012 17:09:50 +0000 (17:09 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Sun, 28 Oct 2012 17:09:50 +0000 (17:09 +0000)
Now there is an extra function BKE_libblock_free_data, which is called explicitly in ntreeFreeTree if the tree is not part of the library data (ntreeCopyTree does a similar thing using BKE_libblock_copy_data).

source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/node.c

index 91756448297e649b53e1c5c06234f289d513a452..bc081b7f3085d3d1e5b18b33512a9f6f8cc2a7a5 100644 (file)
@@ -81,6 +81,7 @@ int set_listbasepointers(struct Main *main, struct ListBase **lb);
 
 void BKE_libblock_free(struct ListBase *lb, void *idv);
 void BKE_libblock_free_us(struct ListBase *lb, void *idv);
+void BKE_libblock_free_data(struct ID *id);
 void free_main(struct Main *mainvar);
 
 void tag_main_idcode(struct Main *mainvar, const short type, const short tag);
index 2f5e48e0ac66d74e0cc9167b778a41cc9fbb57b3..942e71b50522d43ac3027acc4995c741af096b16 100644 (file)
@@ -796,6 +796,18 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata
        }
 }
 
+void BKE_libblock_free_data(ID *id)
+{
+       Main *bmain = G.main;  /* should eventually be an arg */
+       
+       if (id->properties) {
+               IDP_FreeProperty(id->properties);
+               MEM_freeN(id->properties);
+       }
+       
+       /* this ID may be a driver target! */
+       BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
+}
 
 /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */
 void BKE_libblock_free(ListBase *lb, void *idv)
@@ -904,15 +916,9 @@ void BKE_libblock_free(ListBase *lb, void *idv)
                        break;
        }
 
-       if (id->properties) {
-               IDP_FreeProperty(id->properties);
-               MEM_freeN(id->properties);
-       }
-
        BLI_remlink(lb, id);
 
-       /* this ID may be a driver target! */
-       BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
+       BKE_libblock_free_data(id);
 
        MEM_freeN(id);
 }
index 3f30da7f349a03913442e1b2bfb692f094000e89..3112e8dc13d9a2697747eb01b7ae14f55ab5b6e6 100644 (file)
@@ -1013,6 +1013,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
 /* do not free ntree itself here, BKE_libblock_free calls this function too */
 void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
 {
+       bNodeTree *tntree;
        bNode *node, *next;
        bNodeSocket *sock;
        
@@ -1069,6 +1070,14 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
        for (sock = ntree->outputs.first; sock; sock = sock->next)
                node_socket_free_default_value(sock->type, sock->default_value);
        BLI_freelistN(&ntree->outputs);
+       
+       /* if ntree is not part of library, free the libblock data explicitly */
+       for (tntree = G.main->nodetree.first; tntree; tntree = tntree->id.next)
+               if (tntree == ntree)
+                       break;
+       if (tntree == NULL) {
+               BKE_libblock_free_data(&ntree->id);
+       }
 }
 /* same as ntreeFreeTree_ex but always manage users */
 void ntreeFreeTree(bNodeTree *ntree)