Commit: 5797a5fc65c87b69460d910a82d219b5e3ea12ad
Author: Miguel Porces
Date:   Sat Mar 16 18:54:00 2019 +0100
Branches: master
https://developer.blender.org/rB5797a5fc65c87b69460d910a82d219b5e3ea12ad

Fix ID user counting issues with NodeCustomGroup.

User counting now happens before init() and after free() methods, so that
the ID users are in a valid state when Python might modify them. ID user
counting was moved into node.c and simplified.

Patch by Miguel with further refactoring by Brecht. Ref D4370.

===================================================================

M       source/blender/blenkernel/BKE_node.h
M       source/blender/blenkernel/intern/node.c
M       source/blender/editors/space_node/node_edit.c
M       source/blender/editors/space_node/node_group.c
M       source/blender/editors/space_node/node_templates.c
M       source/blender/editors/transform/transform_conversions.c
M       source/blender/makesrna/intern/rna_nodetree.c
M       source/blender/nodes/shader/node_shader_tree.c
M       source/blender/nodes/texture/node_texture_tree.c
M       source/blender/windowmanager/intern/wm_init_exit.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_node.h 
b/source/blender/blenkernel/BKE_node.h
index 6e6ec31aa6a..951962d26f1 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -337,6 +337,7 @@ void              ntreeUserDecrefID(struct bNodeTree 
*ntree);
 struct bNodeTree *ntreeFromID(const struct ID *id);
 
 void              ntreeMakeLocal(struct Main *bmain, struct bNodeTree *ntree, 
bool id_in_mainlist, const bool lib_local);
+void              ntreeFreeLocalNode(struct bNodeTree *ntree, struct bNode 
*node);
 void              ntreeFreeLocalTree(struct bNodeTree *ntree);
 struct bNode     *ntreeFindType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasType(const struct bNodeTree *ntree, int type);
@@ -445,10 +446,8 @@ 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);
+/* Delete node, associated animation data and ID user count. */
+void            nodeRemoveNode(struct Main *bmain, struct bNodeTree *ntree, 
struct bNode *node, bool do_id_user);
 
 struct bNode    *BKE_node_copy_ex(struct bNodeTree *ntree, struct bNode 
*node_src, const int flag);
 
@@ -502,6 +501,7 @@ void            ntreeTagUsedSockets(struct bNodeTree 
*ntree);
 /* Node Clipboard */
 void                   BKE_node_clipboard_init(struct bNodeTree *ntree);
 void                   BKE_node_clipboard_clear(void);
+void                   BKE_node_clipboard_free(void);
 bool                   BKE_node_clipboard_validate(void);
 void                   BKE_node_clipboard_add_node(struct bNode *node);
 void                   BKE_node_clipboard_add_link(struct bNodeLink *link);
diff --git a/source/blender/blenkernel/intern/node.c 
b/source/blender/blenkernel/intern/node.c
index 09b44db02e5..57dcbcbebf8 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -139,6 +139,9 @@ static void node_init(const struct bContext *C, bNodeTree 
*ntree, bNode *node)
        if (ntree->typeinfo->node_add_init != NULL)
                ntree->typeinfo->node_add_init(ntree, node);
 
+       if (node->id)
+               id_us_plus(node->id);
+
        /* extra init callback */
        if (ntype->initfunc_api) {
                PointerRNA ptr;
@@ -151,9 +154,6 @@ static void node_init(const struct bContext *C, bNodeTree 
*ntree, bNode *node)
                ntype->initfunc_api(C, &ptr);
        }
 
-       if (node->id)
-               id_us_plus(node->id);
-
        node->flag |= NODE_INIT;
 }
 
@@ -1007,7 +1007,8 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree, bNode 
*node_src, const int flag)
        node_src->new_node = node_dst;
        node_dst->new_node = NULL;
 
