From d2869943d2c02f1535270f0e206a67aab78c8ebb Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 6 Mar 2021 16:51:06 +0100 Subject: Nodes: refactor derived node tree This is a complete rewrite of the derived node tree data structure. It is a much thinner abstraction about `NodeTreeRef` than before. This gives the user of the derived node tree more control and allows for greater introspection capabilities (e.g. before muted nodes were completely abstracted away; this was convenient, but came with limitations). Another nice benefit of the new structure is that it is much cheaper to build, because it does not inline all nodes and sockets in nested node groups. Differential Revision: https://developer.blender.org/D10620 --- .../blender/nodes/NOD_node_tree_multi_function.hh | 107 ++++++++++----------- 1 file changed, 49 insertions(+), 58 deletions(-) (limited to 'source/blender/nodes/NOD_node_tree_multi_function.hh') diff --git a/source/blender/nodes/NOD_node_tree_multi_function.hh b/source/blender/nodes/NOD_node_tree_multi_function.hh index 552ef5509fa..df31ee18369 100644 --- a/source/blender/nodes/NOD_node_tree_multi_function.hh +++ b/source/blender/nodes/NOD_node_tree_multi_function.hh @@ -28,14 +28,15 @@ #include "NOD_derived_node_tree.hh" #include "NOD_type_callbacks.hh" +#include "BLI_multi_value_map.hh" #include "BLI_resource_collector.hh" namespace blender::nodes { /** - * A MFNetworkTreeMap maps various components of a DerivedNodeTree to components of a - * fn::MFNetwork. This is necessary for further processing of a multi-function network that has - * been generated from a node tree. + * A MFNetworkTreeMap maps various components of a node tree to components of a fn::MFNetwork. This + * is necessary for further processing of a multi-function network that has been generated from a + * node tree. */ class MFNetworkTreeMap { private: @@ -47,15 +48,11 @@ class MFNetworkTreeMap { */ const DerivedNodeTree &tree_; fn::MFNetwork &network_; - Array> sockets_by_dsocket_id_; - Array socket_by_group_input_id_; + MultiValueMap sockets_by_dsocket_; public: MFNetworkTreeMap(const DerivedNodeTree &tree, fn::MFNetwork &network) - : tree_(tree), - network_(network), - sockets_by_dsocket_id_(tree.sockets().size()), - socket_by_group_input_id_(tree.group_inputs().size(), nullptr) + : tree_(tree), network_(network) { } @@ -76,96 +73,95 @@ class MFNetworkTreeMap { void add(const DSocket &dsocket, fn::MFSocket &socket) { - BLI_assert(dsocket.is_input() == socket.is_input()); - BLI_assert(dsocket.is_input() || sockets_by_dsocket_id_[dsocket.id()].size() == 0); - sockets_by_dsocket_id_[dsocket.id()].append(&socket); + BLI_assert(dsocket->is_input() == socket.is_input()); + BLI_assert(dsocket->is_input() || sockets_by_dsocket_.lookup(dsocket).is_empty()); + sockets_by_dsocket_.add(dsocket, &socket); } void add(const DInputSocket &dsocket, fn::MFInputSocket &socket) { - sockets_by_dsocket_id_[dsocket.id()].append(&socket); + sockets_by_dsocket_.add(dsocket, &socket); } void add(const DOutputSocket &dsocket, fn::MFOutputSocket &socket) { /* There can be at most one matching output socket. */ - BLI_assert(sockets_by_dsocket_id_[dsocket.id()].size() == 0); - sockets_by_dsocket_id_[dsocket.id()].append(&socket); + BLI_assert(sockets_by_dsocket_.lookup(dsocket).is_empty()); + sockets_by_dsocket_.add(dsocket, &socket); } - void add(Span dsockets, Span sockets) + void add(const DTreeContext &context, + Span dsockets, + Span sockets) { assert_same_size(dsockets, sockets); for (int i : dsockets.index_range()) { - this->add(*dsockets[i], *sockets[i]); + this->add(DInputSocket(&context, dsockets[i]), *sockets[i]); } } - void add(Span dsockets, Span sockets) + void add(const DTreeContext &context, + Span dsockets, + Span sockets) { assert_same_size(dsockets, sockets); for (int i : dsockets.index_range()) { - this->add(*dsockets[i], *sockets[i]); + this->add(DOutputSocket(&context, dsockets[i]), *sockets[i]); } } - void add(const DGroupInput &group_input, fn::MFOutputSocket &socket) - { - BLI_assert(socket_by_group_input_id_[group_input.id()] == nullptr); - socket_by_group_input_id_[group_input.id()] = &socket; - } - void add_try_match(const DNode &dnode, fn::MFNode &node) { - this->add_try_match(dnode.inputs().cast(), + this->add_try_match(*dnode.context(), + dnode->inputs().cast(), node.inputs().cast()); - this->add_try_match(dnode.outputs().cast(), + this->add_try_match(*dnode.context(), + dnode->outputs().cast(), node.outputs().cast()); } - void add_try_match(Span dsockets, Span sockets) + void add_try_match(const DTreeContext &context, + Span dsockets, + Span sockets) { - this->add_try_match(dsockets.cast(), sockets.cast()); + this->add_try_match( + context, dsockets.cast(), sockets.cast()); } - void add_try_match(Span dsockets, Span sockets) + void add_try_match(const DTreeContext &context, + Span dsockets, + Span sockets) { - this->add_try_match(dsockets.cast(), sockets.cast()); + this->add_try_match( + context, dsockets.cast(), sockets.cast()); } - void add_try_match(Span dsockets, Span sockets) + void add_try_match(const DTreeContext &context, + Span dsockets, + Span sockets) { int used_sockets = 0; - for (const DSocket *dsocket : dsockets) { + for (const SocketRef *dsocket : dsockets) { if (!dsocket->is_available()) { continue; } - if (!socket_is_mf_data_socket(*dsocket->bsocket()->typeinfo)) { + if (!socket_is_mf_data_socket(*dsocket->typeinfo())) { continue; } fn::MFSocket *socket = sockets[used_sockets]; - this->add(*dsocket, *socket); + this->add(DSocket(&context, dsocket), *socket); used_sockets++; } } - fn::MFOutputSocket &lookup(const DGroupInput &group_input) - { - fn::MFOutputSocket *socket = socket_by_group_input_id_[group_input.id()]; - BLI_assert(socket != nullptr); - return *socket; - } - fn::MFOutputSocket &lookup(const DOutputSocket &dsocket) { - auto &sockets = sockets_by_dsocket_id_[dsocket.id()]; - BLI_assert(sockets.size() == 1); - return sockets[0]->as_output(); + return sockets_by_dsocket_.lookup(dsocket)[0]->as_output(); } Span lookup(const DInputSocket &dsocket) { - return sockets_by_dsocket_id_[dsocket.id()].as_span().cast(); + return sockets_by_dsocket_.lookup(dsocket).cast(); } fn::MFInputSocket &lookup_dummy(const DInputSocket &dsocket) @@ -186,7 +182,7 @@ class MFNetworkTreeMap { bool is_mapped(const DSocket &dsocket) const { - return sockets_by_dsocket_id_[dsocket.id()].size() >= 1; + return !sockets_by_dsocket_.lookup(dsocket).is_empty(); } }; @@ -258,12 +254,7 @@ class SocketMFNetworkBuilder : public MFNetworkBuilderBase { public: SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DSocket &dsocket) - : MFNetworkBuilderBase(common), bsocket_(dsocket.bsocket()) - { - } - - SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DGroupInput &group_input) - : MFNetworkBuilderBase(common), bsocket_(group_input.bsocket()) + : MFNetworkBuilderBase(common), bsocket_(dsocket->bsocket()) { } @@ -331,10 +322,10 @@ class SocketMFNetworkBuilder : public MFNetworkBuilderBase { */ class NodeMFNetworkBuilder : public MFNetworkBuilderBase { private: - const DNode &dnode_; + DNode dnode_; public: - NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &dnode) + NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, DNode dnode) : MFNetworkBuilderBase(common), dnode_(dnode) { } @@ -352,7 +343,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase { const fn::MultiFunction &get_not_implemented_fn() { - return this->get_default_fn("Not Implemented (" + dnode_.name() + ")"); + return this->get_default_fn("Not Implemented (" + dnode_->name() + ")"); } const fn::MultiFunction &get_default_fn(StringRef name); @@ -377,7 +368,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase { */ bNode &bnode() { - return *dnode_.node_ref().bnode(); + return *dnode_->bnode(); } /** @@ -393,7 +384,7 @@ MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network, const DerivedNodeTree &tree, ResourceCollector &resources); -using MultiFunctionByNode = Map; +using MultiFunctionByNode = Map; MultiFunctionByNode get_multi_function_per_node(const DerivedNodeTree &tree, ResourceCollector &resources); -- cgit v1.2.3