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:
Diffstat (limited to 'source/blender/functions/FN_multi_function_network.h')
-rw-r--r--source/blender/functions/FN_multi_function_network.h868
1 files changed, 868 insertions, 0 deletions
diff --git a/source/blender/functions/FN_multi_function_network.h b/source/blender/functions/FN_multi_function_network.h
new file mode 100644
index 00000000000..18cc4a603e4
--- /dev/null
+++ b/source/blender/functions/FN_multi_function_network.h
@@ -0,0 +1,868 @@
+#ifndef __FN_MULTI_FUNCTION_NETWORK_H__
+#define __FN_MULTI_FUNCTION_NETWORK_H__
+
+#include "FN_multi_function.h"
+
+#include "BLI_array_cxx.h"
+#include "BLI_linear_allocated_vector.h"
+#include "BLI_map.h"
+#include "BLI_optional.h"
+#include "BLI_set.h"
+#include "BLI_vector_set.h"
+
+namespace FN {
+
+using BLI::Array;
+using BLI::LinearAllocatedVector;
+using BLI::Map;
+using BLI::Optional;
+using BLI::Set;
+using BLI::VectorSet;
+
+/* MFNetwork Builder
+ ****************************************/
+
+class MFBuilderNode;
+class MFBuilderFunctionNode;
+class MFBuilderDummyNode;
+
+class MFBuilderSocket;
+class MFBuilderInputSocket;
+class MFBuilderOutputSocket;
+
+class MFNetworkBuilder;
+
+class MFBuilderNode : BLI::NonCopyable, BLI::NonMovable {
+ protected:
+ MFNetworkBuilder *m_network;
+ ArrayRef<MFBuilderInputSocket *> m_inputs;
+ ArrayRef<MFBuilderOutputSocket *> m_outputs;
+ bool m_is_dummy;
+ uint m_id;
+
+ friend MFNetworkBuilder;
+
+ public:
+ MFNetworkBuilder &network();
+
+ ArrayRef<MFBuilderInputSocket *> inputs();
+ ArrayRef<MFBuilderOutputSocket *> outputs();
+
+ MFBuilderInputSocket &input(uint index);
+ MFBuilderOutputSocket &output(uint index);
+
+ StringRefNull name();
+ uint id();
+
+ bool is_function();
+ bool is_dummy();
+
+ MFBuilderFunctionNode &as_function();
+ MFBuilderDummyNode &as_dummy();
+
+ template<typename FuncT> void foreach_target_socket(const FuncT &func);
+ template<typename FuncT> void foreach_target_node(const FuncT &func);
+ template<typename FuncT> void foreach_origin_node(const FuncT &func);
+ template<typename FuncT> void foreach_linked_node(const FuncT &func);
+};
+
+class MFBuilderFunctionNode : public MFBuilderNode {
+ private:
+ const MultiFunction *m_function;
+ ArrayRef<uint> m_input_param_indices;
+ ArrayRef<uint> m_output_param_indices;
+
+ friend MFNetworkBuilder;
+
+ public:
+ const MultiFunction &function();
+
+ ArrayRef<uint> input_param_indices();
+ ArrayRef<uint> output_param_indices();
+};
+
+class MFBuilderDummyNode : public MFBuilderNode {
+ private:
+ StringRefNull m_name;
+ MutableArrayRef<StringRefNull> m_input_names;
+ MutableArrayRef<StringRefNull> m_output_names;
+
+ friend MFNetworkBuilder;
+ friend MFBuilderSocket;
+ friend MFBuilderNode;
+};
+
+class MFBuilderSocket : BLI::NonCopyable, BLI::NonMovable {
+ private:
+ MFBuilderNode *m_node;
+ bool m_is_output;
+ uint m_index;
+ MFDataType m_data_type;
+ uint m_id;
+
+ friend MFNetworkBuilder;
+
+ public:
+ MFBuilderNode &node();
+ MFDataType data_type();
+
+ uint index();
+ StringRefNull name();
+ uint id();
+
+ bool is_input();
+ bool is_output();
+
+ MFBuilderInputSocket &as_input();
+ MFBuilderOutputSocket &as_output();
+};
+
+class MFBuilderInputSocket : public MFBuilderSocket {
+ private:
+ MFBuilderOutputSocket *m_origin;
+
+ friend MFNetworkBuilder;
+
+ public:
+ MFBuilderOutputSocket *origin();
+};
+
+class MFBuilderOutputSocket : public MFBuilderSocket {
+ private:
+ LinearAllocatedVector<MFBuilderInputSocket *> m_targets;
+
+ friend MFNetworkBuilder;
+
+ public:
+ ArrayRef<MFBuilderInputSocket *> targets();
+};
+
+class MFNetworkBuilder : BLI::NonCopyable, BLI::NonMovable {
+ private:
+ LinearAllocator<> m_allocator;
+
+ VectorSet<MFBuilderFunctionNode *> m_function_nodes;
+ VectorSet<MFBuilderDummyNode *> m_dummy_nodes;
+
+ Vector<MFBuilderNode *> m_node_or_null_by_id;
+ Vector<MFBuilderSocket *> m_socket_or_null_by_id;
+
+ public:
+ ~MFNetworkBuilder();
+
+ std::string to_dot(const Set<MFBuilderNode *> &marked_nodes = {});
+ void to_dot__clipboard(const Set<MFBuilderNode *> &marked_nodes = {});
+
+ MFBuilderFunctionNode &add_function(const MultiFunction &function);
+ MFBuilderDummyNode &add_dummy(StringRef name,
+ ArrayRef<MFDataType> input_types,
+ ArrayRef<MFDataType> output_types,
+ ArrayRef<StringRef> input_names,
+ ArrayRef<StringRef> output_names);
+ MFBuilderDummyNode &add_input_dummy(StringRef name, MFBuilderInputSocket &socket);
+ MFBuilderDummyNode &add_output_dummy(StringRef name, MFBuilderOutputSocket &socket);
+
+ void add_link(MFBuilderOutputSocket &from, MFBuilderInputSocket &to);
+ void remove_link(MFBuilderOutputSocket &from, MFBuilderInputSocket &to);
+ void remove_node(MFBuilderNode &node);
+ void remove_nodes(ArrayRef<MFBuilderNode *> nodes);
+ void replace_origin(MFBuilderOutputSocket &old_origin, MFBuilderOutputSocket &new_origin);
+
+ Array<bool> find_nodes_to_the_right_of__inclusive__mask(ArrayRef<MFBuilderNode *> nodes);
+ Array<bool> find_nodes_to_the_left_of__inclusive__mask(ArrayRef<MFBuilderNode *> nodes);
+ Vector<MFBuilderNode *> find_nodes_not_to_the_left_of__exclusive__vector(
+ ArrayRef<MFBuilderNode *> nodes);
+
+ Vector<MFBuilderNode *> nodes_by_id_inverted_id_mask(ArrayRef<bool> id_mask);
+
+ uint current_index_of(MFBuilderFunctionNode &node) const
+ {
+ return m_function_nodes.index(&node);
+ }
+
+ uint current_index_of(MFBuilderDummyNode &node) const
+ {
+ return m_dummy_nodes.index(&node);
+ }
+
+ uint node_id_amount() const
+ {
+ return m_node_or_null_by_id.size();
+ }
+
+ bool node_id_is_valid(uint id) const
+ {
+ return m_node_or_null_by_id[id] != nullptr;
+ }
+
+ MFBuilderNode &node_by_id(uint id)
+ {
+ BLI_assert(this->node_id_is_valid(id));
+ return *m_node_or_null_by_id[id];
+ }
+
+ MFBuilderFunctionNode &function_by_id(uint id)
+ {
+ return this->node_by_id(id).as_function();
+ }
+
+ MFBuilderDummyNode &dummy_by_id(uint id)
+ {
+ return this->node_by_id(id).as_dummy();
+ }
+
+ uint socket_id_amount()
+ {
+ return m_socket_or_null_by_id.size();
+ }
+
+ bool socket_id_is_valid(uint id) const
+ {
+ return m_socket_or_null_by_id[id] != nullptr;
+ }
+
+ MFBuilderSocket &socket_by_id(uint id)
+ {
+ BLI_assert(m_socket_or_null_by_id[id] != nullptr);
+ return *m_socket_or_null_by_id[id];
+ }
+
+ MFBuilderInputSocket &input_by_id(uint id)
+ {
+ return this->socket_by_id(id).as_input();
+ }
+
+ MFBuilderOutputSocket &output_by_id(uint id)
+ {
+ return this->socket_by_id(id).as_output();
+ }
+
+ ArrayRef<MFBuilderSocket *> sockets_or_null_by_id()
+ {
+ return m_socket_or_null_by_id;
+ }
+
+ ArrayRef<MFBuilderFunctionNode *> function_nodes() const
+ {
+ return m_function_nodes;
+ }
+
+ ArrayRef<MFBuilderDummyNode *> dummy_nodes() const
+ {
+ return m_dummy_nodes;
+ }
+};
+
+void optimize_multi_function_network(MFNetworkBuilder &network);
+
+/* Network
+ ******************************************/
+
+class MFNode;
+class MFFunctionNode;
+class MFDummyNode;
+
+class MFSocket;
+class MFInputSocket;
+class MFOutputSocket;
+
+class MFNetwork;
+
+class MFNode : BLI::NonCopyable, BLI::NonMovable {
+ private:
+ MFNetwork *m_network;
+ ArrayRef<MFInputSocket *> m_inputs;
+ ArrayRef<MFOutputSocket *> m_outputs;
+ bool m_is_dummy;
+ uint m_id;
+
+ friend MFNetwork;
+
+ public:
+ const MFNetwork &network() const;
+
+ StringRefNull name() const;
+
+ const MFInputSocket &input(uint index) const;
+ const MFOutputSocket &output(uint index) const;
+
+ ArrayRef<const MFInputSocket *> inputs() const;
+ ArrayRef<const MFOutputSocket *> outputs() const;
+
+ uint id() const;
+
+ bool is_function() const;
+ bool is_dummy() const;
+
+ const MFFunctionNode &as_function() const;
+ const MFDummyNode &as_dummy() const;
+
+ template<typename FuncT> void foreach_origin_node(const FuncT &func) const;
+ template<typename FuncT> void foreach_origin_socket(const FuncT &func) const;
+};
+
+class MFFunctionNode final : public MFNode {
+ private:
+ const MultiFunction *m_function;
+ ArrayRef<uint> m_input_param_indices;
+ ArrayRef<uint> m_output_param_indices;
+
+ friend MFNetwork;
+
+ public:
+ const MultiFunction &function() const;
+
+ ArrayRef<uint> input_param_indices() const;
+ ArrayRef<uint> output_param_indices() const;
+
+ const MFInputSocket &input_for_param(uint param_index) const;
+ const MFOutputSocket &output_for_param(uint param_index) const;
+};
+
+class MFDummyNode final : public MFNode {
+ private:
+ StringRefNull m_name;
+ MutableArrayRef<StringRefNull> m_input_names;
+ MutableArrayRef<StringRefNull> m_output_names;
+
+ friend MFNetwork;
+};
+
+class MFSocket : BLI::NonCopyable, BLI::NonMovable {
+ private:
+ MFNode *m_node;
+ bool m_is_output;
+ uint m_index;
+ MFDataType m_data_type;
+ uint m_id;
+
+ friend MFNetwork;
+
+ public:
+ const MFNode &node() const;
+ MFDataType data_type() const;
+ uint param_index() const;
+ MFParamType param_type() const;
+
+ uint index() const;
+ uint id() const;
+
+ bool is_input() const;
+ bool is_output() const;
+
+ MFInputSocket &as_input();
+ MFOutputSocket &as_output();
+
+ const MFInputSocket &as_input() const;
+ const MFOutputSocket &as_output() const;
+};
+
+class MFInputSocket final : public MFSocket {
+ private:
+ MFOutputSocket *m_origin;
+
+ friend MFNetwork;
+
+ public:
+ const MFOutputSocket &origin() const;
+};
+
+class MFOutputSocket final : public MFSocket {
+ private:
+ Vector<const MFInputSocket *> m_targets;
+
+ friend MFNetwork;
+
+ public:
+ ArrayRef<const MFInputSocket *> targets() const;
+ uint target_amount() const;
+};
+
+class MFNetwork : BLI::NonCopyable, BLI::NonMovable {
+ private:
+ LinearAllocator<> m_allocator;
+
+ Vector<MFNode *> m_node_by_id;
+ Vector<MFSocket *> m_socket_by_id;
+
+ Vector<MFFunctionNode *> m_function_nodes;
+ Vector<MFDummyNode *> m_dummy_nodes;
+ Vector<MFInputSocket *> m_input_sockets;
+ Vector<MFOutputSocket *> m_output_sockets;
+
+ Array<uint> m_max_dependency_depth_per_node;
+
+ public:
+ MFNetwork(MFNetworkBuilder &builder);
+ ~MFNetwork();
+
+ const MFNode &node_by_id(uint id) const;
+ const MFSocket &socket_by_id(uint id) const;
+ IndexRange socket_ids() const;
+ IndexRange node_ids() const;
+
+ ArrayRef<const MFDummyNode *> dummy_nodes() const;
+ ArrayRef<const MFFunctionNode *> function_nodes() const;
+
+ Vector<const MFOutputSocket *> find_dummy_dependencies(
+ ArrayRef<const MFInputSocket *> sockets) const;
+
+ Vector<const MFFunctionNode *> find_function_dependencies(
+ ArrayRef<const MFInputSocket *> sockets) const;
+
+ ArrayRef<uint> max_dependency_depth_per_node() const;
+
+ const MFDummyNode &find_dummy_node(MFBuilderDummyNode &builder_node) const;
+ const MFInputSocket &find_dummy_socket(MFBuilderInputSocket &builder_socket) const;
+ const MFOutputSocket &find_dummy_socket(MFBuilderOutputSocket &builder_socket) const;
+
+ private:
+ void create_links_to_node(MFNetworkBuilder &builder,
+ MFNode *to_node,
+ MFBuilderNode *to_builder_node);
+
+ void create_link_to_socket(MFNetworkBuilder &builder,
+ MFInputSocket *to_socket,
+ MFBuilderInputSocket *to_builder_socket);
+
+ void compute_max_dependency_depths();
+};
+
+/* Builder Implementations
+ *******************************************/
+
+inline MFNetworkBuilder &MFBuilderNode::network()
+{
+ return *m_network;
+}
+
+inline ArrayRef<MFBuilderInputSocket *> MFBuilderNode::inputs()
+{
+ return m_inputs;
+}
+inline ArrayRef<MFBuilderOutputSocket *> MFBuilderNode::outputs()
+{
+ return m_outputs;
+}
+
+inline MFBuilderInputSocket &MFBuilderNode::input(uint index)
+{
+ return *m_inputs[index];
+}
+
+inline MFBuilderOutputSocket &MFBuilderNode::output(uint index)
+{
+ return *m_outputs[index];
+}
+
+inline StringRefNull MFBuilderNode::name()
+{
+ if (this->is_function()) {
+ return this->as_function().function().name();
+ }
+ else {
+ return this->as_dummy().m_name;
+ }
+}
+
+inline uint MFBuilderNode::id()
+{
+ return m_id;
+}
+
+inline bool MFBuilderNode::is_function()
+{
+ return !m_is_dummy;
+}
+inline bool MFBuilderNode::is_dummy()
+{
+ return m_is_dummy;
+}
+
+inline MFBuilderFunctionNode &MFBuilderNode::as_function()
+{
+ BLI_assert(this->is_function());
+ return *(MFBuilderFunctionNode *)this;
+}
+
+inline MFBuilderDummyNode &MFBuilderNode::as_dummy()
+{
+ BLI_assert(this->is_dummy());
+ return *(MFBuilderDummyNode *)this;
+}
+
+template<typename FuncT> inline void MFBuilderNode::foreach_target_socket(const FuncT &func)
+{
+ for (MFBuilderOutputSocket *socket : m_outputs) {
+ for (MFBuilderInputSocket *target : socket->targets()) {
+ func(*target);
+ }
+ }
+}
+
+template<typename FuncT> inline void MFBuilderNode::foreach_target_node(const FuncT &func)
+{
+ for (MFBuilderOutputSocket *socket : m_outputs) {
+ for (MFBuilderInputSocket *target : socket->targets()) {
+ func(target->node());
+ }
+ }
+}
+
+template<typename FuncT> inline void MFBuilderNode::foreach_origin_node(const FuncT &func)
+{
+ for (MFBuilderInputSocket *socket : m_inputs) {
+ MFBuilderOutputSocket *origin = socket->origin();
+ if (origin != nullptr) {
+ func(origin->node());
+ }
+ }
+}
+
+template<typename FuncT> inline void MFBuilderNode::foreach_linked_node(const FuncT &func)
+{
+ this->foreach_origin_node(func);
+ this->foreach_target_node(func);
+}
+
+inline const MultiFunction &MFBuilderFunctionNode::function()
+{
+ return *m_function;
+}
+
+inline ArrayRef<uint> MFBuilderFunctionNode::input_param_indices()
+{
+ return m_input_param_indices;
+}
+
+inline ArrayRef<uint> MFBuilderFunctionNode::output_param_indices()
+{
+ return m_output_param_indices;
+}
+
+inline MFBuilderNode &MFBuilderSocket::node()
+{
+ return *m_node;
+}
+
+inline MFDataType MFBuilderSocket::data_type()
+{
+ return m_data_type;
+}
+
+inline uint MFBuilderSocket::index()
+{
+ return m_index;
+}
+
+inline StringRefNull MFBuilderSocket::name()
+{
+ if (m_node->is_function()) {
+ MFBuilderFunctionNode &node = m_node->as_function();
+ if (m_is_output) {
+ return node.function().param_name(node.output_param_indices()[m_index]);
+ }
+ else {
+ return node.function().param_name(node.input_param_indices()[m_index]);
+ }
+ }
+ else {
+ MFBuilderDummyNode &node = m_node->as_dummy();
+ if (m_is_output) {
+ return node.m_output_names[m_index];
+ }
+ else {
+ return node.m_input_names[m_index];
+ }
+ }
+}
+
+inline uint MFBuilderSocket::id()
+{
+ return m_id;
+}
+
+inline bool MFBuilderSocket::is_input()
+{
+ return !m_is_output;
+}
+inline bool MFBuilderSocket::is_output()
+{
+ return m_is_output;
+}
+
+inline MFBuilderInputSocket &MFBuilderSocket::as_input()
+{
+ BLI_assert(this->is_input());
+ return *(MFBuilderInputSocket *)this;
+}
+inline MFBuilderOutputSocket &MFBuilderSocket::as_output()
+{
+ BLI_assert(this->is_output());
+ return *(MFBuilderOutputSocket *)this;
+}
+
+inline MFBuilderOutputSocket *MFBuilderInputSocket::origin()
+{
+ return m_origin;
+}
+
+inline ArrayRef<MFBuilderInputSocket *> MFBuilderOutputSocket::targets()
+{
+ return m_targets;
+}
+
+/* MFNetwork Implementations
+ **************************************/
+
+inline const MFNetwork &MFNode::network() const
+{
+ return *m_network;
+}
+
+inline ArrayRef<const MFInputSocket *> MFNode::inputs() const
+{
+ return m_inputs;
+}
+
+inline ArrayRef<const MFOutputSocket *> MFNode::outputs() const
+{
+ return m_outputs;
+}
+
+inline const MFInputSocket &MFNode::input(uint index) const
+{
+ return *m_inputs[index];
+}
+
+inline const MFOutputSocket &MFNode::output(uint index) const
+{
+ return *m_outputs[index];
+}
+
+inline uint MFNode::id() const
+{
+ return m_id;
+}
+
+inline StringRefNull MFNode::name() const
+{
+ if (this->is_function()) {
+ return this->as_function().function().name();
+ }
+ else {
+ return "Dummy";
+ }
+}
+
+inline bool MFNode::is_function() const
+{
+ return !m_is_dummy;
+}
+
+inline bool MFNode::is_dummy() const
+{
+ return m_is_dummy;
+}
+
+inline const MFFunctionNode &MFNode::as_function() const
+{
+ BLI_assert(this->is_function());
+ return *(MFFunctionNode *)this;
+}
+
+inline const MFDummyNode &MFNode::as_dummy() const
+{
+ BLI_assert(this->is_dummy());
+ return *(const MFDummyNode *)this;
+}
+
+template<typename FuncT> inline void MFNode::foreach_origin_node(const FuncT &func) const
+{
+ for (const MFInputSocket *socket : m_inputs) {
+ const MFOutputSocket &origin_socket = socket->origin();
+ const MFNode &origin_node = origin_socket.node();
+ func(origin_node);
+ }
+}
+
+template<typename FuncT> inline void MFNode::foreach_origin_socket(const FuncT &func) const
+{
+ for (const MFInputSocket *socket : m_inputs) {
+ const MFOutputSocket &origin_socket = socket->origin();
+ func(origin_socket);
+ }
+}
+
+inline const MultiFunction &MFFunctionNode::function() const
+{
+ return *m_function;
+}
+
+inline ArrayRef<uint> MFFunctionNode::input_param_indices() const
+{
+ return m_input_param_indices;
+}
+
+inline ArrayRef<uint> MFFunctionNode::output_param_indices() const
+{
+ return m_output_param_indices;
+}
+
+inline const MFInputSocket &MFFunctionNode::input_for_param(uint param_index) const
+{
+ return this->input(m_input_param_indices.first_index(param_index));
+}
+
+inline const MFOutputSocket &MFFunctionNode::output_for_param(uint param_index) const
+{
+ return this->output(m_output_param_indices.first_index(param_index));
+}
+
+inline const MFNode &MFSocket::node() const
+{
+ return *m_node;
+}
+
+inline MFDataType MFSocket::data_type() const
+{
+ return m_data_type;
+}
+
+inline uint MFSocket::param_index() const
+{
+ const MFFunctionNode &node = m_node->as_function();
+ if (m_is_output) {
+ return node.output_param_indices()[m_index];
+ }
+ else {
+ return node.input_param_indices()[m_index];
+ }
+}
+
+inline MFParamType MFSocket::param_type() const
+{
+ uint param_index = this->param_index();
+ return m_node->as_function().function().param_type(param_index);
+}
+
+inline uint MFSocket::index() const
+{
+ return m_index;
+}
+
+inline uint MFSocket::id() const
+{
+ return m_id;
+}
+
+inline bool MFSocket::is_input() const
+{
+ return !m_is_output;
+}
+
+inline bool MFSocket::is_output() const
+{
+ return m_is_output;
+}
+
+inline MFInputSocket &MFSocket::as_input()
+{
+ BLI_assert(this->is_input());
+ return *(MFInputSocket *)this;
+}
+
+inline MFOutputSocket &MFSocket::as_output()
+{
+ BLI_assert(this->is_output());
+ return *(MFOutputSocket *)this;
+}
+
+inline const MFInputSocket &MFSocket::as_input() const
+{
+ BLI_assert(this->is_input());
+ return *(const MFInputSocket *)this;
+}
+
+inline const MFOutputSocket &MFSocket::as_output() const
+{
+ BLI_assert(this->is_output());
+ return *(const MFOutputSocket *)this;
+}
+
+inline const MFOutputSocket &MFInputSocket::origin() const
+{
+ return *m_origin;
+}
+
+inline ArrayRef<const MFInputSocket *> MFOutputSocket::targets() const
+{
+ return m_targets;
+}
+
+inline uint MFOutputSocket::target_amount() const
+{
+ return m_targets.size();
+}
+
+inline const MFNode &MFNetwork::node_by_id(uint index) const
+{
+ return *m_node_by_id[index];
+}
+
+inline const MFSocket &MFNetwork::socket_by_id(uint index) const
+{
+ return *m_socket_by_id[index];
+}
+
+inline IndexRange MFNetwork::socket_ids() const
+{
+ return IndexRange(m_socket_by_id.size());
+}
+
+inline IndexRange MFNetwork::node_ids() const
+{
+ return IndexRange(m_node_by_id.size());
+}
+
+inline ArrayRef<const MFDummyNode *> MFNetwork::dummy_nodes() const
+{
+ return m_dummy_nodes.as_ref();
+}
+
+inline ArrayRef<const MFFunctionNode *> MFNetwork::function_nodes() const
+{
+ return m_function_nodes.as_ref();
+}
+
+inline ArrayRef<uint> MFNetwork::max_dependency_depth_per_node() const
+{
+ return m_max_dependency_depth_per_node;
+}
+
+inline const MFDummyNode &MFNetwork::find_dummy_node(MFBuilderDummyNode &builder_node) const
+{
+ uint node_index = builder_node.network().current_index_of(builder_node);
+ const MFDummyNode &node = *this->m_dummy_nodes[node_index];
+ return node;
+}
+
+inline const MFInputSocket &MFNetwork::find_dummy_socket(
+ MFBuilderInputSocket &builder_socket) const
+{
+ const MFDummyNode &node = this->find_dummy_node(builder_socket.node().as_dummy());
+ const MFInputSocket &socket = node.input(builder_socket.index());
+ return socket;
+}
+
+inline const MFOutputSocket &MFNetwork::find_dummy_socket(
+ MFBuilderOutputSocket &builder_socket) const
+{
+ const MFDummyNode &node = this->find_dummy_node(builder_socket.node().as_dummy());
+ const MFOutputSocket &socket = node.output(builder_socket.index());
+ return socket;
+}
+
+} // namespace FN
+
+#endif /* __FN_MULTI_FUNCTION_NETWORK_H__ */