[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55416] trunk/blender/source/blender: Nicer handling of undefined node, tree and socket types.

Lukas Toenne lukas.toenne at googlemail.com
Tue Mar 19 14:40:16 CET 2013


Revision: 55416
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55416
Author:   lukastoenne
Date:     2013-03-19 13:40:16 +0000 (Tue, 19 Mar 2013)
Log Message:
-----------
Nicer handling of undefined node, tree and socket types.

When nodes are loaded from a .blend file they can potentially have undefined types. This can happen if a type has been deprecated and removed, or if node types were defined in a python script that has not been loaded correctly. Previously all such nodes would automatically be removed from a node tree, assuming that their types were deprecated and no longer in use (more commonly caused by loading new nodes in an older Blender version). Due to the possibility of dynamic registration it is no longer feasible to simply delete such nodes.

Display and handling of node trees was simply disabled before this patch, so that a node tree where any node or socket type was undefined would not be displayed at all. To give more information and avoid problems caused by necessary checks for the typeinfo pointer, there is now a 'Undefined' fallback type for trees, nodes and sockets. These types are used as placeholders in case the real type is not registered and can provide useful visual feedback on undefined nodes.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_node.h
    trunk/blender/source/blender/blenkernel/intern/node.c
    trunk/blender/source/blender/editors/screen/screen_ops.c
    trunk/blender/source/blender/editors/space_buttons/buttons_texture.c
    trunk/blender/source/blender/editors/space_node/drawnode.c
    trunk/blender/source/blender/editors/space_node/node_buttons.c
    trunk/blender/source/blender/editors/space_node/node_draw.c
    trunk/blender/source/blender/editors/space_node/node_templates.c
    trunk/blender/source/blender/editors/space_node/space_node.c
    trunk/blender/source/blender/makesrna/intern/rna_nodetree.c
    trunk/blender/source/blender/nodes/intern/node_exec.c

Modified: trunk/blender/source/blender/blenkernel/BKE_node.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_node.h	2013-03-19 13:38:43 UTC (rev 55415)
+++ trunk/blender/source/blender/blenkernel/BKE_node.h	2013-03-19 13:40:16 UTC (rev 55416)
@@ -83,6 +83,7 @@
 struct ColorManagedDisplaySettings;
 struct bNodeInstanceHash;
 
+
 /* ************** NODE TYPE DEFINITIONS ***** */
 
 /** Compact definition of a node socket.
@@ -331,6 +332,7 @@
 struct bNodeTreeType *ntreeTypeFind(const char *idname);
 void ntreeTypeAdd(struct bNodeTreeType *nt);
 void ntreeTypeFreeLink(struct bNodeTreeType *nt);
+bool ntreeIsRegistered(struct bNodeTree *ntree);
 struct GHashIterator *ntreeTypeGetIterator(void);
 
 /* helper macros for iterating over tree types */
@@ -346,7 +348,6 @@
 }
 
 void ntreeSetTypes(const struct bContext *C, struct bNodeTree *ntree);
-int ntreeIsValid(struct bNodeTree *ntree);
 
 struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char *idname);
 
@@ -407,6 +408,7 @@
 struct bNodeType *nodeTypeFind(const char *idname);
 void			nodeRegisterType(struct bNodeType *ntype);
 void			nodeUnregisterType(struct bNodeType *ntype);
+bool			nodeIsRegistered(struct bNode *node);
 struct GHashIterator *nodeTypeGetIterator(void);
 
 /* helper macros for iterating over node types */
@@ -424,6 +426,7 @@
 struct bNodeSocketType *nodeSocketTypeFind(const char *idname);
 void			nodeRegisterSocketType(struct bNodeSocketType *stype);
 void			nodeUnregisterSocketType(struct bNodeSocketType *stype);
+bool			nodeSocketIsRegistered(struct bNodeSocket *sock);
 struct GHashIterator *nodeSocketTypeGetIterator(void);
 const char *	nodeStaticSocketType(int type, int subtype);
 const char *	nodeStaticSocketInterfaceType(int type, int subtype);

Modified: trunk/blender/source/blender/blenkernel/intern/node.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/node.c	2013-03-19 13:38:43 UTC (rev 55415)
+++ trunk/blender/source/blender/blenkernel/intern/node.c	2013-03-19 13:40:16 UTC (rev 55416)
@@ -74,7 +74,12 @@
 #include "NOD_shader.h"
 #include "NOD_texture.h"
 
+/* Fallback types for undefined tree, nodes, sockets */
+bNodeTreeType NodeTreeTypeUndefined;
+bNodeType NodeTypeUndefined;
+bNodeSocketType NodeSocketTypeUndefined;
 
