| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup fn | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A multi-function network (`MFNetwork`) allows you to connect multiple multi-functions. The | 
					
						
							|  |  |  |  * `MFNetworkEvaluator` is a multi-function that wraps an entire network into a new multi-function | 
					
						
							|  |  |  |  * (which can be used in another network and so on). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A MFNetwork is a graph data structure with two kinds of nodes: | 
					
						
							|  |  |  |  * - MFFunctionNode: Represents a multi-function. Its input and output sockets correspond to | 
					
						
							|  |  |  |  *       parameters of the referenced multi-function. | 
					
						
							|  |  |  |  * - MFDummyNode: Does not reference a multi-function. Instead it just has sockets that can be | 
					
						
							|  |  |  |  *       used to represent node group inputs and outputs. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Links represent data flow. Unlinked input sockets have no value. In order to execute a function | 
					
						
							|  |  |  |  * node, all its inputs have to be connected to something. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Links are only allowed between sockets with the exact same MFDataType. There are no implicit | 
					
						
							|  |  |  |  * conversions. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Every input and output parameter of a multi-function corresponds to exactly one input or output | 
					
						
							|  |  |  |  * socket respectively. A multiple parameter belongs to exactly one input AND one output socket. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * There is an .to_dot() method that generates a graph in dot format for debugging purposes. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "FN_multi_function.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_vector_set.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:25:20 +02:00
										 |  |  | namespace blender::fn { | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class MFNode; | 
					
						
							|  |  |  | class MFFunctionNode; | 
					
						
							|  |  |  | class MFDummyNode; | 
					
						
							|  |  |  | class MFSocket; | 
					
						
							|  |  |  | class MFInputSocket; | 
					
						
							|  |  |  | class MFOutputSocket; | 
					
						
							|  |  |  | class MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFNode : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  protected: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   MFNetwork *network_; | 
					
						
							|  |  |  |   Span<MFInputSocket *> inputs_; | 
					
						
							|  |  |  |   Span<MFOutputSocket *> outputs_; | 
					
						
							|  |  |  |   bool is_dummy_; | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int id_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   StringRefNull name() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int id() const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   MFNetwork &network(); | 
					
						
							|  |  |  |   const MFNetwork &network() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool is_dummy() const; | 
					
						
							|  |  |  |   bool is_function() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFDummyNode &as_dummy(); | 
					
						
							|  |  |  |   const MFDummyNode &as_dummy() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFFunctionNode &as_function(); | 
					
						
							|  |  |  |   const MFFunctionNode &as_function() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   MFInputSocket &input(int index); | 
					
						
							|  |  |  |   const MFInputSocket &input(int index) const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   MFOutputSocket &output(int index); | 
					
						
							|  |  |  |   const MFOutputSocket &output(int index) const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Span<MFInputSocket *> inputs(); | 
					
						
							|  |  |  |   Span<const MFInputSocket *> inputs() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Span<MFOutputSocket *> outputs(); | 
					
						
							|  |  |  |   Span<const MFOutputSocket *> outputs() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 17:20:05 +02:00
										 |  |  |   bool has_unlinked_inputs() const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   void destruct_sockets(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFFunctionNode : public MFNode { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   const MultiFunction *function_; | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   Span<int> input_param_indices_; | 
					
						
							|  |  |  |   Span<int> output_param_indices_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   StringRefNull name() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const MultiFunction &function() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   const MFInputSocket &input_for_param(int param_index) const; | 
					
						
							|  |  |  |   const MFOutputSocket &output_for_param(int param_index) const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFDummyNode : public MFNode { | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |  protected: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   StringRefNull name_; | 
					
						
							|  |  |  |   MutableSpan<StringRefNull> input_names_; | 
					
						
							|  |  |  |   MutableSpan<StringRefNull> output_names_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   StringRefNull name() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Span<StringRefNull> input_names() const; | 
					
						
							|  |  |  |   Span<StringRefNull> output_names() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFSocket : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  protected: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   MFNode *node_; | 
					
						
							|  |  |  |   bool is_output_; | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int index_; | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   MFDataType data_type_; | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int id_; | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   StringRefNull name_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   StringRefNull name() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int id() const; | 
					
						
							|  |  |  |   int index() const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const MFDataType &data_type() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFNode &node(); | 
					
						
							|  |  |  |   const MFNode &node() const; | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   bool is_input() const; | 
					
						
							|  |  |  |   bool is_output() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFInputSocket &as_input(); | 
					
						
							|  |  |  |   const MFInputSocket &as_input() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFOutputSocket &as_output(); | 
					
						
							|  |  |  |   const MFOutputSocket &as_output() const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFInputSocket : public MFSocket { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   MFOutputSocket *origin_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFOutputSocket *origin(); | 
					
						
							|  |  |  |   const MFOutputSocket *origin() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFOutputSocket : public MFSocket { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   Vector<MFInputSocket *, 1> targets_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend MFNetwork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   Span<MFInputSocket *> targets(); | 
					
						
							|  |  |  |   Span<const MFInputSocket *> targets() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MFNetwork : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   LinearAllocator<> allocator_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   VectorSet<MFFunctionNode *> function_nodes_; | 
					
						
							|  |  |  |   VectorSet<MFDummyNode *> dummy_nodes_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   Vector<MFNode *> node_or_null_by_id_; | 
					
						
							|  |  |  |   Vector<MFSocket *> socket_or_null_by_id_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   MFNetwork() = default; | 
					
						
							|  |  |  |   ~MFNetwork(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFFunctionNode &add_function(const MultiFunction &function); | 
					
						
							|  |  |  |   MFDummyNode &add_dummy(StringRef name, | 
					
						
							|  |  |  |                          Span<MFDataType> input_types, | 
					
						
							|  |  |  |                          Span<MFDataType> output_types, | 
					
						
							|  |  |  |                          Span<StringRef> input_names, | 
					
						
							|  |  |  |                          Span<StringRef> output_names); | 
					
						
							|  |  |  |   void add_link(MFOutputSocket &from, MFInputSocket &to); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MFOutputSocket &add_input(StringRef name, MFDataType data_type); | 
					
						
							|  |  |  |   MFInputSocket &add_output(StringRef name, MFDataType data_type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  |   void relink(MFOutputSocket &old_output, MFOutputSocket &new_output); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void remove(MFNode &node); | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  |   void remove(Span<MFNode *> nodes); | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int socket_id_amount() const; | 
					
						
							|  |  |  |   int node_id_amount() const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  |   Span<MFDummyNode *> dummy_nodes(); | 
					
						
							|  |  |  |   Span<MFFunctionNode *> function_nodes(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   MFNode *node_or_null_by_id(int id); | 
					
						
							|  |  |  |   const MFNode *node_or_null_by_id(int id) const; | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   MFSocket *socket_or_null_by_id(int id); | 
					
						
							|  |  |  |   const MFSocket *socket_or_null_by_id(int id) const; | 
					
						
							| 
									
										
										
										
											2020-07-08 15:06:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:22:35 +02:00
										 |  |  |   void find_dependencies(Span<const MFInputSocket *> sockets, | 
					
						
							|  |  |  |                          VectorSet<const MFOutputSocket *> &r_dummy_sockets, | 
					
						
							|  |  |  |                          VectorSet<const MFInputSocket *> &r_unlinked_inputs) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 10:51:38 +02:00
										 |  |  |   bool have_dummy_or_unlinked_dependencies(Span<const MFInputSocket *> sockets) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  |   std::string to_dot(Span<const MFNode *> marked_nodes = {}) const; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFNode inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline StringRefNull MFNode::name() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   if (is_dummy_) { | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  |     return this->as_dummy().name(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     return this->as_function().name(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline int MFNode::id() const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return id_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFNetwork &MFNode::network() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *network_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFNetwork &MFNode::network() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *network_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool MFNode::is_dummy() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return is_dummy_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool MFNode::is_function() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return !is_dummy_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFDummyNode &MFNode::as_dummy() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   BLI_assert(is_dummy_); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<MFDummyNode &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFDummyNode &MFNode::as_dummy() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   BLI_assert(is_dummy_); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<const MFDummyNode &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFFunctionNode &MFNode::as_function() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   BLI_assert(!is_dummy_); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<MFFunctionNode &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFFunctionNode &MFNode::as_function() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   BLI_assert(!is_dummy_); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<const MFFunctionNode &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline MFInputSocket &MFNode::input(int index) | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *inputs_[index]; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline const MFInputSocket &MFNode::input(int index) const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *inputs_[index]; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline MFOutputSocket &MFNode::output(int index) | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *outputs_[index]; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline const MFOutputSocket &MFNode::output(int index) const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *outputs_[index]; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFInputSocket *> MFNode::inputs() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return inputs_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const MFInputSocket *> MFNode::inputs() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return inputs_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFOutputSocket *> MFNode::outputs() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return outputs_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const MFOutputSocket *> MFNode::outputs() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return outputs_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 17:20:05 +02:00
										 |  |  | inline bool MFNode::has_unlinked_inputs() const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   for (const MFInputSocket *socket : inputs_) { | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  |     if (socket->origin() == nullptr) { | 
					
						
							| 
									
										
										
										
											2020-07-21 17:20:05 +02:00
										 |  |  |       return true; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-21 17:20:05 +02:00
										 |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFFunctionNode inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline StringRefNull MFFunctionNode::name() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return function_->name(); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MultiFunction &MFFunctionNode::function() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *function_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline const MFInputSocket &MFFunctionNode::input_for_param(int param_index) const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return this->input(input_param_indices_.first_index(param_index)); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline const MFOutputSocket &MFFunctionNode::output_for_param(int param_index) const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return this->output(output_param_indices_.first_index(param_index)); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFDummyNode inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline StringRefNull MFDummyNode::name() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return name_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<StringRefNull> MFDummyNode::input_names() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return input_names_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<StringRefNull> MFDummyNode::output_names() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return output_names_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFSocket inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline StringRefNull MFSocket::name() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return name_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline int MFSocket::id() const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return id_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline int MFSocket::index() const | 
					
						
							| 
									
										
										
										
											2020-07-08 15:06:04 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return index_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | inline const MFDataType &MFSocket::data_type() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return data_type_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFNode &MFSocket::node() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *node_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFNode &MFSocket::node() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return *node_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | inline bool MFSocket::is_input() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return !is_output_; | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool MFSocket::is_output() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return is_output_; | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFInputSocket &MFSocket::as_input() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_input()); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<MFInputSocket &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFInputSocket &MFSocket::as_input() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_input()); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<const MFInputSocket &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFOutputSocket &MFSocket::as_output() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_output()); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<MFOutputSocket &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFOutputSocket &MFSocket::as_output() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_output()); | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<const MFOutputSocket &>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-30 18:03:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFInputSocket inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline MFOutputSocket *MFInputSocket::origin() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return origin_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const MFOutputSocket *MFInputSocket::origin() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return origin_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFOutputSocket inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFInputSocket *> MFOutputSocket::targets() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:20:42 +02:00
										 |  |  |   return targets_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const MFInputSocket *> MFOutputSocket::targets() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-08 22:29:10 +02:00
										 |  |  |   return targets_; | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * MFNetwork inline methods. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  | inline Span<MFDummyNode *> MFNetwork::dummy_nodes() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return dummy_nodes_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<MFFunctionNode *> MFNetwork::function_nodes() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return function_nodes_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline MFNode *MFNetwork::node_or_null_by_id(int id) | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return node_or_null_by_id_[id]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline const MFNode *MFNetwork::node_or_null_by_id(int id) const | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return node_or_null_by_id_[id]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline MFSocket *MFNetwork::socket_or_null_by_id(int id) | 
					
						
							| 
									
										
										
										
											2020-07-08 15:06:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return socket_or_null_by_id_[id]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline const MFSocket *MFNetwork::socket_or_null_by_id(int id) const | 
					
						
							| 
									
										
										
										
											2020-07-08 15:06:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return socket_or_null_by_id_[id]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline int MFNetwork::socket_id_amount() const | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return socket_or_null_by_id_.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | inline int MFNetwork::node_id_amount() const | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-07 18:45:34 +02:00
										 |  |  |   return node_or_null_by_id_.size(); | 
					
						
							| 
									
										
										
										
											2020-06-23 10:16:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:25:20 +02:00
										 |  |  | }  // namespace blender::fn
 |