diff options
author | Jacques Lucke <jacques@blender.org> | 2020-07-17 12:36:59 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-07-17 12:36:59 +0300 |
commit | 5910dbdbf7dc7999597a680f81c261fa7bbcf011 (patch) | |
tree | edc962ebd6b11d89d3c29e571caeee0dcbe4ad79 /source/blender/blenkernel | |
parent | 0a40c671b0b5a6735bd0137ebcb3ab7568ae4481 (diff) |
Nodes: move some code from blenkernel directory to nodes
This also introduces the `blender::nodes` namespace. Eventually,
we want to move most/all of the node implementation files into
this namespace.
The reason for this file-move is that the code fits much better
into the `nodes` directory than in the `blenkernel` directory.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_derived_node_tree.hh | 517 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_node_tree_multi_function.hh | 390 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_node_tree_ref.hh | 445 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/derived_node_tree.cc | 441 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_tree_multi_function.cc | 346 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_tree_ref.cc | 177 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/simulation.cc | 44 |
9 files changed, 29 insertions, 2345 deletions
diff --git a/source/blender/blenkernel/BKE_derived_node_tree.hh b/source/blender/blenkernel/BKE_derived_node_tree.hh deleted file mode 100644 index 083057835a5..00000000000 --- a/source/blender/blenkernel/BKE_derived_node_tree.hh +++ /dev/null @@ -1,517 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __BKE_DERIVED_NODE_TREE_HH__ -#define __BKE_DERIVED_NODE_TREE_HH__ - -/** \file - * \ingroup bke - * - * DerivedNodeTree provides a flattened view on a bNodeTree, i.e. node groups are inlined. It - * builds on top of NodeTreeRef and supports similar queries efficiently. - * - * Every inlined node remembers its path to the parent ("call stack"). - * - * Unlinked group node inputs are handled separately from other sockets. - * - * There is a dot graph exporter for debugging purposes. - */ - -#include "BKE_node_tree_ref.hh" - -namespace blender::bke { - -class DSocket; -class DInputSocket; -class DOutputSocket; -class DNode; -class DParentNode; -class DGroupInput; -class DerivedNodeTree; - -class DSocket : NonCopyable, NonMovable { - protected: - DNode *node_; - const SocketRef *socket_ref_; - uint id_; - - friend DerivedNodeTree; - - public: - const DNode &node() const; - - uint id() const; - uint index() const; - - bool is_input() const; - bool is_output() const; - - const DSocket &as_base() const; - const DInputSocket &as_input() const; - const DOutputSocket &as_output() const; - - PointerRNA *rna() const; - StringRefNull idname() const; - StringRefNull name() const; - - const SocketRef &socket_ref() const; - bNodeSocket *bsocket() const; - - bool is_available() const; -}; - -class DInputSocket : public DSocket { - private: - Vector<DOutputSocket *> linked_sockets_; - Vector<DGroupInput *> linked_group_inputs_; - - friend DerivedNodeTree; - - public: - const InputSocketRef &socket_ref() const; - - Span<const DOutputSocket *> linked_sockets() const; - Span<const DGroupInput *> linked_group_inputs() const; - - bool is_linked() const; -}; - -class DOutputSocket : public DSocket { - private: - Vector<DInputSocket *> linked_sockets_; - - friend DerivedNodeTree; - - public: - const OutputSocketRef &socket_ref() const; - Span<const DInputSocket *> linked_sockets() const; -}; - -class DGroupInput : NonCopyable, NonMovable { - private: - const InputSocketRef *socket_ref_; - DParentNode *parent_; - Vector<DInputSocket *> linked_sockets_; - uint id_; - - friend DerivedNodeTree; - - public: - const InputSocketRef &socket_ref() const; - bNodeSocket *bsocket() const; - const DParentNode *parent() const; - Span<const DInputSocket *> linked_sockets() const; - uint id() const; - StringRefNull name() const; -}; - -class DNode : NonCopyable, NonMovable { - private: - const NodeRef *node_ref_; - DParentNode *parent_; - - Span<DInputSocket *> inputs_; - Span<DOutputSocket *> outputs_; - - uint id_; - - friend DerivedNodeTree; - - public: - const NodeRef &node_ref() const; - const DParentNode *parent() const; - - Span<const DInputSocket *> inputs() const; - Span<const DOutputSocket *> outputs() const; - - const DInputSocket &input(uint index) const; - const DOutputSocket &output(uint index) const; - - const DInputSocket &input(uint index, StringRef expected_name) const; - const DOutputSocket &output(uint index, StringRef expected_name) const; - - uint id() const; - - PointerRNA *rna() const; - StringRefNull idname() const; - StringRefNull name() const; - - private: - void destruct_with_sockets(); -}; - -class DParentNode : NonCopyable, NonMovable { - private: - const NodeRef *node_ref_; - DParentNode *parent_; - uint id_; - - friend DerivedNodeTree; - - public: - const DParentNode *parent() const; - const NodeRef &node_ref() const; - uint id() const; -}; - -using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>; - -class DerivedNodeTree : NonCopyable, NonMovable { - private: - LinearAllocator<> allocator_; - bNodeTree *btree_; - Vector<DNode *> nodes_by_id_; - Vector<DGroupInput *> group_inputs_; - Vector<DParentNode *> parent_nodes_; - - Vector<DSocket *> sockets_by_id_; - Vector<DInputSocket *> input_sockets_; - Vector<DOutputSocket *> output_sockets_; - - Map<const bNodeType *, Vector<DNode *>> nodes_by_type_; - - public: - DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs); - ~DerivedNodeTree(); - - Span<const DNode *> nodes() const; - Span<const DNode *> nodes_by_type(StringRefNull idname) const; - Span<const DNode *> nodes_by_type(const bNodeType *nodetype) const; - - Span<const DSocket *> sockets() const; - Span<const DInputSocket *> input_sockets() const; - Span<const DOutputSocket *> output_sockets() const; - - Span<const DGroupInput *> group_inputs() const; - - std::string to_dot() const; - - private: - /* Utility functions used during construction. */ - void insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref, - DParentNode *parent, - Vector<DNode *> &all_nodes); - DNode &create_node(const NodeRef &node_ref, - DParentNode *parent, - MutableSpan<DSocket *> r_sockets_map); - void expand_groups(Vector<DNode *> &all_nodes, - Vector<DGroupInput *> &all_group_inputs, - Vector<DParentNode *> &all_parent_nodes, - NodeTreeRefMap &node_tree_refs); - void expand_group_node(DNode &group_node, - Vector<DNode *> &all_nodes, - Vector<DGroupInput *> &all_group_inputs, - Vector<DParentNode *> &all_parent_nodes, - NodeTreeRefMap &node_tree_refs); - void create_group_inputs_for_unlinked_inputs(DNode &node, - Vector<DGroupInput *> &all_group_inputs); - void relink_group_inputs(const NodeTreeRef &group_ref, - Span<DNode *> nodes_by_id, - DNode &group_node); - void relink_group_outputs(const NodeTreeRef &group_ref, - Span<DNode *> nodes_by_id, - DNode &group_node); - void remove_expanded_group_interfaces(Vector<DNode *> &all_nodes); - void remove_unused_group_inputs(Vector<DGroupInput *> &all_group_inputs); - void store_in_this_and_init_ids(Vector<DNode *> &&all_nodes, - Vector<DGroupInput *> &&all_group_inputs, - Vector<DParentNode *> &&all_parent_nodes); -}; - -/* -------------------------------------------------------------------- - * DSocket inline methods. - */ - -inline const DNode &DSocket::node() const -{ - return *node_; -} - -inline uint DSocket::id() const -{ - return id_; -} - -inline uint DSocket::index() const -{ - return socket_ref_->index(); -} - -inline bool DSocket::is_input() const -{ - return socket_ref_->is_input(); -} - -inline bool DSocket::is_output() const -{ - return socket_ref_->is_output(); -} - -inline const DSocket &DSocket::as_base() const -{ - return *this; -} - -inline const DInputSocket &DSocket::as_input() const -{ - return *(DInputSocket *)this; -} - -inline const DOutputSocket &DSocket::as_output() const -{ - return *(DOutputSocket *)this; -} - -inline PointerRNA *DSocket::rna() const -{ - return socket_ref_->rna(); -} - -inline StringRefNull DSocket::idname() const -{ - return socket_ref_->idname(); -} - -inline StringRefNull DSocket::name() const -{ - return socket_ref_->name(); -} - -inline const SocketRef &DSocket::socket_ref() const -{ - return *socket_ref_; -} - -inline bNodeSocket *DSocket::bsocket() const -{ - return socket_ref_->bsocket(); -} - -inline bool DSocket::is_available() const -{ - return (socket_ref_->bsocket()->flag & SOCK_UNAVAIL) == 0; -} - -/* -------------------------------------------------------------------- - * DInputSocket inline methods. - */ - -inline const InputSocketRef &DInputSocket::socket_ref() const -{ - return socket_ref_->as_input(); -} - -inline Span<const DOutputSocket *> DInputSocket::linked_sockets() const -{ - return linked_sockets_; -} - -inline Span<const DGroupInput *> DInputSocket::linked_group_inputs() const -{ - return linked_group_inputs_; -} - -inline bool DInputSocket::is_linked() const -{ - return linked_sockets_.size() > 0 || linked_group_inputs_.size() > 0; -} - -/* -------------------------------------------------------------------- - * DOutputSocket inline methods. - */ - -inline const OutputSocketRef &DOutputSocket::socket_ref() const -{ - return socket_ref_->as_output(); -} - -inline Span<const DInputSocket *> DOutputSocket::linked_sockets() const -{ - return linked_sockets_; -} - -/* -------------------------------------------------------------------- - * DGroupInput inline methods. - */ - -inline const InputSocketRef &DGroupInput::socket_ref() const -{ - return *socket_ref_; -} - -inline bNodeSocket *DGroupInput::bsocket() const -{ - return socket_ref_->bsocket(); -} - -inline const DParentNode *DGroupInput::parent() const -{ - return parent_; -} - -inline Span<const DInputSocket *> DGroupInput::linked_sockets() const -{ - return linked_sockets_; -} - -inline uint DGroupInput::id() const -{ - return id_; -} - -inline StringRefNull DGroupInput::name() const -{ - return socket_ref_->name(); -} - -/* -------------------------------------------------------------------- - * DNode inline methods. - */ - -inline const NodeRef &DNode::node_ref() const -{ - return *node_ref_; -} - -inline const DParentNode *DNode::parent() const -{ - return parent_; -} - -inline Span<const DInputSocket *> DNode::inputs() const -{ - return inputs_; -} - -inline Span<const DOutputSocket *> DNode::outputs() const -{ - return outputs_; -} - -inline const DInputSocket &DNode::input(uint index) const -{ - return *inputs_[index]; -} - -inline const DOutputSocket &DNode::output(uint index) const -{ - return *outputs_[index]; -} - -inline const DInputSocket &DNode::input(uint index, StringRef expected_name) const -{ - const DInputSocket &socket = *inputs_[index]; - BLI_assert(socket.name() == expected_name); - UNUSED_VARS_NDEBUG(expected_name); - return socket; -} - -inline const DOutputSocket &DNode::output(uint index, StringRef expected_name) const -{ - const DOutputSocket &socket = *outputs_[index]; - BLI_assert(socket.name() == expected_name); - UNUSED_VARS_NDEBUG(expected_name); - return socket; -} - -inline uint DNode::id() const -{ - return id_; -} - -inline PointerRNA *DNode::rna() const -{ - return node_ref_->rna(); -} - -inline StringRefNull DNode::idname() const -{ - return node_ref_->idname(); -} - -inline StringRefNull DNode::name() const -{ - return node_ref_->name(); -} - -/* -------------------------------------------------------------------- - * DParentNode inline methods. - */ - -inline const DParentNode *DParentNode::parent() const -{ - return parent_; -} - -inline const NodeRef &DParentNode::node_ref() const -{ - return *node_ref_; -} - -inline uint DParentNode::id() const -{ - return id_; -} - -/* -------------------------------------------------------------------- - * DerivedNodeTree inline methods. - */ - -inline Span<const DNode *> DerivedNodeTree::nodes() const -{ - return nodes_by_id_; -} - -inline Span<const DNode *> DerivedNodeTree::nodes_by_type(StringRefNull idname) const -{ - const bNodeType *nodetype = nodeTypeFind(idname.data()); - return this->nodes_by_type(nodetype); -} - -inline Span<const DNode *> DerivedNodeTree::nodes_by_type(const bNodeType *nodetype) const -{ - const Vector<DNode *> *nodes = nodes_by_type_.lookup_ptr(nodetype); - if (nodes == nullptr) { - return {}; - } - else { - return *nodes; - } -} - -inline Span<const DSocket *> DerivedNodeTree::sockets() const -{ - return sockets_by_id_; -} - -inline Span<const DInputSocket *> DerivedNodeTree::input_sockets() const -{ - return input_sockets_; -} - -inline Span<const DOutputSocket *> DerivedNodeTree::output_sockets() const -{ - return output_sockets_; -} - -inline Span<const DGroupInput *> DerivedNodeTree::group_inputs() const -{ - return group_inputs_; -} - -} // namespace blender::bke - -#endif /* __BKE_DERIVED_NODE_TREE_HH__ */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index acd4c75befd..1d01436c7e4 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -106,18 +106,18 @@ typedef struct bNodeSocketTemplate { * However, achieving this requires quite a few changes currently. */ #ifdef __cplusplus namespace blender { -namespace bke { +namespace nodes { class SocketMFNetworkBuilder; class NodeMFNetworkBuilder; -} // namespace bke +} // namespace nodes namespace fn { class MFDataType; } } // namespace blender -using NodeExpandInMFNetworkFunction = void (*)(blender::bke::NodeMFNetworkBuilder &builder); +using NodeExpandInMFNetworkFunction = void (*)(blender::nodes::NodeMFNetworkBuilder &builder); using SocketGetMFDataTypeFunction = blender::fn::MFDataType (*)(); -using SocketExpandInMFNetworkFunction = void (*)(blender::bke::SocketMFNetworkBuilder &builder); +using SocketExpandInMFNetworkFunction = void (*)(blender::nodes::SocketMFNetworkBuilder &builder); #else typedef void *NodeExpandInMFNetworkFunction; diff --git a/source/blender/blenkernel/BKE_node_tree_multi_function.hh b/source/blender/blenkernel/BKE_node_tree_multi_function.hh deleted file mode 100644 index 7219eb1726a..00000000000 --- a/source/blender/blenkernel/BKE_node_tree_multi_function.hh +++ /dev/null @@ -1,390 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __BKE_NODE_TREE_FUNCTION_HH__ -#define __BKE_NODE_TREE_FUNCTION_HH__ - -/** \file - * \ingroup bke - * - * This file allows you to generate a multi-function network from a user-generated node tree. - */ - -#include "FN_multi_function_builder.hh" -#include "FN_multi_function_network.hh" - -#include "BKE_derived_node_tree.hh" - -#include "BLI_resource_collector.hh" - -namespace blender { -namespace bke { - -/* Maybe this should be moved to BKE_node.h. */ -inline bool is_multi_function_data_socket(const bNodeSocket *bsocket) -{ - if (bsocket->typeinfo->get_mf_data_type != nullptr) { - BLI_assert(bsocket->typeinfo->expand_in_mf_network != nullptr); - return true; - } - return false; -} - -/** - * A MFNetworkTreeMap maps various components of a bke::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. - */ -class MFNetworkTreeMap { - private: - /** - * Store by id instead of using a hash table to avoid unnecessary hash table lookups. - * - * Input sockets in a node tree can have multiple corresponding sockets in the generated - * MFNetwork. This is because nodes are allowed to expand into multiple multi-function nodes. - */ - const DerivedNodeTree &tree_; - fn::MFNetwork &network_; - Array<Vector<fn::MFSocket *, 1>> sockets_by_dsocket_id_; - Array<fn::MFOutputSocket *> socket_by_group_input_id_; - - 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) - { - } - - const DerivedNodeTree &tree() const - { - return tree_; - } - - const fn::MFNetwork &network() const - { - return network_; - } - - fn::MFNetwork &network() - { - return network_; - } - - 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); - } - - void add(const DInputSocket &dsocket, fn::MFInputSocket &socket) - { - sockets_by_dsocket_id_[dsocket.id()].append(&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); - } - - void add(Span<const DInputSocket *> dsockets, Span<fn::MFInputSocket *> sockets) - { - assert_same_size(dsockets, sockets); - for (uint i : dsockets.index_range()) { - this->add(*dsockets[i], *sockets[i]); - } - } - - void add(Span<const DOutputSocket *> dsockets, Span<fn::MFOutputSocket *> sockets) - { - assert_same_size(dsockets, sockets); - for (uint i : dsockets.index_range()) { - this->add(*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(), node.inputs()); - this->add_try_match(dnode.outputs(), node.outputs()); - } - - void add_try_match(Span<const DSocket *> dsockets, Span<fn::MFSocket *> sockets) - { - uint used_sockets = 0; - for (const DSocket *dsocket : dsockets) { - if (!dsocket->is_available()) { - continue; - } - if (!is_multi_function_data_socket(dsocket->bsocket())) { - continue; - } - fn::MFSocket *socket = sockets[used_sockets]; - this->add(*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(); - } - - Span<fn::MFInputSocket *> lookup(const DInputSocket &dsocket) - { - return sockets_by_dsocket_id_[dsocket.id()].as_span().cast<fn::MFInputSocket *>(); - } - - fn::MFInputSocket &lookup_dummy(const DInputSocket &dsocket) - { - Span<fn::MFInputSocket *> sockets = this->lookup(dsocket); - BLI_assert(sockets.size() == 1); - fn::MFInputSocket &socket = *sockets[0]; - BLI_assert(socket.node().is_dummy()); - return socket; - } - - fn::MFOutputSocket &lookup_dummy(const DOutputSocket &dsocket) - { - fn::MFOutputSocket &socket = this->lookup(dsocket); - BLI_assert(socket.node().is_dummy()); - return socket; - } - - bool is_mapped(const DSocket &dsocket) const - { - return sockets_by_dsocket_id_[dsocket.id()].size() >= 1; - } -}; - -/** - * This data is necessary throughout the generation of a MFNetwork from a node tree. - */ -struct CommonMFNetworkBuilderData { - ResourceCollector &resources; - fn::MFNetwork &network; - MFNetworkTreeMap &network_map; - const DerivedNodeTree &tree; -}; - -class MFNetworkBuilderBase { - protected: - CommonMFNetworkBuilderData &common_; - - public: - MFNetworkBuilderBase(CommonMFNetworkBuilderData &common) : common_(common) - { - } - - /** - * Returns the network that is currently being built. - */ - fn::MFNetwork &network() - { - return common_.network; - } - - /** - * Returns the map between the node tree and the multi-function network that is being built. - */ - MFNetworkTreeMap &network_map() - { - return common_.network_map; - } - - /** - * Returns a resource collector that will only be destructed after the multi-function network is - * destructed. - */ - ResourceCollector &resources() - { - return common_.resources; - } - - /** - * Constructs a new function that will live at least as long as the MFNetwork. - */ - template<typename T, typename... Args> T &construct_fn(Args &&... args) - { - BLI_STATIC_ASSERT((std::is_base_of_v<fn::MultiFunction, T>), ""); - void *buffer = common_.resources.linear_allocator().allocate(sizeof(T), alignof(T)); - T *fn = new (buffer) T(std::forward<Args>(args)...); - common_.resources.add(destruct_ptr<T>(fn), fn->name().data()); - return *fn; - } -}; - -/** - * This class is used by socket implementations to define how an unlinked input socket is handled - * in a multi-function network. - */ -class SocketMFNetworkBuilder : public MFNetworkBuilderBase { - private: - const DSocket *dsocket_ = nullptr; - const DGroupInput *group_input_ = nullptr; - bNodeSocket *bsocket_; - fn::MFOutputSocket *built_socket_ = nullptr; - - public: - SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DSocket &dsocket) - : MFNetworkBuilderBase(common), dsocket_(&dsocket), bsocket_(dsocket.bsocket()) - { - } - - SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DGroupInput &group_input) - : MFNetworkBuilderBase(common), group_input_(&group_input), bsocket_(group_input.bsocket()) - { - } - - /** - * Returns the socket that is currently being built. - */ - bNodeSocket &bsocket() - { - return *bsocket_; - } - - /** - * Utility method that returns bsocket->default_value for the current socket. - */ - template<typename T> T *socket_default_value() - { - return (T *)bsocket_->default_value; - } - - /** - * Builds a function node for that socket that outputs the given constant value. - */ - template<typename T> void set_constant_value(T value) - { - const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_Constant<T>>(std::move(value)); - this->set_generator_fn(fn); - } - - /** - * Uses the first output of the given multi-function as value of the socket. - */ - void set_generator_fn(const fn::MultiFunction &fn) - { - fn::MFFunctionNode &node = common_.network.add_function(fn); - this->set_socket(node.output(0)); - } - - /** - * Define a multi-function socket that outputs the value of the bsocket. - */ - void set_socket(fn::MFOutputSocket &socket) - { - built_socket_ = &socket; - } - - fn::MFOutputSocket *built_socket() - { - return built_socket_; - } -}; - -/** - * This class is used by node implementations to define how a user-level node expands into - * multi-function nodes internally. - */ -class NodeMFNetworkBuilder : public MFNetworkBuilderBase { - private: - const DNode &dnode_; - - public: - NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &dnode) - : MFNetworkBuilderBase(common), dnode_(dnode) - { - } - - /** - * Tells the builder to build a function that corresponds to the node that is being built. It - * will try to match up sockets. - */ - template<typename T, typename... Args> T &construct_and_set_matching_fn(Args &&... args) - { - T &function = this->construct_fn<T>(std::forward<Args>(args)...); - this->set_matching_fn(function); - return function; - } - - const fn::MultiFunction &get_not_implemented_fn() - { - return this->get_default_fn("Not Implemented (" + dnode_.name() + ")"); - } - - const fn::MultiFunction &get_default_fn(StringRef name); - - const void set_not_implemented() - { - this->set_matching_fn(this->get_not_implemented_fn()); - } - - /** - * Tells the builder that the given function corresponds to the node that is being built. It will - * try to match up sockets. For that it skips unavailable and non-data sockets. - */ - void set_matching_fn(const fn::MultiFunction &function) - { - fn::MFFunctionNode &node = common_.network.add_function(function); - common_.network_map.add_try_match(dnode_, node); - } - - /** - * Returns the node that is currently being built. - */ - bNode &bnode() - { - return *dnode_.node_ref().bnode(); - } - - /** - * Returns the node that is currently being built. - */ - const DNode &dnode() const - { - return dnode_; - } -}; - -MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network, - const DerivedNodeTree &tree, - ResourceCollector &resources); - -} // namespace bke -} // namespace blender - -#endif /* __BKE_NODE_TREE_FUNCTION_HH__ */ diff --git a/source/blender/blenkernel/BKE_node_tree_ref.hh b/source/blender/blenkernel/BKE_node_tree_ref.hh deleted file mode 100644 index b1e8904d718..00000000000 --- a/source/blender/blenkernel/BKE_node_tree_ref.hh +++ /dev/null @@ -1,445 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __BKE_NODE_TREE_REF_HH__ -#define __BKE_NODE_TREE_REF_HH__ - -/** \file - * \ingroup bke - * - * NodeTreeRef makes querying information about a bNodeTree more efficient. It is an immutable data - * structure. It should not be used after anymore, after the underlying node tree changed. - * - * The following queries are supported efficiently: - * - socket -> index of socket - * - socket -> directly linked sockets - * - socket -> linked sockets when skipping reroutes - * - socket -> node - * - socket/node -> rna pointer - * - node -> inputs/outputs - * - node -> tree - * - tree -> all nodes - * - tree -> all (input/output) sockets - * - idname -> nodes - * - * Every socket has an id. The id-space is shared between input and output sockets. - * When storing data per socket, it is often better to use the id as index into an array, instead - * of a hash table. - * - * Every node has an id as well. The same rule regarding hash tables applies. - * - * There is an utility to export this data structure as graph in dot format. - */ - -#include "BLI_array.hh" -#include "BLI_linear_allocator.hh" -#include "BLI_map.hh" -#include "BLI_string_ref.hh" -#include "BLI_timeit.hh" -#include "BLI_utility_mixins.hh" -#include "BLI_vector.hh" - -#include "BKE_node.h" - -#include "DNA_node_types.h" - -#include "RNA_access.h" - -namespace blender::bke { - -class SocketRef; -class InputSocketRef; -class OutputSocketRef; -class NodeRef; -class NodeTreeRef; - -class SocketRef : NonCopyable, NonMovable { - protected: - NodeRef *node_; - bNodeSocket *bsocket_; - bool is_input_; - uint id_; - uint index_; - PointerRNA rna_; - Vector<SocketRef *> linked_sockets_; - Vector<SocketRef *> directly_linked_sockets_; - - friend NodeTreeRef; - - public: - Span<const SocketRef *> linked_sockets() const; - Span<const SocketRef *> directly_linked_sockets() const; - bool is_linked() const; - - const NodeRef &node() const; - const NodeTreeRef &tree() const; - - uint id() const; - uint index() const; - - bool is_input() const; - bool is_output() const; - - const SocketRef &as_base() const; - const InputSocketRef &as_input() const; - const OutputSocketRef &as_output() const; - - PointerRNA *rna() const; - - StringRefNull idname() const; - StringRefNull name() const; - - bNodeSocket *bsocket() const; - bNode *bnode() const; - bNodeTree *btree() const; -}; - -class InputSocketRef final : public SocketRef { - public: - Span<const OutputSocketRef *> linked_sockets() const; - Span<const OutputSocketRef *> directly_linked_sockets() const; -}; - -class OutputSocketRef final : public SocketRef { - public: - Span<const InputSocketRef *> linked_sockets() const; - Span<const InputSocketRef *> directly_linked_sockets() const; -}; - -class NodeRef : NonCopyable, NonMovable { - private: - NodeTreeRef *tree_; - bNode *bnode_; - PointerRNA rna_; - uint id_; - Vector<InputSocketRef *> inputs_; - Vector<OutputSocketRef *> outputs_; - - friend NodeTreeRef; - - public: - const NodeTreeRef &tree() const; - - Span<const InputSocketRef *> inputs() const; - Span<const OutputSocketRef *> outputs() const; - - const InputSocketRef &input(uint index) const; - const OutputSocketRef &output(uint index) const; - - bNode *bnode() const; - bNodeTree *btree() const; - - PointerRNA *rna() const; - StringRefNull idname() const; - StringRefNull name() const; - - uint id() const; - - bool is_reroute_node() const; - bool is_group_node() const; - bool is_group_input_node() const; - bool is_group_output_node() const; -}; - -class NodeTreeRef : NonCopyable, NonMovable { - private: - LinearAllocator<> allocator_; - bNodeTree *btree_; - Vector<NodeRef *> nodes_by_id_; - Vector<SocketRef *> sockets_by_id_; - Vector<InputSocketRef *> input_sockets_; - Vector<OutputSocketRef *> output_sockets_; - Map<const bNodeType *, Vector<NodeRef *>> nodes_by_type_; - - public: - NodeTreeRef(bNodeTree *btree); - ~NodeTreeRef(); - - Span<const NodeRef *> nodes() const; - Span<const NodeRef *> nodes_by_type(StringRefNull idname) const; - Span<const NodeRef *> nodes_by_type(const bNodeType *nodetype) const; - - Span<const SocketRef *> sockets() const; - Span<const InputSocketRef *> input_sockets() const; - Span<const OutputSocketRef *> output_sockets() const; - - bNodeTree *btree() const; - - std::string to_dot() const; - - private: - /* Utility functions used during construction. */ - 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); -}; - -/* -------------------------------------------------------------------- - * SocketRef inline methods. - */ - -inline Span<const SocketRef *> SocketRef::linked_sockets() const -{ - return linked_sockets_; -} - -inline Span<const SocketRef *> SocketRef::directly_linked_sockets() const -{ - return directly_linked_sockets_; -} - -inline bool SocketRef::is_linked() const -{ - return linked_sockets_.size() > 0; -} - -inline const NodeRef &SocketRef::node() const -{ - return *node_; -} - -inline const NodeTreeRef &SocketRef::tree() const -{ - return node_->tree(); -} - -inline uint SocketRef::id() const -{ - return id_; -} - -inline uint SocketRef::index() const -{ - return index_; -} - -inline bool SocketRef::is_input() const -{ - return is_input_; -} - -inline bool SocketRef::is_output() const -{ - return !is_input_; -} - -inline const SocketRef &SocketRef::as_base() const -{ - return *this; -} - -inline const InputSocketRef &SocketRef::as_input() const -{ - BLI_assert(this->is_input()); - return *(const InputSocketRef *)this; -} - -inline const OutputSocketRef &SocketRef::as_output() const -{ - BLI_assert(this->is_output()); - return *(const OutputSocketRef *)this; -} - -inline PointerRNA *SocketRef::rna() const -{ - return const_cast<PointerRNA *>(&rna_); -} - -inline StringRefNull SocketRef::idname() const -{ - return bsocket_->idname; -} - -inline StringRefNull SocketRef::name() const -{ - return bsocket_->name; -} - -inline bNodeSocket *SocketRef::bsocket() const -{ - return bsocket_; -} - -inline bNode *SocketRef::bnode() const -{ - return node_->bnode(); -} - -inline bNodeTree *SocketRef::btree() const -{ - return node_->btree(); -} - -/* -------------------------------------------------------------------- - * InputSocketRef inline methods. - */ - -inline Span<const OutputSocketRef *> InputSocketRef::linked_sockets() const -{ - return linked_sockets_.as_span().cast<const OutputSocketRef *>(); -} - -inline Span<const OutputSocketRef *> InputSocketRef::directly_linked_sockets() const -{ - return directly_linked_sockets_.as_span().cast<const OutputSocketRef *>(); -} - -/* -------------------------------------------------------------------- - * OutputSocketRef inline methods. - */ - -inline Span<const InputSocketRef *> OutputSocketRef::linked_sockets() const -{ - return linked_sockets_.as_span().cast<const InputSocketRef *>(); -} - -inline Span<const InputSocketRef *> OutputSocketRef::directly_linked_sockets() const -{ - return directly_linked_sockets_.as_span().cast<const InputSocketRef *>(); -} - -/* -------------------------------------------------------------------- - * NodeRef inline methods. - */ - -inline const NodeTreeRef &NodeRef::tree() const -{ - return *tree_; -} - -inline Span<const InputSocketRef *> NodeRef::inputs() const -{ - return inputs_; -} - -inline Span<const OutputSocketRef *> NodeRef::outputs() const -{ - return outputs_; -} - -inline const InputSocketRef &NodeRef::input(uint index) const -{ - return *inputs_[index]; -} - -inline const OutputSocketRef &NodeRef::output(uint index) const -{ - return *outputs_[index]; -} - -inline bNode *NodeRef::bnode() const -{ - return bnode_; -} - -inline bNodeTree *NodeRef::btree() const -{ - return tree_->btree(); -} - -inline PointerRNA *NodeRef::rna() const -{ - return const_cast<PointerRNA *>(&rna_); -} - -inline StringRefNull NodeRef::idname() const -{ - return bnode_->idname; -} - -inline StringRefNull NodeRef::name() const -{ - return bnode_->name; -} - -inline uint NodeRef::id() const -{ - return id_; -} - -inline bool NodeRef::is_reroute_node() const -{ - return bnode_->type == NODE_REROUTE; -} - -inline bool NodeRef::is_group_node() const -{ - return bnode_->type == NODE_GROUP; -} - -inline bool NodeRef::is_group_input_node() const -{ - return bnode_->type == NODE_GROUP_INPUT; -} - -inline bool NodeRef::is_group_output_node() const -{ - return bnode_->type == NODE_GROUP_OUTPUT; -} - -/* -------------------------------------------------------------------- - * NodeRef inline methods. - */ - -inline Span<const NodeRef *> NodeTreeRef::nodes() const -{ - return nodes_by_id_; -} - -inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(StringRefNull idname) const -{ - const bNodeType *nodetype = nodeTypeFind(idname.data()); - return this->nodes_by_type(nodetype); -} - -inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(const bNodeType *nodetype) const -{ - const Vector<NodeRef *> *nodes = nodes_by_type_.lookup_ptr(nodetype); - if (nodes == nullptr) { - return {}; - } - else { - return *nodes; - } -} - -inline Span<const SocketRef *> NodeTreeRef::sockets() const -{ - return sockets_by_id_; -} - -inline Span<const InputSocketRef *> NodeTreeRef::input_sockets() const -{ - return input_sockets_; -} - -inline Span<const OutputSocketRef *> NodeTreeRef::output_sockets() const -{ - return output_sockets_; -} - -inline bNodeTree *NodeTreeRef::btree() const -{ - return btree_; -} - -} // namespace blender::bke - -#endif /* __BKE_NODE_TREE_REF_HH__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 46cf8e5b9b3..800fa7d18ee 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -107,7 +107,6 @@ set(SRC intern/customdata_file.c intern/data_transfer.c intern/deform.c - intern/derived_node_tree.cc intern/displist.c intern/displist_tangent.c intern/dynamicpaint.c @@ -188,8 +187,6 @@ set(SRC intern/multires_unsubdivide.c intern/nla.c intern/node.c - intern/node_tree_multi_function.cc - intern/node_tree_ref.cc intern/object.c intern/object_deform.c intern/object_dupli.c @@ -298,7 +295,6 @@ set(SRC BKE_customdata_file.h BKE_data_transfer.h BKE_deform.h - BKE_derived_node_tree.hh BKE_displist.h BKE_displist_tangent.h BKE_duplilist.h @@ -359,8 +355,6 @@ set(SRC BKE_multires.h BKE_nla.h BKE_node.h - BKE_node_tree_multi_function.hh - BKE_node_tree_ref.hh BKE_object.h BKE_object_deform.h BKE_object_facemap.h diff --git a/source/blender/blenkernel/intern/derived_node_tree.cc b/source/blender/blenkernel/intern/derived_node_tree.cc deleted file mode 100644 index 01317eeb5ce..00000000000 --- a/source/blender/blenkernel/intern/derived_node_tree.cc +++ /dev/null @@ -1,441 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "BKE_derived_node_tree.hh" - -#include "BLI_dot_export.hh" - -#define UNINITIALIZED_ID UINT32_MAX - -namespace blender::bke { - -static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree *btree) -{ - return *node_tree_refs.lookup_or_add_cb(btree, - [&]() { return std::make_unique<NodeTreeRef>(btree); }); -} - -DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : btree_(btree) -{ - const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree); - - Vector<DNode *> all_nodes; - Vector<DGroupInput *> all_group_inputs; - Vector<DParentNode *> all_parent_nodes; - - this->insert_nodes_and_links_in_id_order(main_tree_ref, nullptr, all_nodes); - this->expand_groups(all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs); - this->remove_expanded_group_interfaces(all_nodes); - this->remove_unused_group_inputs(all_group_inputs); - this->store_in_this_and_init_ids( - std::move(all_nodes), std::move(all_group_inputs), std::move(all_parent_nodes)); -} - -BLI_NOINLINE void DerivedNodeTree::insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref, - DParentNode *parent, - Vector<DNode *> &all_nodes) -{ - Array<DSocket *, 64> sockets_map(tree_ref.sockets().size()); - - /* Insert nodes. */ - for (const NodeRef *node_ref : tree_ref.nodes()) { - DNode &node = this->create_node(*node_ref, parent, sockets_map); - all_nodes.append(&node); - } - - /* Insert links. */ - for (const NodeRef *node_ref : tree_ref.nodes()) { - for (const InputSocketRef *to_socket_ref : node_ref->inputs()) { - DInputSocket *to_socket = (DInputSocket *)sockets_map[to_socket_ref->id()]; - for (const OutputSocketRef *from_socket_ref : to_socket_ref->linked_sockets()) { - DOutputSocket *from_socket = (DOutputSocket *)sockets_map[from_socket_ref->id()]; - to_socket->linked_sockets_.append(from_socket); - from_socket->linked_sockets_.append(to_socket); - } - } - } -} - -DNode &DerivedNodeTree::create_node(const NodeRef &node_ref, - DParentNode *parent, - MutableSpan<DSocket *> r_sockets_map) -{ - DNode &node = *allocator_.construct<DNode>(); - node.node_ref_ = &node_ref; - node.parent_ = parent; - node.id_ = UNINITIALIZED_ID; - - node.inputs_ = allocator_.construct_elements_and_pointer_array<DInputSocket>( - node_ref.inputs().size()); - node.outputs_ = allocator_.construct_elements_and_pointer_array<DOutputSocket>( - node_ref.outputs().size()); - - for (uint i : node.inputs_.index_range()) { - const InputSocketRef &socket_ref = node_ref.input(i); - DInputSocket &socket = *node.inputs_[i]; - - socket.id_ = UNINITIALIZED_ID; - socket.node_ = &node; - socket.socket_ref_ = &socket_ref; - - r_sockets_map[socket_ref.id()] = &socket; - } - - for (uint i : node.outputs_.index_range()) { - const OutputSocketRef &socket_ref = node_ref.output(i); - DOutputSocket &socket = *node.outputs_[i]; - - socket.id_ = UNINITIALIZED_ID; - socket.node_ = &node; - socket.socket_ref_ = &socket_ref; - - r_sockets_map[socket_ref.id()] = &socket; - } - - return node; -} - -BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes, - Vector<DGroupInput *> &all_group_inputs, - Vector<DParentNode *> &all_parent_nodes, - NodeTreeRefMap &node_tree_refs) -{ - for (uint i = 0; i < all_nodes.size(); i++) { - DNode &node = *all_nodes[i]; - if (node.node_ref_->is_group_node()) { - this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs); - } - } -} - -BLI_NOINLINE void DerivedNodeTree::expand_group_node(DNode &group_node, - Vector<DNode *> &all_nodes, - Vector<DGroupInput *> &all_group_inputs, - Vector<DParentNode *> &all_parent_nodes, - NodeTreeRefMap &node_tree_refs) -{ - const NodeRef &group_node_ref = *group_node.node_ref_; - BLI_assert(group_node_ref.is_group_node()); - - bNodeTree *btree = (bNodeTree *)group_node_ref.bnode()->id; - if (btree == nullptr) { - return; - } - - const NodeTreeRef &group_ref = get_tree_ref(node_tree_refs, btree); - - DParentNode &parent = *allocator_.construct<DParentNode>(); - parent.id_ = all_parent_nodes.append_and_get_index(&parent); - parent.parent_ = group_node.parent_; - parent.node_ref_ = &group_node_ref; - - this->insert_nodes_and_links_in_id_order(group_ref, &parent, all_nodes); - Span<DNode *> new_nodes_by_id = all_nodes.as_span().take_back(group_ref.nodes().size()); - - this->create_group_inputs_for_unlinked_inputs(group_node, all_group_inputs); - this->relink_group_inputs(group_ref, new_nodes_by_id, group_node); - this->relink_group_outputs(group_ref, new_nodes_by_id, group_node); -} - -BLI_NOINLINE void DerivedNodeTree::create_group_inputs_for_unlinked_inputs( - DNode &node, Vector<DGroupInput *> &all_group_inputs) -{ - for (DInputSocket *input_socket : node.inputs_) { - if (input_socket->is_linked()) { - continue; - } - - DGroupInput &group_input = *allocator_.construct<DGroupInput>(); - group_input.id_ = UNINITIALIZED_ID; - group_input.socket_ref_ = &input_socket->socket_ref(); - group_input.parent_ = node.parent_; - - group_input.linked_sockets_.append(input_socket); - input_socket->linked_group_inputs_.append(&group_input); - all_group_inputs.append(&group_input); - } -} - -BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_ref, - Span<DNode *> nodes_by_id, - DNode &group_node) -{ - Span<const NodeRef *> node_refs = group_ref.nodes_by_type("NodeGroupInput"); - if (node_refs.size() == 0) { - return; - } - /* TODO: Pick correct group input node if there are more than one. */ - const NodeRef &input_node_ref = *node_refs[0]; - DNode &input_node = *nodes_by_id[input_node_ref.id()]; - - uint input_amount = group_node.inputs().size(); - BLI_assert(input_amount == input_node_ref.outputs().size() - 1); - - for (uint input_index : IndexRange(input_amount)) { - DInputSocket *outside_group = group_node.inputs_[input_index]; - DOutputSocket *inside_group = input_node.outputs_[input_index]; - - for (DOutputSocket *outside_connected : outside_group->linked_sockets_) { - outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group); - } - - for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) { - outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group); - } - - for (DInputSocket *inside_connected : inside_group->linked_sockets_) { - inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group); - - for (DOutputSocket *outside_connected : outside_group->linked_sockets_) { - inside_connected->linked_sockets_.append(outside_connected); - outside_connected->linked_sockets_.append(inside_connected); - } - - for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) { - inside_connected->linked_group_inputs_.append(outside_connected); - outside_connected->linked_sockets_.append(inside_connected); - } - } - - inside_group->linked_sockets_.clear(); - outside_group->linked_sockets_.clear(); - outside_group->linked_group_inputs_.clear(); - } -} - -BLI_NOINLINE void DerivedNodeTree::relink_group_outputs(const NodeTreeRef &group_ref, - Span<DNode *> nodes_by_id, - DNode &group_node) -{ - Span<const NodeRef *> node_refs = group_ref.nodes_by_type("NodeGroupOutput"); - if (node_refs.size() == 0) { - return; - } - /* TODO: Pick correct group output node if there are more than one. */ - const NodeRef &output_node_ref = *node_refs[0]; - DNode &output_node = *nodes_by_id[output_node_ref.id()]; - - uint output_amount = group_node.outputs().size(); - BLI_assert(output_amount == output_node_ref.inputs().size() - 1); - - for (uint output_index : IndexRange(output_amount)) { - DOutputSocket *outside_group = group_node.outputs_[output_index]; - DInputSocket *inside_group = output_node.inputs_[output_index]; - - for (DInputSocket *outside_connected : outside_group->linked_sockets_) { - outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group); - } - - for (DOutputSocket *inside_connected : inside_group->linked_sockets_) { - inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group); - - for (DInputSocket *outside_connected : outside_group->linked_sockets_) { - inside_connected->linked_sockets_.append(outside_connected); - outside_connected->linked_sockets_.append(inside_connected); - } - } - - for (DGroupInput *inside_connected : inside_group->linked_group_inputs_) { - inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group); - - for (DInputSocket *outside_connected : outside_group->linked_sockets_) { - inside_connected->linked_sockets_.append(outside_connected); - outside_connected->linked_group_inputs_.append(inside_connected); - } - } - - outside_group->linked_sockets_.clear(); - inside_group->linked_sockets_.clear(); - } -} - -BLI_NOINLINE void DerivedNodeTree::remove_expanded_group_interfaces(Vector<DNode *> &all_nodes) -{ - int index = 0; - while (index < all_nodes.size()) { - DNode &node = *all_nodes[index]; - const NodeRef &node_ref = *node.node_ref_; - if (node_ref.is_group_node() || - (node.parent_ != nullptr && - (node_ref.is_group_input_node() || node_ref.is_group_output_node()))) { - all_nodes.remove_and_reorder(index); - node.destruct_with_sockets(); - } - else { - index++; - } - } -} - -BLI_NOINLINE void DerivedNodeTree::remove_unused_group_inputs( - Vector<DGroupInput *> &all_group_inputs) -{ - int index = 0; - while (index < all_group_inputs.size()) { - DGroupInput &group_input = *all_group_inputs[index]; - if (group_input.linked_sockets_.is_empty()) { - all_group_inputs.remove_and_reorder(index); - group_input.~DGroupInput(); - } - else { - index++; - } - } -} - -void DNode::destruct_with_sockets() -{ - for (DInputSocket *socket : inputs_) { - socket->~DInputSocket(); - } - for (DOutputSocket *socket : outputs_) { - socket->~DOutputSocket(); - } - this->~DNode(); -} - -BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids( - Vector<DNode *> &&all_nodes, - Vector<DGroupInput *> &&all_group_inputs, - Vector<DParentNode *> &&all_parent_nodes) -{ - nodes_by_id_ = std::move(all_nodes); - group_inputs_ = std::move(all_group_inputs); - parent_nodes_ = std::move(all_parent_nodes); - - for (uint node_index : nodes_by_id_.index_range()) { - DNode *node = nodes_by_id_[node_index]; - node->id_ = node_index; - - const bNodeType *nodetype = node->node_ref_->bnode()->typeinfo; - nodes_by_type_.lookup_or_add_default(nodetype).append(node); - - for (DInputSocket *socket : node->inputs_) { - socket->id_ = sockets_by_id_.append_and_get_index(socket); - input_sockets_.append(socket); - } - for (DOutputSocket *socket : node->outputs_) { - socket->id_ = sockets_by_id_.append_and_get_index(socket); - output_sockets_.append(socket); - } - } - - for (uint i : group_inputs_.index_range()) { - group_inputs_[i]->id_ = i; - } -} - -DerivedNodeTree::~DerivedNodeTree() -{ - for (DInputSocket *socket : input_sockets_) { - socket->~DInputSocket(); - } - for (DOutputSocket *socket : output_sockets_) { - socket->~DOutputSocket(); - } - for (DNode *node : nodes_by_id_) { - node->~DNode(); - } - for (DGroupInput *group_input : group_inputs_) { - group_input->~DGroupInput(); - } - for (DParentNode *parent : parent_nodes_) { - parent->~DParentNode(); - } -} - -static dot::Cluster *get_cluster_for_parent(dot::DirectedGraph &graph, - Map<const DParentNode *, dot::Cluster *> &clusters, - const DParentNode *parent) -{ - if (parent == nullptr) { - return nullptr; - } - return clusters.lookup_or_add_cb(parent, [&]() { - dot::Cluster *parent_cluster = get_cluster_for_parent(graph, clusters, parent->parent()); - bNodeTree *btree = (bNodeTree *)parent->node_ref().bnode()->id; - dot::Cluster *new_cluster = &graph.new_cluster(parent->node_ref().name() + " / " + - StringRef(btree->id.name + 2)); - new_cluster->set_parent_cluster(parent_cluster); - return new_cluster; - }); -} - -std::string DerivedNodeTree::to_dot() const -{ - dot::DirectedGraph digraph; - digraph.set_rankdir(dot::Attr_rankdir::LeftToRight); - - Map<const DNode *, dot::NodeWithSocketsRef> dot_nodes; - Map<const DGroupInput *, dot::NodeWithSocketsRef> dot_group_inputs; - Map<const DParentNode *, dot::Cluster *> dot_clusters; - - for (const DNode *node : nodes_by_id_) { - dot::Node &dot_node = digraph.new_node(""); - dot_node.set_background_color("white"); - - Vector<std::string> input_names; - for (const DInputSocket *socket : node->inputs()) { - input_names.append(socket->name()); - } - Vector<std::string> output_names; - for (const DOutputSocket *socket : node->outputs()) { - output_names.append(socket->name()); - } - - dot_nodes.add_new(node, - dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names)); - - dot::Cluster *cluster = get_cluster_for_parent(digraph, dot_clusters, node->parent()); - dot_node.set_parent_cluster(cluster); - } - - for (const DGroupInput *group_input : group_inputs_) { - dot::Node &dot_node = digraph.new_node(""); - dot_node.set_background_color("white"); - - std::string group_input_name = group_input->name(); - dot_group_inputs.add_new( - group_input, dot::NodeWithSocketsRef(dot_node, "Group Input", {}, {group_input_name})); - - dot::Cluster *cluster = get_cluster_for_parent(digraph, dot_clusters, group_input->parent()); - dot_node.set_parent_cluster(cluster); - } - - for (const DNode *to_node : nodes_by_id_) { - dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(to_node); - - for (const DInputSocket *to_socket : to_node->inputs()) { - for (const DOutputSocket *from_socket : to_socket->linked_sockets()) { - const DNode *from_node = &from_socket->node(); - dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(from_node); - - digraph.new_edge(from_dot_node.output(from_socket->index()), - to_dot_node.input(to_socket->index())); - } - for (const DGroupInput *group_input : to_socket->linked_group_inputs()) { - dot::NodeWithSocketsRef &from_dot_node = dot_group_inputs.lookup(group_input); - - digraph.new_edge(from_dot_node.output(0), to_dot_node.input(to_socket->index())); - } - } - } - - digraph.set_random_cluster_bgcolors(); - return digraph.to_dot_string(); -} - -} // namespace blender::bke diff --git a/source/blender/blenkernel/intern/node_tree_multi_function.cc b/source/blender/blenkernel/intern/node_tree_multi_function.cc deleted file mode 100644 index 537ec056126..00000000000 --- a/source/blender/blenkernel/intern/node_tree_multi_function.cc +++ /dev/null @@ -1,346 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "BKE_node_tree_multi_function.hh" - -#include "BLI_color.hh" -#include "BLI_float3.hh" - -namespace blender { -namespace bke { - -/* Maybe this should be moved to BKE_node.h. */ -static std::optional<fn::MFDataType> try_get_multi_function_data_type_of_socket( - const bNodeSocket *bsocket) -{ - if (bsocket->typeinfo->get_mf_data_type == nullptr) { - return {}; - } - return bsocket->typeinfo->get_mf_data_type(); -} - -const fn::MultiFunction &NodeMFNetworkBuilder::get_default_fn(StringRef name) -{ - Vector<fn::MFDataType, 10> input_types; - Vector<fn::MFDataType, 10> output_types; - - for (const DInputSocket *dsocket : dnode_.inputs()) { - if (dsocket->is_available()) { - std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket( - dsocket->bsocket()); - if (data_type.has_value()) { - input_types.append(*data_type); - } - } - } - for (const DOutputSocket *dsocket : dnode_.outputs()) { - if (dsocket->is_available()) { - std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket( - dsocket->bsocket()); - if (data_type.has_value()) { - output_types.append(*data_type); - } - } - } - - const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_DefaultOutput>( - name, input_types, output_types); - return fn; -} - -static void insert_dummy_node(CommonMFNetworkBuilderData &common, const DNode &dnode) -{ - constexpr uint stack_capacity = 10; - - Vector<fn::MFDataType, stack_capacity> input_types; - Vector<StringRef, stack_capacity> input_names; - Vector<const DInputSocket *, stack_capacity> input_dsockets; - - for (const DInputSocket *dsocket : dnode.inputs()) { - if (dsocket->is_available()) { - std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket( - dsocket->bsocket()); - if (data_type.has_value()) { - input_types.append(*data_type); - input_names.append(dsocket->name()); - input_dsockets.append(dsocket); - } - } - } - - Vector<fn::MFDataType, stack_capacity> output_types; - Vector<StringRef, stack_capacity> output_names; - Vector<const DOutputSocket *, stack_capacity> output_dsockets; - - for (const DOutputSocket *dsocket : dnode.outputs()) { - if (dsocket->is_available()) { - std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket( - dsocket->bsocket()); - if (data_type.has_value()) { - output_types.append(*data_type); - output_names.append(dsocket->name()); - output_dsockets.append(dsocket); - } - } - } - - fn::MFDummyNode &dummy_node = common.network.add_dummy( - dnode.name(), input_types, output_types, input_names, output_names); - - common.network_map.add(input_dsockets, dummy_node.inputs()); - common.network_map.add(output_dsockets, dummy_node.outputs()); -} - -static bool has_data_sockets(const DNode &dnode) -{ - for (const DInputSocket *socket : dnode.inputs()) { - if (is_multi_function_data_socket(socket->bsocket())) { - return true; - } - } - for (const DOutputSocket *socket : dnode.outputs()) { - if (is_multi_function_data_socket(socket->bsocket())) { - return true; - } - } - return false; -} - -/** - * Expands all function nodes in the multi-function network. Nodes that don't have an expand - * function, but do have data sockets, will get corresponding dummy nodes. - */ -static void insert_nodes(CommonMFNetworkBuilderData &common) -{ - for (const DNode *dnode : common.tree.nodes()) { - const bNodeType *node_type = dnode->node_ref().bnode()->typeinfo; - if (node_type->expand_in_mf_network != nullptr) { - NodeMFNetworkBuilder builder{common, *dnode}; - node_type->expand_in_mf_network(builder); - } - else if (has_data_sockets(*dnode)) { - insert_dummy_node(common, *dnode); - } - } -} - -static void insert_group_inputs(CommonMFNetworkBuilderData &common) -{ - for (const DGroupInput *group_input : common.tree.group_inputs()) { - bNodeSocket *bsocket = group_input->bsocket(); - if (is_multi_function_data_socket(bsocket)) { - bNodeSocketType *socktype = bsocket->typeinfo; - BLI_assert(socktype->expand_in_mf_network != nullptr); - - SocketMFNetworkBuilder builder{common, *group_input}; - socktype->expand_in_mf_network(builder); - - fn::MFOutputSocket *from_socket = builder.built_socket(); - BLI_assert(from_socket != nullptr); - common.network_map.add(*group_input, *from_socket); - } - } -} - -static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common, - const DInputSocket &to_dsocket) -{ - Span<const DOutputSocket *> from_dsockets = to_dsocket.linked_sockets(); - Span<const DGroupInput *> from_group_inputs = to_dsocket.linked_group_inputs(); - uint total_linked_amount = from_dsockets.size() + from_group_inputs.size(); - BLI_assert(total_linked_amount <= 1); - - if (total_linked_amount == 0) { - return nullptr; - } - - if (from_dsockets.size() == 1) { - const DOutputSocket &from_dsocket = *from_dsockets[0]; - if (!from_dsocket.is_available()) { - return nullptr; - } - if (is_multi_function_data_socket(from_dsocket.bsocket())) { - return &common.network_map.lookup(from_dsocket); - } - return nullptr; - } - else { - const DGroupInput &from_group_input = *from_group_inputs[0]; - if (is_multi_function_data_socket(from_group_input.bsocket())) { - return &common.network_map.lookup(from_group_input); - } - return nullptr; - } -} - -using ImplicitConversionsMap = - Map<std::pair<fn::MFDataType, fn::MFDataType>, const fn::MultiFunction *>; - -template<typename From, typename To> -static void add_implicit_conversion(ImplicitConversionsMap &map) -{ - static fn::CustomMF_Convert<From, To> function; - map.add({fn::MFDataType::ForSingle<From>(), fn::MFDataType::ForSingle<To>()}, &function); -} - -template<typename From, typename To, typename ConversionF> -static void add_implicit_conversion(ImplicitConversionsMap &map, - StringRef name, - ConversionF conversion) -{ - static fn::CustomMF_SI_SO<From, To> function{name, conversion}; - map.add({fn::MFDataType::ForSingle<From>(), fn::MFDataType::ForSingle<To>()}, &function); -} - -static ImplicitConversionsMap get_implicit_conversions() -{ - ImplicitConversionsMap conversions; - add_implicit_conversion<float, int32_t>(conversions); - add_implicit_conversion<float, float3>(conversions); - add_implicit_conversion<int32_t, float>(conversions); - add_implicit_conversion<float3, float>( - conversions, "Vector Length", [](float3 a) { return a.length(); }); - add_implicit_conversion<int32_t, float3>( - conversions, "int32 to float3", [](int32_t a) { return float3((float)a); }); - add_implicit_conversion<float3, Color4f>( - conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); }); - add_implicit_conversion<Color4f, float3>( - conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); }); - return conversions; -} - -static const fn::MultiFunction *try_get_conversion_function(fn::MFDataType from, fn::MFDataType to) -{ - static const ImplicitConversionsMap conversions = get_implicit_conversions(); - const fn::MultiFunction *function = conversions.lookup_default({from, to}, nullptr); - return function; -} - -static fn::MFOutputSocket &insert_default_value_for_type(CommonMFNetworkBuilderData &common, - fn::MFDataType type) -{ - const fn::MultiFunction *default_fn; - if (type.is_single()) { - default_fn = &common.resources.construct<fn::CustomMF_GenericConstant>( - AT, type.single_type(), type.single_type().default_value()); - } - else { - default_fn = &common.resources.construct<fn::CustomMF_GenericConstantArray>( - AT, fn::GSpan(type.vector_base_type())); - } - - fn::MFNode &node = common.network.add_function(*default_fn); - return node.output(0); -} - -static void insert_links(CommonMFNetworkBuilderData &common) -{ - for (const DInputSocket *to_dsocket : common.tree.input_sockets()) { - if (!to_dsocket->is_available()) { - continue; - } - if (!to_dsocket->is_linked()) { - continue; - } - if (!is_multi_function_data_socket(to_dsocket->bsocket())) { - continue; - } - - Span<fn::MFInputSocket *> to_sockets = common.network_map.lookup(*to_dsocket); - BLI_assert(to_sockets.size() >= 1); - fn::MFDataType to_type = to_sockets[0]->data_type(); - - fn::MFOutputSocket *from_socket = try_find_origin(common, *to_dsocket); - if (from_socket == nullptr) { - from_socket = &insert_default_value_for_type(common, to_type); - } - - fn::MFDataType from_type = from_socket->data_type(); - - if (from_type != to_type) { - const fn::MultiFunction *conversion_fn = try_get_conversion_function(from_type, to_type); - if (conversion_fn != nullptr) { - fn::MFNode &node = common.network.add_function(*conversion_fn); - common.network.add_link(*from_socket, node.input(0)); - from_socket = &node.output(0); - } - else { - from_socket = &insert_default_value_for_type(common, to_type); - } - } - - for (fn::MFInputSocket *to_socket : to_sockets) { - common.network.add_link(*from_socket, *to_socket); - } - } -} - -static void insert_unlinked_input(CommonMFNetworkBuilderData &common, const DInputSocket &dsocket) -{ - bNodeSocket *bsocket = dsocket.bsocket(); - bNodeSocketType *socktype = bsocket->typeinfo; - BLI_assert(socktype->expand_in_mf_network != nullptr); - - SocketMFNetworkBuilder builder{common, dsocket}; - socktype->expand_in_mf_network(builder); - - fn::MFOutputSocket *from_socket = builder.built_socket(); - BLI_assert(from_socket != nullptr); - - for (fn::MFInputSocket *to_socket : common.network_map.lookup(dsocket)) { - common.network.add_link(*from_socket, *to_socket); - } -} - -static void insert_unlinked_inputs(CommonMFNetworkBuilderData &common) -{ - Vector<const DInputSocket *> unlinked_data_inputs; - for (const DInputSocket *dsocket : common.tree.input_sockets()) { - if (dsocket->is_available()) { - if (is_multi_function_data_socket(dsocket->bsocket())) { - if (!dsocket->is_linked()) { - insert_unlinked_input(common, *dsocket); - } - } - } - } -} - -/** - * Expands all function nodes contained in the given node tree within the given multi-function - * network. - * - * Returns a mapping between the original node tree and the generated nodes/sockets for further - * processing. - */ -MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network, - const DerivedNodeTree &tree, - ResourceCollector &resources) -{ - MFNetworkTreeMap network_map{tree, network}; - - CommonMFNetworkBuilderData common{resources, network, network_map, tree}; - - insert_nodes(common); - insert_group_inputs(common); - insert_links(common); - insert_unlinked_inputs(common); - - return network_map; -} - -} // namespace bke -} // namespace blender diff --git a/source/blender/blenkernel/intern/node_tree_ref.cc b/source/blender/blenkernel/intern/node_tree_ref.cc deleted file mode 100644 index 5c998a06cb5..00000000000 --- a/source/blender/blenkernel/intern/node_tree_ref.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "BKE_node_tree_ref.hh" - -#include "BLI_dot_export.hh" - -namespace blender::bke { - -NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree) -{ - Map<bNode *, NodeRef *> node_mapping; - - LISTBASE_FOREACH (bNode *, bnode, &btree->nodes) { - NodeRef &node = *allocator_.construct<NodeRef>(); - - node.tree_ = this; - node.bnode_ = bnode; - node.id_ = nodes_by_id_.append_and_get_index(&node); - RNA_pointer_create(&btree->id, &RNA_Node, bnode, &node.rna_); - - LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->inputs) { - InputSocketRef &socket = *allocator_.construct<InputSocketRef>(); - socket.node_ = &node; - socket.index_ = node.inputs_.append_and_get_index(&socket); - socket.is_input_ = true; - socket.bsocket_ = bsocket; - socket.id_ = sockets_by_id_.append_and_get_index(&socket); - RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_); - } - - LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->outputs) { - OutputSocketRef &socket = *allocator_.construct<OutputSocketRef>(); - socket.node_ = &node; - socket.index_ = node.outputs_.append_and_get_index(&socket); - socket.is_input_ = false; - socket.bsocket_ = bsocket; - socket.id_ = sockets_by_id_.append_and_get_index(&socket); - RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_); - } - - input_sockets_.extend(node.inputs_.as_span()); - output_sockets_.extend(node.outputs_.as_span()); - - 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.directly_linked_sockets_.append(&to_socket); - to_socket.directly_linked_sockets_.append(&from_socket); - } - - for (OutputSocketRef *socket : output_sockets_) { - if (!socket->node_->is_reroute_node()) { - this->find_targets_skipping_reroutes(*socket, socket->linked_sockets_); - for (SocketRef *target : socket->linked_sockets_) { - target->linked_sockets_.append(socket); - } - } - } - - for (NodeRef *node : nodes_by_id_) { - const bNodeType *nodetype = node->bnode_->typeinfo; - nodes_by_type_.lookup_or_add_default(nodetype).append(node); - } -} - -NodeTreeRef::~NodeTreeRef() -{ - for (NodeRef *node : nodes_by_id_) { - node->~NodeRef(); - } - for (InputSocketRef *socket : input_sockets_) { - socket->~InputSocketRef(); - } - for (OutputSocketRef *socket : output_sockets_) { - socket->~OutputSocketRef(); - } -} - -InputSocketRef &NodeTreeRef::find_input_socket(Map<bNode *, NodeRef *> &node_mapping, - bNode *bnode, - bNodeSocket *bsocket) -{ - NodeRef *node = node_mapping.lookup(bnode); - for (SocketRef *socket : node->inputs_) { - if (socket->bsocket_ == bsocket) { - return *(InputSocketRef *)socket; - } - } - BLI_assert(false); - return *node->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->outputs_) { - if (socket->bsocket_ == bsocket) { - return *(OutputSocketRef *)socket; - } - } - BLI_assert(false); - return *node->outputs_[0]; -} - -void NodeTreeRef::find_targets_skipping_reroutes(OutputSocketRef &socket, - Vector<SocketRef *> &r_targets) -{ - for (SocketRef *direct_target : socket.directly_linked_sockets_) { - if (direct_target->node_->is_reroute_node()) { - this->find_targets_skipping_reroutes(*direct_target->node_->outputs_[0], r_targets); - } - else { - r_targets.append_non_duplicates(direct_target); - } - } -} - -std::string NodeTreeRef::to_dot() const -{ - dot::DirectedGraph digraph; - digraph.set_rankdir(dot::Attr_rankdir::LeftToRight); - - Map<const NodeRef *, dot::NodeWithSocketsRef> dot_nodes; - - for (const NodeRef *node : nodes_by_id_) { - dot::Node &dot_node = digraph.new_node(""); - dot_node.set_background_color("white"); - - Vector<std::string> input_names; - Vector<std::string> output_names; - for (const InputSocketRef *socket : node->inputs()) { - input_names.append(socket->name()); - } - for (const OutputSocketRef *socket : node->outputs()) { - output_names.append(socket->name()); - } - - dot_nodes.add_new(node, - dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names)); - } - - for (const OutputSocketRef *from_socket : output_sockets_) { - for (const InputSocketRef *to_socket : from_socket->directly_linked_sockets()) { - dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(&from_socket->node()); - dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(&to_socket->node()); - - digraph.new_edge(from_dot_node.output(from_socket->index()), - to_dot_node.input(to_socket->index())); - } - } - - return digraph.to_dot_string(); -} - -} // namespace blender::bke diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc index 831de084500..f38001bf69f 100644 --- a/source/blender/blenkernel/intern/simulation.cc +++ b/source/blender/blenkernel/intern/simulation.cc @@ -45,10 +45,10 @@ #include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_node_tree_multi_function.hh" #include "BKE_pointcache.h" #include "BKE_simulation.h" +#include "NOD_node_tree_multi_function.hh" #include "NOD_simulation.h" #include "BLT_translation.h" @@ -216,16 +216,19 @@ static void copy_states_to_cow(Simulation *simulation_orig, Simulation *simulati } static Map<const fn::MFOutputSocket *, std::string> deduplicate_attribute_nodes( - fn::MFNetwork &network, MFNetworkTreeMap &network_map, const DerivedNodeTree &tree) + fn::MFNetwork &network, + nodes::MFNetworkTreeMap &network_map, + const nodes::DerivedNodeTree &tree) { - Span<const DNode *> attribute_dnodes = tree.nodes_by_type("SimulationNodeParticleAttribute"); + Span<const nodes::DNode *> attribute_dnodes = tree.nodes_by_type( + "SimulationNodeParticleAttribute"); uint amount = attribute_dnodes.size(); if (amount == 0) { return {}; } Vector<fn::MFInputSocket *> name_sockets; - for (const DNode *dnode : attribute_dnodes) { + for (const nodes::DNode *dnode : attribute_dnodes) { fn::MFInputSocket &name_socket = network_map.lookup_dummy(dnode->input(0)); name_sockets.append(&name_socket); } @@ -309,10 +312,10 @@ class CustomDataAttributesRef { } }; -static std::string dnode_to_path(const DNode &dnode) +static std::string dnode_to_path(const nodes::DNode &dnode) { std::string path; - for (const DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) { + for (const nodes::DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) { path = parent->node_ref().name() + "/" + path; } path = path + dnode.name(); @@ -373,10 +376,10 @@ static void add_missing_particle_states(Simulation *simulation, Span<std::string } static void reinitialize_empty_simulation_states(Simulation *simulation, - const DerivedNodeTree &tree) + const nodes::DerivedNodeTree &tree) { VectorSet<std::string> state_names; - for (const DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) { + for (const nodes::DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) { state_names.add(dnode_to_path(*dnode)); } @@ -385,10 +388,11 @@ static void reinitialize_empty_simulation_states(Simulation *simulation, add_missing_particle_states(simulation, state_names); } -static void update_simulation_state_list(Simulation *simulation, const DerivedNodeTree &tree) +static void update_simulation_state_list(Simulation *simulation, + const nodes::DerivedNodeTree &tree) { VectorSet<std::string> state_names; - for (const DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) { + for (const nodes::DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) { state_names.add(dnode_to_path(*dnode)); } @@ -672,14 +676,15 @@ class ParticleFunctionForce : public ParticleForce { }; static Vector<const ParticleForce *> create_forces_for_particle_simulation( - const DNode &simulation_node, - MFNetworkTreeMap &network_map, + const nodes::DNode &simulation_node, + nodes::MFNetworkTreeMap &network_map, ResourceCollector &resources, const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs) { Vector<const ParticleForce *> forces; - for (const DOutputSocket *origin_socket : simulation_node.input(2, "Forces").linked_sockets()) { - const DNode &origin_node = origin_socket->node(); + for (const nodes::DOutputSocket *origin_socket : + simulation_node.input(2, "Forces").linked_sockets()) { + const nodes::DNode &origin_node = origin_socket->node(); if (origin_node.idname() != "SimulationNodeForce") { continue; } @@ -701,12 +706,13 @@ static Vector<const ParticleForce *> create_forces_for_particle_simulation( } static Map<std::string, Vector<const ParticleForce *>> collect_forces( - MFNetworkTreeMap &network_map, + nodes::MFNetworkTreeMap &network_map, ResourceCollector &resources, const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs) { Map<std::string, Vector<const ParticleForce *>> forces_by_simulation; - for (const DNode *dnode : network_map.tree().nodes_by_type("SimulationNodeParticleSimulation")) { + for (const nodes::DNode *dnode : + network_map.tree().nodes_by_type("SimulationNodeParticleSimulation")) { std::string name = dnode_to_path(*dnode); Vector<const ParticleForce *> forces = create_forces_for_particle_simulation( *dnode, network_map, resources, attribute_inputs); @@ -729,12 +735,12 @@ static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulatio Simulation *simulation_orig = (Simulation *)DEG_get_original_id(&simulation_cow->id); - NodeTreeRefMap tree_refs; + nodes::NodeTreeRefMap tree_refs; /* TODO: Use simulation_cow, but need to add depsgraph relations before that. */ - const DerivedNodeTree tree{simulation_orig->nodetree, tree_refs}; + const nodes::DerivedNodeTree tree{simulation_orig->nodetree, tree_refs}; fn::MFNetwork network; ResourceCollector resources; - MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources); + nodes::MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources); Map<const fn::MFOutputSocket *, std::string> attribute_inputs = deduplicate_attribute_nodes( network, network_map, tree); fn::mf_network_optimization::constant_folding(network, resources); |