-       if (node_dst->typeinfo->copyfunc_api) {
+       bool do_copy_api = !((flag & LIB_ID_CREATE_NO_MAIN) || (flag & 
LIB_ID_COPY_LOCALIZE));
+       if (node_dst->typeinfo->copyfunc_api && do_copy_api) {
                PointerRNA ptr;
                RNA_pointer_create((ID *)ntree, &RNA_Node, node_dst, &ptr);
 
@@ -1677,26 +1678,12 @@ static void node_unlink_attached(bNodeTree *ntree, 
bNode *parent)
        }
 }
 
-/** \note caller needs to manage node->id user */
-static void node_free_node_ex(
-        Main *bmain, bNodeTree *ntree, bNode *node,
-        bool remove_animdata, bool use_api_free_cb)
+/* Free the node itself. ID user refcounting is up the caller,
+ * that does not happen here. */
+static void node_free_node(bNodeTree *ntree, bNode *node)
 {
        bNodeSocket *sock, *nextsock;
 
-       /* don't remove node animdata if the tree is localized,
-        * Action is shared with the original tree (T38221)
-        */
-       remove_animdata &= ntree && !(ntree->id.tag & LIB_TAG_LOCALIZED);
-
-       /* extra free callback */
-       if (use_api_free_cb && node->typeinfo->freefunc_api) {
-               PointerRNA ptr;
-               RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
-
-               node->typeinfo->freefunc_api(&ptr);
-       }
-
        /* since it is called while free database, node->id is undefined */
 
        /* can be called for nodes outside a node tree (e.g. clipboard) */
@@ -1707,20 +1694,6 @@ static void node_free_node_ex(
 
                BLI_remlink(&ntree->nodes, node);
 
-               if (remove_animdata) {
-                       char propname_esc[MAX_IDPROP_NAME * 2];
-                       char prefix[MAX_IDPROP_NAME * 2];
-
-                       BLI_strescape(propname_esc, node->name, 
sizeof(propname_esc));
-                       BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", 
propname_esc);
-
-                       if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) 
{
-                               if (bmain != NULL) {
-                                       DEG_relations_tag_update(bmain);
-                               }
-                       }
-               }
-
                if (ntree->typeinfo->free_node_cache)
                        ntree->typeinfo->free_node_cache(ntree, node);
 
@@ -1762,14 +1735,49 @@ static void node_free_node_ex(
                ntree->update |= NTREE_UPDATE_NODES;
 }
 
-void nodeFreeNode(bNodeTree *ntree, bNode *node)
+void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node)
 {
-       node_free_node_ex(NULL, ntree, node, false, true);
+       /* For removing nodes while editing localized node trees. */
+       BLI_assert((ntree->id.tag & LIB_TAG_LOCALIZED) != 0);
+       node_free_node(ntree, node);
 }
 
-void nodeDeleteNode(Main *bmain, bNodeTree *ntree, bNode *node)
+void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool 
do_id_user)
 {
-       node_free_node_ex(bmain, ntree, node, true, true);
+       /* This function is not for localized node trees, we do not want
+        * do to ID user refcounting and removal of animdation data then. */
+       BLI_assert((ntree->id.tag & LIB_TAG_LOCALIZED) == 0);
+
+       if (do_id_user) {
+               /* Free callback for NodeCustomGroup. */
+               if (node->typeinfo->freefunc_api) {
+                       PointerRNA ptr;
+                       RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
+
+                       node->typeinfo->freefunc_api(&ptr);
+               }
+
+               /* Do user counting. */
+               if (node->id) {
+                       id_us_min(node->id);
+               }
+       }
+
+       /* Remove animation data. */
+       char propname_esc[MAX_IDPROP_NAME * 2];
+       char prefix[MAX_IDPROP_NAME * 2];
+
+       BLI_strescape(propname_esc, node->name, sizeof(propname_esc));
+       BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
+
+       if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) {
+               if (bmain != NULL) {
+                       DEG_relations_tag_update(bmain);
+               }
+       }
+
+       /* Free node itself. */
+       node_free_node(ntree, node);
 }
 
 static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket 
