[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