+
 static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
 {
 	bNodeSocketTemplate *sockdef;
@@ -101,12 +106,11 @@
 /* Note: This function is called to initialize node data based on the type.
  * The bNodeType may not be registered at creation time of the node,
  * so this can be delayed until the node type gets registered.
- * The node->typeinfo must not be used in that case until it is defined!
  */
 static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
 {
 	bNodeType *ntype = node->typeinfo;
-	if (!ntype)
+	if (ntype == &NodeTypeUndefined)
 		return;
 	
 	/* only do this once */
@@ -151,22 +155,24 @@
 
 static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
 {
-	ntree->typeinfo = typeinfo;
-	
 	if (typeinfo) {
+		ntree->typeinfo = typeinfo;
+		
 		/* deprecated integer type */
 		ntree->type = typeinfo->type;
 	}
 	else {
+		ntree->typeinfo = &NodeTreeTypeUndefined;
+		
 		ntree->init &= ~NTREE_TYPE_INIT;
 	}
 }
 
 static void node_set_typeinfo(const struct bContext *C, bNodeTree *ntree, bNode *node, bNodeType *typeinfo)
 {
-	node->typeinfo = typeinfo;
-	
 	if (typeinfo) {
+		node->typeinfo = typeinfo;
+		
 		/* deprecated integer type */
 		node->type = typeinfo->type;
 		
@@ -174,21 +180,25 @@
 		node_init(C, ntree, node);
 	}
 	else {
+		node->typeinfo = &NodeTypeUndefined;
+		
 		ntree->init &= ~NTREE_TYPE_INIT;
 	}
 }
 
 static void node_socket_set_typeinfo(bNodeTree *ntree, bNodeSocket *sock, bNodeSocketType *typeinfo)
 {
-	sock->typeinfo = typeinfo;
-
 	if (typeinfo) {
+		sock->typeinfo = typeinfo;
+	
 		if (sock->default_value == NULL) {
 			/* initialize the default_value pointer used by standard socket types */
 			node_socket_init_default_value(sock);
 		}
 	}
 	else {
+		sock->typeinfo = &NodeSocketTypeUndefined;
+		
 		ntree->init &= ~NTREE_TYPE_INIT;
 	}
 }
@@ -301,14 +311,14 @@
 	BLI_ghash_remove(nodetreetypes_hash, nt->idname, NULL, ntree_free_type);
 }
 
-GHashIterator *ntreeTypeGetIterator(void)
+bool ntreeIsRegistered(bNodeTree *ntree)
 {
-	return BLI_ghashIterator_new(nodetreetypes_hash);
+	return (ntree->typeinfo != &NodeTreeTypeUndefined);
 }
 
-int ntreeIsValid(bNodeTree *ntree)
+GHashIterator *ntreeTypeGetIterator(void)
 {
-	return (ntree && (ntree->init & NTREE_TYPE_INIT));
+	return BLI_ghashIterator_new(nodetreetypes_hash);
 }
 
 bNodeType *nodeTypeFind(const char *idname)
@@ -370,6 +380,11 @@
 	BLI_ghash_remove(nodetypes_hash, nt->idname, NULL, node_free_type);
 }
 
+bool nodeIsRegistered(bNode *node)
+{
+	return (node->typeinfo != &NodeTypeUndefined);
+}
+
 GHashIterator *nodeTypeGetIterator(void)
 {
 	return BLI_ghashIterator_new(nodetypes_hash);
@@ -410,6 +425,11 @@
 	BLI_ghash_remove(nodesockettypes_hash, st->idname, NULL, node_free_socket_type);
 }
 