*sock)
@@ -1804,7 +1812,8 @@ static void free_localized_node_groups(bNodeTree *ntree)
        }
 }
 
-/** Free (or release) any data used by this nodetree (does not free the 
nodetree itself). */
+/* Free (or release) any data used by this nodetree. Does not free the
+ * nodetree itself and does no ID user counting. */
 void ntreeFreeTree(bNodeTree *ntree)
 {
        bNode *node, *next;
@@ -1839,7 +1848,7 @@ void ntreeFreeTree(bNodeTree *ntree)
 
        for (node = ntree->nodes.first; node; node = next) {
                next = node->next;
-               node_free_node_ex(NULL, ntree, node, false, false);
+               node_free_node(ntree, node);
        }
 
        /* free interface sockets */
@@ -2594,7 +2603,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, NULL, node, false, false);
+               node_free_node(NULL, node);
        }
        BLI_listbase_clear(&node_clipboard.nodes);
 
@@ -2697,6 +2706,11 @@ int BKE_node_clipboard_get_type(void)
        return node_clipboard.type;
 }
 
+void BKE_node_clipboard_free(void)
+{
+       BKE_node_clipboard_validate();
+       BKE_node_clipboard_clear();
+}
 
 /* Node Instance Hash */
 
diff --git a/source/blender/editors/space_node/node_edit.c 
b/source/blender/editors/space_node/node_edit.c
index b1cada9752a..1a18e886808 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1590,11 +1590,8 @@ static int node_delete_exec(bContext *C, wmOperator 
*UNUSED(op))
        for (node = snode->edittree->nodes.first; node; node = next) {
                next = node->next;
                if (node->flag & SELECT) {
-                       /* check id user here, nodeFreeNode is called for free 
dbase too */
                        do_tag_update |= (do_tag_update || 
node_connected_to_output(bmain, snode->edittree, node));
-                       if (node->id)
-                               id_us_min(node->id);
-                       nodeDeleteNode(bmain, snode->edittree, node);
+                       nodeRemoveNode(bmain, snode->edittree, node, true);
                }
        }
 
@@ -1684,11 +1681,7 @@ static int node_delete_reconnect_exec(bContext *C, 
wmOperator *UNUSED(op))
                next = node->next;
                if (node->flag & SELECT) {
                        nodeInternalRelink(snode->edittree, node);
-
-                       /* check id user here, nodeFreeNode is called for free 
dbase too */
-                       if (node->id)
-                               id_us_min(node->id);
-                       nodeDeleteNode(bmain, snode->edittree, node);
+                       nodeRemoveNode(bmain, snode->edittree, node, true);
                }
        }
 
diff --git a/source/blender/editors/space_node/node_group.c 
b/source/blender/editors/space_node/node_group.c
index 8c5bf60bc5d..808d9375d22 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -337,11 +337,11 @@ static int node_group_ungroup(Main *bmain, bNodeTree 
*ntree, bNode *gnode)
 
        while (nodes_delayed_free) {
                node = BLI_linklist_pop(&nodes_delayed_free);
-               nodeDeleteNode(bmain, ntree, node);
+               nodeRemoveNode(bmain, ntree, node, false);
        }
 
        /* delete the group instance */
-       nodeDeleteNode(bmain, ntree, gnode);
+       nodeRemoveNode(bmain, ntree, gnode, false);
 
        ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
 
diff --git a/source/blender/editors/space_node/node_templates.c 
b/source/blender/editors/space_node/node_templates.c
index aef36b49814..b3edf98c470 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -143,9 +143,7 @@ static void node_remove_linked(Main *bmain, bNodeTree 
*ntree, bNode *rem_node)
                next = node->next;
 
                if (node->flag & NODE_TEST) {
-                       if (node->id)
-                               id_us_min(node->id);
-                       nodeDeleteNode(bmain, ntree, node);
+                       nodeRemoveNode(bmain, ntree, node, true);
                }
        }
 }
diff --git a/source/

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to