Fix T57996: Crash - delete node with a driven parameter

This commit is contained in:
Sergey Sharybin 2018-11-23 17:02:55 +01:00
parent e5abce9220
commit 3bf7c846ee
Notes: blender-bot 2023-02-14 06:32:27 +01:00
Referenced by issue #57996, Crash - delete node with a driven parameter
7 changed files with 35 additions and 17 deletions

View File

@ -450,7 +450,11 @@ struct bNode *nodeAddStaticNode(const struct bContext *C, struct bNodeTree *ntre
void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node);
/* Frees the node itself, without affect to anything else. */
void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
/* Will additionally cleanup things like f-curves which uses this node. */
void nodeDeleteNode(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
struct bNode *BKE_node_copy_ex(struct bNodeTree *ntree, struct bNode *node_src, const int flag);
struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);

View File

@ -76,6 +76,7 @@
#include "NOD_texture.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#define NODE_DEFAULT_MAX_WIDTH 700
@ -1688,7 +1689,9 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
}
/** \note caller needs to manage node->id user */
static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool remove_animdata, bool use_api_free_cb)
static void node_free_node_ex(
Main *bmain, bNodeTree *ntree, bNode *node,
bool remove_animdata, bool use_api_free_cb)
{
bNodeSocket *sock, *nextsock;
@ -1722,7 +1725,11 @@ static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool remove_animdat
BLI_strescape(propname_esc, node->name, sizeof(propname_esc));
BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
BKE_animdata_fix_paths_remove((ID *)ntree, prefix);
if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) {
if (bmain != NULL) {
DEG_relations_tag_update(bmain);
}
}
}
if (ntree->typeinfo->free_node_cache)
@ -1765,7 +1772,12 @@ static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool remove_animdat
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
node_free_node_ex(ntree, node, true, true);
node_free_node_ex(NULL, ntree, node, false, true);
}
void nodeDeleteNode(Main *bmain, bNodeTree *ntree, bNode *node)
{
node_free_node_ex(bmain, ntree, node, true, true);
}
static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *sock)
@ -1835,7 +1847,7 @@ void ntreeFreeTree(bNodeTree *ntree)
for (node = ntree->nodes.first; node; node = next) {
next = node->next;
node_free_node_ex(ntree, node, false, false);
node_free_node_ex(NULL, ntree, node, false, false);
}
/* free interface sockets */
@ -2577,7 +2589,7 @@ void BKE_node_clipboard_clear(void)
for (node = node_clipboard.nodes.first; node; node = node_next) {
node_next = node->next;
node_free_node_ex(NULL, node, false, false);
node_free_node_ex(NULL, NULL, node, false, false);
}
BLI_listbase_clear(&node_clipboard.nodes);

View File

@ -1586,7 +1586,7 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, node));
if (node->id)
id_us_min(node->id);
nodeFreeNode(snode->edittree, node);
nodeDeleteNode(bmain, snode->edittree, node);
}
}
@ -1666,6 +1666,7 @@ void NODE_OT_switch_view_update(wmOperatorType *ot)
/* ****************** Delete with reconnect ******************* */
static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node, *next;
@ -1679,7 +1680,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
/* check id user here, nodeFreeNode is called for free dbase too */
if (node->id)
id_us_min(node->id);
nodeFreeNode(snode->edittree, node);
nodeDeleteNode(bmain, snode->edittree, node);
}
}

View File

@ -342,11 +342,11 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
while (nodes_delayed_free) {
node = BLI_linklist_pop(&nodes_delayed_free);
nodeFreeNode(ntree, node);
nodeDeleteNode(bmain, ntree, node);
}
/* delete the group instance */
nodeFreeNode(ntree, gnode);
nodeDeleteNode(bmain, ntree, gnode);
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;

View File

@ -124,7 +124,7 @@ static void node_clear_recursive(bNode *node)
node_clear_recursive(input->link->fromnode);
}
static void node_remove_linked(bNodeTree *ntree, bNode *rem_node)
static void node_remove_linked(Main *bmain, bNodeTree *ntree, bNode *rem_node)
{
bNode *node, *next;
bNodeSocket *sock;
@ -152,7 +152,7 @@ static void node_remove_linked(bNodeTree *ntree, bNode *rem_node)
if (node->flag & NODE_TEST) {
if (node->id)
id_us_min(node->id);
nodeFreeNode(ntree, node);
nodeDeleteNode(bmain, ntree, node);
}
}
}
@ -178,7 +178,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN
if (!sock_to->link)
return;
node_remove_linked(ntree, sock_to->link->fromnode);
node_remove_linked(bmain, ntree, sock_to->link->fromnode);
sock_to->flag |= SOCK_COLLAPSED;
nodeUpdate(ntree, node_to);
@ -269,7 +269,7 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *
}
/* remove node */
node_remove_linked(ntree, node_prev);
node_remove_linked(bmain, ntree, node_prev);
}
nodeUpdate(ntree, node_from);

View File

@ -6281,8 +6281,9 @@ static void special_aftertrans_update__mask(bContext *C, TransInfo *t)
}
}
static void special_aftertrans_update__node(bContext *UNUSED(C), TransInfo *t)
static void special_aftertrans_update__node(bContext *C, TransInfo *t)
{
Main *bmain = CTX_data_main(C);
const bool canceled = (t->state == TRANS_CANCEL);
if (canceled && t->remove_on_cancel) {
@ -6294,7 +6295,7 @@ static void special_aftertrans_update__node(bContext *UNUSED(C), TransInfo *t)
for (node = ntree->nodes.first; node; node = node_next) {
node_next = node->next;
if (node->flag & NODE_SELECT)
nodeFreeNode(ntree, node);
nodeDeleteNode(bmain, ntree, node);
}
}
}

View File

@ -748,7 +748,7 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree, Main *bmain, ReportList *
}
id_us_min(node->id);
nodeFreeNode(ntree, node);
nodeDeleteNode(bmain, ntree, node);
RNA_POINTER_INVALIDATE(node_ptr);
ntreeUpdateTree(bmain, ntree); /* update group node socket links */
@ -768,7 +768,7 @@ static void rna_NodeTree_node_clear(bNodeTree *ntree, Main *bmain, ReportList *r
if (node->id)
id_us_min(node->id);
nodeFreeNode(ntree, node);
nodeDeleteNode(bmain, ntree, node);
node = next_node;
}