[Bf-blender-cvs] [97642e0] object_nodes: More elegant construction of implicit node blocks, by copying argument node first.

Lukas Tönne noreply at git.blender.org
Tue Jan 12 12:38:32 CET 2016


Commit: 97642e0c9656093b4b88ccd4ce0ca0a8415879bc
Author: Lukas Tönne
Date:   Mon Jan 11 15:24:36 2016 +0100
Branches: object_nodes
https://developer.blender.org/rB97642e0c9656093b4b88ccd4ce0ca0a8415879bc

More elegant construction of implicit node blocks, by copying argument node first.

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

M	source/blender/blenvm/compile/bvm_nodegraph.cc
M	source/blender/blenvm/compile/bvm_nodegraph.h
M	source/blender/blenvm/util/bvm_util_debug.h

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

diff --git a/source/blender/blenvm/compile/bvm_nodegraph.cc b/source/blender/blenvm/compile/bvm_nodegraph.cc
index 957ecd4..e67a05c 100644
--- a/source/blender/blenvm/compile/bvm_nodegraph.cc
+++ b/source/blender/blenvm/compile/bvm_nodegraph.cc
@@ -418,12 +418,12 @@ bool InputKey::is_expression() const
 /* ------------------------------------------------------------------------- */
 
 NodeInstance::NodeInstance(const NodeType *type, const string &name) :
-    type(type), name(name), index(0)
+    type(type), name(name), index(0), block(NULL)
 {
 }
 
 NodeInstance::NodeInstance(const NodeInstance *other, const string &name) :
