[Bf-blender-cvs] [406309c] master: Refactor/enhance ntreeMakeLocal().

Bastien Montagne noreply at git.blender.org
Sun Jul 10 17:15:02 CEST 2016


Commit: 406309cd8c9a2bc89f8ec56cb22f298e2d48d042
Author: Bastien Montagne
Date:   Sun Jul 10 16:55:55 2016 +0200
Branches: master
https://developer.blender.org/rB406309cd8c9a2bc89f8ec56cb22f298e2d48d042

Refactor/enhance ntreeMakeLocal().

Now using modern features from libquery/libremap areas.

Provides same kind of fixes/improvements as for BKE_object_make_local() (see rBd1a4ae3f395a6).

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

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 c5d1044..b44cb22 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -346,7 +346,7 @@ void              ntreeUserDecrefID(struct bNodeTree *ntree);
 
 struct bNodeTree *ntreeFromID(struct ID *id);
 
-void              ntreeMakeLocal(struct bNodeTree *ntree, bool id_in_mainlist);
+void              ntreeMakeLocal(struct Main *bmain, struct bNodeTree *ntree, bool id_in_mainlist);
 struct bNode     *ntreeFindType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 5f548b4..d5b9e5e 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -321,7 +321,7 @@ bool id_make_local(Main *bmain, ID *id, bool test)
 			if (!test) BKE_action_make_local((bAction *)id);
 			return true;
 		case ID_NT:
-			if (!test) ntreeMakeLocal((bNodeTree *)id, true);
+			if (!test) ntreeMakeLocal(bmain, (bNodeTree *)id, true);
 			return true;
 		case ID_BR:
 			if (!test) BKE_brush_make_local(bmain, (Brush *)id);
@@ -1469,7 +1469,7 @@ void id_clear_lib_data_ex(Main *bmain, ID *id, bool id_in_mainlist)
 	ntree = ntreeFromID(id);
 
 	if (ntree) {
-		ntreeMakeLocal(ntree, false);
+		ntreeMakeLocal(bmain, ntree, false);
 	}
 
 	if (GS(id->name) == ID_OB) {
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index aaba5df..b188272 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -58,6 +58,8 @@
 #include "BKE_global.h"
 #include "BKE_idprop.h"
 #include "BKE_library.h"
+#include "BKE_library_query.h"
+#include "BKE_library_remap.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
 
@@ -1948,70 +1950,51 @@ bNodeTree *ntreeFromID(ID *id)
 	}
 }
 
-static void extern_local_ntree(bNodeTree *ntree)
+static int extern_local_ntree_callback(
+        void *UNUSED(user_data), struct ID *UNUSED(id_self), struct ID **id_pointer, int cd_flag)
 {
-	for (bNode *node = ntree->nodes.first; node; node = node->next) {
-		if (node->id) {
-			id_lib_extern(node->id);
-		}
+	/* We only tag usercounted ID usages as extern... Why? */
+	if ((cd_flag & IDWALK_USER) && *id_pointer) {
+		id_lib_extern(*id_pointer);
 	}
+	return IDWALK_RET_NOP;
+}
+
+static void extern_local_ntree(bNodeTree *ntree)
+{
+	BKE_library_foreach_ID_link(&ntree->id, extern_local_ntree_callback, NULL, 0);
 }
 
-void ntreeMakeLocal(bNodeTree *ntree, bool id_in_mainlist)
+void ntreeMakeLocal(Main *bmain, bNodeTree *ntree, bool id_in_mainlist)
 {
-	Main *bmain = G.main;
-	bool lib = false, local = false;
+	bool is_lib = false, is_local = false;
 	
 	/* - only lib users: do nothing
 	 * - only local users: set flag
 	 * - mixed: make copy
 	 */
-	
-	if (!ID_IS_LINKED_DATABLOCK(ntree)) return;
-	if (ntree->id.us == 1) {
-		id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist);
-		extern_local_ntree(ntree);
+
+	if (!ID_IS_LINKED_DATABLOCK(ntree)) {
 		return;
 	}
-	
-	/* now check users of groups... again typedepending, callback... */
-	FOREACH_NODETREE(G.main, tntree, owner_id) {
-		bNode *node;
-		/* find if group is in tree */
-		for (node = tntree->nodes.first; node; node = node->next) {
-			if (node->id == (ID *)ntree) {
-				if (owner_id->lib)
-					lib = true;
-				else
-					local = true;
-			}
+
+	BKE_library_ID_test_usages(bmain, ntree, &is_local, &is_lib);
+
+	if (is_local) {
+		if (!is_lib) {
+			id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist);
+			extern_local_ntree(ntree);
+		}
+		else {
+			bNodeTree *ntree_new = ntreeCopyTree(bmain, ntree);
+
+			ntree_new->id.us = 0;
+
+			/* Remap paths of new ID using old library as base. */
+			BKE_id_lib_local_paths(bmain, ntree->id.lib, &ntree_new->id);
+
+			BKE_libblock_remap(bmain, ntree, ntree_new, ID_REMAP_SKIP_INDIRECT_USAGE);
 		}
-	} FOREACH_NODETREE_END
-	
-	/* if all users are local, we simply make tree local */
-	if (local && !lib) {
-		id_clear_lib_data_ex(bmain, (ID *)ntree, id_in_mainlist);
-		extern_local_ntree(ntree);
-	}
-	else if (local && lib) {
-		/* this is the mixed case, we copy the tree and assign it to local users */
-		bNodeTree *newtree = ntreeCopyTree(bmain, ntree);
-		
-		newtree->id.us = 0;
-		
-		FOREACH_NODETREE(bmain, tntree, owner_id) {
-			bNode *node;
-			/* find if group is in tree */
-			for (node = tntree->nodes.first; node; node = node->next) {
-				if (node->id == (ID *)ntree) {
-					if (owner_id->lib == NULL) {
-						node->id = (ID *)newtree;
-						id_us_plus(&newtree->id);
-						id_us_min(&ntree->id);
-					}
-				}
-			}
-		} FOREACH_NODETREE_END
 	}
 }




More information about the Bf-blender-cvs mailing list