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:
authorJacques Lucke <jacques@blender.org>2022-08-31 13:15:57 +0300
committerJacques Lucke <jacques@blender.org>2022-08-31 13:16:13 +0300
commit25e307d725d0b924fb0e87e4ffde84f915b74310 (patch)
tree016cf4a37ccbc2fbdf40c92cd16e96a9090bcd01 /source/blender/editors/space_node/node_relationships.cc
parent5a60535a20393a4215f7a03fe77d927bacb71438 (diff)
Nodes: move NodeTreeRef functionality into node runtime data
The purpose of `NodeTreeRef` was to speed up various queries on a read-only `bNodeTree`. Not that we have runtime data in nodes and sockets, we can also store the result of some queries there. This has some benefits: * No need for a read-only separate node tree data structure which increased complexity. * Makes it easier to reuse cached queries in more parts of Blender that can benefit from it. A downside is that we loose some type safety that we got by having different types for input and output sockets, as well as internal and non-internal links. This patch also refactors `DerivedNodeTree` so that it does not use `NodeTreeRef` anymore, but uses `bNodeTree` directly instead. To provide a convenient API (that is also close to what `NodeTreeRef` has), a new approach is implemented: `bNodeTree`, `bNode`, `bNodeSocket` and `bNodeLink` now have C++ methods declared in `DNA_node_types.h` which are implemented in `BKE_node_runtime.hh`. To make this work, `makesdna` now skips c++ sections when parsing dna header files. No user visible changes are expected. Differential Revision: https://developer.blender.org/D15491
Diffstat (limited to 'source/blender/editors/space_node/node_relationships.cc')
-rw-r--r--source/blender/editors/space_node/node_relationships.cc83
1 files changed, 38 insertions, 45 deletions
diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc
index d911e53be7f..3a8bb56bc5e 100644
--- a/source/blender/editors/space_node/node_relationships.cc
+++ b/source/blender/editors/space_node/node_relationships.cc
@@ -18,6 +18,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_screen.h"
@@ -46,14 +47,11 @@
#include "BLT_translation.h"
#include "NOD_node_declaration.hh"
-#include "NOD_node_tree_ref.hh"
#include "NOD_socket_declarations.hh"
#include "NOD_socket_declarations_geometry.hh"
#include "node_intern.hh" /* own include */
-using namespace blender::nodes::node_tree_ref_types;
-
struct bNodeListItem {
struct bNodeListItem *next, *prev;
struct bNode *node;
@@ -434,18 +432,18 @@ namespace viewer_linking {
* \{ */
/* Depending on the node tree type, different socket types are supported by viewer nodes. */
-static bool socket_can_be_viewed(const OutputSocketRef &socket)
+static bool socket_can_be_viewed(const bNodeSocket &socket)
{
- if (nodeSocketIsHidden(socket.bsocket())) {
+ if (nodeSocketIsHidden(&socket)) {
return false;
}
- if (socket.idname() == "NodeSocketVirtual") {
+ if (STREQ(socket.idname, "NodeSocketVirtual")) {
return false;
}
- if (socket.tree().btree()->type != NTREE_GEOMETRY) {
+ if (socket.owner_tree().type != NTREE_GEOMETRY) {
return true;
}
- return ELEM(socket.typeinfo()->type,
+ return ELEM(socket.typeinfo->type,
SOCK_GEOMETRY,
SOCK_FLOAT,
SOCK_VECTOR,
@@ -502,15 +500,15 @@ static bNodeSocket *node_link_viewer_get_socket(bNodeTree &ntree,
return nullptr;
}
-static bool is_viewer_node(const NodeRef &node)
+static bool is_viewer_node(const bNode &node)
{
- return ELEM(node.bnode()->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER);
+ return ELEM(node.type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER);
}
-static Vector<const NodeRef *> find_viewer_nodes(const NodeTreeRef &tree)
+static Vector<const bNode *> find_viewer_nodes(const bNodeTree &tree)
{
- Vector<const NodeRef *> viewer_nodes;
- for (const NodeRef *node : tree.nodes()) {
+ Vector<const bNode *> viewer_nodes;
+ for (const bNode *node : tree.all_nodes()) {
if (is_viewer_node(*node)) {
viewer_nodes.append(node);
}
@@ -518,20 +516,20 @@ static Vector<const NodeRef *> find_viewer_nodes(const NodeTreeRef &tree)
return viewer_nodes;
}
-static bool is_viewer_socket_in_viewer(const InputSocketRef &socket)
+static bool is_viewer_socket_in_viewer(const bNodeSocket &socket)
{
- const NodeRef &node = socket.node();
+ const bNode &node = socket.owner_node();
BLI_assert(is_viewer_node(node));
- if (node.typeinfo()->type == GEO_NODE_VIEWER) {
+ if (node.typeinfo->type == GEO_NODE_VIEWER) {
return true;
}
return socket.index() == 0;
}
-static bool is_linked_to_viewer(const OutputSocketRef &socket, const NodeRef &viewer_node)
+static bool is_linked_to_viewer(const bNodeSocket &socket, const bNode &viewer_node)
{
- for (const InputSocketRef *target_socket : socket.directly_linked_sockets()) {
- if (&target_socket->node() != &viewer_node) {
+ for (const bNodeSocket *target_socket : socket.directly_linked_sockets()) {
+ if (&target_socket->owner_node() != &viewer_node) {
continue;
}
if (!target_socket->is_available()) {
@@ -561,39 +559,39 @@ static void remove_links_to_unavailable_viewer_sockets(bNodeTree &btree, bNode &
}
}
-static const NodeRef *get_existing_viewer(const NodeTreeRef &tree)
+static const bNode *get_existing_viewer(const bNodeTree &tree)
{
- Vector<const NodeRef *> viewer_nodes = find_viewer_nodes(tree);
+ Vector<const bNode *> viewer_nodes = find_viewer_nodes(tree);
/* Check if there is already an active viewer node that should be used. */
- for (const NodeRef *viewer_node : viewer_nodes) {
- if (viewer_node->bnode()->flag & NODE_DO_OUTPUT) {
+ for (const bNode *viewer_node : viewer_nodes) {
+ if (viewer_node->flag & NODE_DO_OUTPUT) {
return viewer_node;
}
}
/* If no active but non-active viewers exist, make one active. */
if (!viewer_nodes.is_empty()) {
- viewer_nodes[0]->bnode()->flag |= NODE_DO_OUTPUT;
+ const_cast<bNode *>(viewer_nodes[0])->flag |= NODE_DO_OUTPUT;
return viewer_nodes[0];
}
return nullptr;
}
-static const OutputSocketRef *find_output_socket_to_be_viewed(const NodeRef *active_viewer_node,
- const NodeRef &node_to_view)
+static const bNodeSocket *find_output_socket_to_be_viewed(const bNode *active_viewer_node,
+ const bNode &node_to_view)
{
/* Check if any of the output sockets is selected, which is the case when the user just clicked
* on the socket. */
- for (const OutputSocketRef *output_socket : node_to_view.outputs()) {
- if (output_socket->bsocket()->flag & SELECT) {
+ for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
+ if (output_socket->flag & SELECT) {
return output_socket;
}
}
- const OutputSocketRef *last_socket_linked_to_viewer = nullptr;
+ const bNodeSocket *last_socket_linked_to_viewer = nullptr;
if (active_viewer_node != nullptr) {
- for (const OutputSocketRef *output_socket : node_to_view.outputs()) {
+ for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
if (!socket_can_be_viewed(*output_socket)) {
continue;
}
@@ -604,7 +602,7 @@ static const OutputSocketRef *find_output_socket_to_be_viewed(const NodeRef *act
}
if (last_socket_linked_to_viewer == nullptr) {
/* If no output is connected to a viewer, use the first output that can be viewed. */
- for (const OutputSocketRef *output_socket : node_to_view.outputs()) {
+ for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
if (socket_can_be_viewed(*output_socket)) {
return output_socket;
}
@@ -612,10 +610,10 @@ static const OutputSocketRef *find_output_socket_to_be_viewed(const NodeRef *act
}
else {
/* Pick the next socket to be linked to the viewer. */
- const int tot_outputs = node_to_view.outputs().size();
+ const int tot_outputs = node_to_view.output_sockets().size();
for (const int offset : IndexRange(1, tot_outputs - 1)) {
const int index = (last_socket_linked_to_viewer->index() + offset) % tot_outputs;
- const OutputSocketRef &output_socket = node_to_view.output(index);
+ const bNodeSocket &output_socket = node_to_view.output_socket(index);
if (!socket_can_be_viewed(output_socket)) {
continue;
}
@@ -682,20 +680,15 @@ static int node_link_viewer(const bContext &C, bNode &bnode_to_view)
{
SpaceNode &snode = *CTX_wm_space_node(&C);
bNodeTree *btree = snode.edittree;
+ btree->ensure_topology_cache();
- const NodeTreeRef tree{btree};
- const NodeRef &node_to_view = *tree.find_node(bnode_to_view);
- const NodeRef *active_viewer_node = get_existing_viewer(tree);
-
- const OutputSocketRef *socket_to_view = find_output_socket_to_be_viewed(active_viewer_node,
- node_to_view);
- if (socket_to_view == nullptr) {
+ bNode *active_viewer_bnode = const_cast<bNode *>(get_existing_viewer(*btree));
+ bNodeSocket *bsocket_to_view = const_cast<bNodeSocket *>(
+ find_output_socket_to_be_viewed(active_viewer_bnode, bnode_to_view));
+ if (bsocket_to_view == nullptr) {
return OPERATOR_FINISHED;
}
-
- bNodeSocket &bsocket_to_view = *socket_to_view->bsocket();
- bNode *viewer_bnode = active_viewer_node ? active_viewer_node->bnode() : nullptr;
- return link_socket_to_viewer(C, viewer_bnode, bnode_to_view, bsocket_to_view);
+ return link_socket_to_viewer(C, active_viewer_bnode, bnode_to_view, *bsocket_to_view);
}
/** \} */
@@ -2048,7 +2041,7 @@ static bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketIn
/* Try to get the main socket based on the socket declaration. */
nodeDeclarationEnsure(&ntree, &node);
- const nodes::NodeDeclaration *node_decl = node.runtime->declaration;
+ const nodes::NodeDeclaration *node_decl = node.declaration();
if (node_decl != nullptr) {
Span<nodes::SocketDeclarationPtr> socket_decls = (in_out == SOCK_IN) ? node_decl->inputs() :
node_decl->outputs();