[Bf-blender-cvs] [8382494] master: Avoid node tree update tag when changed nodes which are not affecting result

Sergey Sharybin noreply at git.blender.org
Wed Mar 2 13:58:50 CET 2016


Commit: 83824947ba40c31a480819072b6f0fb2e7029a59
Author: Sergey Sharybin
Date:   Fri Feb 5 01:39:42 2016 +0500
Branches: master
https://developer.blender.org/rB83824947ba40c31a480819072b6f0fb2e7029a59

Avoid node tree update tag when changed nodes which are not affecting result

This was we don't have re-compo or viewport re-rendering happening when changing
nodes which are not connected to the output at all (for example when adding new
nodes or changing settings for unconnected nodes).

Only basic operations are covered for now. checks could be added to more tools
when needed.

Currently it's not fully optimal implementation, but seems to work fast enough.
Don't see reliable alternative to that -- keeping tag in the node wouldn't work
because of the node groups (which are probably already broken, but should be
easy to solve with current approach). So guess it's more matter of optimizing
path search from a node to output.

Before processing forward let's check whether it's indeed something we want
and whether the approach is indeed not fully bad.

Reviewers: campbellbarton, mont29

Subscribers: sebastian_k

Differential Revision: https://developer.blender.org/D1765

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

M	source/blender/editors/include/ED_node.h
M	source/blender/editors/space_node/drawnode.c
M	source/blender/editors/space_node/node_draw.c
M	source/blender/editors/space_node/node_edit.c
M	source/blender/editors/space_node/node_intern.h
M	source/blender/editors/space_node/node_relationships.c
M	source/blender/editors/space_node/node_templates.c
M	source/blender/editors/uvedit/uvedit_ops.c
M	source/blender/makesrna/intern/rna_color.c
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/makesrna/intern/rna_texture.c

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

diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 1445308..7fe9a0c 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -80,7 +80,7 @@ void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, Node
 /* node_draw.c */
 void ED_node_tree_update(const struct bContext *C);
 void ED_node_tag_update_id(struct ID *id);
-void ED_node_tag_update_nodetree(struct Main *bmain, struct bNodeTree *ntree);
+void ED_node_tag_update_nodetree(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
 void ED_node_sort(struct bNodeTree *ntree);
 float ED_node_grid_size(void);
 
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index ed207e2..623afb2 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2884,7 +2884,8 @@ static void node_texture_set_butfunc(bNodeType *ntype)
 static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
 {
 	bNodeTree *ntree = ptr->id.data;
-	ED_node_tag_update_nodetree(bmain, ntree);
+	bNode *node = ptr->data;
+	ED_node_tag_update_nodetree(bmain, ntree, node);
 }
 
 static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocketTemplate *stemp)
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index a4e2d54..85c8f50 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -153,18 +153,27 @@ void ED_node_tag_update_id(ID *id)
 	}
 }
 
-void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree)
+void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree, bNode *node)
 {
 	if (!ntree)
 		return;
-	
+
+	bool do_tag_update = true;
+	if (node != NULL) {
+		if (!node_connected_to_output(ntree, node)) {
+			do_tag_update = false;
+		}
+	}
+
 	/* look through all datablocks, to support groups */
-	FOREACH_NODETREE(bmain, tntree, id) {
-		/* check if nodetree uses the group */
-		if (ntreeHasTree(tntree, ntree))
-			ED_node_tag_update_id(id);
-	} FOREACH_NODETREE_END
-	
+	if (do_tag_update) {
+		FOREACH_NODETREE(bmain, tntree, id) {
+			/* check if nodetree uses the group */
+			if (ntreeHasTree(tntree, ntree))
+				ED_node_tag_update_id(id);
+		} FOREACH_NODETREE_END
+	}
+
 	if (ntree->type == NTREE_TEXTURE)
 		ntreeTexCheckCyclics(ntree);
 }
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index ba5bea4..62431b3 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -657,10 +657,10 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
 				
 				node->flag |= NODE_DO_OUTPUT;
 				if (was_output == 0)
-					ED_node_tag_update_nodetree(bmain, ntree);
+					ED_node_tag_update_nodetree(bmain, ntree, node);
 			}
 			else if (do_update)
-				ED_node_tag_update_nodetree(bmain, ntree);
+				ED_node_tag_update_nodetree(bmain, ntree, node);
 
 			/* if active texture changed, free glsl materials */
 			if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
@@ -692,7 +692,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
 				
 				node->flag |= NODE_DO_OUTPUT;
 				if (was_output == 0)
-					ED_node_tag_update_nodetree(bmain, ntree);
+					ED_node_tag_update_nodetree(bmain, ntree, node);
 				
 				/* addnode() doesnt link this yet... */
 				node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
@@ -722,11 +722,11 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
 							tnode->flag &= ~NODE_DO_OUTPUT;
 					
 					node->flag |= NODE_DO_OUTPUT;
-					ED_node_tag_update_nodetree(bmain, ntree);
+					ED_node_tag_update_nodetree(bmain, ntree, node);
 				}
 			}
 			else if (do_update)
-				ED_node_tag_update_nodetree(bmain, ntree);
+				ED_node_tag_update_nodetree(bmain, ntree, node);
 		}
 		else if (ntree->type == NTREE_TEXTURE) {
 			// XXX
@@ -1177,7 +1177,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
 	bNode *node, *newnode, *lastnode;
 	bNodeLink *link, *newlink, *lastlink;
 	const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
-	
+	bool do_tag_update = false;
+
 	ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
 	
 	lastnode = ntree->nodes.last;
@@ -1254,6 +1255,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
 			nodeSetSelected(node, false);
 			node->flag &= ~NODE_ACTIVE;
 			nodeSetSelected(newnode, true);
+
+			do_tag_update |= (do_tag_update || node_connected_to_output(ntree, newnode));
 		}
 		
 		/* make sure we don't copy new nodes again! */
