diff options
-rw-r--r-- | source/blender/blenkernel/BKE_node_tree_ref.hh | 21 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_tree_ref.cc | 101 |
2 files changed, 121 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_node_tree_ref.hh b/source/blender/blenkernel/BKE_node_tree_ref.hh index 61dd0a23425..cd62b199ff7 100644 --- a/source/blender/blenkernel/BKE_node_tree_ref.hh +++ b/source/blender/blenkernel/BKE_node_tree_ref.hh @@ -18,11 +18,14 @@ #define __BKE_NODE_TREE_REF_HH__ #include "BLI_linear_allocator.hh" +#include "BLI_map.hh" #include "BLI_string_map.hh" #include "BLI_string_ref.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" +#include "BKE_node.h" + #include "DNA_node_types.h" #include "RNA_access.h" @@ -31,6 +34,7 @@ namespace BKE { using BLI::ArrayRef; using BLI::LinearAllocator; +using BLI::Map; using BLI::StringMap; using BLI::StringRef; using BLI::StringRefNull; @@ -123,6 +127,8 @@ class NodeRef : BLI::NonCopyable, BLI::NonMovable { StringRefNull name() const; uint id() const; + + bool is_reroute() const; }; class NodeTreeRef : BLI::NonCopyable, BLI::NonMovable { @@ -147,6 +153,16 @@ class NodeTreeRef : BLI::NonCopyable, BLI::NonMovable { ArrayRef<const OutputSocketRef *> output_sockets() const; bNodeTree *btree() const; + + private: + /* Utility functions used by constructor. */ + InputSocketRef &find_input_socket(Map<bNode *, NodeRef *> &node_mapping, + bNode *bnode, + bNodeSocket *bsocket); + OutputSocketRef &find_output_socket(Map<bNode *, NodeRef *> &node_mapping, + bNode *bnode, + bNodeSocket *bsocket); + void find_targets_skipping_reroutes(OutputSocketRef &socket_ref, Vector<SocketRef *> &r_targets); }; /* -------------------------------------------------------------------- @@ -332,6 +348,11 @@ inline uint NodeRef::id() const return m_id; } +inline bool NodeRef::is_reroute() const +{ + return m_bnode->type == NODE_REROUTE; +} + /* -------------------------------------------------------------------- * NodeRef inline methods. */ diff --git a/source/blender/blenkernel/intern/node_tree_ref.cc b/source/blender/blenkernel/intern/node_tree_ref.cc index fd912178f98..3bf589fbb87 100644 --- a/source/blender/blenkernel/intern/node_tree_ref.cc +++ b/source/blender/blenkernel/intern/node_tree_ref.cc @@ -18,12 +18,111 @@ namespace BKE { -NodeTreeRef::NodeTreeRef(bNodeTree *UNUSED(btree)) +NodeTreeRef::NodeTreeRef(bNodeTree *btree) { + Map<bNode *, NodeRef *> node_mapping; + + LISTBASE_FOREACH (bNode *, bnode, &btree->nodes) { + NodeRef &node = *m_allocator.construct<NodeRef>(); + + node.m_tree = this; + node.m_bnode = bnode; + node.m_id = m_nodes_by_id.append_and_get_index(&node); + RNA_pointer_create(&btree->id, &RNA_Node, bnode, &node.m_rna); + + LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->inputs) { + InputSocketRef &socket = *m_allocator.construct<InputSocketRef>(); + socket.m_node = &node; + socket.m_index = node.m_inputs.append_and_get_index(&socket); + socket.m_is_input = true; + socket.m_bsocket = bsocket; + socket.m_id = m_sockets_by_id.append_and_get_index(&socket); + RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.m_rna); + } + + LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->outputs) { + OutputSocketRef &socket = *m_allocator.construct<OutputSocketRef>(); + socket.m_node = &node; + socket.m_index = node.m_outputs.append_and_get_index(&socket); + socket.m_is_input = false; + socket.m_bsocket = bsocket; + socket.m_id = m_sockets_by_id.append_and_get_index(&socket); + RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.m_rna); + } + + m_input_sockets.extend(node.m_inputs); + m_output_sockets.extend(node.m_outputs); + + node_mapping.add_new(bnode, &node); + } + + LISTBASE_FOREACH (bNodeLink *, blink, &btree->links) { + OutputSocketRef &from_socket = this->find_output_socket( + node_mapping, blink->fromnode, blink->fromsock); + InputSocketRef &to_socket = this->find_input_socket( + node_mapping, blink->tonode, blink->tosock); + + from_socket.m_directly_linked_sockets.append(&to_socket); + to_socket.m_directly_linked_sockets.append(&from_socket); + } + + for (OutputSocketRef *socket : m_output_sockets) { + if (!socket->m_node->is_reroute()) { + this->find_targets_skipping_reroutes(*socket, socket->m_linked_sockets); + for (SocketRef *target : socket->m_linked_sockets) { + target->m_linked_sockets.append(socket); + } + } + } + + for (NodeRef *node : m_nodes_by_id) { + m_nodes_by_idname.lookup_or_add_default(node->idname()).append(node); + } } NodeTreeRef::~NodeTreeRef() { } +InputSocketRef &NodeTreeRef::find_input_socket(Map<bNode *, NodeRef *> &node_mapping, + bNode *bnode, + bNodeSocket *bsocket) +{ + NodeRef *node = node_mapping.lookup(bnode); + for (SocketRef *socket : node->m_inputs) { + if (socket->m_bsocket == bsocket) { + return *(InputSocketRef *)socket; + } + } + BLI_assert(false); + return *node->m_inputs[0]; +} + +OutputSocketRef &NodeTreeRef::find_output_socket(Map<bNode *, NodeRef *> &node_mapping, + bNode *bnode, + bNodeSocket *bsocket) +{ + NodeRef *node = node_mapping.lookup(bnode); + for (SocketRef *socket : node->m_outputs) { + if (socket->m_bsocket == bsocket) { + return *(OutputSocketRef *)socket; + } + } + BLI_assert(false); + return *node->m_outputs[0]; +} + +void NodeTreeRef::find_targets_skipping_reroutes(OutputSocketRef &socket, + Vector<SocketRef *> &r_targets) +{ + for (SocketRef *direct_target : socket.m_directly_linked_sockets) { + if (direct_target->m_node->is_reroute()) { + this->find_targets_skipping_reroutes(*direct_target->m_node->m_outputs[0], r_targets); + } + else { + r_targets.append_non_duplicates(direct_target); + } + } +} + } // namespace BKE |