+bool nodeSocketIsRegistered(bNodeSocket *sock)
+{
+	return (sock->typeinfo != &NodeSocketTypeUndefined);
+}
+
 GHashIterator *nodeSocketTypeGetIterator(void)
 {
 	return BLI_ghashIterator_new(nodesockettypes_hash);
@@ -1887,7 +1907,7 @@
 /* returns localized tree for execution in threads */
 bNodeTree *ntreeLocalize(bNodeTree *ntree)
 {
-	if (ntreeIsValid(ntree)) {
+	if (ntree) {
 		bNodeTree *ltree;
 		bNode *node;
 		
@@ -1944,7 +1964,7 @@
 /* is called by jobs manager, outside threads, so it doesnt happen during draw */
 void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
 {
-	if (localtree && ntreeIsValid(ntree)) {
+	if (localtree && ntree) {
 		/* XXX syncing was disabled for compositor nodes.
 		 * It has to be ensured that there is no concurrent read/write access!
 		 * Possibly needs a mutex lock or a flag to disable for certain tree types ...
@@ -1960,7 +1980,7 @@
 /* we have to assume the editor already changed completely */
 void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
 {
-	if (localtree && ntreeIsValid(ntree)) {
+	if (localtree && ntree) {
 		BKE_node_preview_merge_tree(ntree, localtree);
 		
 		if (ntree->typeinfo->local_merge)
@@ -2831,11 +2851,8 @@
 	FOREACH_NODETREE(main, ntree, owner_id) {
 		bNode *node;
 		
-		if (!ntreeIsValid(ntree))
-			return;
-		
 		for (node = ntree->nodes.first; node; node = node->next)
-			if (node->typeinfo && node->typeinfo->verifyfunc)
+			if (node->typeinfo->verifyfunc)
 				node->typeinfo->verifyfunc(ntree, node, id);
 	} FOREACH_NODETREE_END
 }
@@ -2844,15 +2861,14 @@
 {
 	bNode *node;
 	
+	if (!ntree)
+		return;
+	
 	/* avoid reentrant updates, can be caused by RNA update callbacks */
 	if (ntree->is_updating)
 		return;
 	ntree->is_updating = TRUE;
 	
-	/* only if types are initialized */
-	if (!ntreeIsValid(ntree))
-		return;
-	
 	if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) {
 		/* set the bNodeSocket->link pointers */
 		ntree_update_link_pointers(ntree);
@@ -3239,6 +3255,34 @@
 	ntype->compatibility = compatibility;
 }
 
+/* callbacks for undefined types */
+
+static int node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree))
+{
+	/* this type can not be added deliberately, it's just a placeholder */
+	return false;
+}
+
+/* register fallback types used for undefined tree, nodes, sockets */
+static void register_undefined_types(void)
+{
+	/* Note: these types are not registered in the type hashes,
+	 * they are just used as placeholders in case the actual types are not registered.
+	 */
+	
+	strcpy(NodeTreeTypeUndefined.idname, "NodeTreeUndefined");
+	strcpy(NodeTreeTypeUndefined.ui_name, "Undefined");
+	strcpy(NodeTreeTypeUndefined.ui_description, "Undefined Node Tree Type");
+	
+	node_type_base_custom(&NodeTypeUndefined, "NodeUndefined", "Undefined", 0, 0);
+	NodeTypeUndefined.poll = node_undefined_poll;
+	
+	BLI_strncpy(NodeSocketTypeUndefined.idname, "NodeSocketUndefined", sizeof(NodeSocketTypeUndefined.idname));
+	/* extra type info for standard socket types */
+	NodeSocketTypeUndefined.type = SOCK_CUSTOM;
+	NodeSocketTypeUndefined.subtype = PROP_NONE;
+}
+
 static void registerCompositNodes(void)
 {
 	register_node_type_cmp_group();
@@ -3464,6 +3508,8 @@
 	nodetypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodetypes_hash gh");
 	nodesockettypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodesockettypes_hash gh");
 
+	register_undefined_types();
+
 	register_standard_node_socket_types();
 
 	register_node_tree_type_cmp();

Modified: trunk/blender/source/blender/editors/screen/screen_ops.c
===================================================================
--- trunk/blender/source/blender/editors/screen/screen_ops.c	2013-03-19 13:38:43 UTC (rev 55415)
+++ trunk/blender/source/blender/editors/screen/screen_ops.c	2013-03-19 13:40:16 UTC (rev 55416)
@@ -254,7 +254,7 @@
 {
 	SpaceNode *snode = CTX_wm_space_node(C);
 	
-	if (snode && ntreeIsValid(snode->edittree))
+	if (snode && snode->edittree)
 		return 1;
 	
 	return 0;

Modified: trunk/blender/source/blender/editors/space_buttons/buttons_texture.c
===================================================================
--- trunk/blender/source/blender/editors/space_buttons/buttons_texture.c	2013-03-19 13:38:43 UTC (rev 55415)
+++ trunk/blender/source/blender/editors/space_buttons/buttons_texture.c	2013-03-19 13:40:16 UTC (rev 55416)
@@ -113,15 +113,15 @@
 {
 	bNode *node;
 
-	if (ntreeIsValid(ntree)) {
+	if (ntree) {
 		for (node = ntree->nodes.first; node; node = node->next) {
 			if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
 				PointerRNA ptr;
 				/* PropertyRNA *prop; */ /* UNUSED */
-
+				
 				RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
 				/* prop = RNA_struct_find_property(&ptr, "texture"); */ /* UNUSED */
-
+				
 				buttons_texture_user_node_add(users, id, ntree, node,
 				                              category, RNA_struct_ui_icon(ptr.type), node->name);
 			}

Modified: trunk/blender/source/blender/editors/space_node/drawnode.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/drawnode.c	2013-03-19 13:38:43 UTC (rev 55415)
+++ trunk/blender/source/blender/editors/space_node/drawnode.c	2013-03-19 13:40:16 UTC (rev 55416)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list