Blender V4.5
NOD_node_declaration.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
7#include <cstdint>
8#include <functional>
9#include <type_traits>
10
11#include "BLI_array.hh"
12#include "BLI_string_ref.hh"
13#include "BLI_utildefines.h"
14#include "BLI_vector.hh"
15
16#include "BLT_translation.hh" /* IWYU pragma: export */
17
18#include "DNA_node_types.h"
19
20#include "RNA_types.hh"
21
22struct bContext;
23struct bNode;
24struct uiLayout;
25
26namespace blender::nodes {
27
30
39
51
60
80
90
104
106
116
126
136
146
161
162std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations);
163
164} // namespace anonymous_attribute_lifetime
165namespace aal = anonymous_attribute_lifetime;
166
169 public:
170 const PanelDeclaration *parent = nullptr;
171
172 virtual ~ItemDeclaration() = default;
173};
174
175using ItemDeclarationPtr = std::unique_ptr<ItemDeclaration>;
176
181
191
193
198 public:
199 std::string name;
200 std::string short_label;
201 std::string identifier;
202 std::string description;
203 std::optional<std::string> translation_context;
209 bool hide_label = false;
210 bool hide_value = false;
211 bool compact = false;
212 bool is_multi_input = false;
213 bool no_mute_links = false;
214 bool is_available = true;
215 bool is_attribute_name = false;
220 bool is_panel_toggle = false;
221 bool is_layer_name = false;
222
224 int index = -1;
225
228
229 StructureType structure_type = StructureType::Single;
230
231 private:
232 CompositorInputRealizationMode compositor_realization_mode_ =
234
238 int compositor_domain_priority_ = -1;
239
242 bool compositor_expects_single_value_ = false;
243
245 std::function<void(bNode &)> make_available_fn_;
246
247 public:
249 NodeDefaultInputType default_input_type = NodeDefaultInputType::NODE_DEFAULT_INPUT_VALUE;
254 std::unique_ptr<SocketNameRNA> socket_name_rna;
258 std::unique_ptr<CustomSocketDrawFn> custom_draw_fn;
259
262 template<typename SocketDecl> friend class SocketDeclarationBuilder;
263
264 ~SocketDeclaration() override = default;
265
266 virtual bNodeSocket &build(bNodeTree &ntree, bNode &node) const = 0;
267 virtual bool matches(const bNodeSocket &socket) const = 0;
268 virtual bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const;
269
274 virtual bool can_connect(const bNodeSocket &socket) const = 0;
275
281 void make_available(bNode &node) const;
282
284 int compositor_domain_priority() const;
286
287 protected:
288 void set_common_flags(bNodeSocket &socket) const;
289 bool matches_common_data(const bNodeSocket &socket) const;
290};
291
295
297 protected:
299 bool field_on_all_ = false;
303
306
307 public:
308 virtual ~BaseSocketDeclarationBuilder() = default;
309
310 BaseSocketDeclarationBuilder &hide_label(bool value = true);
311
312 BaseSocketDeclarationBuilder &hide_value(bool value = true);
313
314 BaseSocketDeclarationBuilder &multi_input(bool value = true);
315
316 BaseSocketDeclarationBuilder &compact(bool value = true);
317
318 BaseSocketDeclarationBuilder &short_label(std::string value = "");
319
320 BaseSocketDeclarationBuilder &description(std::string value = "");
321
323 std::optional<std::string> value = std::nullopt);
324
326
331 BaseSocketDeclarationBuilder &available(bool value = true);
332
334
336
338
341
350
353
356
359
362 Span<int> input_indices);
363
366
369
372
378
383
388
393
395
401
407
414 BaseSocketDeclarationBuilder &make_available(std::function<void(bNode &)> fn);
415
420
426
433 const StructRNA *srna,
434 const void *data,
435 StringRef property_name);
439 BaseSocketDeclarationBuilder &panel_toggle(bool value = true);
440
442
444
446 int index() const;
447
448 bool is_input() const;
449 bool is_output() const;
450};
451
457template<typename SocketDecl>
459 protected:
460 using Self = typename SocketDecl::Builder;
461 static_assert(std::is_base_of_v<SocketDeclaration, SocketDecl>);
462 SocketDecl *decl_;
463
466};
467
468using SocketDeclarationPtr = std::unique_ptr<SocketDeclaration>;
469
471
473
475 public:
476 std::function<DrawNodeLayoutFn> draw;
481 bool is_default = false;
482};
483
488 public:
490 std::string name;
491 std::string description;
492 std::optional<std::string> translation_context;
493 bool default_collapsed = false;
496 int index = -1;
498
499 private:
500 friend NodeDeclarationBuilder;
502
503 public:
504 ~PanelDeclaration() override = default;
505
506 void build(bNodePanelState &panel) const;
507 bool matches(const bNodePanelState &panel) const;
508 void update_or_build(const bNodePanelState &old_panel, bNodePanelState &new_panel) const;
509
510 int depth() const;
511
513 const SocketDeclaration *panel_input_decl() const;
514};
515
521 public:
525
531
532 template<typename DeclType>
533 typename DeclType::Builder &add_socket(StringRef name,
534 StringRef identifier,
535 eNodeSocketInOut in_out);
536
537 template<typename DeclType>
538 typename DeclType::Builder &add_input(StringRef name, StringRef identifier = "");
539 template<typename DeclType>
540 typename DeclType::Builder &add_output(StringRef name, StringRef identifier = "");
541
543 StringRef name,
544 StringRef identifier = "");
546 StringRef name,
547 StringRef identifier = "");
549 StringRef name,
550 StringRef identifier = "");
552 StringRef name,
553 StringRef identifier = "");
554
555 PanelDeclarationBuilder &add_panel(StringRef name, int identifier = -1);
556
557 void add_separator();
558 void add_default_layout();
559 void add_layout(std::function<void(uiLayout *, bContext *, PointerRNA *)> draw);
560};
561
563 protected:
566
568
569 public:
571 : DeclarationListBuilder(node_builder, decl.items), decl_(&decl)
572 {
573 this->parent_panel_decl = &decl;
574 }
575
576 Self &description(std::string value = "");
577 Self &translation_context(std::optional<std::string> value = std::nullopt);
578 Self &default_closed(bool closed);
579};
580
581using PanelDeclarationPtr = std::unique_ptr<PanelDeclaration>;
582
584 public:
593 std::unique_ptr<aal::RelationsInNode> anonymous_attribute_relations_;
594
599
603
607
612
614
616 void assert_valid() const;
617
618 bool matches(const bNode &node) const;
620
621 const aal::RelationsInNode *anonymous_attribute_relations() const
622 {
624 }
625
626 MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration")
627};
628
629class NodeDeclarationBuilder : public DeclarationListBuilder {
630 private:
631 const bke::bNodeType &typeinfo_;
632 NodeDeclaration &declaration_;
633 const bNodeTree *ntree_ = nullptr;
634 const bNode *node_ = nullptr;
636 Vector<BaseSocketDeclarationBuilder *> input_socket_builders_;
637 Vector<BaseSocketDeclarationBuilder *> output_socket_builders_;
639 bool is_function_node_ = false;
640
641 friend DeclarationListBuilder;
642
643 public:
646 const bNodeTree *ntree = nullptr,
647 const bNode *node = nullptr);
648
649 const bNode *node_or_null() const
650 {
651 declaration_.is_context_dependent = true;
652 return node_;
653 }
654
655 const bNodeTree *tree_or_null() const
656 {
657 declaration_.is_context_dependent = true;
658 return ntree_;
659 }
660
666 {
667 is_function_node_ = true;
668 }
669
670 void finalize();
671
672 void use_custom_socket_order(bool enable = true);
673 void allow_any_socket_order(bool enable = true);
674
675 aal::RelationsInNode &get_anonymous_attribute_relations()
676 {
677 if (!declaration_.anonymous_attribute_relations_) {
678 declaration_.anonymous_attribute_relations_ = std::make_unique<aal::RelationsInNode>();
679 }
680 return *declaration_.anonymous_attribute_relations_;
681 }
682
684 {
685 return declaration_;
686 }
687
688 private:
689 void build_remaining_anonymous_attribute_relations();
690};
691
692using ImplicitInputValueFn = std::function<void(const bNode &node, void *r_value)>;
693std::optional<ImplicitInputValueFn> get_implicit_input_value_fn(NodeDefaultInputType type);
695 NodeDefaultInputType input_type);
696
697void build_node_declaration(const bke::bNodeType &typeinfo,
698 NodeDeclaration &r_declaration,
699 const bNodeTree *ntree,
700 const bNode *node);
701
702std::unique_ptr<SocketDeclaration> make_declaration_for_socket_type(
703 eNodeSocketDatatype socket_type);
704
705/* -------------------------------------------------------------------- */
708
709template<typename DeclType>
710inline typename DeclType::Builder &DeclarationListBuilder::add_input(StringRef name,
711 StringRef identifier)
712{
713 return this->add_socket<DeclType>(name, identifier, SOCK_IN);
714}
715
716template<typename DeclType>
717inline typename DeclType::Builder &DeclarationListBuilder::add_output(StringRef name,
718 StringRef identifier)
719{
720 return this->add_socket<DeclType>(name, identifier, SOCK_OUT);
721}
722
723template<typename DeclType>
724inline typename DeclType::Builder &DeclarationListBuilder::add_socket(StringRef name,
725 StringRef identifier,
726 eNodeSocketInOut in_out)
727{
728 static_assert(std::is_base_of_v<SocketDeclaration, DeclType>);
729 using SocketBuilder = typename DeclType::Builder;
730
731 BLI_assert(ELEM(in_out, SOCK_IN, SOCK_OUT));
732
733 std::unique_ptr<SocketBuilder> socket_decl_builder_ptr = std::make_unique<SocketBuilder>();
734 SocketBuilder &socket_decl_builder = *socket_decl_builder_ptr;
735 this->node_decl_builder.socket_builders_.append(std::move(socket_decl_builder_ptr));
736
737 std::unique_ptr<DeclType> socket_decl_ptr = std::make_unique<DeclType>();
738 DeclType &socket_decl = *socket_decl_ptr;
739 this->node_decl_builder.declaration_.all_items.append(std::move(socket_decl_ptr));
740 this->items.append(&socket_decl);
741
742 socket_decl.parent = this->parent_panel_decl;
743 socket_decl_builder.node_decl_builder_ = &this->node_decl_builder;
744
745 socket_decl_builder.decl_ = &socket_decl;
746 socket_decl_builder.decl_base_ = &socket_decl;
747 socket_decl.name = name;
748 socket_decl.identifier = identifier.is_empty() ? name : identifier;
749 socket_decl.in_out = in_out;
750 socket_decl.socket_type = DeclType::static_socket_type;
751
752 if (this->node_decl_builder.is_function_node_) {
753 if (in_out == SOCK_IN) {
754 socket_decl_builder.supports_field();
755 }
756 else {
757 socket_decl_builder.dependent_field();
758 }
759 }
760
761 if (in_out == SOCK_IN) {
762 this->node_decl_builder.input_socket_builders_.append(&socket_decl_builder);
763 socket_decl.index = this->node_decl_builder.declaration_.inputs.append_and_get_index(
764 &socket_decl);
765 }
766 else {
767 this->node_decl_builder.output_socket_builders_.append(&socket_decl_builder);
768 socket_decl.index = this->node_decl_builder.declaration_.outputs.append_and_get_index(
769 &socket_decl);
770 }
771 return socket_decl_builder;
772}
773
775
776/* -------------------------------------------------------------------- */
779
781{
782 return decl_base_->index;
783}
784
786{
787 return decl_base_->in_out == SOCK_IN;
788}
789
791{
792 return decl_base_->in_out == SOCK_OUT;
793}
794
796
797} // namespace blender::nodes
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_STRUCT_EQUALITY_OPERATORS_5(Type, m1, m2, m3, m4, m5)
#define BLI_STRUCT_EQUALITY_OPERATORS_2(Type, m1, m2)
#define ELEM(...)
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
eNodeSocketDatatype
BMesh const char void * data
void append(const T &value)
constexpr bool is_empty() const
void append(const T &value)
BaseSocketDeclarationBuilder & is_layer_name(bool value=true)
BaseSocketDeclarationBuilder & dependent_field()
BaseSocketDeclarationBuilder & align_with_previous(bool value=true)
BaseSocketDeclarationBuilder & make_available(std::function< void(bNode &)> fn)
BaseSocketDeclarationBuilder & field_source()
BaseSocketDeclarationBuilder & compositor_realization_mode(CompositorInputRealizationMode value)
BaseSocketDeclarationBuilder & propagate_all()
BaseSocketDeclarationBuilder & available(bool value=true)
BaseSocketDeclarationBuilder & implicit_field(NodeDefaultInputType default_input)
BaseSocketDeclarationBuilder & field_on_all()
BaseSocketDeclarationBuilder & is_attribute_name(bool value=true)
BaseSocketDeclarationBuilder & reference_pass(Span< int > input_indices)
BaseSocketDeclarationBuilder & compact(bool value=true)
BaseSocketDeclarationBuilder & structure_type(StructureType structure_type)
BaseSocketDeclarationBuilder & description(std::string value="")
BaseSocketDeclarationBuilder & socket_name_ptr(PointerRNA ptr, StringRef property_name)
BaseSocketDeclarationBuilder & compositor_expects_single_value(bool value=true)
BaseSocketDeclarationBuilder & short_label(std::string value="")
BaseSocketDeclarationBuilder & supports_field()
BaseSocketDeclarationBuilder & hide_label(bool value=true)
BaseSocketDeclarationBuilder & implicit_field_on_all(NodeDefaultInputType default_input)
BaseSocketDeclarationBuilder & translation_context(std::optional< std::string > value=std::nullopt)
BaseSocketDeclarationBuilder & multi_input(bool value=true)
BaseSocketDeclarationBuilder & custom_draw(CustomSocketDrawFn fn)
BaseSocketDeclarationBuilder & panel_toggle(bool value=true)
BaseSocketDeclarationBuilder & is_default_link_socket(bool value=true)
BaseSocketDeclarationBuilder & compositor_domain_priority(int priority)
BaseSocketDeclarationBuilder & field_source_reference_all()
BaseSocketDeclarationBuilder & field_on(Span< int > indices)
BaseSocketDeclarationBuilder & hide_value(bool value=true)
BaseSocketDeclarationBuilder & propagate_all_instance_attributes()
BaseSocketDeclarationBuilder & implicit_field_on(NodeDefaultInputType default_input, Span< int > input_indices)
BaseSocketDeclarationBuilder & no_muted_links(bool value=true)
BaseSocketDeclarationBuilder & reference_pass_all()
BaseSocketDeclarationBuilder & default_input_type(NodeDefaultInputType value)
DeclType::Builder & add_output(StringRef name, StringRef identifier="")
DeclType::Builder & add_socket(StringRef name, StringRef identifier, eNodeSocketInOut in_out)
void add_layout(std::function< void(uiLayout *, bContext *, PointerRNA *)> draw)
PanelDeclarationBuilder & add_panel(StringRef name, int identifier=-1)
DeclType::Builder & add_input(StringRef name, StringRef identifier="")
DeclarationListBuilder(NodeDeclarationBuilder &node_decl_builder, Vector< ItemDeclaration * > &items)
virtual ~ItemDeclaration()=default
std::function< DrawNodeLayoutFn > draw
NodeDeclarationBuilder(const bke::bNodeType &typeinfo, NodeDeclaration &declaration, const bNodeTree *ntree=nullptr, const bNode *node=nullptr)
aal::RelationsInNode & get_anonymous_attribute_relations()
std::unique_ptr< aal::RelationsInNode > anonymous_attribute_relations_
Vector< ItemDeclaration * > root_items
Vector< SocketDeclaration * > inputs
bool matches(const bNode &node) const
const aal::RelationsInNode * anonymous_attribute_relations() const
Vector< SocketDeclaration * > outputs
Vector< PanelDeclaration * > panels
Vector< ItemDeclarationPtr > all_items
Span< SocketDeclaration * > sockets(eNodeSocketInOut in_out) const
static OutputFieldDependency ForPartiallyDependentField(Vector< int > indices)
static OutputFieldDependency ForDataSource()
static OutputFieldDependency ForDependentField()
static OutputFieldDependency ForFieldSource()
OutputSocketFieldType field_type() const
Self & description(std::string value="")
Self & translation_context(std::optional< std::string > value=std::nullopt)
PanelDeclarationBuilder(NodeDeclarationBuilder &node_builder, PanelDeclaration &decl)
std::optional< std::string > translation_context
Vector< ItemDeclaration * > items
~PanelDeclaration() override=default
void update_or_build(const bNodePanelState &old_panel, bNodePanelState &new_panel) const
bool matches(const bNodePanelState &panel) const
const SocketDeclaration * panel_input_decl() const
void build(bNodePanelState &panel) const
virtual bool matches(const bNodeSocket &socket) const =0
std::unique_ptr< SocketNameRNA > socket_name_rna
std::unique_ptr< CustomSocketDrawFn > custom_draw_fn
bool matches_common_data(const bNodeSocket &socket) const
const CompositorInputRealizationMode & compositor_realization_mode() const
void make_available(bNode &node) const
~SocketDeclaration() override=default
virtual bool can_connect(const bNodeSocket &socket) const =0
std::optional< std::string > translation_context
virtual bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const
void set_common_flags(bNodeSocket &socket) const
virtual bNodeSocket & build(bNodeTree &ntree, bNode &node) const =0
static ushort indices[]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
std::ostream & operator<<(std::ostream &stream, const RelationsInNode &relations)
std::unique_ptr< SocketDeclaration > SocketDeclarationPtr
std::optional< ImplicitInputValueFn > get_implicit_input_value_fn(const NodeDefaultInputType type)
void(uiLayout *, bContext *, PointerRNA *) DrawNodeLayoutFn
void build_node_declaration(const bke::bNodeType &typeinfo, NodeDeclaration &r_declaration, const bNodeTree *ntree, const bNode *node)
std::unique_ptr< ItemDeclaration > ItemDeclarationPtr
bool socket_type_supports_default_input_type(const bke::bNodeSocketType &socket_type, const NodeDefaultInputType input_type)
std::function< void(CustomSocketDrawParams &params)> CustomSocketDrawFn
std::unique_ptr< SocketDeclaration > make_declaration_for_socket_type(const eNodeSocketDatatype socket_type)
std::unique_ptr< PanelDeclaration > PanelDeclarationPtr
std::function< void(const bNode &node, void *r_value)> ImplicitInputValueFn
const PointerRNA PointerRNA_NULL
Definition DNA_ID.h:404
Defines a socket type.
Definition BKE_node.hh:152
Defines a node type.
Definition BKE_node.hh:226
PointerRNA * ptr
Definition wm_files.cc:4226