-    type(other->type), name(name), index(0)
+    type(other->type), name(name), index(0), block(NULL)
 {
 	for (InputMap::const_iterator it = other->inputs.begin(); it != other->inputs.end(); ++it) {
 		const string &input_name = it->first;
@@ -551,6 +551,49 @@ bool NodeInstance::input_value_set(const string &name, Value *value)
 
 /* ------------------------------------------------------------------------- */
 
+NodeBlock::NodeBlock(const string &name, NodeBlock *parent) :
+    m_name(name),
+    m_parent(parent)
+{}
+
+ConstOutputKey NodeBlock::local_arg(const string &name) const
+{
+	ArgumentMap::const_iterator it = m_local_args.find(name);
+	if (it != m_local_args.end())
+		return it->second;
+	else
+		return ConstOutputKey();
+}
+
+void NodeBlock::local_arg_set(const string &name, const ConstOutputKey &arg)
+{
+	m_local_args[name] = arg;
+}
+
+void NodeBlock::insert(NodeInstance *node)
+{
+	m_nodes.insert(node);
+	node->block = this;
+}
+
+void NodeBlock::prune(const NodeSet &used_nodes)
+{
+	NodeSet used_block_nodes;
+	std::set_intersection(used_nodes.begin(), used_nodes.end(),
+	                      m_nodes.begin(), m_nodes.end(),
+	                      std::inserter(used_block_nodes, used_block_nodes.end()));
+	m_nodes = used_block_nodes;
+	
+	for (ArgumentMap::iterator it = m_local_args.begin(); it != m_local_args.end(); ++it) {
+		NodeInstance *node = const_cast<NodeInstance *>(it->second.node);
+		if (used_nodes.find(node) == used_nodes.end()) {
+			it->second = ConstOutputKey();
+		}
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
 NodeGraph::NodeTypeMap NodeGraph::node_types;
 
 const NodeType *NodeGraph::find_node_type(const string &name)
@@ -867,128 +910,73 @@ void NodeGraph::skip_pass_nodes()
 	}
 }
 
-static void used_nodes_append(NodeInstance *node, NodeSet &used_nodes)
+void NodeGraph::make_args_local(NodeBlock &block, NodeMap &block_map, NodeSet &block_visited, const NodeInstance *arg_node)
 {
-	if (used_nodes.find(node) != used_nodes.end())
+	if (!arg_node->type->is_kernel_node())
 		return;
-	used_nodes.insert(node);
 	
-	for (NodeInstance::InputMap::iterator it = node->inputs.begin(); it != node->inputs.end(); ++it) {
-		NodeInstance::InputInstance &input = it->second;
-		if (input.link) {
-			used_nodes_append(input.link.node, used_nodes);
-		}
-	}
-}
-
-void NodeGraph::remove_unused_nodes()
-{
-	NodeSet used_nodes;
-	/* all output nodes and their inputs subgraphs are used */
-	for (NodeGraph::OutputList::iterator it = outputs.begin(); it != outputs.end(); ++it) {
-		Output &output = *it;
-		used_nodes_append(output.key.node, used_nodes);
-	}
-	/* make sure unused inputs don't leave dangling node pointers */
-	for (NodeGraph::NodeBlockList::iterator it = blocks.begin(); it != blocks.end(); ++it) {
-		NodeBlock &block = *it;
-		NodeSet used_block_nodes;
-		std::set_intersection(used_nodes.begin(), used_nodes.end(),
-		                      block.nodes.begin(), block.nodes.end(),
-		                      std::inserter(used_block_nodes, used_block_nodes.end()));
-		block.nodes = used_block_nodes;
-	}
-	for (NodeGraph::InputList::iterator it = inputs.begin(); it != inputs.end(); ++it) {
-		Input &input = *it;
-		if (used_nodes.find(input.key.node) == used_nodes.end()) {
-			input.key = OutputKey();
-		}
-	}
-	
-	NodeInstanceMap::iterator it = nodes.begin();
-	while (it != nodes.end()) {
-		if (used_nodes.find(it->second) == used_nodes.end()) {
-			/* it_del is invalidated on erase */
-			NodeInstanceMap::iterator it_del = it;
-			
-			++it;
-			
-			delete it_del->second;
-			nodes.erase(it_del);
-		}
-		else
-			it++;
-	}
-}
-
-void NodeGraph::get_local_args(const NodeInstance *node, OutputSet &local_args) const
-{
-	if (!node->type->is_kernel_node())
-		return;
-	
-	for (int i = 0; i < node->num_outputs(); ++i) {
-		const NodeOutput *output = node->type->find_output(i);
+	for (int i = 0; i < arg_node->num_outputs(); ++i) {
+		const NodeOutput *output = arg_node->type->find_output(i);
 		
 		if (output->value_type == OUTPUT_LOCAL) {
 			const Input *graph_input = get_input(output->name);
 			assert(graph_input);
 			
 			if (graph_input->key) {
-				local_args.insert(graph_input->key);
+				block_visited.insert(graph_input->key.node);
+				OutputKey local_arg(copy_node(graph_input->key.node, block_map), graph_input->key.socket);
+				block.insert(local_arg.node);
+				block.local_arg_set(output->name, local_arg);
 			}
 		}
 	}
 }
 
-static bool is_arg_node(const NodeInstance *node, const OutputSet &args)
-{
-	for (int i = 0; i < node->num_outputs(); ++i) {
-		ConstOutputKey output = node->output(i);
-		if (args.find(output) != args.end())
-			return true;
-	}
-	return false;
-}
-
-bool NodeGraph::add_block_node(NodeInstance *node, const OutputSet &block_args,
-                               NodeBlock &block, NodeMap &block_map)
+bool NodeGraph::add_block_node(NodeInstance *node, NodeBlock &block, NodeMap &block_map, NodeSet &block_visited)
 {
-	bool is_block_node = false; /* determines if the node is part of the block */
+	/* determines if the node is part of the block */
+	bool is_block_node = block_map.find(node) != block_map.end();
 	
-	is_block_node |= is_arg_node(node, block_args);
-	
-	OutputSet local_args;
-	get_local_args(node, local_args);
+	if (block_visited.find(node) != block_visited.end())
+		return is_block_node;
+	assert(!is_block_node); /* can't have been mapped yet */
+	block_visited.insert(node);
 	
 	for (int i = 0; i < node->num_inputs(); ++i) {
 		InputKey input = node->input(i);
 		if (input.is_constant()) {
-			if (!block.parent)
+			if (!block.parent())
 				is_block_node |= true;
 		}
 		else if (input.is_expression()) {
-			if (!block.parent)
-				is_block_node |= blockify_expression(input, block_args, local_args, block, block_map);
+			if (!block.parent())
+				is_block_node |= blockify_expression(input, block, block_map, block_visited);
 		}
 		else {
 			OutputKey output = input.link();
 			if (output) {
-				is_block_node |= add_block_node(output.node, block_args, block, block_map);
+				is_block_node |= add_block_node(output.node, block, block_map, block_visited);
 			}
 		}
 	}
 	
 	if (is_block_node) {
-		NodeInstance *block_node = (block.parent) ? copy_node(node, block_map) : node;
-		block.nodes.insert(block_node);
+		NodeInstance *block_node;
+		if (block.parent()) {
+			block_node = copy_node(node, block_map);
+		}
+		else {
+			block_node = node;
+			block_map[node] = node;
+		}
+		block.insert(block_node);
 		return true;
 	}
 	else
 		return false;
 }
 
-bool NodeGraph::blockify_expression(const InputKey &input, const OutputSet &block_args, const OutputSet &local_args,
-                                    NodeBlock &block, NodeMap &block_map)
+bool NodeGraph::blockify_expression(const InputKey &input, NodeBlock &block, NodeMap &block_map, NodeSet &block_visited)
 {
 	OutputKey link_key = input.link();
 	if (!link_key)
@@ -998,30 +986,34 @@ bool NodeGraph::blockify_expression(const InputKey &input, const OutputSet &bloc
 	bool is_block_node = false;
 	
 	/* generate a local block for the input expression */
-	blocks.push_back(NodeBlock(&block));
+	blocks.push_back(NodeBlock(input.node->name + ":" + input.socket->name, &block));
 	NodeBlock &expr_block = blocks.back();
+	NodeSet expr_visited;
 	NodeMap expr_block_map;
 	
-	add_block_node(link_node, local_args, expr_block, expr_block_map);
-	if (expr_block.nodes.empty()) {
-		/* use the input directly if no expression nodes are generated (no local arg dependencies) */
-		is_block_node |= add_block_node(link_node, block_args, block, block_map);
-	}
-	else {
+	make_args_local(expr_block, expr_block_map, expr_visited, input.node);
+	
+	add_block_node(link_node, expr_block, expr_block_map, expr_visited);
+	
+	if (expr_block_map.find(link_node) != expr_block_map.end()) {
 		/* remap the input link */
 		input.link_set(OutputKey(expr_block_map.at(link_node), link_key.socket));
 	}
+	else {
+		/* use the input directly if no expression nodes are generated (no local arg dependencies) */
+		is_block_node |= add_block_node(link_node, block, block_map, block_visited);
+	}
 	
 	/* find node inputs in the expression block that use values outside of it,
 	 * which means these must be included in the parent block
 	 */
-	for (NodeSet::iterator it = expr_block.nodes.begin(); it != expr_block.nodes.end(); ++it) {
+	for (NodeSet::iterator it = expr_block.nodes().begin(); it != expr_block.nodes().end(); ++it) {
 		NodeInstance *node = *it;
 		for (int i = 0; i < node->num_inputs(); ++i) {
 			InputKey expr_input = node->input(i);
 			NodeInstance *link_node = expr_input.link().node;
-			if (link_node && expr_block.nodes.find(link_node) == expr_block.nodes.end())
-				is_block_node |= add_block_node(link_node, block_args, block, block_map);
+			if (link_node && expr_block.nodes().find(link_node) == expr_block.nodes().end())
+				is_block_node |= add_block_node(link_node, block, block_map, block_visited);
 		}
 	}
 	
@@ -1030,31 +1022,80 @@ bool NodeGraph::blockify_expression(const InputKey &input, const OutputSet &bloc
 
 void NodeGraph::blockify_nodes()
 {
-	OutputSet main_args;
+	blocks.push_back(NodeBlock("main", NULL));
+	NodeBlock &main = blocks.back();
+	NodeSet main_visited;
+	NodeMap main_map;
+	
+	/* input argument nodes must always be included in main,
+	 * to provide reliable storage for caller arguments
+	 */
 	for (InputList::const_iterator it = inputs.begin(); it != inputs.end(); ++it) {
 		const Input &input = *it;
-		if (input.key)
-			main_args.insert(input.key);
+		if (in

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list