[Bf-blender-cvs] [b7145a2662d] id_copy_refactor: Initial work on new copying for nodetrees.
Bastien Montagne
noreply at git.blender.org
Mon Jun 26 11:01:34 CEST 2017
Commit: b7145a2662dd67251deecafd4ffadc8ef0a7cd8c
Author: Bastien Montagne
Date: Mon Jun 26 10:53:51 2017 +0200
Branches: id_copy_refactor
https://developer.blender.org/rBb7145a2662dd67251deecafd4ffadc8ef0a7cd8c
Initial work on new copying for nodetrees.
Note that those are an nightmare to handle correctly, current code is
like a plate of noodle, so... most likeley not fully working, think I'll
have to nuke localize code as well :(
===================================================================
M source/blender/blenkernel/BKE_node.h
M source/blender/blenkernel/intern/library.c
M source/blender/blenkernel/intern/node.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index d5279c5b0ce..0d6890f2350 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -335,6 +335,7 @@ struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char
/* copy/free funcs, need to manage ID users */
void ntreeFreeTree(struct bNodeTree *ntree);
+void BKE_node_tree_copy_ex(struct Main *bmain, struct bNodeTree *ntree_dst, const struct bNodeTree *ntree_src, const int flag);
struct bNodeTree *ntreeCopyTree_ex(const struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
struct bNodeTree *ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntree);
/* node->id user count */
@@ -452,6 +453,7 @@ void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node);
void nodeFreeNode(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);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 54113fcb4f0..03687846eeb 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -530,7 +530,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, con
* Ideally, usercount should never be handled by IDType-specific copying code, but for now let's allow it... */
const int flag_idtype_copy = flag | LIB_ID_COPY_NO_USER_REFCOUNT;
-#define ITEMS_IMPLEMENTED ID_OB, ID_ME, ID_CU, ID_MB, ID_LT, ID_LA, ID_SPK, ID_CA, ID_KE, ID_AR
+#define ITEMS_IMPLEMENTED ID_OB, ID_ME, ID_CU, ID_MB, ID_LT, ID_LA, ID_SPK, ID_CA, ID_KE, ID_AR, ID_NT
if (!test) {
/* Check to be removed of course, just here until all BKE_xxx_copy_ex functions are done. */
@@ -592,7 +592,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, con
if (!test) *r_newid = (ID *)BKE_action_copy(bmain, (bAction *)id);
break;
case ID_NT:
- if (!test) *r_newid = (ID *)ntreeCopyTree(bmain, (bNodeTree *)id);
+ if (!test) BKE_node_tree_copy_ex(bmain, (bNodeTree *)*r_newid, (bNodeTree *)id, flag_idtype_copy);
break;
case ID_BR:
if (!test) *r_newid = (ID *)BKE_brush_copy(bmain, (Brush *)id);
@@ -1239,7 +1239,7 @@ void *BKE_libblock_copy_nolib(const ID *id, const bool do_action)
{
ID *idn;
- BKE_libblock_copy_ex(NULL, id, &idn, LIB_ID_COPY_NO_MAIN | (do_action ? LIB_ID_COPY_ACTIONS : 0));
+ BKE_libblock_copy_ex(NULL, id, &idn, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_USER_REFCOUNT | (do_action ? LIB_ID_COPY_ACTIONS : 0));
return idn;
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index dd28a534d22..9c31eaa994d 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -902,80 +902,100 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
return nodeAddNode(C, ntree, idname);
}
-static void node_socket_copy(bNodeSocket *dst, bNodeSocket *src)
+static void node_socket_copy(bNodeSocket *sock_dst, bNodeSocket *sock_src, const int flag)
{
- src->new_sock = dst;
-
- if (src->prop)
- dst->prop = IDP_CopyProperty(src->prop);
-
- if (src->default_value)
- dst->default_value = MEM_dupallocN(src->default_value);
-
- dst->stack_index = 0;
+ sock_src->new_sock = sock_dst;
+
+ if (sock_src->prop) {
+ sock_dst->prop = IDP_CopyProperty_ex(sock_src->prop, flag);
+ }
+
+ if (sock_src->default_value) {
+ sock_dst->default_value = MEM_dupallocN(sock_src->default_value);
+ }
+
+ sock_dst->stack_index = 0;
/* XXX some compositor node (e.g. image, render layers) still store
* some persistent buffer data here, need to clear this to avoid dangling pointers.
*/
- dst->cache = NULL;
+ sock_dst->cache = NULL;
}
/* keep socket listorder identical, for copying links */
/* ntree is the target tree */
-bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
+bNode *BKE_node_copy_ex(bNodeTree *ntree, bNode *node_src, const int flag)
{
- bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node");
- bNodeSocket *sock, *oldsock;
- bNodeLink *link, *oldlink;
+ bNode *node_dst = MEM_callocN(sizeof(bNode), "dupli node");
+ bNodeSocket *sock_dst, *sock_src;
+ bNodeLink *link_dst, *link_src;
- *nnode = *node;
+ *node_dst = *node_src;
/* can be called for nodes outside a node tree (e.g. clipboard) */
if (ntree) {
- nodeUniqueName(ntree, nnode);
+ nodeUniqueName(ntree, node_dst);
- BLI_addtail(&ntree->nodes, nnode);
+ BLI_addtail(&ntree->nodes, node_dst);
}
- BLI_duplicatelist(&nnode->inputs, &node->inputs);
- oldsock = node->inputs.first;
- for (sock = nnode->inputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- BLI_duplicatelist(&nnode->outputs, &node->outputs);
- oldsock = node->outputs.first;
- for (sock = nnode->outputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- if (node->prop)
- nnode->prop = IDP_CopyProperty(node->prop);
-
- BLI_duplicatelist(&nnode->internal_links, &node->internal_links);
- oldlink = node->internal_links.first;
- for (link = nnode->internal_links.first; link; link = link->next, oldlink = oldlink->next) {
- link->fromnode = nnode;
- link->tonode = nnode;
- link->fromsock = link->fromsock->new_sock;
- link->tosock = link->tosock->new_sock;
+ BLI_duplicatelist(&node_dst->inputs, &node_src->inputs);
+ for (sock_dst = node_dst->inputs.first, sock_src = node_src->inputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag);
}
-
- /* don't increase node->id users, freenode doesn't decrement either */
-
- if (node->typeinfo->copyfunc)
- node->typeinfo->copyfunc(ntree, nnode, node);
-
- node->new_node = nnode;
- nnode->new_node = NULL;
-
- if (nnode->typeinfo->copyfunc_api) {
+
+ BLI_duplicatelist(&node_dst->outputs, &node_src->outputs);
+ for (sock_dst = node_dst->outputs.first, sock_src = node_src->outputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag);
+ }
+
+ if (node_src->prop) {
+ node_dst->prop = IDP_CopyProperty_ex(node_src->prop, flag);
+ }
+
+ BLI_duplicatelist(&node_dst->internal_links, &node_src->internal_links);
+ for (link_dst = node_dst->internal_links.first, link_src = node_src->internal_links.first;
+ link_dst != NULL;
+ link_dst = link_dst->next, link_src = link_src->next)
+ {
+ link_dst->fromnode = node_dst;
+ link_dst->tonode = node_dst;
+ link_dst->fromsock = link_dst->fromsock->new_sock;
+ link_dst->tosock = link_dst->tosock->new_sock;
+ }
+
+ if ((flag & LIB_ID_COPY_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(node_dst->id);
+ }
+
+ if (node_src->typeinfo->copyfunc) {
+ node_src->typeinfo->copyfunc(ntree, node_dst, node_src);
+ }
+
+ node_src->new_node = node_dst;
+ node_dst->new_node = NULL;
+
+ if (node_dst->typeinfo->copyfunc_api) {
PointerRNA ptr;
- RNA_pointer_create((ID *)ntree, &RNA_Node, nnode, &ptr);
-
- nnode->typeinfo->copyfunc_api(&ptr, node);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node_dst, &ptr);
+
+ node_dst->typeinfo->copyfunc_api(&ptr, node_src);
}
-
- if (ntree)
+
+ if (ntree) {
ntree->update |= NTREE_UPDATE_NODES;
-
- return nnode;
+ }
+
+ return node_dst;
+}
+
+bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
+{
+ return BKE_node_copy_ex(ntree, node, LIB_ID_COPY_NO_USER_REFCOUNT);
}
/* also used via rna api, so we check for proper input output direction */
@@ -1191,119 +1211,96 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
return ntree;
}
-/* Warning: this function gets called during some rather unexpected times
- * - this gets called when executing compositing updates (for threaded previews)
- * - when the nodetree datablock needs to be copied (i.e. when users get copied)
- * - for scene duplication use ntreeSwapID() after so we don't have stale pointers.
+/**
+ * Only copy internal data of NodeTree ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
*
- * do_make_extern: keep enabled for general use, only reason _not_ to enable is when
- * copying for internal use (threads for eg), where you wont want it to modify the
- * scene data.
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
-static bNodeTree *ntreeCopyTree_internal(
- const bNodeTree *ntree, Main *bmain,
- bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews)
+void BKE_node_tree_copy_ex(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bNodeTree *ntree_src, const int flag)
{
- bNodeTree *newtree;
- bNode *node /*, *nnode */ /* UNUSED */, *last;
- bNodeSocket *sock, *oldsock;
- bNodeLink *link;
-
- if (ntree == NULL) return NULL;
-
- /* is ntree part of library? */
- if (bmain && !skip_database && BLI_findindex(&bmain->nodetree, ntree) >= 0) {
- newtree = BKE_libblock_copy(bmain, &ntree->id);
- }
- else {
- newtree = BKE_libblock_copy_nolib(&ntree->id, true);
- }
+ bNode *node_src, *node_src_last;
+ bNodeSocket *sock_dst, *sock_src;
+ bNodeLink *link_dst;
- id_us_plus((ID *)newtree->gpd);
+ if ((flag & LIB_ID_COPY_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)ntree_dst->gpd);
+ }
/* in case a running nodetree is copied */
- newtree->execdata = NULL;
-
- newtree->duplilock = NULL;
-
- BLI_listbase_clear(&newtree->nodes);
- BLI_listbase_clear(&newtree->links);
-
- last = ntree->nodes.last;
- for (node = ntree->nodes.first; node; node = node->next) {
+ ntree_dst->execdata = NULL;
- /* ntreeUserDecrefID inline */
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list