Blender  V3.3
NOD_node_declaration.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
5 #include <functional>
6 #include <type_traits>
7 
8 #include "BLI_string_ref.hh"
9 #include "BLI_vector.hh"
10 
11 #include "DNA_node_types.h"
12 
13 struct bNode;
14 
15 namespace blender::nodes {
16 
17 class NodeDeclarationBuilder;
18 
21  None,
25  Implicit,
26 };
27 
30  None,
38 };
39 
44  private:
46  Vector<int> linked_input_indices_;
47 
48  public:
53 
56 
57  friend bool operator==(const OutputFieldDependency &a, const OutputFieldDependency &b);
58 };
59 
66 };
67 
72  protected:
73  std::string name_;
74  std::string identifier_;
75  std::string description_;
79  bool hide_label_ = false;
80  bool hide_value_ = false;
81  bool compact_ = false;
82  bool is_multi_input_ = false;
83  bool no_mute_links_ = false;
84  bool is_unavailable_ = false;
85  bool is_attribute_name_ = false;
87 
90 
92  std::function<void(bNode &)> make_available_fn_;
93 
95  template<typename SocketDecl> friend class SocketDeclarationBuilder;
96 
97  public:
98  virtual ~SocketDeclaration() = default;
99 
100  virtual bNodeSocket &build(bNodeTree &ntree, bNode &node) const = 0;
101  virtual bool matches(const bNodeSocket &socket) const = 0;
102  virtual bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const;
103 
108  virtual bool can_connect(const bNodeSocket &socket) const = 0;
109 
115  void make_available(bNode &node) const;
116 
117  StringRefNull name() const;
118  StringRefNull description() const;
119  StringRefNull identifier() const;
120  eNodeSocketInOut in_out() const;
121  bool is_attribute_name() const;
122  bool is_default_link_socket() const;
123 
126 
127  protected:
128  void set_common_flags(bNodeSocket &socket) const;
129  bool matches_common_data(const bNodeSocket &socket) const;
130 };
131 
133  public:
134  virtual ~BaseSocketDeclarationBuilder() = default;
135 };
136 
142 template<typename SocketDecl>
144  protected:
145  using Self = typename SocketDecl::Builder;
146  static_assert(std::is_base_of_v<SocketDeclaration, SocketDecl>);
147  SocketDecl *decl_;
148 
150 
151  public:
152  Self &hide_label(bool value = true)
153  {
154  decl_->hide_label_ = value;
155  return *(Self *)this;
156  }
157 
158  Self &hide_value(bool value = true)
159  {
160  decl_->hide_value_ = value;
161  return *(Self *)this;
162  }
163 
164  Self &multi_input(bool value = true)
165  {
166  decl_->is_multi_input_ = value;
167  return *(Self *)this;
168  }
169 
170  Self &description(std::string value = "")
171  {
172  decl_->description_ = std::move(value);
173  return *(Self *)this;
174  }
175 
176  Self &no_muted_links(bool value = true)
177  {
178  decl_->no_mute_links_ = value;
179  return *(Self *)this;
180  }
181 
186  Self &unavailable(bool value = true)
187  {
188  decl_->is_unavailable_ = value;
189  return *(Self *)this;
190  }
191 
192  Self &is_attribute_name(bool value = true)
193  {
194  decl_->is_attribute_name_ = value;
195  return *(Self *)this;
196  }
197 
198  Self &is_default_link_socket(bool value = true)
199  {
200  decl_->is_default_link_socket_ = value;
201  return *(Self *)this;
202  }
203 
206  {
207  decl_->input_field_type_ = InputSocketFieldType::IsSupported;
208  return *(Self *)this;
209  }
210 
213  {
214  this->hide_value();
215  decl_->input_field_type_ = InputSocketFieldType::Implicit;
216  return *(Self *)this;
217  }
218 
221  {
222  decl_->output_field_dependency_ = OutputFieldDependency::ForFieldSource();
223  return *(Self *)this;
224  }
225 
228  {
229  decl_->output_field_dependency_ = OutputFieldDependency::ForDependentField();
230  return *(Self *)this;
231  }
232 
234  Self &dependent_field(Vector<int> input_dependencies)
235  {
236  decl_->output_field_dependency_ = OutputFieldDependency::ForPartiallyDependentField(
237  std::move(input_dependencies));
238  return *(Self *)this;
239  }
240 
247  Self &make_available(std::function<void(bNode &)> fn)
248  {
249  decl_->make_available_fn_ = std::move(fn);
250  return *(Self *)this;
251  }
252 };
253 
254 using SocketDeclarationPtr = std::unique_ptr<SocketDeclaration>;
255 
257  private:
260  bool is_function_node_ = false;
261 
262  friend NodeDeclarationBuilder;
263 
264  public:
265  bool matches(const bNode &node) const;
266 
270 
271  bool is_function_node() const
272  {
273  return is_function_node_;
274  }
275 
276  MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration")
277 };
278 
280  private:
281  NodeDeclaration &declaration_;
283 
284  public:
286 
292  void is_function_node(bool value = true)
293  {
294  BLI_assert_msg(declaration_.inputs().is_empty() && declaration_.outputs().is_empty(),
295  "is_function_node() must be called before any socket is created");
296  declaration_.is_function_node_ = value;
297  }
298 
299  template<typename DeclType>
300  typename DeclType::Builder &add_input(StringRef name, StringRef identifier = "");
301  template<typename DeclType>
302  typename DeclType::Builder &add_output(StringRef name, StringRef identifier = "");
303 
304  private:
305  template<typename DeclType>
306  typename DeclType::Builder &add_socket(StringRef name,
307  StringRef identifier,
308  eNodeSocketInOut in_out);
309 };
310 
311 /* -------------------------------------------------------------------- */
316 {
317  OutputFieldDependency field_dependency;
318  field_dependency.type_ = OutputSocketFieldType::FieldSource;
319  return field_dependency;
320 }
321 
323 {
324  OutputFieldDependency field_dependency;
325  field_dependency.type_ = OutputSocketFieldType::None;
326  return field_dependency;
327 }
328 
330 {
331  OutputFieldDependency field_dependency;
332  field_dependency.type_ = OutputSocketFieldType::DependentField;
333  return field_dependency;
334 }
335 
337 {
338  OutputFieldDependency field_dependency;
339  if (indices.is_empty()) {
340  field_dependency.type_ = OutputSocketFieldType::None;
341  }
342  else {
343  field_dependency.type_ = OutputSocketFieldType::PartiallyDependent;
344  field_dependency.linked_input_indices_ = std::move(indices);
345  }
346  return field_dependency;
347 }
348 
350 {
351  return type_;
352 }
353 
355 {
356  return linked_input_indices_;
357 }
358 
360 {
361  return a.type_ == b.type_ && a.linked_input_indices_ == b.linked_input_indices_;
362 }
363 
365 {
366  return !(a == b);
367 }
368 
371 /* -------------------------------------------------------------------- */
376 {
377  return a.inputs == b.inputs && a.outputs == b.outputs;
378 }
379 
381 {
382  return !(a == b);
383 }
384 
387 /* -------------------------------------------------------------------- */
392 {
393  return name_;
394 }
395 
397 {
398  return identifier_;
399 }
400 
402 {
403  return in_out_;
404 }
405 
407 {
408  return description_;
409 }
410 
412 {
413  return is_attribute_name_;
414 }
415 
417 {
419 }
420 
422 {
423  return input_field_type_;
424 }
425 
427 {
429 }
430 
432 {
433  if (make_available_fn_) {
435  }
436 }
437 
440 /* -------------------------------------------------------------------- */
445  : declaration_(declaration)
446 {
447 }
448 
449 template<typename DeclType>
450 inline typename DeclType::Builder &NodeDeclarationBuilder::add_input(StringRef name,
451  StringRef identifier)
452 {
453  return this->add_socket<DeclType>(name, identifier, SOCK_IN);
454 }
455 
456 template<typename DeclType>
457 inline typename DeclType::Builder &NodeDeclarationBuilder::add_output(StringRef name,
458  StringRef identifier)
459 {
460  return this->add_socket<DeclType>(name, identifier, SOCK_OUT);
461 }
462 
463 template<typename DeclType>
464 inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket(StringRef name,
465  StringRef identifier,
466  eNodeSocketInOut in_out)
467 {
468  static_assert(std::is_base_of_v<SocketDeclaration, DeclType>);
469  using Builder = typename DeclType::Builder;
470 
471  Vector<SocketDeclarationPtr> &declarations = in_out == SOCK_IN ? declaration_.inputs_ :
472  declaration_.outputs_;
473 
474  std::unique_ptr<DeclType> socket_decl = std::make_unique<DeclType>();
475  std::unique_ptr<Builder> socket_decl_builder = std::make_unique<Builder>();
476  socket_decl_builder->decl_ = &*socket_decl;
477  socket_decl->name_ = name;
478  socket_decl->identifier_ = identifier.is_empty() ? name : identifier;
479  socket_decl->in_out_ = in_out;
480  if (declaration_.is_function_node()) {
481  socket_decl->input_field_type_ = InputSocketFieldType::IsSupported;
482  socket_decl->output_field_dependency_ = OutputFieldDependency::ForDependentField();
483  }
484  declarations.append(std::move(socket_decl));
485  Builder &socket_decl_builder_ref = *socket_decl_builder;
486  builders_.append(std::move(socket_decl_builder));
487  return socket_decl_builder_ref;
488 }
489 
492 /* -------------------------------------------------------------------- */
497 {
498  return inputs_;
499 }
500 
502 {
503  return outputs_;
504 }
505 
507 {
508  if (in_out == SOCK_IN) {
509  return inputs_;
510  }
511  return outputs_;
512 }
513 
516 } // namespace blender::nodes
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
constexpr bool is_empty() const
void append(const T &value)
Definition: BLI_vector.hh:433
NodeDeclarationBuilder(NodeDeclaration &declaration)
DeclType::Builder & add_input(StringRef name, StringRef identifier="")
DeclType::Builder & add_output(StringRef name, StringRef identifier="")
bool matches(const bNode &node) const
Span< SocketDeclarationPtr > outputs() const
Span< SocketDeclarationPtr > inputs() const
Span< SocketDeclarationPtr > sockets(eNodeSocketInOut in_out) const
friend bool operator==(const OutputFieldDependency &a, const OutputFieldDependency &b)
static OutputFieldDependency ForPartiallyDependentField(Vector< int > indices)
static OutputFieldDependency ForDataSource()
static OutputFieldDependency ForDependentField()
static OutputFieldDependency ForFieldSource()
OutputSocketFieldType field_type() const
Self & make_available(std::function< void(bNode &)> fn)
Self & dependent_field(Vector< int > input_dependencies)
virtual bool matches(const bNodeSocket &socket) const =0
bool matches_common_data(const bNodeSocket &socket) const
const OutputFieldDependency & output_field_dependency() const
virtual ~SocketDeclaration()=default
virtual bool can_connect(const bNodeSocket &socket) const =0
OutputFieldDependency output_field_dependency_
std::function< void(bNode &)> make_available_fn_
virtual bNodeSocket & build(bNodeTree &ntree, bNode &node) const =0
virtual bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const
InputSocketFieldType input_field_type() const
void set_common_flags(bNodeSocket &socket) const
OperationNode * node
SyclQueue void void size_t num_bytes void
bNodeTree * ntree
ccl_gpu_kernel_postfix int ccl_global int * indices
static unsigned a[3]
Definition: RandGen.cpp:78
bool operator!=(const DNode &a, const DNode &b)
std::unique_ptr< SocketDeclaration > SocketDeclarationPtr
bool operator==(const DNode &a, const DNode &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
Vector< OutputFieldDependency > outputs