Blender  V2.93
FN_multi_function_network.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
44 #include "FN_multi_function.hh"
45 
46 #include "BLI_vector_set.hh"
47 
48 namespace blender::fn {
49 
50 class MFNode;
51 class MFFunctionNode;
52 class MFDummyNode;
53 class MFSocket;
54 class MFInputSocket;
55 class MFOutputSocket;
56 class MFNetwork;
57 
59  protected:
63  bool is_dummy_;
64  int id_;
65 
66  friend MFNetwork;
67 
68  public:
69  StringRefNull name() const;
70 
71  int id() const;
72 
73  MFNetwork &network();
74  const MFNetwork &network() const;
75 
76  bool is_dummy() const;
77  bool is_function() const;
78 
80  const MFDummyNode &as_dummy() const;
81 
83  const MFFunctionNode &as_function() const;
84 
85  MFInputSocket &input(int index);
86  const MFInputSocket &input(int index) const;
87 
88  MFOutputSocket &output(int index);
89  const MFOutputSocket &output(int index) const;
90 
93 
96 
97  bool has_unlinked_inputs() const;
98 
99  private:
100  void destruct_sockets();
101 };
102 
103 class MFFunctionNode : public MFNode {
104  private:
105  const MultiFunction *function_;
106  Span<int> input_param_indices_;
107  Span<int> output_param_indices_;
108 
109  friend MFNetwork;
110 
111  public:
112  StringRefNull name() const;
113 
114  const MultiFunction &function() const;
115 
116  const MFInputSocket &input_for_param(int param_index) const;
117  const MFOutputSocket &output_for_param(int param_index) const;
118 };
119 
120 class MFDummyNode : public MFNode {
121  protected:
125 
126  friend MFNetwork;
127 
128  public:
129  StringRefNull name() const;
130 
133 };
134 
136  protected:
139  int index_;
141  int id_;
143 
144  friend MFNetwork;
145 
146  public:
147  StringRefNull name() const;
148 
149  int id() const;
150  int index() const;
151 
152  const MFDataType &data_type() const;
153 
154  MFNode &node();
155  const MFNode &node() const;
156 
157  bool is_input() const;
158  bool is_output() const;
159 
161  const MFInputSocket &as_input() const;
162 
164  const MFOutputSocket &as_output() const;
165 };
166 
167 class MFInputSocket : public MFSocket {
168  private:
169  MFOutputSocket *origin_;
170 
171  friend MFNetwork;
172 
173  public:
175  const MFOutputSocket *origin() const;
176 };
177 
178 class MFOutputSocket : public MFSocket {
179  private:
181 
182  friend MFNetwork;
183 
184  public:
187 };
188 
190  private:
191  LinearAllocator<> allocator_;
192 
193  VectorSet<MFFunctionNode *> function_nodes_;
194  VectorSet<MFDummyNode *> dummy_nodes_;
195 
196  Vector<MFNode *> node_or_null_by_id_;
197  Vector<MFSocket *> socket_or_null_by_id_;
198 
199  public:
200  MFNetwork() = default;
201  ~MFNetwork();
202 
203  MFFunctionNode &add_function(const MultiFunction &function);
205  Span<MFDataType> input_types,
206  Span<MFDataType> output_types,
207  Span<StringRef> input_names,
208  Span<StringRef> output_names);
210 
211  MFOutputSocket &add_input(StringRef name, MFDataType data_type);
212  MFInputSocket &add_output(StringRef name, MFDataType data_type);
213 
214  void relink(MFOutputSocket &old_output, MFOutputSocket &new_output);
215 
216  void remove(MFNode &node);
217  void remove(Span<MFNode *> nodes);
218 
219  int socket_id_amount() const;
220  int node_id_amount() const;
221 
224 
225  MFNode *node_or_null_by_id(int id);
226  const MFNode *node_or_null_by_id(int id) const;
227 
229  const MFSocket *socket_or_null_by_id(int id) const;
230 
232  VectorSet<const MFOutputSocket *> &r_dummy_sockets,
233  VectorSet<const MFInputSocket *> &r_unlinked_inputs) const;
234 
236 
237  std::string to_dot(Span<const MFNode *> marked_nodes = {}) const;
238 };
239 
240 /* --------------------------------------------------------------------
241  * MFNode inline methods.
242  */
243 
245 {
246  if (is_dummy_) {
247  return this->as_dummy().name();
248  }
249  else {
250  return this->as_function().name();
251  }
252 }
253 
254 inline int MFNode::id() const
255 {
256  return id_;
257 }
258 
260 {
261  return *network_;
262 }
263 
264 inline const MFNetwork &MFNode::network() const
265 {
266  return *network_;
267 }
268 
269 inline bool MFNode::is_dummy() const
270 {
271  return is_dummy_;
272 }
273 
274 inline bool MFNode::is_function() const
275 {
276  return !is_dummy_;
277 }
278 
280 {
282  return static_cast<MFDummyNode &>(*this);
283 }
284 
285 inline const MFDummyNode &MFNode::as_dummy() const
286 {
288  return static_cast<const MFDummyNode &>(*this);
289 }
290 
292 {
294  return static_cast<MFFunctionNode &>(*this);
295 }
296 
297 inline const MFFunctionNode &MFNode::as_function() const
298 {
300  return static_cast<const MFFunctionNode &>(*this);
301 }
302 
303 inline MFInputSocket &MFNode::input(int index)
304 {
305  return *inputs_[index];
306 }
307 
308 inline const MFInputSocket &MFNode::input(int index) const
309 {
310  return *inputs_[index];
311 }
312 
313 inline MFOutputSocket &MFNode::output(int index)
314 {
315  return *outputs_[index];
316 }
317 
318 inline const MFOutputSocket &MFNode::output(int index) const
319 {
320  return *outputs_[index];
321 }
322 
324 {
325  return inputs_;
326 }
327 
329 {
330  return inputs_;
331 }
332 
334 {
335  return outputs_;
336 }
337 
339 {
340  return outputs_;
341 }
342 
343 inline bool MFNode::has_unlinked_inputs() const
344 {
345  for (const MFInputSocket *socket : inputs_) {
346  if (socket->origin() == nullptr) {
347  return true;
348  }
349  }
350  return false;
351 }
352 
353 /* --------------------------------------------------------------------
354  * MFFunctionNode inline methods.
355  */
356 
358 {
359  return function_->name();
360 }
361 
363 {
364  return *function_;
365 }
366 
367 inline const MFInputSocket &MFFunctionNode::input_for_param(int param_index) const
368 {
369  return this->input(input_param_indices_.first_index(param_index));
370 }
371 
372 inline const MFOutputSocket &MFFunctionNode::output_for_param(int param_index) const
373 {
374  return this->output(output_param_indices_.first_index(param_index));
375 }
376 
377 /* --------------------------------------------------------------------
378  * MFDummyNode inline methods.
379  */
380 
382 {
383  return name_;
384 }
385 
387 {
388  return input_names_;
389 }
390 
392 {
393  return output_names_;
394 }
395 
396 /* --------------------------------------------------------------------
397  * MFSocket inline methods.
398  */
399 
401 {
402  return name_;
403 }
404 
405 inline int MFSocket::id() const
406 {
407  return id_;
408 }
409 
410 inline int MFSocket::index() const
411 {
412  return index_;
413 }
414 
415 inline const MFDataType &MFSocket::data_type() const
416 {
417  return data_type_;
418 }
419 
421 {
422  return *node_;
423 }
424 
425 inline const MFNode &MFSocket::node() const
426 {
427  return *node_;
428 }
429 
430 inline bool MFSocket::is_input() const
431 {
432  return !is_output_;
433 }
434 
435 inline bool MFSocket::is_output() const
436 {
437  return is_output_;
438 }
439 
441 {
442  BLI_assert(this->is_input());
443  return static_cast<MFInputSocket &>(*this);
444 }
445 
446 inline const MFInputSocket &MFSocket::as_input() const
447 {
448  BLI_assert(this->is_input());
449  return static_cast<const MFInputSocket &>(*this);
450 }
451 
453 {
454  BLI_assert(this->is_output());
455  return static_cast<MFOutputSocket &>(*this);
456 }
457 
458 inline const MFOutputSocket &MFSocket::as_output() const
459 {
460  BLI_assert(this->is_output());
461  return static_cast<const MFOutputSocket &>(*this);
462 }
463 
464 /* --------------------------------------------------------------------
465  * MFInputSocket inline methods.
466  */
467 
469 {
470  return origin_;
471 }
472 
474 {
475  return origin_;
476 }
477 
478 /* --------------------------------------------------------------------
479  * MFOutputSocket inline methods.
480  */
481 
483 {
484  return targets_;
485 }
486 
488 {
489  return targets_;
490 }
491 
492 /* --------------------------------------------------------------------
493  * MFNetwork inline methods.
494  */
495 
497 {
498  return dummy_nodes_;
499 }
500 
502 {
503  return function_nodes_;
504 }
505 
507 {
508  return node_or_null_by_id_[id];
509 }
510 
511 inline const MFNode *MFNetwork::node_or_null_by_id(int id) const
512 {
513  return node_or_null_by_id_[id];
514 }
515 
517 {
518  return socket_or_null_by_id_[id];
519 }
520 
521 inline const MFSocket *MFNetwork::socket_or_null_by_id(int id) const
522 {
523  return socket_or_null_by_id_[id];
524 }
525 
526 inline int MFNetwork::socket_id_amount() const
527 {
528  return socket_or_null_by_id_.size();
529 }
530 
531 inline int MFNetwork::node_id_amount() const
532 {
533  return node_or_null_by_id_.size();
534 }
535 
536 } // namespace blender::fn
#define BLI_assert(a)
Definition: BLI_assert.h:58
constexpr int64_t first_index(const T &search_value) const
Definition: BLI_span.hh:390
int64_t size() const
Definition: BLI_vector.hh:662
Span< StringRefNull > output_names() const
Span< StringRefNull > input_names() const
MutableSpan< StringRefNull > input_names_
MutableSpan< StringRefNull > output_names_
const MultiFunction & function() const
const MFInputSocket & input_for_param(int param_index) const
const MFOutputSocket & output_for_param(int param_index) const
bool have_dummy_or_unlinked_dependencies(Span< const MFInputSocket * > sockets) const
MFSocket * socket_or_null_by_id(int id)
Span< MFFunctionNode * > function_nodes()
void relink(MFOutputSocket &old_output, MFOutputSocket &new_output)
Span< MFDummyNode * > dummy_nodes()
void find_dependencies(Span< const MFInputSocket * > sockets, VectorSet< const MFOutputSocket * > &r_dummy_sockets, VectorSet< const MFInputSocket * > &r_unlinked_inputs) const
MFDummyNode & add_dummy(StringRef name, Span< MFDataType > input_types, Span< MFDataType > output_types, Span< StringRef > input_names, Span< StringRef > output_names)
std::string to_dot(Span< const MFNode * > marked_nodes={}) const
void add_link(MFOutputSocket &from, MFInputSocket &to)
MFFunctionNode & add_function(const MultiFunction &function)
MFOutputSocket & add_input(StringRef name, MFDataType data_type)
MFInputSocket & add_output(StringRef name, MFDataType data_type)
Span< MFInputSocket * > inputs()
Span< MFOutputSocket * > outputs_
MFOutputSocket & output(int index)
MFInputSocket & input(int index)
StringRefNull name() const
Span< MFOutputSocket * > outputs()
Span< MFInputSocket * > inputs_
const MFDataType & data_type() const
StringRefNull name() const
OperationNode * node
StackEntry * from