Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_node_tree_ref.hh21
-rw-r--r--source/blender/blenkernel/intern/node_tree_ref.cc101
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