Fix for freeing node trees that are part of other data blocks (material, world, lamp, texture, scene). These node trees were not properly freeing the IDProperty data, due to not being called from BKE_libblock_free.
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).
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user