[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