@@ -1264,7 +1267,9 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
 	ntreeUpdateTree(CTX_data_main(C), snode->edittree);
 	
 	snode_notify(C, snode);
-	snode_dag_update(C, snode);
+	if (do_tag_update) {
+		snode_dag_update(C, snode);
+	}
 
 	return OPERATOR_FINISHED;
 }
@@ -1623,6 +1628,7 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
 {
 	SpaceNode *snode = CTX_wm_space_node(C);
 	bNode *node;
+	bool do_tag_update = false;
 
 	ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
 
@@ -1631,11 +1637,14 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
 		if ((node->flag & SELECT) && node->typeinfo->update_internal_links) {
 			node->flag ^= NODE_MUTED;
 			snode_update(snode, node);
+			do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, node));
 		}
 	}
 	
 	snode_notify(C, snode);
-	snode_dag_update(C, snode);
+	if (do_tag_update) {
+		snode_dag_update(C, snode);
+	}
 	
 	return OPERATOR_FINISHED;
 }
@@ -1661,13 +1670,15 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
 {
 	SpaceNode *snode = CTX_wm_space_node(C);
 	bNode *node, *next;
-	
+	bool do_tag_update = false;
+
 	ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
 
 	for (node = snode->edittree->nodes.first; node; node = next) {
 		next = node->next;
 		if (node->flag & SELECT) {
 			/* check id user here, nodeFreeNode is called for free dbase too */
+			do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, node));
 			if (node->id)
 				id_us_min(node->id);
 			nodeFreeNode(snode->edittree, node);
@@ -1677,7 +1688,9 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
 	ntreeUpdateTree(CTX_data_main(C), snode->edittree);
 
 	snode_notify(C, snode);
-	snode_dag_update(C, snode);
+	if (do_tag_update) {
+		snode_dag_update(C, snode);
+	}
 	
 	return OPERATOR_FINISHED;
 }
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 444e811..6b8fa0b 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -155,6 +155,8 @@ void NODE_OT_group_edit(struct wmOperatorType *ot);
 
 
 /* node_relationships.c */
+bool node_connected_to_output(struct bNodeTree *ntree, struct bNode *node);
+
 void NODE_OT_link(struct wmOperatorType *ot);
 void NODE_OT_link_make(struct wmOperatorType *ot);
 void NODE_OT_links_cut(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 0852b61..50d7df6 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -59,6 +59,55 @@
 
 #include "node_intern.h"  /* own include */
 
+/* ****************** Relations helpers *********************** */
+
+static bool ntree_check_nodes_connected_dfs(bNodeTree *ntree,
+                                            bNode *from,
+                                            bNode *to)
+{
+	if (from->flag & NODE_TEST) {
+		return false;
+	}
+	from->flag |= NODE_TEST;
+	for (bNodeLink *link = ntree->links.first; link != NULL; link = link->next) {
+		if (link->fromnode == from) {
+			if (link->tonode == to) {
+				return true;
+			}
+			else {
+				if (ntree_check_nodes_connected_dfs(ntree, link->tonode, to)) {
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
+static bool ntree_check_nodes_connected(bNodeTree *ntree, bNode *from, bNode *to)
+{
+	if (from == to) {
+		return true;
+	}
+	ntreeNodeFlagSet(ntree, NODE_TEST, false);
+	return ntree_check_nodes_connected_dfs(ntree, from, to);
+}
+
+bool node_connected_to_output(bNodeTree *ntree, bNode *node)
+{
+	for (bNode *current_node = ntree->nodes.first;
+	     current_node != NULL;
+	     current_node = current_node->next)
+	{
+		if (current_node->flag & NODE_DO_OUTPUT) {
+			if (ntree_check_nodes_connected(ntree, node, current_node)) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
 /* ****************** Add *********************** */
 
 
@@ -468,7 +517,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
 	bNodeTree *ntree = snode->edittree;
 	bNodeLinkDrag *nldrag = op->customdata;
 	LinkData *linkdata;
-	
+	bool do_tag_update = false;
+
 	/* avoid updates while applying links */
 	ntree->is_updating = true;
 	for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
@@ -493,15 +543,27 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
 			
 			/* we might need to remove a link */
 			node_remove_extra_links(snode, link);
+
+			if (link->tonode) {
+				do_tag_update |= (do_tag_update || node_connected_to_output(ntree, link->tonode));
+			}
 		}
-		else
+		else {
+			/* See note below, but basically TEST flag means that the link
+			 * was connected to output (or to a node which affects the
+			 * output).
+			 */
+			do_tag_update |= (link->flag & NODE_LINK_TEST) != 0;
 			nodeRemLink(ntree, link);
+		}
 	}
 	ntree->is_updating = false;
 	
 	ntreeUpdateTree(CTX_data_main(C), ntree);
 	snode_notify(C, snode);
-	snode_dag_update(C, snode);
+	if (do_tag_update) {
+		snode_dag_update(C, snode);
+	}
 	
 	BLI_remlink(&snode->linkdrag, nldrag);
 	/* links->data pointers are either held by the tree or freed already */
@@ -632,7 +694,18 @@ static bNodeLinkDr

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list