Blender V4.5
node_declaration.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_assert.h"
10#include "BLI_utildefines.h"
11
13#include "BKE_node.hh"
14#include "BKE_node_runtime.hh"
16
17#include "RNA_access.hh"
18
19namespace blender::nodes {
20
21static void reset_declaration(NodeDeclaration &declaration)
22{
23 std::destroy_at(&declaration);
24 new (&declaration) NodeDeclaration();
25}
26
28 NodeDeclaration &r_declaration,
29 const bNodeTree *ntree,
30 const bNode *node)
31{
32 reset_declaration(r_declaration);
33 NodeDeclarationBuilder node_decl_builder{typeinfo, r_declaration, ntree, node};
34 typeinfo.declare(node_decl_builder);
35 node_decl_builder.finalize();
36}
37
38void NodeDeclarationBuilder::build_remaining_anonymous_attribute_relations()
39{
40 auto is_data_socket_decl = [](const SocketDeclaration *socket_decl) {
41 return ELEM(socket_decl->socket_type, SOCK_GEOMETRY, SOCK_BUNDLE, SOCK_CLOSURE);
42 };
43
44 Vector<int> geometry_inputs;
45 for (const int i : declaration_.inputs.index_range()) {
46 if (is_data_socket_decl(declaration_.inputs[i])) {
47 geometry_inputs.append(i);
48 }
49 }
50 Vector<int> geometry_outputs;
51 for (const int i : declaration_.outputs.index_range()) {
52 if (is_data_socket_decl(declaration_.outputs[i])) {
53 geometry_outputs.append(i);
54 }
55 }
56
57 for (BaseSocketDeclarationBuilder *socket_builder : input_socket_builders_) {
58 if (socket_builder->field_on_all_) {
59 aal::RelationsInNode &relations = this->get_anonymous_attribute_relations();
60 const int field_input = socket_builder->decl_base_->index;
61 for (const int geometry_input : geometry_inputs) {
62 relations.eval_relations.append({field_input, geometry_input});
63 }
64 }
65 }
66 for (BaseSocketDeclarationBuilder *socket_builder : output_socket_builders_) {
67 if (socket_builder->field_on_all_) {
68 aal::RelationsInNode &relations = this->get_anonymous_attribute_relations();
69 const int field_output = socket_builder->decl_base_->index;
70 for (const int geometry_output : geometry_outputs) {
71 relations.available_relations.append({field_output, geometry_output});
72 }
73 }
74 if (socket_builder->reference_pass_all_) {
75 aal::RelationsInNode &relations = this->get_anonymous_attribute_relations();
76 const int field_output = socket_builder->decl_base_->index;
77 for (const int input_i : declaration_.inputs.index_range()) {
78 SocketDeclaration &input_socket_decl = *declaration_.inputs[input_i];
79 if (input_socket_decl.input_field_type != InputSocketFieldType::None) {
80 relations.reference_relations.append({input_i, field_output});
81 }
82 }
83 }
84 if (socket_builder->propagate_from_all_) {
85 aal::RelationsInNode &relations = this->get_anonymous_attribute_relations();
86 const int geometry_output = socket_builder->decl_base_->index;
87 for (const int geometry_input : geometry_inputs) {
88 relations.propagate_relations.append({geometry_input, geometry_output});
89 }
90 }
91 }
92}
93
95{
96 this->build_remaining_anonymous_attribute_relations();
97 if (is_function_node_) {
98 for (SocketDeclaration *socket_decl : declaration_.inputs) {
99 socket_decl->structure_type = StructureType::Dynamic;
100 }
101 for (SocketDeclaration *socket_decl : declaration_.outputs) {
102 socket_decl->structure_type = StructureType::Dynamic;
103 }
104 }
105#ifndef NDEBUG
106 declaration_.assert_valid();
107#endif
108}
109
112 const bNodeTree *ntree,
113 const bNode *node)
114 : DeclarationListBuilder(*this, declaration.root_items),
115 typeinfo_(typeinfo),
116 declaration_(declaration),
117 ntree_(ntree),
118 node_(node)
119{
120 /* Unused in release builds, but used for BLI_assert() in debug builds. */
121 UNUSED_VARS(typeinfo_);
122}
123
125{
126 declaration_.use_custom_socket_order = enable;
127}
128
130{
131 BLI_assert(declaration_.use_custom_socket_order);
132 declaration_.allow_any_socket_order = enable;
133}
134
136{
137 if (in_out == SOCK_IN) {
138 return inputs;
139 }
140 return outputs;
141}
142
144
145std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations)
146{
147 stream << "Propagate Relations: " << relations.propagate_relations.size() << "\n";
148 for (const PropagateRelation &relation : relations.propagate_relations) {
149 stream << " " << relation.from_geometry_input << " -> " << relation.to_geometry_output
150 << "\n";
151 }
152 stream << "Reference Relations: " << relations.reference_relations.size() << "\n";
153 for (const ReferenceRelation &relation : relations.reference_relations) {
154 stream << " " << relation.from_field_input << " -> " << relation.to_field_output << "\n";
155 }
156 stream << "Eval Relations: " << relations.eval_relations.size() << "\n";
157 for (const EvalRelation &relation : relations.eval_relations) {
158 stream << " eval " << relation.field_input << " on " << relation.geometry_input << "\n";
159 }
160 stream << "Available Relations: " << relations.available_relations.size() << "\n";
161 for (const AvailableRelation &relation : relations.available_relations) {
162 stream << " " << relation.field_output << " available on " << relation.geometry_output
163 << "\n";
164 }
165 stream << "Available on None: " << relations.available_on_none.size() << "\n";
166 for (const int i : relations.available_on_none) {
167 stream << " output " << i << " available on none\n";
168 }
169 return stream;
170}
171
172} // namespace anonymous_attribute_lifetime
173
177 Vector<const SocketDeclaration *> &r_flat_outputs)
178{
179 /* Expected item order unless any order is allowed: outputs, inputs, panels. */
180 bool found_input = false;
181 bool found_panel = false;
182
183 for (const ItemDeclaration *item_decl : items) {
184 if (const auto *socket_decl = dynamic_cast<const SocketDeclaration *>(item_decl)) {
185 if (socket_decl->in_out == SOCK_IN) {
186 BLI_assert(node_decl.allow_any_socket_order || !found_panel);
187 found_input = true;
188 r_flat_inputs.append(socket_decl);
189 }
190 else {
191 BLI_assert(node_decl.allow_any_socket_order || (!found_input && !found_panel));
192 r_flat_outputs.append(socket_decl);
193 }
194 }
195 else if (const auto *panel_decl = dynamic_cast<const PanelDeclaration *>(item_decl)) {
196 found_panel = true;
197 assert_valid_panels_recursive(node_decl, panel_decl->items, r_flat_inputs, r_flat_outputs);
198 }
199 }
200 UNUSED_VARS(found_input, found_panel);
201}
202
204{
205 if (!this->use_custom_socket_order) {
206 /* Skip validation for conventional socket layouts. Those are reordered in drawing code. */
207 return;
208 }
209
212 assert_valid_panels_recursive(*this, this->root_items, flat_inputs, flat_outputs);
213
214 BLI_assert(this->inputs.as_span() == flat_inputs);
215 BLI_assert(this->outputs.as_span() == flat_outputs);
216}
217
218bool NodeDeclaration::matches(const bNode &node) const
219{
220 const bNodeSocket *current_input = static_cast<bNodeSocket *>(node.inputs.first);
221 const bNodeSocket *current_output = static_cast<bNodeSocket *>(node.outputs.first);
222 const bNodePanelState *current_panel = node.panel_states_array;
223 for (const ItemDeclarationPtr &item_decl : this->all_items) {
224 if (const SocketDeclaration *socket_decl = dynamic_cast<const SocketDeclaration *>(
225 item_decl.get()))
226 {
227 switch (socket_decl->in_out) {
228 case SOCK_IN:
229 if (current_input == nullptr || !socket_decl->matches(*current_input)) {
230 return false;
231 }
232 current_input = current_input->next;
233 break;
234 case SOCK_OUT:
235 if (current_output == nullptr || !socket_decl->matches(*current_output)) {
236 return false;
237 }
238 current_output = current_output->next;
239 break;
240 }
241 }
242 else if (const PanelDeclaration *panel_decl = dynamic_cast<const PanelDeclaration *>(
243 item_decl.get()))
244 {
245 if (!node.panel_states().contains_ptr(current_panel) || !panel_decl->matches(*current_panel))
246 {
247 return false;
248 }
249 ++current_panel;
250 }
251 else if (dynamic_cast<const SeparatorDeclaration *>(item_decl.get()) ||
252 dynamic_cast<const LayoutDeclaration *>(item_decl.get()))
253 {
254 /* Ignored because they don't have corresponding data in DNA. */
255 }
256 else {
257 /* Unknown item type. */
259 }
260 }
261 /* If items are left over, some were removed from the declaration. */
262 if (current_input != nullptr || current_output != nullptr ||
263 node.panel_states().contains_ptr(current_panel))
264 {
265 return false;
266 }
267 return true;
268}
269
271 bNode &node,
272 bNodeSocket &socket) const
273{
274 /* By default just rebuild. */
275 BLI_assert(socket.in_out == this->in_out);
276 UNUSED_VARS_NDEBUG(socket);
277 return this->build(ntree, node);
278}
279
289
291{
292 if (socket.name != this->name) {
293 return false;
294 }
295 if (socket.identifier != this->identifier) {
296 return false;
297 }
298 if (((socket.flag & SOCK_COMPACT) != 0) != this->compact) {
299 return false;
300 }
301 if (((socket.flag & SOCK_HIDE_VALUE) != 0) != this->hide_value) {
302 return false;
303 }
304 if (((socket.flag & SOCK_HIDE_LABEL) != 0) != this->hide_label) {
305 return false;
306 }
307 if (((socket.flag & SOCK_MULTI_INPUT) != 0) != this->is_multi_input) {
308 return false;
309 }
310 if (((socket.flag & SOCK_NO_INTERNAL_LINK) != 0) != this->no_mute_links) {
311 return false;
312 }
313 if (((socket.flag & SOCK_UNAVAIL) != 0) != !this->is_available) {
314 return false;
315 }
316 return true;
317}
318
319template<typename Fn>
320static bool socket_type_to_static_decl_type(const eNodeSocketDatatype socket_type, Fn &&fn)
321{
322 switch (socket_type) {
323 case SOCK_FLOAT:
325 return true;
326 case SOCK_VECTOR:
328 return true;
329 case SOCK_RGBA:
331 return true;
332 case SOCK_BOOLEAN:
334 return true;
335 case SOCK_ROTATION:
337 return true;
338 case SOCK_MATRIX:
340 return true;
341 case SOCK_INT:
343 return true;
344 case SOCK_STRING:
346 return true;
347 case SOCK_GEOMETRY:
349 return true;
350 case SOCK_OBJECT:
352 return true;
353 case SOCK_IMAGE:
355 return true;
356 case SOCK_COLLECTION:
358 return true;
359 case SOCK_MATERIAL:
361 return true;
362 case SOCK_MENU:
364 return true;
365 case SOCK_BUNDLE:
367 return true;
368 case SOCK_CLOSURE:
370 return true;
371 default:
372 return false;
373 }
374}
375
376std::unique_ptr<SocketDeclaration> make_declaration_for_socket_type(
377 const eNodeSocketDatatype socket_type)
378{
379 std::unique_ptr<SocketDeclaration> decl;
380 socket_type_to_static_decl_type(socket_type, [&](auto type_tag) {
381 using DeclT = typename decltype(type_tag)::type;
382 decl = std::make_unique<DeclT>();
383 });
384 return decl;
385}
386
388 const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier)
389{
391 socket_type_to_static_decl_type(socket_type, [&](auto type_tag) {
392 using DeclT = typename decltype(type_tag)::type;
393 decl = &this->add_input<DeclT>(name, identifier);
394 });
395 if (!decl) {
397 decl = &this->add_input<decl::Float>("", "");
398 }
399 return *decl;
400}
401
403 const StringRef name,
404 const StringRef identifier)
405{
406 return this->add_input(*bke::custom_data_type_to_socket_type(data_type), name, identifier);
407}
408
410 const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier)
411{
413 socket_type_to_static_decl_type(socket_type, [&](auto type_tag) {
414 using DeclT = typename decltype(type_tag)::type;
415 decl = &this->add_output<DeclT>(name, identifier);
416 });
417 if (!decl) {
419 decl = &this->add_output<decl::Float>("", "");
420 }
421 return *decl;
422}
423
425 const StringRef name,
426 const StringRef identifier)
427{
428 return this->add_output(*bke::custom_data_type_to_socket_type(data_type), name, identifier);
429}
430
432{
433 auto decl_ptr = std::make_unique<SeparatorDeclaration>();
434 SeparatorDeclaration &decl = *decl_ptr;
435 this->node_decl_builder.declaration_.all_items.append(std::move(decl_ptr));
436 this->items.append(&decl);
437}
438
440{
441 BLI_assert(this->node_decl_builder.typeinfo_.draw_buttons);
442 this->add_layout([](uiLayout *layout, bContext *C, PointerRNA *ptr) {
443 const bNode &node = *static_cast<bNode *>(ptr->data);
444 node.typeinfo->draw_buttons(layout, C, ptr);
445 });
446 static_cast<LayoutDeclaration &>(*this->items.last()).is_default = true;
447}
448
450 std::function<void(uiLayout *, bContext *, PointerRNA *)> draw)
451{
452 auto decl_ptr = std::make_unique<LayoutDeclaration>();
453 LayoutDeclaration &decl = *decl_ptr;
454 decl.draw = std::move(draw);
455 this->node_decl_builder.declaration_.all_items.append(std::move(decl_ptr));
456 this->items.append(&decl);
457}
458
460{
461 auto panel_decl_ptr = std::make_unique<PanelDeclaration>();
462 PanelDeclaration &panel_decl = *panel_decl_ptr;
463 auto panel_decl_builder_ptr = std::make_unique<PanelDeclarationBuilder>(this->node_decl_builder,
464 panel_decl);
465 PanelDeclarationBuilder &panel_decl_builder = *panel_decl_builder_ptr;
466
467 if (identifier >= 0) {
468 panel_decl.identifier = identifier;
469 }
470 else {
471 /* Use index as identifier. */
472 panel_decl.identifier = this->node_decl_builder.declaration_.all_items.size();
473 }
474 panel_decl.name = name;
475 panel_decl.parent_panel = this->parent_panel_decl;
476 panel_decl.index = this->node_decl_builder.declaration_.panels.append_and_get_index(&panel_decl);
477 this->node_decl_builder.declaration_.all_items.append(std::move(panel_decl_ptr));
478 this->node_decl_builder.panel_builders_.append_and_get_index(std::move(panel_decl_builder_ptr));
479 this->items.append(&panel_decl);
480 return panel_decl_builder;
481}
482
484{
485 panel = {0};
486 panel.identifier = this->identifier;
487 SET_FLAG_FROM_TEST(panel.flag, this->default_collapsed, NODE_PANEL_COLLAPSED);
488}
489
491{
492 return panel.identifier == this->identifier;
493}
494
496 bNodePanelState &new_panel) const
497{
498 build(new_panel);
499 /* Copy existing state to the new panel */
500 SET_FLAG_FROM_TEST(new_panel.flag, old_panel.is_collapsed(), NODE_PANEL_COLLAPSED);
501}
502
504{
505 int count = 0;
506 for (const PanelDeclaration *parent = this->parent_panel; parent; parent = parent->parent_panel)
507 {
508 count++;
509 }
510 return count;
511}
512
514{
515 if (this->items.is_empty()) {
516 return nullptr;
517 }
518 const nodes::ItemDeclaration *item_decl = this->items.first();
519 if (const auto *socket_decl = dynamic_cast<const nodes::SocketDeclaration *>(item_decl)) {
520 if (socket_decl->is_panel_toggle && (socket_decl->in_out & SOCK_IN) &&
521 (socket_decl->socket_type & SOCK_BOOLEAN))
522 {
523 return socket_decl;
524 }
525 }
526 return nullptr;
527}
528
530{
531 BLI_assert(this->is_input());
533 this->structure_type(StructureType::Field);
534 return *this;
535}
536
538 Vector<int> input_dependencies)
539{
540 BLI_assert(this->is_output());
541 this->reference_pass(input_dependencies);
543 std::move(input_dependencies));
544 this->structure_type(StructureType::Dynamic);
545 return *this;
546}
547
549{
550 decl_base_->hide_label = value;
551 return *this;
552}
553
555{
556 decl_base_->hide_value = value;
557 return *this;
558}
559
561{
562 BLI_assert(this->is_input());
563 decl_base_->is_multi_input = value;
564 return *this;
565}
566
568{
569 decl_base_->compact = value;
570 return *this;
571}
572
574 const Span<int> input_indices)
575{
576 BLI_assert(this->is_output());
577 aal::RelationsInNode &relations = node_decl_builder_->get_anonymous_attribute_relations();
578 for (const int from_input : input_indices) {
579 aal::ReferenceRelation relation;
580 relation.from_field_input = from_input;
581 relation.to_field_output = decl_base_->index;
582 relations.reference_relations.append(relation);
583 }
584 return *this;
585}
586
588{
589 aal::RelationsInNode &relations = node_decl_builder_->get_anonymous_attribute_relations();
590 if (this->is_input()) {
591 this->supports_field();
592 for (const int input_index : indices) {
593 aal::EvalRelation relation;
594 relation.field_input = decl_base_->index;
595 relation.geometry_input = input_index;
596 relations.eval_relations.append(relation);
597 }
598 }
599 else {
600 this->field_source();
601 for (const int output_index : indices) {
602 aal::AvailableRelation relation;
603 relation.field_output = decl_base_->index;
604 relation.geometry_output = output_index;
605 relations.available_relations.append(relation);
606 }
607 }
608 this->structure_type(StructureType::Field);
609 return *this;
610}
611
613{
614 decl_base_->short_label = std::move(value);
615 return *this;
616}
617
619{
620 decl_base_->description = std::move(value);
621 return *this;
622}
623
625 std::optional<std::string> value)
626{
627 decl_base_->translation_context = std::move(value);
628 return *this;
629}
630
632{
633 decl_base_->no_mute_links = value;
634 return *this;
635}
636
638{
639 decl_base_->is_available = value;
640 return *this;
641}
642
644{
645 decl_base_->is_attribute_name = value;
646 return *this;
647}
648
650{
651 decl_base_->is_default_link_socket = value;
652 return *this;
653}
654
656 const NodeDefaultInputType value)
657{
658 decl_base_->default_input_type = value;
659 return *this;
660}
661
663{
664 if (this->is_input()) {
665 this->supports_field();
666 }
667 if (this->is_output()) {
668 this->field_source();
669 }
670 field_on_all_ = true;
671 this->structure_type(StructureType::Field);
672 return *this;
673}
674
676{
677 BLI_assert(this->is_output());
678 decl_base_->output_field_dependency = OutputFieldDependency::ForFieldSource();
679 this->structure_type(StructureType::Field);
680 return *this;
681}
682
685{
686 BLI_assert(this->is_input());
687 this->hide_value();
688 this->structure_type(StructureType::Dynamic);
689 decl_base_->input_field_type = InputSocketFieldType::Implicit;
690 decl_base_->default_input_type = default_input_type;
691 return *this;
692}
693
696{
697 this->implicit_field(default_input_type);
698 field_on_all_ = true;
699 this->structure_type(StructureType::Field);
700 return *this;
701}
702
704 const NodeDefaultInputType default_input_type, const Span<int> input_indices)
705{
706 this->field_on(input_indices);
707 this->implicit_field(default_input_type);
708 this->structure_type(StructureType::Field);
709 return *this;
710}
711
713{
714 BLI_assert(this->is_output());
715 decl_base_->output_field_dependency = OutputFieldDependency::ForDependentField();
716 this->structure_type(StructureType::Dynamic);
717 this->reference_pass_all();
718 return *this;
719}
720
727
733
739
741{
742 /* We can't distinguish between actually propagating everything or just instance attributes
743 * currently. It's still nice to be more explicit at the node declaration level. */
744 this->propagate_all();
745 return *this;
746}
747
750{
751 decl_base_->compositor_realization_mode_ = value;
752 return *this;
753}
754
756 int priority)
757{
758 BLI_assert(priority >= 0);
759 decl_base_->compositor_domain_priority_ = priority;
760 return *this;
761}
762
764 bool value)
765{
766 decl_base_->compositor_expects_single_value_ = value;
767 return *this;
768}
769
771 std::function<void(bNode &)> fn)
772{
773 decl_base_->make_available_fn_ = std::move(fn);
774 return *this;
775}
776
778{
779 decl_base_->custom_draw_fn = std::make_unique<CustomSocketDrawFn>(std::move(fn));
780 return *this;
781}
782
784{
785 decl_base_->align_with_previous_socket = value;
786 return *this;
787}
788
790 const StructureType structure_type)
791{
792 decl_base_->structure_type = structure_type;
793 return *this;
794}
795
796BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder ::socket_name_ptr(
797 const PointerRNA ptr, const StringRef property_name)
798{
799 decl_base_->socket_name_rna = std::make_unique<SocketNameRNA>();
800 decl_base_->socket_name_rna->owner = ptr;
801 decl_base_->socket_name_rna->property_name = property_name;
802 return *this;
803}
804
806 const ID *id, const StructRNA *srna, const void *data, StringRef property_name)
807{
808 /* Doing const-casts here because this data is generally only available as const when creating
809 * the declaration, but it's still valid to modify later. */
810 return this->socket_name_ptr(RNA_pointer_create_discrete(const_cast<ID *>(id),
811 const_cast<StructRNA *>(srna),
812 const_cast<void *>(data)),
813 property_name);
814}
815
817{
818 decl_base_->is_panel_toggle = value;
819 return *this;
820}
821
823{
824 decl_base_->is_layer_name = value;
825 return *this;
826}
827
829{
830 OutputFieldDependency field_dependency;
831 field_dependency.type_ = OutputSocketFieldType::FieldSource;
832 return field_dependency;
833}
834
836{
837 OutputFieldDependency field_dependency;
838 field_dependency.type_ = OutputSocketFieldType::None;
839 return field_dependency;
840}
841
843{
844 OutputFieldDependency field_dependency;
845 field_dependency.type_ = OutputSocketFieldType::DependentField;
846 return field_dependency;
847}
848
850{
851 OutputFieldDependency field_dependency;
852 if (indices.is_empty()) {
853 field_dependency.type_ = OutputSocketFieldType::None;
854 }
855 else {
856 field_dependency.type_ = OutputSocketFieldType::PartiallyDependent;
857 field_dependency.linked_input_indices_ = std::move(indices);
858 }
859 return field_dependency;
860}
861
866
868{
869 return linked_input_indices_;
870}
871
873{
874 return compositor_realization_mode_;
875}
876
878{
879 return compositor_domain_priority_;
880}
881
883{
884 return compositor_expects_single_value_;
885}
886
888{
889 if (make_available_fn_) {
890 make_available_fn_(node);
891 }
892}
893
895{
896 decl_->description = std::move(value);
897 return *this;
898}
899
901 std::optional<std::string> value)
902{
903 decl_->translation_context = value;
904 return *this;
905}
906
908{
909 decl_->default_collapsed = closed;
910 return *this;
911}
912
914
915static void position(const bNode & /*node*/, void *r_value)
916{
918}
919
920static void normal(const bNode & /*node*/, void *r_value)
921{
922 new (r_value)
923 bke::SocketValueVariant(fn::Field<float3>(std::make_shared<bke::NormalFieldInput>()));
924}
925
926static void index(const bNode & /*node*/, void *r_value)
927{
928 new (r_value) bke::SocketValueVariant(fn::Field<int>(std::make_shared<fn::IndexFieldInput>()));
929}
930
931static void id_or_index(const bNode & /*node*/, void *r_value)
932{
933 new (r_value)
934 bke::SocketValueVariant(fn::Field<int>(std::make_shared<bke::IDAttributeFieldInput>()));
935}
936
937static void instance_transform(const bNode & /*node*/, void *r_value)
938{
939 new (r_value)
941}
942
943static void handle_left(const bNode & /*node*/, void *r_value)
944{
946}
947
948static void handle_right(const bNode & /*node*/, void *r_value)
949{
951}
952
953} // namespace implicit_field_inputs
954
955std::optional<ImplicitInputValueFn> get_implicit_input_value_fn(const NodeDefaultInputType type)
956{
957 switch (type) {
959 return std::nullopt;
961 return std::make_optional(implicit_field_inputs::index);
963 return std::make_optional(implicit_field_inputs::id_or_index);
965 return std::make_optional(implicit_field_inputs::normal);
967 return std::make_optional(implicit_field_inputs::position);
969 return std::make_optional(implicit_field_inputs::instance_transform);
971 return std::make_optional(implicit_field_inputs::handle_left);
973 return std::make_optional(implicit_field_inputs::handle_right);
974 }
975 return std::nullopt;
976}
977
979 const NodeDefaultInputType input_type)
980{
981 const eNodeSocketDatatype stype = socket_type.type;
982 switch (input_type) {
984 return true;
987 return stype == SOCK_INT;
992 return stype == SOCK_VECTOR;
994 return stype == SOCK_MATRIX;
995 }
996 return false;
997}
998
999} // namespace blender::nodes
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define UNUSED_VARS(...)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
float[3] Vector
@ NODE_DEFAULT_INPUT_POSITION_FIELD
@ NODE_DEFAULT_INPUT_HANDLE_RIGHT_FIELD
@ NODE_DEFAULT_INPUT_HANDLE_LEFT_FIELD
@ NODE_DEFAULT_INPUT_ID_INDEX_FIELD
@ NODE_DEFAULT_INPUT_INSTANCE_TRANSFORM_FIELD
@ NODE_DEFAULT_INPUT_NORMAL_FIELD
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDE_LABEL
@ SOCK_HIDE_VALUE
@ SOCK_MULTI_INPUT
@ SOCK_COMPACT
@ SOCK_UNAVAIL
@ SOCK_NO_INTERNAL_LINK
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_CLOSURE
@ SOCK_BOOLEAN
@ SOCK_MATERIAL
@ SOCK_MATRIX
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_BUNDLE
@ SOCK_GEOMETRY
@ SOCK_ROTATION
@ SOCK_OBJECT
@ SOCK_STRING
@ SOCK_RGBA
@ SOCK_MENU
@ NODE_PANEL_COLLAPSED
#define C
Definition RandGen.cpp:29
BMesh const char void * data
InputSocketFieldType input_field_type
void append(const T &value)
int64_t size() const
void append(const T &value)
static fn::GField Create(std::string name, const CPPType &type, std::optional< std::string > socket_inspection_name=std::nullopt)
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="")
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="")
NodeDeclarationBuilder(const bke::bNodeType &typeinfo, NodeDeclaration &declaration, const bNodeTree *ntree=nullptr, const bNode *node=nullptr)
aal::RelationsInNode & get_anonymous_attribute_relations()
Vector< ItemDeclaration * > root_items
Vector< SocketDeclaration * > inputs
bool matches(const bNode &node) const
Vector< SocketDeclaration * > outputs
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)
Vector< ItemDeclaration * > items
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
bool matches_common_data(const bNodeSocket &socket) const
const CompositorInputRealizationMode & compositor_realization_mode() const
void make_available(bNode &node) const
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[]
#define this
int count
std::optional< eNodeSocketDatatype > custom_data_type_to_socket_type(eCustomDataType type)
Definition node.cc:5379
std::ostream & operator<<(std::ostream &stream, const RelationsInNode &relations)
static void position(const bNode &, void *r_value)
static void id_or_index(const bNode &, void *r_value)
static void handle_left(const bNode &, void *r_value)
static void index(const bNode &, void *r_value)
static void instance_transform(const bNode &, void *r_value)
static void handle_right(const bNode &, void *r_value)
static void normal(const bNode &, void *r_value)
std::optional< ImplicitInputValueFn > get_implicit_input_value_fn(const NodeDefaultInputType type)
static void assert_valid_panels_recursive(const NodeDeclaration &node_decl, const Span< const ItemDeclaration * > items, Vector< const SocketDeclaration * > &r_flat_inputs, Vector< const SocketDeclaration * > &r_flat_outputs)
void build_node_declaration(const bke::bNodeType &typeinfo, NodeDeclaration &r_declaration, const bNodeTree *ntree, const bNode *node)
static bool socket_type_to_static_decl_type(const eNodeSocketDatatype socket_type, Fn &&fn)
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
static void reset_declaration(NodeDeclaration &declaration)
std::unique_ptr< SocketDeclaration > make_declaration_for_socket_type(const eNodeSocketDatatype socket_type)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
Definition DNA_ID.h:404
void * first
struct bNodeSocket * next
char identifier[64]
bNodeTypeHandle * typeinfo
ListBase inputs
bNodePanelState * panel_states_array
ListBase outputs
Defines a socket type.
Definition BKE_node.hh:152
eNodeSocketDatatype type
Definition BKE_node.hh:187
Defines a node type.
Definition BKE_node.hh:226
NodeDeclareFunction declare
Definition BKE_node.hh:355
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4227