Fix T61506: Wrong user counting with ID properties in pynodes.
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 13 Feb 2019 13:58:38 +0000 (14:58 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 13 Feb 2019 14:02:24 +0000 (15:02 +0100)
Nuke away old nodeCopyNode(), much better to use new BKE_node_copy_ex(),
which behaves as expected for the various optional flags that can be passed.

This also removes the need to handle ID refcounting in calling code
(ugly!) and allows us to remove an even uglier name from our codebase! :D

Note that this fixes three related issues actually, that bug was also
affecting copy/paste of nodes, and 'Separate with copy' operator (the
latter being actually fully wrong, since it was not refcounting
anything, not even node->id pointer...).

source/blender/blenkernel/BKE_node.h
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_group.c

index 7061b68..5d15256 100644 (file)
@@ -450,7 +450,6 @@ void            nodeFreeNode(struct bNodeTree *ntree, struct bNode *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);
 
 struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock);
 void            nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
index 8321278..c14d378 100644 (file)
@@ -1112,15 +1112,10 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
        lastnode = ntree->nodes.last;
        for (node = ntree->nodes.first; node; node = node->next) {
                if (node->flag & SELECT) {
-                       newnode = nodeCopyNode(ntree, node);
-
-                       if (newnode->id) {
-                               /* simple id user adjustment, node internal functions don't touch this
-                                * but operators and readfile.c do. */
-                               id_us_plus(newnode->id);
-                               /* to ensure redraws or rerenders happen */
-                               ED_node_tag_update_id(snode->id);
-                       }
+                       newnode = BKE_node_copy_ex(ntree, node, LIB_ID_COPY_DEFAULT);
+
+                       /* to ensure redraws or rerenders happen */
+                       ED_node_tag_update_id(snode->id);
                }
 
                /* make sure we don't copy new nodes again! */
@@ -1926,8 +1921,8 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
 
        for (node = ntree->nodes.first; node; node = node->next) {
                if (node->flag & SELECT) {
-                       bNode *new_node;
-                       new_node = nodeCopyNode(NULL, node);
+                       /* No ID refcounting, this node is virtual, detached from any actual Blender data currently. */
+                       bNode *new_node = BKE_node_copy_ex(ntree, node, LIB_ID_CREATE_NO_USER_REFCOUNT);
                        BKE_node_clipboard_add_node(new_node);
                }
        }
@@ -2047,10 +2042,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
 
        /* copy nodes from clipboard */
        for (node = clipboard_nodes_lb->first; node; node = node->next) {
-               bNode *new_node = nodeCopyNode(ntree, node);
-
-               /* needed since nodeCopyNode() doesn't increase ID's */
-               id_us_plus(node->id);
+               bNode *new_node = BKE_node_copy_ex(ntree, node, LIB_ID_COPY_DEFAULT);
 
                /* pasted nodes are selected */
                nodeSetSelected(new_node, true);
index e29d6e0..24036a9 100644 (file)
@@ -404,7 +404,7 @@ static int node_group_separate_selected(
        for (node = ntree->nodes.first; node; node = node->next)
                nodeSetSelected(node, false);
 
-       /* clear new pointers, set in nodeCopyNode */
+       /* clear new pointers, set in BKE_node_copy_ex(). */
        for (node = ngroup->nodes.first; node; node = node->next)
                node->new_node = NULL;
 
@@ -422,7 +422,7 @@ static int node_group_separate_selected(
 
                if (make_copy) {
                        /* make a copy */
-                       newnode = nodeCopyNode(ngroup, node);
+                       newnode = BKE_node_copy_ex(ngroup, node, LIB_ID_COPY_DEFAULT);
                }
                else {
                        /* use the existing node */
@@ -541,13 +541,13 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
 
        switch (type) {
                case NODE_GS_COPY:
-                       if (!node_group_separate_selected(bmain, nparent, ngroup, offx, offy, 1)) {
+                       if (!node_group_separate_selected(bmain, nparent, ngroup, offx, offy, true)) {
                                BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes");
                                return OPERATOR_CANCELLED;
                        }
                        break;
                case NODE_GS_MOVE:
-                       if (!node_group_separate_selected(bmain, nparent, ngroup, offx, offy, 0)) {
+                       if (!node_group_separate_selected(bmain, nparent, ngroup, offx, offy, false)) {
                                BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes");
                                return OPERATOR_CANCELLED;
                        }