Blender V5.0
rna_node_tree_interface.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
10
11#include "RNA_define.hh"
12#include "RNA_enum_types.hh"
13#include "RNA_types.hh"
14
15#include "rna_internal.hh"
16
17#include "WM_types.hh"
18
20 {NODE_INTERFACE_SOCKET, "SOCKET", 0, "Socket", ""},
21 {NODE_INTERFACE_PANEL, "PANEL", 0, "Panel", ""},
22 {0, nullptr, 0, nullptr, nullptr}};
23
25 {NODE_INTERFACE_SOCKET_INPUT, "INPUT", 0, "Input", "Generate a input node socket"},
26 {NODE_INTERFACE_SOCKET_OUTPUT, "OUTPUT", 0, "Output", "Generate a output node socket"},
27 {0, nullptr, 0, nullptr, nullptr}};
28
31 "AUTO",
32 0,
33 "Auto",
34 "Automatically detect a good structure type based on how the socket is used"},
36 "DYNAMIC",
37 0,
38 "Dynamic",
39 "Socket can work with different kinds of structures"},
40 {NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_FIELD, "FIELD", 0, "Field", "Socket expects a field"},
41 {NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_GRID, "GRID", 0, "Grid", "Socket expects a grid"},
42 {NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_LIST, "LIST", 0, "List", "Socket expects a list"},
44 "SINGLE",
45 0,
46 "Single",
47 "Socket expects a single value"},
48 {0, nullptr, 0, nullptr, nullptr}};
49
51 {NODE_DEFAULT_INPUT_VALUE, "VALUE", 0, "Default Value", "The node socket's default value"},
52 {NODE_DEFAULT_INPUT_INDEX_FIELD, "INDEX", 0, "Index", "The index from the context"},
54 "ID_OR_INDEX",
55 0,
56 "ID or Index",
57 "The \"id\" attribute if available, otherwise the index"},
58 {NODE_DEFAULT_INPUT_NORMAL_FIELD, "NORMAL", 0, "Normal", "The geometry's normal direction"},
60 "POSITION",
61 0,
62 "Position",
63 "The position from the context"},
65 "INSTANCE_TRANSFORM",
66 0,
67 "Instance Transform",
68 "Transformation of each instance from the geometry context"},
70 "HANDLE_LEFT",
71 0,
72 "Left Handle",
73 "The left Bézier control point handle from the context"},
75 "HANDLE_RIGHT",
76 0,
77 "Right Handle",
78 "The right Bézier control point handle from the context"},
79 {0, nullptr, 0, nullptr, nullptr}};
80
81#ifdef RNA_RUNTIME
82
83# include <fmt/format.h>
84
85# include "BLI_string_ref.hh"
86
87# include "BKE_attribute.hh"
88# include "BKE_main_invariants.hh"
89# include "BKE_node.hh"
90# include "BKE_node_enum.hh"
91# include "BKE_node_runtime.hh"
94
95# include "BLI_set.hh"
96
97# include "BLT_translation.hh"
98
100# include "NOD_rna_define.hh"
101# include "NOD_socket.hh"
102
103# include "DNA_material_types.h"
104
105# include "WM_api.hh"
106
107# include "ED_node.hh"
108
109/* Internal RNA function declarations, used to invoke registered callbacks. */
110extern FunctionRNA rna_NodeTreeInterfaceSocket_draw_func;
111extern FunctionRNA rna_NodeTreeInterfaceSocket_init_socket_func;
112extern FunctionRNA rna_NodeTreeInterfaceSocket_from_socket_func;
113
115
116static void rna_NodeTreeInterfaceItem_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
117{
118 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
119 if (!ntree) {
120 /* This can happen because of the dummy socket in #rna_NodeTreeInterfaceSocket_register. */
121 return;
122 }
123 ntree->tree_interface.tag_item_property_changed();
124 BKE_main_ensure_invariants(*bmain, ntree->id);
125}
126
127static StructRNA *rna_NodeTreeInterfaceItem_refine(PointerRNA *ptr)
128{
129 bNodeTreeInterfaceItem *item = static_cast<bNodeTreeInterfaceItem *>(ptr->data);
130
131 switch (NodeTreeInterfaceItemType(item->item_type)) {
134 *item);
135 if (socket.socket_type) {
137 socket.socket_type);
138 if (socket_typeinfo && socket_typeinfo->ext_interface.srna) {
139 return socket_typeinfo->ext_interface.srna;
140 }
141 }
142 return &RNA_NodeTreeInterfaceSocket;
143 }
145 return &RNA_NodeTreeInterfacePanel;
146 default:
147 return &RNA_NodeTreeInterfaceItem;
148 }
149}
150
151static std::optional<std::string> rna_NodeTreeInterfaceItem_path(const PointerRNA *ptr)
152{
153 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
154 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
155 if (!ntree->runtime) {
156 return std::nullopt;
157 }
158
159 ntree->ensure_interface_cache();
160 for (const int index : ntree->interface_items().index_range()) {
161 if (ntree->interface_items()[index] == item) {
162 return fmt::format("interface.items_tree[{}]", index);
163 }
164 }
165 return std::nullopt;
166}
167
168static PointerRNA rna_NodeTreeInterfaceItem_parent_get(PointerRNA *ptr)
169{
170 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
171 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
172 bNodeTreeInterfacePanel *parent = ntree->tree_interface.find_item_parent(*item, true);
173 PointerRNA result = RNA_pointer_create_discrete(&ntree->id, &RNA_NodeTreeInterfacePanel, parent);
174 return result;
175}
176
177static int rna_NodeTreeInterfaceItem_position_get(PointerRNA *ptr)
178{
179 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
180 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
181 return ntree->tree_interface.find_item_position(*item);
182}
183
184static int rna_NodeTreeInterfaceItem_index_get(PointerRNA *ptr)
185{
186 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
187 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
188 return ntree->tree_interface.find_item_index(*item);
189}
190
191static bool rna_NodeTreeInterfaceSocket_unregister(Main * /*bmain*/, StructRNA *type)
192{
195 if (!st) {
196 return false;
197 }
198
200
202
203 /* update while blender is running */
205 return true;
206}
207
208static void rna_NodeTreeInterfaceSocket_draw_builtin(ID *id,
209 bNodeTreeInterfaceSocket *interface_socket,
210 bContext *C,
211 uiLayout *layout)
212{
213 blender::bke::bNodeSocketType *typeinfo = interface_socket->socket_typeinfo();
214 if (typeinfo && typeinfo->interface_draw) {
215 typeinfo->interface_draw(id, interface_socket, C, layout);
216 }
217}
218
219static void rna_NodeTreeInterfaceSocket_draw_custom(ID *id,
220 bNodeTreeInterfaceSocket *interface_socket,
221 bContext *C,
222 uiLayout *layout)
223{
225 interface_socket->socket_type);
226 if (typeinfo == nullptr) {
227 return;
228 }
229
230 PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_NodeTreeInterfaceSocket, interface_socket);
231
232 FunctionRNA *func = &rna_NodeTreeInterfaceSocket_draw_func;
233
234 ParameterList list;
235 RNA_parameter_list_create(&list, &ptr, func);
236 RNA_parameter_set_lookup(&list, "context", &C);
237 RNA_parameter_set_lookup(&list, "layout", &layout);
238 typeinfo->ext_interface.call(C, &ptr, func, &list);
239
241}
242
243static void rna_NodeTreeInterfaceSocket_init_socket_builtin(
244 ID *id,
245 bNodeTreeInterfaceSocket *interface_socket,
246 bNode *node,
247 bNodeSocket *socket,
248 const char *data_path)
249{
250 blender::bke::bNodeSocketType *typeinfo = interface_socket->socket_typeinfo();
251 if (typeinfo && typeinfo->interface_draw) {
252 typeinfo->interface_init_socket(id, interface_socket, node, socket, data_path);
253 }
254}
255
256static void rna_NodeTreeInterfaceSocket_init_socket_custom(
257 ID *id,
258 const bNodeTreeInterfaceSocket *interface_socket,
259 bNode *node,
260 bNodeSocket *socket,
261 const blender::StringRefNull data_path)
262{
264 interface_socket->socket_type);
265 if (typeinfo == nullptr) {
266 return;
267 }
268
270 id, &RNA_NodeTreeInterfaceSocket, const_cast<bNodeTreeInterfaceSocket *>(interface_socket));
271
272 FunctionRNA *func = &rna_NodeTreeInterfaceSocket_init_socket_func;
273
274 ParameterList list;
275 RNA_parameter_list_create(&list, &ptr, func);
276 RNA_parameter_set_lookup(&list, "node", node);
277 RNA_parameter_set_lookup(&list, "socket", socket);
278 RNA_parameter_set_lookup(&list, "data_path", &data_path);
279 typeinfo->ext_interface.call(nullptr, &ptr, func, &list);
280
282}
283
284static void rna_NodeTreeInterfaceSocket_from_socket_builtin(
285 ID *id, bNodeTreeInterfaceSocket *interface_socket, bNode *node, bNodeSocket *socket)
286{
287 blender::bke::bNodeSocketType *typeinfo = interface_socket->socket_typeinfo();
288 if (typeinfo && typeinfo->interface_draw) {
289 typeinfo->interface_from_socket(id, interface_socket, node, socket);
290 }
291}
292
293static void rna_NodeTreeInterfaceSocket_from_socket_custom(
294 ID *id,
295 bNodeTreeInterfaceSocket *interface_socket,
296 const bNode *node,
297 const bNodeSocket *socket)
298{
300 interface_socket->socket_type);
301 if (typeinfo == nullptr) {
302 return;
303 }
304
305 PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_NodeTreeInterfaceSocket, interface_socket);
306
307 FunctionRNA *func = &rna_NodeTreeInterfaceSocket_from_socket_func;
308
309 ParameterList list;
310 RNA_parameter_list_create(&list, &ptr, func);
311 RNA_parameter_set_lookup(&list, "node", node);
312 RNA_parameter_set_lookup(&list, "socket", socket);
313 typeinfo->ext_interface.call(nullptr, &ptr, func, &list);
314
316}
317
318static StructRNA *rna_NodeTreeInterfaceSocket_register(Main * /*bmain*/,
319 ReportList * /*reports*/,
320 void *data,
321 const char *identifier,
322 StructValidateFunc validate,
325{
326 bNodeTreeInterfaceSocket dummy_socket = {};
327 /* Set #item_type so that refining the type ends up with RNA_NodeTreeInterfaceSocket. */
328 dummy_socket.item.item_type = NODE_INTERFACE_SOCKET;
329
330 PointerRNA dummy_socket_ptr = RNA_pointer_create_discrete(
331 nullptr, &RNA_NodeTreeInterfaceSocket, &dummy_socket);
332
333 /* Validate the python class. */
334 bool have_function[3];
335 if (validate(&dummy_socket_ptr, data, have_function) != 0) {
336 return nullptr;
337 }
338
339 /* Check if we have registered this socket type before. */
341 dummy_socket.socket_type);
342 if (st) {
343 /* Socket type registered before. */
344 }
345 else {
346 /* Create a new node socket type. */
347 st = MEM_new<blender::bke::bNodeSocketType>(__func__);
348 st->idname = dummy_socket.socket_type;
349
351 }
352
353 st->free_self = [](blender::bke::bNodeSocketType *type) { MEM_delete(type); };
354
355 /* if RNA type is already registered, unregister first */
356 if (st->ext_interface.srna) {
357 StructRNA *srna = st->ext_interface.srna;
360 }
362 &BLENDER_RNA, identifier, &RNA_NodeTreeInterfaceSocket);
363 st->ext_interface.data = data;
364 st->ext_interface.call = call;
365 st->ext_interface.free = free;
367
368 st->interface_draw = (have_function[0]) ? rna_NodeTreeInterfaceSocket_draw_custom : nullptr;
369 st->interface_init_socket = (have_function[1]) ? rna_NodeTreeInterfaceSocket_init_socket_custom :
370 nullptr;
371 st->interface_from_socket = (have_function[2]) ? rna_NodeTreeInterfaceSocket_from_socket_custom :
372 nullptr;
373
374 /* Cleanup local dummy type. */
375 MEM_SAFE_FREE(dummy_socket.socket_type);
376
377 /* Update while blender is running */
379
380 return st->ext_interface.srna;
381}
382
383static IDProperty **rna_NodeTreeInterfaceSocket_idprops(PointerRNA *ptr)
384{
385 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
386 return &socket->properties;
387}
388
389static void rna_NodeTreeInterfaceSocket_identifier_get(PointerRNA *ptr, char *value)
390{
391 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
392 strcpy(value, socket->identifier);
393}
394
395static int rna_NodeTreeInterfaceSocket_identifier_length(PointerRNA *ptr)
396{
397 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
398 return strlen(socket->identifier);
399}
400
401static int rna_NodeTreeInterfaceSocket_socket_type_get(PointerRNA *ptr)
402{
403 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
405}
406
407static void rna_NodeTreeInterfaceSocket_socket_type_set(PointerRNA *ptr, int value)
408{
410
411 if (typeinfo) {
412 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
413 socket->set_socket_type(typeinfo->idname);
414 }
415}
416
417static bool is_socket_type_supported(blender::bke::bNodeTreeType *ntreetype,
419{
420 /* Check if the node tree supports the socket type. */
421 if (ntreetype->valid_socket_type && !ntreetype->valid_socket_type(ntreetype, socket_type)) {
422 return false;
423 }
424
425 /* Only basic socket types are supported. Custom sockets don't have a base type. */
426 if (socket_type->type != SOCK_CUSTOM) {
428 socket_type->type, PROP_NONE);
429 BLI_assert(base_socket_type != nullptr);
430 if (socket_type != base_socket_type) {
431 return false;
432 }
433 }
434
435 return true;
436}
437
438static blender::bke::bNodeSocketType *find_supported_socket_type(
439 blender::bke::bNodeTreeType *ntree_type)
440{
442 if (is_socket_type_supported(ntree_type, socket_type)) {
443 return socket_type;
444 }
445 }
446 return nullptr;
447}
448
449static bool rna_NodeTreeInterfaceSocket_socket_type_poll(
450 void *userdata, blender::bke::bNodeSocketType *socket_type)
451{
452 blender::bke::bNodeTreeType *ntreetype = static_cast<blender::bke::bNodeTreeType *>(userdata);
453 return is_socket_type_supported(ntreetype, socket_type);
454}
455
456static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_socket_type_itemf(
457 bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free)
458{
459 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
460
461 if (!ntree) {
463 }
464
466 ntree->typeinfo, rna_NodeTreeInterfaceSocket_socket_type_poll, r_free);
467}
468
473static void rna_NodeTreeInterfaceSocket_force_non_field_set(PointerRNA *ptr, const bool value)
474{
475 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
479}
480
482 const bNodeTree *ntree, const eNodeSocketDatatype socket_type, bool *r_free)
483{
484 if (!ntree) {
486 }
487 const bool is_geometry_nodes = ntree->type == NTREE_GEOMETRY;
488
489 const bool supports_fields = is_geometry_nodes &&
491 const bool supports_grids = is_geometry_nodes &&
493 const bool supports_lists = is_geometry_nodes && supports_fields;
494
495 *r_free = true;
496 EnumPropertyItem *items = nullptr;
497 int items_count = 0;
498
499 for (const EnumPropertyItem *item = rna_enum_node_socket_structure_type_items; item->identifier;
500 item++)
501 {
502 switch (NodeSocketInterfaceStructureType(item->value)) {
505 RNA_enum_item_add(&items, &items_count, item);
506 break;
507 }
509 if (supports_fields || supports_grids) {
510 RNA_enum_item_add(&items, &items_count, item);
511 }
512 break;
513 }
515 if (supports_fields) {
516 RNA_enum_item_add(&items, &items_count, item);
517 }
518 break;
519 }
521 if (supports_grids) {
522 RNA_enum_item_add(&items, &items_count, item);
523 }
524 break;
525 }
527 if (U.experimental.use_geometry_nodes_lists) {
528 if (supports_lists) {
529 RNA_enum_item_add(&items, &items_count, item);
530 }
531 }
532 break;
533 }
534 }
535 }
536 RNA_enum_item_end(&items, &items_count);
537 return items;
538}
539
540static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_structure_type_itemf(
541 bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free)
542{
543 const bNodeTree *ntree = reinterpret_cast<const bNodeTree *>(ptr->owner_id);
544 const bNodeTreeInterfaceSocket *socket = static_cast<const bNodeTreeInterfaceSocket *>(
545 ptr->data);
546 const eNodeSocketDatatype socket_type = socket->socket_typeinfo()->type;
547 return rna_NodeSocket_structure_type_item_filter(ntree, socket_type, r_free);
548}
549
550static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_default_input_itemf(
551 bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free)
552{
553 const bNodeTree *ntree = reinterpret_cast<const bNodeTree *>(ptr->owner_id);
554 const bNodeTreeInterfaceSocket *socket = static_cast<const bNodeTreeInterfaceSocket *>(
555 ptr->data);
556 if (!ntree) {
558 }
559 const blender::bke::bNodeSocketType *stype = socket->socket_typeinfo();
560 if (!stype) {
562 }
563
564 *r_free = true;
565 EnumPropertyItem *items = nullptr;
566 int items_count = 0;
567
568 for (const EnumPropertyItem *item = node_default_input_items; item->identifier; item++) {
569 if (item->value == NODE_DEFAULT_INPUT_VALUE) {
570 RNA_enum_item_add(&items, &items_count, item);
571 }
572 else if (ntree->type == NTREE_GEOMETRY) {
574 *stype, NodeDefaultInputType(item->value)))
575 {
576 RNA_enum_item_add(&items, &items_count, item);
577 }
578 }
579 }
580
581 RNA_enum_item_end(&items, &items_count);
582 return items;
583}
584
585static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_attribute_domain_itemf(
586 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
587{
588 using namespace blender;
589 EnumPropertyItem *item_array = nullptr;
590 int items_len = 0;
591
592 for (const EnumPropertyItem *item = rna_enum_attribute_domain_items; item->identifier != nullptr;
593 item++)
594 {
595 RNA_enum_item_add(&item_array, &items_len, item);
596 }
597 RNA_enum_item_end(&item_array, &items_len);
598
599 *r_free = true;
600 return item_array;
601}
602
603static PointerRNA rna_NodeTreeInterfaceItems_active_get(PointerRNA *ptr)
604{
605 bNodeTreeInterface *interface = static_cast<bNodeTreeInterface *>(ptr->data);
607 ptr->owner_id, &RNA_NodeTreeInterfaceItem, interface->active_item());
608 return ptr_result;
609}
610
611static void rna_NodeTreeInterfaceItems_active_set(PointerRNA *ptr,
612 PointerRNA value,
613 ReportList * /*reports*/)
614{
615 bNodeTreeInterface *interface = static_cast<bNodeTreeInterface *>(ptr->data);
616 bNodeTreeInterfaceItem *item = static_cast<bNodeTreeInterfaceItem *>(value.data);
617 interface->active_item_set(item);
618}
619
620static bNodeTreeInterfaceSocket *rna_NodeTreeInterfaceItems_new_socket(
621 ID *id,
623 Main *bmain,
624 ReportList *reports,
625 const char *name,
626 const char *description,
627 int in_out,
628 int socket_type_enum,
630{
631 if (parent != nullptr && !interface->find_item(parent->item)) {
632 BKE_report(reports, RPT_ERROR_INVALID_INPUT, "Parent is not part of the interface");
633 return nullptr;
634 }
635 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
637 if (typeinfo == nullptr) {
638 BKE_report(reports, RPT_ERROR_INVALID_INPUT, "Unknown socket type");
639 return nullptr;
640 }
641
642 /* If data type is unsupported try to find a valid type. */
643 if (!is_socket_type_supported(ntree->typeinfo, typeinfo)) {
644 typeinfo = find_supported_socket_type(ntree->typeinfo);
645 if (typeinfo == nullptr) {
646 BKE_report(reports, RPT_ERROR, "Could not find supported socket type");
647 return nullptr;
648 }
649 }
650 const blender::StringRef socket_type = typeinfo->idname;
652 bNodeTreeInterfaceSocket *socket = interface->add_socket(
653 name, description, socket_type, flag, parent);
654
655 if (socket == nullptr) {
656 BKE_report(reports, RPT_ERROR, "Unable to create socket");
657 }
658 else {
659 BKE_main_ensure_invariants(*bmain, ntree->id);
661 }
662
663 return socket;
664}
665
666static bNodeTreeInterfacePanel *rna_NodeTreeInterfaceItems_new_panel(ID *id,
668 Main *bmain,
669 ReportList *reports,
670 const char *name,
671 const char *description,
672 bool default_closed)
673{
676
677 bNodeTreeInterfacePanel *panel = interface->add_panel(
678 name ? name : "", description ? description : "", flag, nullptr);
679
680 if (panel == nullptr) {
681 BKE_report(reports, RPT_ERROR, "Unable to create panel");
682 }
683 else {
684 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
685 BKE_main_ensure_invariants(*bmain, ntree->id);
687 }
688
689 return panel;
690}
691
692static bNodeTreeInterfaceItem *rna_NodeTreeInterfaceItems_copy_to_parent(
693 ID *id,
695 Main *bmain,
696 ReportList *reports,
699{
700 if (parent != nullptr) {
701 if (!interface->find_item(parent->item)) {
702 BKE_report(reports, RPT_ERROR_INVALID_INPUT, "Parent is not part of the interface");
703 return nullptr;
704 }
705 }
706
707 if (parent == nullptr) {
708 parent = &interface->root_panel;
709 }
710 const int index = parent->items().as_span().first_index_try(item);
711 if (!parent->items().index_range().contains(index)) {
712 return nullptr;
713 }
714
715 bNodeTreeInterfaceItem *item_copy = interface->insert_item_copy(*item, parent, index + 1);
716
717 if (item_copy == nullptr) {
718 BKE_report(reports, RPT_ERROR, "Unable to copy item");
719 }
720 else {
721 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
722 BKE_main_ensure_invariants(*bmain, ntree->id);
724 }
725
726 return item_copy;
727}
728
729static bNodeTreeInterfaceItem *rna_NodeTreeInterfaceItems_copy(ID *id,
731 Main *bmain,
732 ReportList *reports,
734{
735 /* Copy to same parent as the item. */
736 bNodeTreeInterfacePanel *parent = interface->find_item_parent(*item);
737 return rna_NodeTreeInterfaceItems_copy_to_parent(id, interface, bmain, reports, item, parent);
738}
739
740static void rna_NodeTreeInterfaceItems_remove(ID *id,
742 Main *bmain,
744 bool move_content_to_parent)
745{
746 interface->remove_item(*item, move_content_to_parent);
747
748 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
749 BKE_main_ensure_invariants(*bmain, ntree->id);
751}
752
753static void rna_NodeTreeInterfaceItems_clear(ID *id, bNodeTreeInterface *interface, Main *bmain)
754{
755 interface->clear_items();
756
757 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
758 BKE_main_ensure_invariants(*bmain, ntree->id);
760}
761
762static void rna_NodeTreeInterfaceItems_move(ID *id,
764 Main *bmain,
766 int to_position)
767{
768 interface->move_item(*item, to_position);
769
770 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
771 BKE_main_ensure_invariants(*bmain, ntree->id);
773}
774
775static void rna_NodeTreeInterfaceItems_move_to_parent(ID *id,
777 Main *bmain,
778 ReportList * /*reports*/,
781 int to_position)
782{
783 interface->move_item_to_parent(*item, parent, to_position);
784
785 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
786 BKE_main_ensure_invariants(*bmain, ntree->id);
788}
789
790/* ******** Node Socket Subtypes ******** */
791
792static const EnumPropertyItem *rna_subtype_filter_itemf(const blender::Set<int> &subtypes,
793 bool *r_free)
794{
795 if (subtypes.is_empty()) {
797 }
798
799 EnumPropertyItem *items = nullptr;
800 int items_count = 0;
801 for (const EnumPropertyItem *item = rna_enum_property_subtype_items; item->name != nullptr;
802 item++)
803 {
804 if (subtypes.contains(item->value)) {
805 RNA_enum_item_add(&items, &items_count, item);
806 }
807 }
808
809 if (items_count == 0) {
811 }
812
813 RNA_enum_item_end(&items, &items_count);
814 *r_free = true;
815 return items;
816}
817
818static const EnumPropertyItem *rna_NodeTreeInterfaceSocketFloat_subtype_itemf(
819 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
820{
821 return rna_subtype_filter_itemf({PROP_PERCENTAGE,
824 PROP_TIME,
830 PROP_NONE},
831 r_free);
832}
833
834void rna_NodeTreeInterfaceSocketFloat_default_value_range(
835 PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
836{
837 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
838 bNodeSocketValueFloat *dval = static_cast<bNodeSocketValueFloat *>(socket->socket_data);
840 socket->socket_type);
841 int subtype = socket_typeinfo ? socket_typeinfo->subtype : PROP_NONE;
842
843 if (dval->max < dval->min) {
844 dval->max = dval->min;
845 }
846
847 *min = (subtype == PROP_UNSIGNED ? 0.0f : -FLT_MAX);
848 *max = FLT_MAX;
849 *softmin = dval->min;
850 *softmax = dval->max;
851}
852
853static const EnumPropertyItem *rna_NodeTreeInterfaceSocketInt_subtype_itemf(bContext * /*C*/,
854 PointerRNA * /*ptr*/,
855 PropertyRNA * /*prop*/,
856 bool *r_free)
857{
858 return rna_subtype_filter_itemf({PROP_PERCENTAGE, PROP_FACTOR, PROP_NONE}, r_free);
859}
860
861void rna_NodeTreeInterfaceSocketInt_default_value_range(
862 PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
863{
864 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
865 bNodeSocketValueInt *dval = static_cast<bNodeSocketValueInt *>(socket->socket_data);
867 socket->socket_type);
868 int subtype = socket_typeinfo ? socket_typeinfo->subtype : PROP_NONE;
869
870 if (dval->max < dval->min) {
871 dval->max = dval->min;
872 }
873
874 *min = (subtype == PROP_UNSIGNED ? 0 : INT_MIN);
875 *max = INT_MAX;
876 *softmin = dval->min;
877 *softmax = dval->max;
878}
879
880static const EnumPropertyItem *rna_NodeTreeInterfaceSocketVector_subtype_itemf(
881 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
882{
883 return rna_subtype_filter_itemf({PROP_FACTOR,
890 PROP_XYZ,
891 PROP_NONE},
892 r_free);
893}
894
895void rna_NodeTreeInterfaceSocketVector_default_value_range(
896 PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
897{
898 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
899 bNodeSocketValueVector *dval = static_cast<bNodeSocketValueVector *>(socket->socket_data);
900
901 if (dval->max < dval->min) {
902 dval->max = dval->min;
903 }
904
905 *min = -FLT_MAX;
906 *max = FLT_MAX;
907 *softmin = dval->min;
908 *softmax = dval->max;
909}
910
911static const EnumPropertyItem *rna_NodeTreeInterfaceSocketString_subtype_itemf(
912 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
913{
914 return rna_subtype_filter_itemf({PROP_FILEPATH, PROP_NONE}, r_free);
915}
916
917/* If the dimensions of the vector socket changed, we need to update the socket type, since each
918 * dimensions value has its own sub-type. */
919static void rna_NodeTreeInterfaceSocketVector_dimensions_update(Main *bmain,
920 Scene *scene,
922{
923
924 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
925
926 /* Store a copy of the existing default value since it will be freed when setting the socket type
927 * below. */
928 const bNodeSocketValueVector default_value = *static_cast<bNodeSocketValueVector *>(
929 socket->socket_data);
930
932 SOCK_VECTOR, default_value.subtype, default_value.dimensions);
933
934 socket->set_socket_type(socket_idname);
935
936 /* Restore existing default value. */
937 *static_cast<bNodeSocketValueVector *>(socket->socket_data) = default_value;
938
939 rna_NodeTreeInterfaceItem_update(bmain, scene, ptr);
940}
941
942static bool rna_NodeTreeInterfaceSocketMaterial_default_value_poll(PointerRNA * /*ptr*/,
943 PointerRNA value)
944{
945 /* Do not show grease pencil materials for now. */
946 Material *ma = static_cast<Material *>(value.data);
947 return ma->gp_style == nullptr;
948}
949
950static void rna_NodeTreeInterface_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
951{
952 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
953 if (!ntree->runtime) {
954 return;
955 }
956
957 ntree->ensure_interface_cache();
959 ptr,
960 const_cast<bNodeTreeInterfaceItem **>(ntree->interface_items().data()),
961 sizeof(bNodeTreeInterfaceItem *),
962 ntree->interface_items().size(),
963 false,
964 nullptr);
965}
966
967static int rna_NodeTreeInterface_items_length(PointerRNA *ptr)
968{
969 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
970 if (!ntree->runtime) {
971 return 0;
972 }
973
974 ntree->ensure_interface_cache();
975 return ntree->interface_items().size();
976}
977
978static bool rna_NodeTreeInterface_items_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
979{
980 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
981 if (!ntree->runtime) {
982 return false;
983 }
984
985 ntree->ensure_interface_cache();
986 if (!ntree->interface_items().index_range().contains(index)) {
987 return false;
988 }
989
991 *ptr, &RNA_NodeTreeInterfaceItem, ntree->interface_items()[index], *r_ptr);
992 return true;
993}
994
995static bool rna_NodeTreeInterface_items_lookup_string(PointerRNA *ptr,
996 const char *key,
997 PointerRNA *r_ptr)
998{
999 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
1000 if (!ntree->runtime) {
1001 return false;
1002 }
1003
1004 ntree->ensure_interface_cache();
1005 for (bNodeTreeInterfaceItem *item : ntree->interface_items()) {
1006 switch (NodeTreeInterfaceItemType(item->item_type)) {
1007 case NODE_INTERFACE_SOCKET: {
1008 bNodeTreeInterfaceSocket *socket = reinterpret_cast<bNodeTreeInterfaceSocket *>(item);
1009 if (STREQ(socket->identifier, key)) {
1010 rna_pointer_create_with_ancestors(*ptr, &RNA_NodeTreeInterfaceSocket, socket, *r_ptr);
1011 return true;
1012 }
1013 break;
1014 }
1015 default:
1016 break;
1017 }
1018 }
1019 for (bNodeTreeInterfaceItem *item : ntree->interface_items()) {
1020 switch (NodeTreeInterfaceItemType(item->item_type)) {
1021 case NODE_INTERFACE_SOCKET: {
1022 bNodeTreeInterfaceSocket *socket = reinterpret_cast<bNodeTreeInterfaceSocket *>(item);
1023 if (STREQ(socket->name, key)) {
1024 rna_pointer_create_with_ancestors(*ptr, &RNA_NodeTreeInterfaceSocket, socket, *r_ptr);
1025 return true;
1026 }
1027 break;
1028 }
1029 case NODE_INTERFACE_PANEL: {
1030 bNodeTreeInterfacePanel *panel = reinterpret_cast<bNodeTreeInterfacePanel *>(item);
1031 if (STREQ(panel->name, key)) {
1032 rna_pointer_create_with_ancestors(*ptr, &RNA_NodeTreeInterfacePanel, panel, *r_ptr);
1033 return true;
1034 }
1035 break;
1036 }
1037 }
1038 }
1039 return false;
1040}
1041
1042const EnumPropertyItem *RNA_node_tree_interface_socket_menu_itemf(bContext * /*C*/,
1043 PointerRNA *ptr,
1044 PropertyRNA * /*prop*/,
1045 bool *r_free)
1046{
1047 const bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
1048 if (!socket) {
1049 *r_free = false;
1051 }
1052 const bNodeSocketValueMenu *data = static_cast<bNodeSocketValueMenu *>(socket->socket_data);
1053 if (!data->enum_items) {
1054 *r_free = false;
1056 }
1057 return RNA_node_enum_definition_itemf(*data->enum_items, r_free);
1058}
1059
1060#else
1061
1063{
1064 StructRNA *srna;
1065 PropertyRNA *prop;
1066
1067 srna = RNA_def_struct(brna, "NodeTreeInterfaceItem", nullptr);
1068 RNA_def_struct_ui_text(srna, "Node Tree Interface Item", "Item in a node tree interface");
1069 RNA_def_struct_sdna(srna, "bNodeTreeInterfaceItem");
1070 RNA_def_struct_refine_func(srna, "rna_NodeTreeInterfaceItem_refine");
1071 RNA_def_struct_path_func(srna, "rna_NodeTreeInterfaceItem_path");
1072
1073 prop = RNA_def_property(srna, "item_type", PROP_ENUM, PROP_NONE);
1074 RNA_def_property_enum_sdna(prop, nullptr, "item_type");
1077 RNA_def_property_ui_text(prop, "Item Type", "Type of interface item");
1078
1079 prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
1080 RNA_def_property_struct_type(prop, "NodeTreeInterfacePanel");
1082 prop, "rna_NodeTreeInterfaceItem_parent_get", nullptr, nullptr, nullptr);
1085 RNA_def_property_ui_text(prop, "Parent", "Panel that contains the item");
1086
1087 prop = RNA_def_property(srna, "position", PROP_INT, PROP_NONE);
1088 RNA_def_property_int_funcs(prop, "rna_NodeTreeInterfaceItem_position_get", nullptr, nullptr);
1089 RNA_def_property_range(prop, -1, INT_MAX);
1091 RNA_def_property_ui_text(prop, "Position", "Position of the item in its parent panel");
1092
1093 prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
1094 RNA_def_property_int_funcs(prop, "rna_NodeTreeInterfaceItem_index_get", nullptr, nullptr);
1095 RNA_def_property_range(prop, -1, INT_MAX);
1098 prop, "Index", "Global index of the item among all items in the interface");
1099}
1100
1102{
1103 StructRNA *srna;
1104 PropertyRNA *prop;
1105 FunctionRNA *func;
1106 PropertyRNA *parm;
1107
1108 srna = RNA_def_struct(brna, "NodeTreeInterfaceSocket", "NodeTreeInterfaceItem");
1109 RNA_def_struct_ui_text(srna, "Node Tree Interface Socket", "Declaration of a node socket");
1110 RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket");
1112 "rna_NodeTreeInterfaceSocket_register",
1113 "rna_NodeTreeInterfaceSocket_unregister",
1114 nullptr);
1115 RNA_def_struct_system_idprops_func(srna, "rna_NodeTreeInterfaceSocket_idprops");
1116
1117 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1118 RNA_def_property_ui_text(prop, "Name", "Socket name");
1119 RNA_def_struct_name_property(srna, prop);
1120 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1121
1122 prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
1124 "rna_NodeTreeInterfaceSocket_identifier_get",
1125 "rna_NodeTreeInterfaceSocket_identifier_length",
1126 nullptr);
1128 RNA_def_property_ui_text(prop, "Identifier", "Unique identifier for mapping sockets");
1129
1130 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
1131 RNA_def_property_string_sdna(prop, nullptr, "description");
1132 RNA_def_property_ui_text(prop, "Description", "Socket description");
1133 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1134
1135 prop = RNA_def_property(srna, "socket_type", PROP_ENUM, PROP_NONE);
1138 "rna_NodeTreeInterfaceSocket_socket_type_get",
1139 "rna_NodeTreeInterfaceSocket_socket_type_set",
1140 "rna_NodeTreeInterfaceSocket_socket_type_itemf");
1143 prop, "Socket Type", "Type of the socket generated by this interface item");
1144 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1145
1146 prop = RNA_def_property(srna, "in_out", PROP_ENUM, PROP_NONE);
1147 RNA_def_property_enum_bitflag_sdna(prop, nullptr, "flag");
1150 RNA_def_property_ui_text(prop, "Input/Output Type", "Input or output socket type");
1151
1152 prop = RNA_def_property(srna, "hide_value", PROP_BOOLEAN, PROP_NONE);
1156 prop, "Hide Value", "Hide the socket input value even when the socket is not connected");
1157 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1158
1159 prop = RNA_def_property(srna, "hide_in_modifier", PROP_BOOLEAN, PROP_NONE);
1163 "Hide in Modifier",
1164 "Don't show the input value in the geometry nodes modifier interface");
1165 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1166
1167 prop = RNA_def_property(srna, "force_non_field", PROP_BOOLEAN, PROP_NONE);
1169 prop, nullptr, "flag", NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY_LEGACY);
1170 RNA_def_property_boolean_funcs(prop, nullptr, "rna_NodeTreeInterfaceSocket_force_non_field_set");
1173 prop,
1174 "Single Value",
1175 "Only allow single value inputs rather than field.\nDeprecated. Will be remove in 5.0.");
1176 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1177
1178 prop = RNA_def_property(srna, "is_inspect_output", PROP_BOOLEAN, PROP_NONE);
1182 "Is Inspect Output",
1183 "Take link out of node group to connect to root tree output node");
1184 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1185
1186 prop = RNA_def_property(srna, "is_panel_toggle", PROP_BOOLEAN, PROP_NONE);
1190 "Is Panel Toggle",
1191 "This socket is meant to be used as the toggle in its panel header");
1192 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1193
1194 prop = RNA_def_property(srna, "layer_selection_field", PROP_BOOLEAN, PROP_NONE);
1198 prop, "Layer Selection", "Take Grease Pencil Layer or Layer Group as selection field");
1199 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1200
1201 prop = RNA_def_property(srna, "menu_expanded", PROP_BOOLEAN, PROP_NONE);
1205 prop, "Menu Expanded", "Draw the menu socket as an expanded drop-down menu");
1206 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1207
1208 prop = RNA_def_property(srna, "optional_label", PROP_BOOLEAN, PROP_NONE);
1212 prop,
1213 "Optional Label",
1214 "Indicate that the label of this socket is not necessary to understand its meaning. This "
1215 "may result in the label being skipped in some cases");
1216 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1217
1218 prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE);
1221 prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_attribute_domain_itemf");
1223 prop,
1224 "Attribute Domain",
1225 "Attribute domain used by the geometry nodes modifier to create an attribute output");
1226 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1227
1228 prop = RNA_def_property(srna, "default_attribute_name", PROP_STRING, PROP_NONE);
1229 RNA_def_property_string_sdna(prop, nullptr, "default_attribute_name");
1231 "Default Attribute",
1232 "The attribute name used by default when the node group is used by a "
1233 "geometry nodes modifier");
1234 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1235
1236 prop = RNA_def_property(srna, "structure_type", PROP_ENUM, PROP_NONE);
1239 prop,
1240 "Structure Type",
1241 "What kind of higher order types are expected to flow through this socket");
1243 prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_structure_type_itemf");
1244 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1245
1246 prop = RNA_def_property(srna, "default_input", PROP_ENUM, PROP_NONE);
1249 prop,
1250 "Default Input",
1251 "Input to use when the socket is unconnected. Requires \"Hide Value\".");
1253 prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_default_input_itemf");
1254 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1255
1256 /* Registered properties and functions for custom socket types. */
1257 prop = RNA_def_property(srna, "bl_socket_idname", PROP_STRING, PROP_NONE);
1258 RNA_def_property_string_sdna(prop, nullptr, "socket_type");
1260 RNA_def_property_ui_text(prop, "Socket Type Name", "Name of the socket type");
1261 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1262
1263 func = RNA_def_function(srna, "draw", nullptr);
1265 RNA_def_function_ui_description(func, "Draw properties of the socket interface");
1266 parm = RNA_def_pointer(func, "context", "Context", "", "");
1268 parm = RNA_def_property(func, "layout", PROP_POINTER, PROP_NONE);
1269 RNA_def_property_struct_type(parm, "UILayout");
1270 RNA_def_property_ui_text(parm, "Layout", "Layout in the UI");
1272
1273 func = RNA_def_function(srna, "init_socket", nullptr);
1274 RNA_def_function_ui_description(func, "Initialize a node socket instance");
1276 parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the socket to initialize");
1278 parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Socket to initialize");
1280 parm = RNA_def_string(
1281 func, "data_path", nullptr, 0, "Data Path", "Path to specialized socket data");
1283
1284 func = RNA_def_function(srna, "from_socket", nullptr);
1285 RNA_def_function_ui_description(func, "Setup template parameters from an existing socket");
1287 parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the original socket");
1289 parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Original socket");
1291}
1292
1294{
1295 StructRNA *srna;
1296 PropertyRNA *prop;
1297
1298 srna = RNA_def_struct(brna, "NodeTreeInterfacePanel", "NodeTreeInterfaceItem");
1299 RNA_def_struct_ui_text(srna, "Node Tree Interface Item", "Declaration of a node panel");
1300 RNA_def_struct_sdna(srna, "bNodeTreeInterfacePanel");
1301
1302 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1303 RNA_def_property_ui_text(prop, "Name", "Panel name");
1304 RNA_def_struct_name_property(srna, prop);
1305 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1306
1307 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
1308 RNA_def_property_string_sdna(prop, nullptr, "description");
1309 RNA_def_property_ui_text(prop, "Description", "Panel description");
1310 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1311
1312 prop = RNA_def_property(srna, "default_closed", PROP_BOOLEAN, PROP_NONE);
1315 RNA_def_property_ui_text(prop, "Default Closed", "Panel is closed by default on new nodes");
1316 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1317
1318 prop = RNA_def_property(srna, "interface_items", PROP_COLLECTION, PROP_NONE);
1319 RNA_def_property_collection_sdna(prop, nullptr, "items_array", "items_num");
1320 RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
1322 RNA_def_property_ui_text(prop, "Items", "Items in the node panel");
1323
1324 prop = RNA_def_property(srna, "persistent_uid", PROP_INT, PROP_NONE);
1325 RNA_def_property_int_sdna(prop, nullptr, "identifier");
1327 prop, "Persistent Identifier", "Unique identifier for this panel within this node tree");
1329}
1330
1332{
1333 PropertyRNA *prop;
1334 PropertyRNA *parm;
1335 FunctionRNA *func;
1336
1337 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
1338 RNA_def_property_int_sdna(prop, nullptr, "active_index");
1339 RNA_def_property_ui_text(prop, "Active Index", "Index of the active item");
1341 RNA_def_property_update(prop, NC_NODE, nullptr);
1342
1343 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1344 RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
1347 "rna_NodeTreeInterfaceItems_active_get",
1348 "rna_NodeTreeInterfaceItems_active_set",
1349 nullptr,
1350 nullptr);
1351 RNA_def_property_ui_text(prop, "Active", "Active item");
1352 RNA_def_property_update(prop, NC_NODE, nullptr);
1353
1354 func = RNA_def_function(srna, "new_socket", "rna_NodeTreeInterfaceItems_new_socket");
1355 RNA_def_function_ui_description(func, "Add a new socket to the interface");
1357 parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of the socket");
1359 RNA_def_string(func, "description", nullptr, 0, "Description", "Description of the socket");
1360 RNA_def_enum(func,
1361 "in_out",
1364 "Input/Output Type",
1365 "Create an input or output socket");
1366 parm = RNA_def_enum(func,
1367 "socket_type",
1369 0,
1370 "Socket Type",
1371 "Type of socket generated on nodes");
1372 /* NOTE: itemf callback works for the function parameter, it does not require a data pointer. */
1374 parm, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_socket_type_itemf");
1376 func, "parent", "NodeTreeInterfacePanel", "Parent", "Panel to add the socket in");
1377 /* return value */
1378 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceSocket", "Socket", "New socket");
1379 RNA_def_function_return(func, parm);
1380
1381 func = RNA_def_function(srna, "new_panel", "rna_NodeTreeInterfaceItems_new_panel");
1382 RNA_def_function_ui_description(func, "Add a new panel to the interface");
1384 parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of the new panel");
1385 RNA_def_string(func, "description", nullptr, 0, "Description", "Description of the panel");
1387 func, "default_closed", false, "Default Closed", "Panel is closed by default on new nodes");
1389 /* return value */
1390 parm = RNA_def_pointer(func, "item", "NodeTreeInterfacePanel", "Panel", "New panel");
1391 RNA_def_function_return(func, parm);
1392
1393 func = RNA_def_function(srna, "copy", "rna_NodeTreeInterfaceItems_copy");
1394 RNA_def_function_ui_description(func, "Add a copy of an item to the interface");
1396 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "Item to copy");
1398 /* return value */
1399 parm = RNA_def_pointer(
1400 func, "item_copy", "NodeTreeInterfaceItem", "Item Copy", "Copy of the item");
1401 RNA_def_function_return(func, parm);
1402
1403 func = RNA_def_function(srna, "remove", "rna_NodeTreeInterfaceItems_remove");
1404 RNA_def_function_ui_description(func, "Remove an item from the interface");
1406 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "The item to remove");
1409 func,
1410 "move_content_to_parent",
1411 true,
1412 "Move Content",
1413 "If the item is a panel, move the contents to the parent instead of deleting it");
1414
1415 func = RNA_def_function(srna, "clear", "rna_NodeTreeInterfaceItems_clear");
1416 RNA_def_function_ui_description(func, "Remove all items from the interface");
1418
1419 func = RNA_def_function(srna, "move", "rna_NodeTreeInterfaceItems_move");
1420 RNA_def_function_ui_description(func, "Move an item to another position");
1422 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "The item to move");
1424 parm = RNA_def_int(func,
1425 "to_position",
1426 -1,
1427 0,
1428 INT_MAX,
1429 "To Position",
1430 "Target position for the item in its current panel",
1431 0,
1432 10000);
1434
1435 func = RNA_def_function(srna, "move_to_parent", "rna_NodeTreeInterfaceItems_move_to_parent");
1436 RNA_def_function_ui_description(func, "Move an item to a new panel and/or position.");
1438 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "The item to move");
1440 parm = RNA_def_pointer(
1441 func, "parent", "NodeTreeInterfacePanel", "Parent", "New parent of the item");
1443 parm = RNA_def_int(func,
1444 "to_position",
1445 -1,
1446 0,
1447 INT_MAX,
1448 "To Position",
1449 "Target position for the item in the new parent panel",
1450 0,
1451 10000);
1453}
1454
1456{
1457 StructRNA *srna;
1458 PropertyRNA *prop;
1459
1460 srna = RNA_def_struct(brna, "NodeTreeInterface", nullptr);
1462 srna, "Node Tree Interface", "Declaration of sockets and ui panels of a node group");
1463 RNA_def_struct_sdna(srna, "bNodeTreeInterface");
1464
1465 prop = RNA_def_property(srna, "items_tree", PROP_COLLECTION, PROP_NONE);
1467 "rna_NodeTreeInterface_items_begin",
1468 "rna_iterator_array_next",
1469 "rna_iterator_array_end",
1470 "rna_iterator_array_dereference_get",
1471 "rna_NodeTreeInterface_items_length",
1472 "rna_NodeTreeInterface_items_lookup_int",
1473 "rna_NodeTreeInterface_items_lookup_string",
1474 nullptr);
1475 RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
1477 RNA_def_property_ui_text(prop, "Items", "Items in the node interface");
1478
1480}
1481
1491
1492#endif
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
@ RPT_ERROR_INVALID_INPUT
Definition BKE_report.hh:40
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert(a)
Definition BLI_assert.h:46
void BLI_kdtree_nd_ free(KDTree *tree)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define STREQ(a, b)
@ NODE_INTERFACE_PANEL_DEFAULT_CLOSED
@ NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY_LEGACY
@ NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER
@ NODE_INTERFACE_SOCKET_PANEL_TOGGLE
@ NODE_INTERFACE_SOCKET_INSPECT
@ NODE_INTERFACE_SOCKET_OPTIONAL_LABEL
@ NODE_INTERFACE_SOCKET_LAYER_SELECTION
@ NODE_INTERFACE_SOCKET_MENU_EXPANDED
@ NODE_INTERFACE_SOCKET_HIDE_VALUE
@ 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
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_GRID
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_SINGLE
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_LIST
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_FIELD
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_DYNAMIC
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO
@ NTREE_GEOMETRY
eNodeSocketDatatype
@ SOCK_VECTOR
@ SOCK_CUSTOM
#define MEM_SAFE_FREE(v)
const EnumPropertyItem * rna_NodeSocket_structure_type_item_filter(const bNodeTree *ntree, const eNodeSocketDatatype socket_type, bool *r_free)
const EnumPropertyItem * RNA_node_enum_definition_itemf(const blender::bke::RuntimeNodeEnumItems &enum_items, bool *r_free)
int rna_node_socket_idname_to_enum(const char *idname)
blender::bke::bNodeSocketType * rna_node_socket_type_from_enum(int value)
const EnumPropertyItem * rna_node_socket_type_itemf(void *data, bool(*poll)(void *data, blender::bke::bNodeSocketType *), bool *r_free)
@ PARM_REQUIRED
Definition RNA_types.hh:545
@ FUNC_USE_REPORTS
Definition RNA_types.hh:914
@ FUNC_USE_MAIN
Definition RNA_types.hh:912
@ FUNC_USE_SELF_ID
Definition RNA_types.hh:889
@ FUNC_REGISTER_OPTIONAL
Definition RNA_types.hh:923
@ FUNC_ALLOW_WRITE
Definition RNA_types.hh:929
int(*)(PointerRNA *ptr, void *data, bool *have_function) StructValidateFunc
Definition RNA_types.hh:985
@ PROP_BOOLEAN
Definition RNA_types.hh:162
@ PROP_ENUM
Definition RNA_types.hh:166
@ PROP_INT
Definition RNA_types.hh:163
@ PROP_STRING
Definition RNA_types.hh:165
@ PROP_POINTER
Definition RNA_types.hh:167
@ PROP_COLLECTION
Definition RNA_types.hh:168
int(*)(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *list) StructCallbackFunc
Definition RNA_types.hh:986
void(*)(void *data) StructFreeFunc
Definition RNA_types.hh:990
@ PROPOVERRIDE_NO_COMPARISON
Definition RNA_types.hh:511
PropertyFlag
Definition RNA_types.hh:300
@ PROP_ANIMATABLE
Definition RNA_types.hh:319
@ PROP_EDITABLE
Definition RNA_types.hh:306
@ PROP_NEVER_NULL
Definition RNA_types.hh:377
@ PROP_REGISTER
Definition RNA_types.hh:411
@ PROP_TIME
Definition RNA_types.hh:253
@ PROP_DIRECTION
Definition RNA_types.hh:262
@ PROP_XYZ
Definition RNA_types.hh:269
@ PROP_DISTANCE
Definition RNA_types.hh:256
@ PROP_ACCELERATION
Definition RNA_types.hh:264
@ PROP_ANGLE
Definition RNA_types.hh:252
@ PROP_TIME_ABSOLUTE
Definition RNA_types.hh:254
@ PROP_EULER
Definition RNA_types.hh:266
@ PROP_COLOR_TEMPERATURE
Definition RNA_types.hh:290
@ PROP_NONE
Definition RNA_types.hh:233
@ PROP_PERCENTAGE
Definition RNA_types.hh:250
@ PROP_FREQUENCY
Definition RNA_types.hh:292
@ PROP_FACTOR
Definition RNA_types.hh:251
@ PROP_TRANSLATION
Definition RNA_types.hh:261
@ PROP_UNSIGNED
Definition RNA_types.hh:249
@ PROP_FILEPATH
Definition RNA_types.hh:236
@ PROP_VELOCITY
Definition RNA_types.hh:263
@ PROP_WAVELENGTH
Definition RNA_types.hh:287
#define C
Definition RandGen.cpp:29
#define NC_NODE
Definition WM_types.hh:394
#define NA_EDITED
Definition WM_types.hh:584
#define U
BMesh const char void * data
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool is_empty() const
Definition BLI_set.hh:595
#define interface
T & get_item_as(bNodeTreeInterfaceItem &item)
Span< bNodeSocketType * > node_socket_types_get()
Definition node.cc:2457
void node_register_socket_type(bNodeSocketType &stype)
Definition node.cc:2494
bNodeSocketType * node_socket_type_find(StringRef idname)
Definition node.cc:2462
bNodeSocketType * node_socket_type_find_static(int type, int subtype=0)
Definition node.cc:2471
std::optional< StringRefNull > node_static_socket_type(int type, int subtype, std::optional< int > dimensions=std::nullopt)
Definition node.cc:2835
bool socket_type_supports_default_input_type(const bke::bNodeSocketType &socket_type, const NodeDefaultInputType input_type)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
bool socket_type_supports_grids(const eNodeSocketDatatype socket_type)
const char * name
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
void * RNA_struct_blender_type_get(StructRNA *srna)
void RNA_parameter_list_free(ParameterList *parms)
void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, const void *value)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr, void *data, size_t itemsize, int64_t length, bool free_ptr, IteratorSkipFunc skip)
void rna_pointer_create_with_ancestors(const PointerRNA &parent, StructRNA *type, void *data, PointerRNA &r_ptr)
ParameterList * RNA_parameter_list_create(ParameterList *parms, PointerRNA *, FunctionRNA *func)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const EnumPropertyItem rna_enum_attribute_domain_items[]
void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t booleanbit)
void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
void RNA_def_struct_path_func(StructRNA *srna, const char *path)
void RNA_def_struct_system_idprops_func(StructRNA *srna, const char *system_idproperties)
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
void RNA_def_struct_register_funcs(StructRNA *srna, const char *reg, const char *unreg, const char *instance)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
StructRNA * RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structname, const char *propname)
StructRNA * RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_def_function_flag(FunctionRNA *func, int flag)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *rna_ext)
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *type_fn, const char *poll)
void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
BlenderRNA BLENDER_RNA
void rna_def_node_socket_interface_subtypes(BlenderRNA *brna)
static void rna_def_node_tree_interface_items_api(StructRNA *srna)
const EnumPropertyItem rna_enum_node_socket_structure_type_items[]
static const EnumPropertyItem node_tree_interface_socket_in_out_items[]
static const EnumPropertyItem node_default_input_items[]
const EnumPropertyItem rna_enum_node_tree_interface_item_type_items[]
static void rna_def_node_interface_item(BlenderRNA *brna)
void RNA_def_node_tree_interface(BlenderRNA *brna)
static void rna_def_node_interface_socket(BlenderRNA *brna)
static void rna_def_node_interface_panel(BlenderRNA *brna)
static void rna_def_node_tree_interface(BlenderRNA *brna)
const EnumPropertyItem rna_enum_dummy_NULL_items[]
Definition rna_rna.cc:26
const EnumPropertyItem rna_enum_property_subtype_items[]
Definition rna_rna.cc:126
const EnumPropertyItem rna_enum_dummy_DEFAULT_items[]
Definition rna_rna.cc:32
#define min(a, b)
Definition sort.cc:36
#define FLT_MAX
Definition stdcycles.h:14
StructRNA * srna
StructCallbackFunc call
StructFreeFunc free
Definition DNA_ID.h:414
struct MaterialGPencilStyle * gp_style
void * data
Definition RNA_types.hh:53
bNodeTreeRuntimeHandle * runtime
bNodeTreeTypeHandle * typeinfo
bNodeTreeInterface tree_interface
Defines a socket type.
Definition BKE_node.hh:158
void(* interface_init_socket)(ID *id, const bNodeTreeInterfaceSocket *interface_socket, bNode *node, bNodeSocket *socket, StringRefNull data_path)
Definition BKE_node.hh:178
void(* free_self)(bNodeSocketType *stype)
Definition BKE_node.hh:202
void(* interface_draw)(ID *id, bNodeTreeInterfaceSocket *socket, bContext *C, uiLayout *layout)
Definition BKE_node.hh:174
eNodeSocketDatatype type
Definition BKE_node.hh:193
void(* interface_from_socket)(ID *id, bNodeTreeInterfaceSocket *interface_socket, const bNode *node, const bNodeSocket *socket)
Definition BKE_node.hh:183
bool(* valid_socket_type)(bNodeTreeType *ntreetype, bNodeSocketType *socket_type)
Definition BKE_node.hh:529
max
Definition text_draw.cc:251
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4238
uint8_t flag
Definition wm_window.cc:145