[Bf-blender-cvs] [f6c377aa5bf] functions: remove unused nodes optimization
Jacques Lucke
noreply at git.blender.org
Sat Jan 18 20:17:40 CET 2020
Commit: f6c377aa5bf12f17b924e17178dbf91d9c8698eb
Author: Jacques Lucke
Date: Sat Jan 11 16:35:35 2020 +0100
Branches: functions
https://developer.blender.org/rBf6c377aa5bf12f17b924e17178dbf91d9c8698eb
remove unused nodes optimization
===================================================================
M source/blender/functions/FN_multi_function_network.h
M source/blender/functions/FN_multi_function_network_optimization.h
M source/blender/functions/intern/multi_function_network_optimization.cc
M source/blender/functions/intern/node_tree_multi_function_network/generate.cc
===================================================================
diff --git a/source/blender/functions/FN_multi_function_network.h b/source/blender/functions/FN_multi_function_network.h
index fa1b6ca6813..386e1de75f4 100644
--- a/source/blender/functions/FN_multi_function_network.h
+++ b/source/blender/functions/FN_multi_function_network.h
@@ -59,6 +59,9 @@ class MFBuilderNode : BLI::NonCopyable, BLI::NonMovable {
MFBuilderDummyNode &as_dummy();
template<typename FuncT> void foreach_target_socket(const FuncT &func);
+ template<typename FuncT> void foreach_target_node(const FuncT &func);
+ template<typename FuncT> void foreach_origin_node(const FuncT &func);
+ template<typename FuncT> void foreach_linked_node(const FuncT &func);
};
class MFBuilderFunctionNode : public MFBuilderNode {
@@ -168,9 +171,19 @@ class MFNetworkBuilder : BLI::NonCopyable, BLI::NonMovable {
return m_dummy_nodes.index(&node);
}
+ uint node_id_amount() const
+ {
+ return m_node_or_null_by_id.size();
+ }
+
+ bool node_id_is_valid(uint id) const
+ {
+ return m_node_or_null_by_id[id] != nullptr;
+ }
+
MFBuilderNode &node_by_id(uint id)
{
- BLI_assert(m_node_or_null_by_id[id] != nullptr);
+ BLI_assert(this->node_id_is_valid(id));
return *m_node_or_null_by_id[id];
}
@@ -445,6 +458,31 @@ template<typename FuncT> inline void MFBuilderNode::foreach_target_socket(const
}
}
+template<typename FuncT> inline void MFBuilderNode::foreach_target_node(const FuncT &func)
+{
+ for (MFBuilderOutputSocket *socket : m_outputs) {
+ for (MFBuilderInputSocket *target : socket->targets()) {
+ func(target->node());
+ }
+ }
+}
+
+template<typename FuncT> inline void MFBuilderNode::foreach_origin_node(const FuncT &func)
+{
+ for (MFBuilderInputSocket *socket : m_inputs) {
+ MFBuilderOutputSocket *origin = socket->origin();
+ if (origin != nullptr) {
+ func(origin->node());
+ }
+ }
+}
+
+template<typename FuncT> inline void MFBuilderNode::foreach_linked_node(const FuncT &func)
+{
+ this->foreach_origin_node(func);
+ this->foreach_target_node(func);
+}
+
inline const MultiFunction &MFBuilderFunctionNode::function()
{
return *m_function;
diff --git a/source/blender/functions/FN_multi_function_network_optimization.h b/source/blender/functions/FN_multi_function_network_optimization.h
index f2117f28032..6d58201c795 100644
--- a/source/blender/functions/FN_multi_function_network_optimization.h
+++ b/source/blender/functions/FN_multi_function_network_optimization.h
@@ -10,6 +10,8 @@ namespace FN {
using BLI::ResourceCollector;
void optimize_network__constant_folding(MFNetworkBuilder &network, ResourceCollector &resources);
+void optimize_network__remove_unused_nodes(MFNetworkBuilder &network_builder,
+ ArrayRef<MFBuilderNode *> fixed_nodes);
} // namespace FN
diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc
index 11528a78a3e..6a44d07fdfd 100644
--- a/source/blender/functions/intern/multi_function_network_optimization.cc
+++ b/source/blender/functions/intern/multi_function_network_optimization.cc
@@ -8,6 +8,39 @@ namespace FN {
using BLI::Stack;
+void optimize_network__remove_unused_nodes(MFNetworkBuilder &network_builder,
+ ArrayRef<MFBuilderNode *> fixed_nodes)
+{
+ Array<bool> unused_tag_per_id(network_builder.node_id_amount(), false);
+
+ for (MFBuilderNode *fixed_node : fixed_nodes) {
+ unused_tag_per_id[fixed_node->id()] = true;
+ }
+
+ Stack<MFBuilderNode *> nodes_to_check = fixed_nodes;
+ while (!nodes_to_check.is_empty()) {
+ MFBuilderNode ¤t_node = *nodes_to_check.pop();
+ if (!unused_tag_per_id[current_node.id()]) {
+ continue;
+ }
+
+ current_node.foreach_origin_node([&](MFBuilderNode &other_node) {
+ bool &other_is_connected = unused_tag_per_id[other_node.id()];
+ if (!other_is_connected) {
+ other_is_connected = true;
+ nodes_to_check.push(&other_node);
+ }
+ });
+ }
+
+ for (uint id : unused_tag_per_id.index_range()) {
+ if (network_builder.node_id_is_valid(id) && !unused_tag_per_id[id]) {
+ MFBuilderNode &node = network_builder.node_by_id(id);
+ network_builder.remove_node(node);
+ }
+ }
+}
+
void optimize_network__constant_folding(MFNetworkBuilder &network_builder,
ResourceCollector &resources)
{
@@ -184,24 +217,10 @@ void optimize_network__constant_folding(MFNetworkBuilder &network_builder,
left_most_constant_nodes.append(constant_node);
}
}
- for (MFBuilderFunctionNode *node : inner_constant_nodes) {
- network_builder.remove_node(*node);
- }
- for (MFBuilderFunctionNode *node : left_most_constant_nodes) {
- uint target_amount = 0;
- for (MFBuilderOutputSocket *output_socket : node->outputs()) {
- target_amount += output_socket->targets().size();
- }
- if (target_amount == 0) {
- network_builder.remove_node(*node);
- }
- }
for (MFBuilderDummyNode *dummy_node : dummy_nodes_to_compute) {
network_builder.remove_node(*dummy_node);
}
-
- network_builder.to_dot__clipboard();
}
} // namespace FN
diff --git a/source/blender/functions/intern/node_tree_multi_function_network/generate.cc b/source/blender/functions/intern/node_tree_multi_function_network/generate.cc
index a2632bdde75..a3d4c4ea34d 100644
--- a/source/blender/functions/intern/node_tree_multi_function_network/generate.cc
+++ b/source/blender/functions/intern/node_tree_multi_function_network/generate.cc
@@ -273,6 +273,8 @@ std::unique_ptr<FunctionTreeMFNetwork> generate_node_tree_multi_function_network
}
optimize_network__constant_folding(network_builder, resources);
+ optimize_network__remove_unused_nodes(network_builder, network_builder.dummy_nodes());
+ // network_builder.to_dot__clipboard();
auto function_tree_network = build(function_tree, network_builder, dummy_socket_mapping);
return function_tree_network;
}
More information about the Bf-blender-cvs
mailing list