Blender V5.0
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_map.hh"
13#include "BLI_string_ref.hh"
14#include "BLI_utildefines.h"
15#include "BLI_vector.hh"
16
17#include "BLT_translation.hh" /* IWYU pragma: export */
18
19#include "DNA_node_types.h"
20
21#include "RNA_types.hh"
22
24
25struct bContext;
26struct bNode;
27struct uiLayout;
28
29namespace blender::nodes {
30
33
42
54
63
83
93
107
109
119
129
139
149
164
165std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations);
166
167} // namespace anonymous_attribute_lifetime
168namespace aal = anonymous_attribute_lifetime;
169
172 public:
173 const PanelDeclaration *parent = nullptr;
174
175 virtual ~ItemDeclaration() = default;
176};
177
178using ItemDeclarationPtr = std::unique_ptr<ItemDeclaration>;
179
184
198
200using InputSocketUsageInferenceFn = std::function<std::optional<bool>(
202
207 public:
208 std::string name;
209 std::string short_label;
210 std::string identifier;
211 std::string description;
212 std::optional<std::string> translation_context;
222 bool optional_label = false;
223 bool hide_value = false;
224 bool compact = false;
225 bool is_multi_input = false;
226 bool no_mute_links = false;
227 bool is_available = true;
228 bool is_attribute_name = false;
233 bool is_panel_toggle = false;
234 bool is_layer_name = false;
236
238 int index = -1;
239
242
243 StructureType structure_type = StructureType::Single;
244
245 private:
246 CompositorInputRealizationMode compositor_realization_mode_ =
248
252 int compositor_domain_priority_ = -1;
253
255 std::function<void(bNode &)> make_available_fn_;
256
257 public:
259 NodeDefaultInputType default_input_type = NodeDefaultInputType::NODE_DEFAULT_INPUT_VALUE;
264 std::unique_ptr<SocketNameRNA> socket_name_rna;
268 std::unique_ptr<CustomSocketDrawFn> custom_draw_fn;
273 std::unique_ptr<InputSocketUsageInferenceFn> usage_inference_fn;
274
277 template<typename SocketDecl> friend class SocketDeclarationBuilder;
278
279 ~SocketDeclaration() override = default;
280
281 virtual bNodeSocket &build(bNodeTree &ntree, bNode &node) const = 0;
282 virtual bool matches(const bNodeSocket &socket) const = 0;
283 virtual bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const;
284
289 virtual bool can_connect(const bNodeSocket &socket) const = 0;
290
296 void make_available(bNode &node) const;
297
299 int compositor_domain_priority() const;
300
301 protected:
302 void set_common_flags(bNodeSocket &socket) const;
303 bool matches_common_data(const bNodeSocket &socket) const;
304};
305
309
311 protected:
313 bool field_on_all_ = false;
317
320
321 public:
322 virtual ~BaseSocketDeclarationBuilder() = default;
323
325
326 BaseSocketDeclarationBuilder &hide_value(bool value = true);
327
328 BaseSocketDeclarationBuilder &multi_input(bool value = true);
329
330 BaseSocketDeclarationBuilder &compact(bool value = true);
331
332 BaseSocketDeclarationBuilder &short_label(std::string value = "");
333
334 BaseSocketDeclarationBuilder &description(std::string value = "");
335
337 std::optional<std::string> value = std::nullopt);
338
340
345 BaseSocketDeclarationBuilder &available(bool value = true);
346
348
350
352
355
364
367
370
373
376 Span<int> input_indices);
377
380
383
386
392
397
402
407
409
415
422 BaseSocketDeclarationBuilder &make_available(std::function<void(bNode &)> fn);
423
428
434
440
445 BaseSocketDeclarationBuilder &usage_by_menu(const StringRef menu_input_identifier,
446 const int menu_value);
447
452 BaseSocketDeclarationBuilder &usage_by_menu(const StringRef menu_input_identifier,
453 const Array<int> menu_values);
454
460
467 const StructRNA *srna,
468 const void *data,
469 StringRef property_name);
473 BaseSocketDeclarationBuilder &panel_toggle(bool value = true);
474
476
479
481 int index() const;
482
483 bool is_input() const;
484 bool is_output() const;
485};
486
492template<typename SocketDecl>
494 protected:
495 using Self = typename SocketDecl::Builder;
496 static_assert(std::is_base_of_v<SocketDeclaration, SocketDecl>);
497 SocketDecl *decl_;
498
501};
502
503using SocketDeclarationPtr = std::unique_ptr<SocketDeclaration>;
504
506
508
510 public:
511 std::function<DrawNodeLayoutFn> draw;
516 bool is_default = false;
517};
518
523 public:
525 std::string name;
526 std::string description;
527 std::optional<std::string> translation_context;
528 bool default_collapsed = false;
531 int index = -1;
533
534 private:
535 friend NodeDeclarationBuilder;
537
538 public:
539 ~PanelDeclaration() override = default;
540
541 void build(bNodePanelState &panel) const;
542 bool matches(const bNodePanelState &panel) const;
543 void update_or_build(const bNodePanelState &old_panel, bNodePanelState &new_panel) const;
544
545 int depth() const;
546
548 const SocketDeclaration *panel_input_decl() const;
549};
550
556 public:
560
566
567 template<typename DeclType>
568 typename DeclType::Builder &add_socket(StringRef name,
569 StringRef identifier,
570 eNodeSocketInOut in_out);
571
572 template<typename DeclType>
573 typename DeclType::Builder &add_input(StringRef name, StringRef identifier = "");
574 template<typename DeclType>
575 typename DeclType::Builder &add_output(StringRef name, StringRef identifier = "");
576
579 StringRef identifier = "");
582 StringRef identifier = "");
585 StringRef identifier = "");
588 StringRef identifier = "");
589
590 PanelDeclarationBuilder &add_panel(StringRef name, int identifier = -1);
591
592 void add_separator();
593 void add_default_layout();
594 void add_layout(std::function<void(uiLayout *, bContext *, PointerRNA *)> draw);
595};
596
598 protected:
601
603
604 public:
606 : DeclarationListBuilder(node_builder, decl.items), decl_(&decl)
607 {
608 this->parent_panel_decl = &decl;
609 }
610
611 Self &description(std::string value = "");
612 Self &translation_context(std::optional<std::string> value = std::nullopt);
613 Self &default_closed(bool closed);
614};
615
616using PanelDeclarationPtr = std::unique_ptr<PanelDeclaration>;
617
619 public:
628 std::unique_ptr<aal::RelationsInNode> anonymous_attribute_relations_;
629
634
638
642
647
649
651 void assert_valid() const;
652
653 bool matches(const bNode &node) const;
655
656 const aal::RelationsInNode *anonymous_attribute_relations() const
657 {
659 }
660
661 MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration")
662};
663
664class NodeDeclarationBuilder : public DeclarationListBuilder {
665 private:
666 const bke::bNodeType &typeinfo_;
667 NodeDeclaration &declaration_;
668 const bNodeTree *ntree_ = nullptr;
669 const bNode *node_ = nullptr;
671 Vector<BaseSocketDeclarationBuilder *> input_socket_builders_;
672 Vector<BaseSocketDeclarationBuilder *> output_socket_builders_;
674 bool is_function_node_ = false;
675
676 friend DeclarationListBuilder;
677
678 public:
681 const bNodeTree *ntree = nullptr,
682 const bNode *node = nullptr);
683
684 const bNode *node_or_null() const
685 {
686 declaration_.is_context_dependent = true;
687 return node_;
688 }
689
690 const bNodeTree *tree_or_null() const
691 {
692 declaration_.is_context_dependent = true;
693 return ntree_;
694 }
695
701 {
702 is_function_node_ = true;
703 }
704
705 void finalize();
706
707 void use_custom_socket_order(bool enable = true);
708 void allow_any_socket_order(bool enable = true);
709
710 aal::RelationsInNode &get_anonymous_attribute_relations()
711 {
712 if (!declaration_.anonymous_attribute_relations_) {
713 declaration_.anonymous_attribute_relations_ = std::make_unique<aal::RelationsInNode>();
714 }
715 return *declaration_.anonymous_attribute_relations_;
716 }
717
719 {
720 return declaration_;
721 }
722
723 private:
724 void build_remaining_anonymous_attribute_relations();
725};
726
727using ImplicitInputValueFn = std::function<void(const bNode &node, void *r_value)>;
728std::optional<ImplicitInputValueFn> get_implicit_input_value_fn(NodeDefaultInputType type);
730 NodeDefaultInputType input_type);
731
732void build_node_declaration(const bke::bNodeType &typeinfo,
733 NodeDeclaration &r_declaration,
734 const bNodeTree *ntree,
735 const bNode *node);
736
737std::unique_ptr<SocketDeclaration> make_declaration_for_socket_type(
738 eNodeSocketDatatype socket_type);
739
740/* -------------------------------------------------------------------- */
743
744template<typename DeclType>
745inline typename DeclType::Builder &DeclarationListBuilder::add_input(StringRef name,
746 StringRef identifier)
747{
748 return this->add_socket<DeclType>(name, identifier, SOCK_IN);
749}
750
751template<typename DeclType>
752inline typename DeclType::Builder &DeclarationListBuilder::add_output(StringRef name,
753 StringRef identifier)
754{
755 return this->add_socket<DeclType>(name, identifier, SOCK_OUT);
756}
757
758template<typename DeclType>
759inline typename DeclType::Builder &DeclarationListBuilder::add_socket(StringRef name,
760 StringRef identifier,
761 eNodeSocketInOut in_out)
762{
763 static_assert(std::is_base_of_v<SocketDeclaration, DeclType>);
764 using SocketBuilder = typename DeclType::Builder;
765
766 BLI_assert(ELEM(in_out, SOCK_IN, SOCK_OUT));
767
768 std::unique_ptr<SocketBuilder> socket_decl_builder_ptr = std::make_unique<SocketBuilder>();
769 SocketBuilder &socket_decl_builder = *socket_decl_builder_ptr;
770 this->node_decl_builder.socket_builders_.append(std::move(socket_decl_builder_ptr));
771
772 std::unique_ptr<DeclType> socket_decl_ptr = std::make_unique<DeclType>();
773 DeclType &socket_decl = *socket_decl_ptr;
774 this->node_decl_builder.declaration_.all_items.append(std::move(socket_decl_ptr));
775 this->items.append(&socket_decl);
776
777 socket_decl.parent = this->parent_panel_decl;
778 socket_decl_builder.node_decl_builder_ = &this->node_decl_builder;
779
780 socket_decl_builder.decl_ = &socket_decl;
781 socket_decl_builder.decl_base_ = &socket_decl;
782 socket_decl.name = name;
783 socket_decl.identifier = identifier.is_empty() ? name : identifier;
784 socket_decl.in_out = in_out;
785 socket_decl.socket_type = DeclType::static_socket_type;
786
787 if (this->node_decl_builder.is_function_node_) {
788 if (in_out == SOCK_IN) {
789 socket_decl_builder.supports_field();
790 }
791 else {
792 socket_decl_builder.dependent_field();
793 }
794 }
795
796 if (in_out == SOCK_IN) {
797 this->node_decl_builder.input_socket_builders_.append(&socket_decl_builder);
798 socket_decl.index = this->node_decl_builder.declaration_.inputs.append_and_get_index(
799 &socket_decl);
800 }
801 else {
802 this->node_decl_builder.output_socket_builders_.append(&socket_decl_builder);
803 socket_decl.index = this->node_decl_builder.declaration_.outputs.append_and_get_index(
804 &socket_decl);
805 }
806 return socket_decl_builder;
807}
808
810
811/* -------------------------------------------------------------------- */
814
816{
817 return decl_base_->index;
818}
819
821{
822 return decl_base_->in_out == SOCK_IN;
823}
824
826{
827 return decl_base_->in_out == SOCK_OUT;
828}
829
831
832} // 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 & optional_label(bool value=true)
BaseSocketDeclarationBuilder & usage_by_menu(const StringRef menu_input_identifier, const int menu_value)
BaseSocketDeclarationBuilder & usage_by_single_menu(const int menu_value)
BaseSocketDeclarationBuilder & compositor_realization_mode(CompositorInputRealizationMode value)
BaseSocketDeclarationBuilder & propagate_all()
BaseSocketDeclarationBuilder & available(bool value=true)
BaseSocketDeclarationBuilder & implicit_field(NodeDefaultInputType default_input)
BaseSocketDeclarationBuilder & usage_inference(InputSocketUsageInferenceFn fn)
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 & short_label(std::string value="")
BaseSocketDeclarationBuilder & supports_field()
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 & is_volume_grid_name(bool value=true)
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
std::unique_ptr< InputSocketUsageInferenceFn > usage_inference_fn
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::function< std::optional< bool >( const socket_usage_inference::InputSocketUsageParams &params)> InputSocketUsageInferenceFn
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 char * name
const PointerRNA PointerRNA_NULL
Definition DNA_ID.h:414
Defines a socket type.
Definition BKE_node.hh:158
Defines a node type.
Definition BKE_node.hh:238
void draw_standard(uiLayout &layout, std::optional< StringRefNull > label_override=std::nullopt)
const Map< const bNode *, const bNode * > * menu_switch_source_by_index_switch
PointerRNA * ptr
Definition wm_files.cc:4238