Blender V4.5
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 "SINGLE",
37 0,
38 "Single",
39 "Socket expects a single value"},
41 "DYNAMIC",
42 0,
43 "Dynamic",
44 "Socket can work with different kinds of structures"},
45 {NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_FIELD, "FIELD", 0, "Field", "Socket expects a field"},
46 {NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_GRID, "GRID", 0, "Grid", "Socket expects a grid"},
47 {0, nullptr, 0, nullptr, nullptr}};
48
50 {NODE_DEFAULT_INPUT_VALUE, "VALUE", 0, "Default Value", "The node socket's default value"},
51 {NODE_DEFAULT_INPUT_INDEX_FIELD, "INDEX", 0, "Index", "The index from the context"},
53 "ID_OR_INDEX",
54 0,
55 "ID or Index",
56 "The \"id\" attribute if available, otherwise the index"},
57 {NODE_DEFAULT_INPUT_NORMAL_FIELD, "NORMAL", 0, "Normal", "The geometry's normal direction"},
59 "POSITION",
60 0,
61 "Position",
62 "The position from the context"},
64 "INSTANCE_TRANSFORM",
65 0,
66 "Instance Transform",
67 "Transformation of each instance from the geometry context"},
69 "HANDLE_LEFT",
70 0,
71 "Left Handle",
72 "The left Bezier control point handle from the context"},
74 "HANDLE_RIGHT",
75 0,
76 "Right Handle",
77 "The right Bezier control point handle from the context"},
78 {0, nullptr, 0, nullptr, nullptr}};
79
80#ifdef RNA_RUNTIME
81
82# include <fmt/format.h>
83
84# include "BLI_string_ref.hh"
85
86# include "BKE_attribute.hh"
87# include "BKE_main_invariants.hh"
88# include "BKE_node.hh"
89# include "BKE_node_enum.hh"
90# include "BKE_node_runtime.hh"
93
94# include "BLI_set.hh"
95
96# include "BLT_translation.hh"
97
99# include "NOD_socket.hh"
100
101# include "DNA_material_types.h"
102# include "ED_node.hh"
103# include "WM_api.hh"
104
105/* Internal RNA function declarations, used to invoke registered callbacks. */
106extern FunctionRNA rna_NodeTreeInterfaceSocket_draw_func;
107extern FunctionRNA rna_NodeTreeInterfaceSocket_init_socket_func;
108extern FunctionRNA rna_NodeTreeInterfaceSocket_from_socket_func;
109
111
112static void rna_NodeTreeInterfaceItem_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
113{
114 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
115 if (!ntree) {
116 /* This can happen because of the dummy socket in #rna_NodeTreeInterfaceSocket_register. */
117 return;
118 }
119 ntree->tree_interface.tag_item_property_changed();
120 BKE_main_ensure_invariants(*bmain, ntree->id);
121}
122
123static StructRNA *rna_NodeTreeInterfaceItem_refine(PointerRNA *ptr)
124{
125 bNodeTreeInterfaceItem *item = static_cast<bNodeTreeInterfaceItem *>(ptr->data);
126
127 switch (NodeTreeInterfaceItemType(item->item_type)) {
130 *item);
131 if (socket.socket_type) {
133 socket.socket_type);
134 if (socket_typeinfo && socket_typeinfo->ext_interface.srna) {
135 return socket_typeinfo->ext_interface.srna;
136 }
137 }
138 return &RNA_NodeTreeInterfaceSocket;
139 }
141 return &RNA_NodeTreeInterfacePanel;
142 default:
143 return &RNA_NodeTreeInterfaceItem;
144 }
145}
146
147static std::optional<std::string> rna_NodeTreeInterfaceItem_path(const PointerRNA *ptr)
148{
149 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
150 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
151 if (!ntree->runtime) {
152 return std::nullopt;
153 }
154
155 ntree->ensure_interface_cache();
156 for (const int index : ntree->interface_items().index_range()) {
157 if (ntree->interface_items()[index] == item) {
158 return fmt::format("interface.items_tree[{}]", index);
159 }
160 }
161 return std::nullopt;
162}
163
164static PointerRNA rna_NodeTreeInterfaceItem_parent_get(PointerRNA *ptr)
165{
166 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
167 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
168 bNodeTreeInterfacePanel *parent = ntree->tree_interface.find_item_parent(*item, true);
169 PointerRNA result = RNA_pointer_create_discrete(&ntree->id, &RNA_NodeTreeInterfacePanel, parent);
170 return result;
171}
172
173static int rna_NodeTreeInterfaceItem_position_get(PointerRNA *ptr)
174{
175 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
176 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
177 return ntree->tree_interface.find_item_position(*item);
178}
179
180static int rna_NodeTreeInterfaceItem_index_get(PointerRNA *ptr)
181{
182 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
183 const bNodeTreeInterfaceItem *item = static_cast<const bNodeTreeInterfaceItem *>(ptr->data);
184 return ntree->tree_interface.find_item_index(*item);
185}
186
187static bool rna_NodeTreeInterfaceSocket_unregister(Main * /*bmain*/, StructRNA *type)
188{
191 if (!st) {
192 return false;
193 }
194
196
198
199 /* update while blender is running */
201 return true;
202}
203
204static void rna_NodeTreeInterfaceSocket_draw_builtin(ID *id,
205 bNodeTreeInterfaceSocket *interface_socket,
206 bContext *C,
207 uiLayout *layout)
208{
209 blender::bke::bNodeSocketType *typeinfo = interface_socket->socket_typeinfo();
210 if (typeinfo && typeinfo->interface_draw) {
211 typeinfo->interface_draw(id, interface_socket, C, layout);
212 }
213}
214
215static void rna_NodeTreeInterfaceSocket_draw_custom(ID *id,
216 bNodeTreeInterfaceSocket *interface_socket,
217 bContext *C,
218 uiLayout *layout)
219{
221 interface_socket->socket_type);
222 if (typeinfo == nullptr) {
223 return;
224 }
225
226 PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_NodeTreeInterfaceSocket, interface_socket);
227
228 FunctionRNA *func = &rna_NodeTreeInterfaceSocket_draw_func;
229
230 ParameterList list;
231 RNA_parameter_list_create(&list, &ptr, func);
232 RNA_parameter_set_lookup(&list, "context", &C);
233 RNA_parameter_set_lookup(&list, "layout", &layout);
234 typeinfo->ext_interface.call(C, &ptr, func, &list);
235
237}
238
239static void rna_NodeTreeInterfaceSocket_init_socket_builtin(
240 ID *id,
241 bNodeTreeInterfaceSocket *interface_socket,
242 bNode *node,
243 bNodeSocket *socket,
244 const char *data_path)
245{
246 blender::bke::bNodeSocketType *typeinfo = interface_socket->socket_typeinfo();
247 if (typeinfo && typeinfo->interface_draw) {
248 typeinfo->interface_init_socket(id, interface_socket, node, socket, data_path);
249 }
250}
251
252static void rna_NodeTreeInterfaceSocket_init_socket_custom(
253 ID *id,
254 const bNodeTreeInterfaceSocket *interface_socket,
255 bNode *node,
256 bNodeSocket *socket,
257 const blender::StringRefNull data_path)
258{
260 interface_socket->socket_type);
261 if (typeinfo == nullptr) {
262 return;
263 }
264
266 id, &RNA_NodeTreeInterfaceSocket, const_cast<bNodeTreeInterfaceSocket *>(interface_socket));
267
268 FunctionRNA *func = &rna_NodeTreeInterfaceSocket_init_socket_func;
269
270 ParameterList list;
271 RNA_parameter_list_create(&list, &ptr, func);
272 RNA_parameter_set_lookup(&list, "node", node);
273 RNA_parameter_set_lookup(&list, "socket", socket);
274 RNA_parameter_set_lookup(&list, "data_path", &data_path);
275 typeinfo->ext_interface.call(nullptr, &ptr, func, &list);
276
278}
279
280static void rna_NodeTreeInterfaceSocket_from_socket_builtin(
281 ID *id, bNodeTreeInterfaceSocket *interface_socket, bNode *node, bNodeSocket *socket)
282{
283 blender::bke::bNodeSocketType *typeinfo = interface_socket->socket_typeinfo();
284 if (typeinfo && typeinfo->interface_draw) {
285 typeinfo->interface_from_socket(id, interface_socket, node, socket);
286 }
287}
288
289static void rna_NodeTreeInterfaceSocket_from_socket_custom(
290 ID *id,
291 bNodeTreeInterfaceSocket *interface_socket,
292 const bNode *node,
293 const bNodeSocket *socket)
294{
296 interface_socket->socket_type);
297 if (typeinfo == nullptr) {
298 return;
299 }
300
301 PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_NodeTreeInterfaceSocket, interface_socket);
302
303 FunctionRNA *func = &rna_NodeTreeInterfaceSocket_from_socket_func;
304
305 ParameterList list;
306 RNA_parameter_list_create(&list, &ptr, func);
307 RNA_parameter_set_lookup(&list, "node", node);
308 RNA_parameter_set_lookup(&list, "socket", socket);
309 typeinfo->ext_interface.call(nullptr, &ptr, func, &list);
310
312}
313
314static StructRNA *rna_NodeTreeInterfaceSocket_register(Main * /*bmain*/,
315 ReportList * /*reports*/,
316 void *data,
317 const char *identifier,
318 StructValidateFunc validate,
321{
322 bNodeTreeInterfaceSocket dummy_socket = {};
323 /* Set #item_type so that refining the type ends up with RNA_NodeTreeInterfaceSocket. */
324 dummy_socket.item.item_type = NODE_INTERFACE_SOCKET;
325
326 PointerRNA dummy_socket_ptr = RNA_pointer_create_discrete(
327 nullptr, &RNA_NodeTreeInterfaceSocket, &dummy_socket);
328
329 /* Validate the python class. */
330 bool have_function[3];
331 if (validate(&dummy_socket_ptr, data, have_function) != 0) {
332 return nullptr;
333 }
334
335 /* Check if we have registered this socket type before. */
337 dummy_socket.socket_type);
338 if (st) {
339 /* Socket type registered before. */
340 }
341 else {
342 /* Create a new node socket type. */
343 st = MEM_new<blender::bke::bNodeSocketType>(__func__);
344 st->idname = dummy_socket.socket_type;
345
347 }
348
349 st->free_self = [](blender::bke::bNodeSocketType *type) { MEM_delete(type); };
350
351 /* if RNA type is already registered, unregister first */
352 if (st->ext_interface.srna) {
353 StructRNA *srna = st->ext_interface.srna;
356 }
358 &BLENDER_RNA, identifier, &RNA_NodeTreeInterfaceSocket);
359 st->ext_interface.data = data;
360 st->ext_interface.call = call;
361 st->ext_interface.free = free;
363
364 st->interface_draw = (have_function[0]) ? rna_NodeTreeInterfaceSocket_draw_custom : nullptr;
365 st->interface_init_socket = (have_function[1]) ? rna_NodeTreeInterfaceSocket_init_socket_custom :
366 nullptr;
367 st->interface_from_socket = (have_function[2]) ? rna_NodeTreeInterfaceSocket_from_socket_custom :
368 nullptr;
369
370 /* Cleanup local dummy type. */
371 MEM_SAFE_FREE(dummy_socket.socket_type);
372
373 /* Update while blender is running */
375
376 return st->ext_interface.srna;
377}
378
379static IDProperty **rna_NodeTreeInterfaceSocket_idprops(PointerRNA *ptr)
380{
381 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
382 return &socket->properties;
383}
384
385static void rna_NodeTreeInterfaceSocket_identifier_get(PointerRNA *ptr, char *value)
386{
387 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
388 strcpy(value, socket->identifier);
389}
390
391static int rna_NodeTreeInterfaceSocket_identifier_length(PointerRNA *ptr)
392{
393 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
394 return strlen(socket->identifier);
395}
396
397static int rna_NodeTreeInterfaceSocket_socket_type_get(PointerRNA *ptr)
398{
399 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
401}
402
403static void rna_NodeTreeInterfaceSocket_socket_type_set(PointerRNA *ptr, int value)
404{
406
407 if (typeinfo) {
408 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
409 socket->set_socket_type(typeinfo->idname);
410 }
411}
412
413static bool is_socket_type_supported(blender::bke::bNodeTreeType *ntreetype,
415{
416 /* Check if the node tree supports the socket type. */
417 if (ntreetype->valid_socket_type && !ntreetype->valid_socket_type(ntreetype, socket_type)) {
418 return false;
419 }
420
421 /* Only basic socket types are supported. Custom sockets don't have a base type. */
422 if (socket_type->type != SOCK_CUSTOM) {
424 socket_type->type, PROP_NONE);
425 BLI_assert(base_socket_type != nullptr);
426 if (socket_type != base_socket_type) {
427 return false;
428 }
429 }
430
431 if (!U.experimental.use_bundle_and_closure_nodes) {
432 if (ELEM(socket_type->type, SOCK_BUNDLE, SOCK_CLOSURE)) {
433 return false;
434 }
435 }
436
437 return true;
438}
439
440static blender::bke::bNodeSocketType *find_supported_socket_type(
441 blender::bke::bNodeTreeType *ntree_type)
442{
444 if (is_socket_type_supported(ntree_type, socket_type)) {
445 return socket_type;
446 }
447 }
448 return nullptr;
449}
450
451static bool rna_NodeTreeInterfaceSocket_socket_type_poll(
452 void *userdata, blender::bke::bNodeSocketType *socket_type)
453{
454 blender::bke::bNodeTreeType *ntreetype = static_cast<blender::bke::bNodeTreeType *>(userdata);
455 return is_socket_type_supported(ntreetype, socket_type);
456}
457
458static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_socket_type_itemf(
459 bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free)
460{
461 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
462
463 if (!ntree) {
465 }
466
468 ntree->typeinfo, rna_NodeTreeInterfaceSocket_socket_type_poll, r_free);
469}
470
475static void rna_NodeTreeInterfaceSocket_force_non_field_set(PointerRNA *ptr, const bool value)
476{
477 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
481}
482
483static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_structure_type_itemf(
484 bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free)
485{
486 const bNodeTree *ntree = reinterpret_cast<const bNodeTree *>(ptr->owner_id);
487 const bNodeTreeInterfaceSocket *socket = static_cast<const bNodeTreeInterfaceSocket *>(
488 ptr->data);
489 if (!ntree) {
491 }
492
493 const bool is_geometry_nodes = ntree->type == NTREE_GEOMETRY;
494
495 const eNodeSocketDatatype socket_type = socket->socket_typeinfo()->type;
496 const bool supports_fields = is_geometry_nodes &&
498 const bool supports_grids = is_geometry_nodes &&
500
501 *r_free = true;
502 EnumPropertyItem *items = nullptr;
503 int items_count = 0;
504
506 item->identifier;
507 item++)
508 {
509 switch (NodeSocketInterfaceStructureType(item->value)) {
512 RNA_enum_item_add(&items, &items_count, item);
513 break;
514 }
516 if (U.experimental.use_socket_structure_type) {
517 if (supports_fields || supports_grids) {
518 RNA_enum_item_add(&items, &items_count, item);
519 }
520 }
521 break;
522 }
524 if (U.experimental.use_socket_structure_type) {
525 if (supports_fields) {
526 RNA_enum_item_add(&items, &items_count, item);
527 }
528 }
529 break;
530 }
532 if (U.experimental.use_socket_structure_type) {
533 if (supports_grids) {
534 RNA_enum_item_add(&items, &items_count, item);
535 }
536 }
537 break;
538 }
539 }
540 }
541 RNA_enum_item_end(&items, &items_count);
542 return items;
543}
544
545static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_default_input_itemf(
546 bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free)
547{
548 const bNodeTree *ntree = reinterpret_cast<const bNodeTree *>(ptr->owner_id);
549 const bNodeTreeInterfaceSocket *socket = static_cast<const bNodeTreeInterfaceSocket *>(
550 ptr->data);
551 if (!ntree) {
553 }
554 const blender::bke::bNodeSocketType *stype = socket->socket_typeinfo();
555 if (!stype) {
557 }
558
559 *r_free = true;
560 EnumPropertyItem *items = nullptr;
561 int items_count = 0;
562
563 for (const EnumPropertyItem *item = node_default_input_items; item->identifier; item++) {
564 if (item->value == NODE_DEFAULT_INPUT_VALUE) {
565 RNA_enum_item_add(&items, &items_count, item);
566 }
567 else if (ntree->type == NTREE_GEOMETRY) {
569 *stype, NodeDefaultInputType(item->value)))
570 {
571 RNA_enum_item_add(&items, &items_count, item);
572 }
573 }
574 }
575
576 RNA_enum_item_end(&items, &items_count);
577 return items;
578}
579
580static const EnumPropertyItem *rna_NodeTreeInterfaceSocket_attribute_domain_itemf(
581 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
582{
583 using namespace blender;
584 EnumPropertyItem *item_array = nullptr;
585 int items_len = 0;
586
587 for (const EnumPropertyItem *item = rna_enum_attribute_domain_items; item->identifier != nullptr;
588 item++)
589 {
590 RNA_enum_item_add(&item_array, &items_len, item);
591 }
592 RNA_enum_item_end(&item_array, &items_len);
593
594 *r_free = true;
595 return item_array;
596}
597
598static PointerRNA rna_NodeTreeInterfaceItems_active_get(PointerRNA *ptr)
599{
600 bNodeTreeInterface *interface = static_cast<bNodeTreeInterface *>(ptr->data);
602 ptr->owner_id, &RNA_NodeTreeInterfaceItem, interface->active_item());
603 return r_ptr;
604}
605
606static void rna_NodeTreeInterfaceItems_active_set(PointerRNA *ptr,
607 PointerRNA value,
608 ReportList * /*reports*/)
609{
610 bNodeTreeInterface *interface = static_cast<bNodeTreeInterface *>(ptr->data);
611 bNodeTreeInterfaceItem *item = static_cast<bNodeTreeInterfaceItem *>(value.data);
612 interface->active_item_set(item);
613}
614
615static bNodeTreeInterfaceSocket *rna_NodeTreeInterfaceItems_new_socket(
616 ID *id,
618 Main *bmain,
620 const char *name,
621 const char *description,
622 int in_out,
623 int socket_type_enum,
625{
626 if (parent != nullptr && !interface->find_item(parent->item)) {
627 BKE_report(reports, RPT_ERROR_INVALID_INPUT, "Parent is not part of the interface");
628 return nullptr;
629 }
630 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
632 if (typeinfo == nullptr) {
633 BKE_report(reports, RPT_ERROR_INVALID_INPUT, "Unknown socket type");
634 return nullptr;
635 }
636
637 /* If data type is unsupported try to find a valid type. */
638 if (!is_socket_type_supported(ntree->typeinfo, typeinfo)) {
639 typeinfo = find_supported_socket_type(ntree->typeinfo);
640 if (typeinfo == nullptr) {
641 BKE_report(reports, RPT_ERROR, "Could not find supported socket type");
642 return nullptr;
643 }
644 }
645 const blender::StringRef socket_type = typeinfo->idname;
647 bNodeTreeInterfaceSocket *socket = interface->add_socket(
648 name, description, socket_type, flag, parent);
649
650 if (socket == nullptr) {
651 BKE_report(reports, RPT_ERROR, "Unable to create socket");
652 }
653 else {
654 BKE_main_ensure_invariants(*bmain, ntree->id);
656 }
657
658 return socket;
659}
660
661static bNodeTreeInterfacePanel *rna_NodeTreeInterfaceItems_new_panel(ID *id,
663 Main *bmain,
665 const char *name,
666 const char *description,
667 bool default_closed)
668{
671
672 bNodeTreeInterfacePanel *panel = interface->add_panel(
673 name ? name : "", description ? description : "", flag, nullptr);
674
675 if (panel == nullptr) {
676 BKE_report(reports, RPT_ERROR, "Unable to create panel");
677 }
678 else {
679 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
680 BKE_main_ensure_invariants(*bmain, ntree->id);
682 }
683
684 return panel;
685}
686
687static bNodeTreeInterfaceItem *rna_NodeTreeInterfaceItems_copy_to_parent(
688 ID *id,
690 Main *bmain,
694{
695 if (parent != nullptr) {
696 if (!interface->find_item(parent->item)) {
697 BKE_report(reports, RPT_ERROR_INVALID_INPUT, "Parent is not part of the interface");
698 return nullptr;
699 }
700 }
701
702 if (parent == nullptr) {
703 parent = &interface->root_panel;
704 }
705 const int index = parent->items().as_span().first_index_try(item);
706 if (!parent->items().index_range().contains(index)) {
707 return nullptr;
708 }
709
710 bNodeTreeInterfaceItem *item_copy = interface->insert_item_copy(*item, parent, index + 1);
711
712 if (item_copy == nullptr) {
713 BKE_report(reports, RPT_ERROR, "Unable to copy item");
714 }
715 else {
716 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
717 BKE_main_ensure_invariants(*bmain, ntree->id);
719 }
720
721 return item_copy;
722}
723
724static bNodeTreeInterfaceItem *rna_NodeTreeInterfaceItems_copy(ID *id,
726 Main *bmain,
729{
730 /* Copy to same parent as the item. */
731 bNodeTreeInterfacePanel *parent = interface->find_item_parent(*item);
732 return rna_NodeTreeInterfaceItems_copy_to_parent(id, interface, bmain, reports, item, parent);
733}
734
735static void rna_NodeTreeInterfaceItems_remove(ID *id,
737 Main *bmain,
739 bool move_content_to_parent)
740{
741 interface->remove_item(*item, move_content_to_parent);
742
743 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
744 BKE_main_ensure_invariants(*bmain, ntree->id);
746}
747
748static void rna_NodeTreeInterfaceItems_clear(ID *id, bNodeTreeInterface *interface, Main *bmain)
749{
750 interface->clear_items();
751
752 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
753 BKE_main_ensure_invariants(*bmain, ntree->id);
755}
756
757static void rna_NodeTreeInterfaceItems_move(ID *id,
759 Main *bmain,
761 int to_position)
762{
763 interface->move_item(*item, to_position);
764
765 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
766 BKE_main_ensure_invariants(*bmain, ntree->id);
768}
769
770static void rna_NodeTreeInterfaceItems_move_to_parent(ID *id,
772 Main *bmain,
773 ReportList * /*reports*/,
776 int to_position)
777{
778 interface->move_item_to_parent(*item, parent, to_position);
779
780 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
781 BKE_main_ensure_invariants(*bmain, ntree->id);
783}
784
785/* ******** Node Socket Subtypes ******** */
786
787static const EnumPropertyItem *rna_subtype_filter_itemf(const blender::Set<int> &subtypes,
788 bool *r_free)
789{
790 if (subtypes.is_empty()) {
792 }
793
794 EnumPropertyItem *items = nullptr;
795 int items_count = 0;
796 for (const EnumPropertyItem *item = rna_enum_property_subtype_items; item->name != nullptr;
797 item++)
798 {
799 if (subtypes.contains(item->value)) {
800 RNA_enum_item_add(&items, &items_count, item);
801 }
802 }
803
804 if (items_count == 0) {
806 }
807
808 RNA_enum_item_end(&items, &items_count);
809 *r_free = true;
810 return items;
811}
812
813static const EnumPropertyItem *rna_NodeTreeInterfaceSocketFloat_subtype_itemf(
814 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
815{
816 return rna_subtype_filter_itemf({PROP_PERCENTAGE,
819 PROP_TIME,
825 PROP_NONE},
826 r_free);
827}
828
829void rna_NodeTreeInterfaceSocketFloat_default_value_range(
830 PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
831{
832 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
833 bNodeSocketValueFloat *dval = static_cast<bNodeSocketValueFloat *>(socket->socket_data);
835 socket->socket_type);
836 int subtype = socket_typeinfo ? socket_typeinfo->subtype : PROP_NONE;
837
838 if (dval->max < dval->min) {
839 dval->max = dval->min;
840 }
841
842 *min = (subtype == PROP_UNSIGNED ? 0.0f : -FLT_MAX);
843 *max = FLT_MAX;
844 *softmin = dval->min;
845 *softmax = dval->max;
846}
847
848static const EnumPropertyItem *rna_NodeTreeInterfaceSocketInt_subtype_itemf(bContext * /*C*/,
849 PointerRNA * /*ptr*/,
850 PropertyRNA * /*prop*/,
851 bool *r_free)
852{
853 return rna_subtype_filter_itemf({PROP_PERCENTAGE, PROP_FACTOR, PROP_NONE}, r_free);
854}
855
856void rna_NodeTreeInterfaceSocketInt_default_value_range(
857 PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
858{
859 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
860 bNodeSocketValueInt *dval = static_cast<bNodeSocketValueInt *>(socket->socket_data);
862 socket->socket_type);
863 int subtype = socket_typeinfo ? socket_typeinfo->subtype : PROP_NONE;
864
865 if (dval->max < dval->min) {
866 dval->max = dval->min;
867 }
868
869 *min = (subtype == PROP_UNSIGNED ? 0 : INT_MIN);
870 *max = INT_MAX;
871 *softmin = dval->min;
872 *softmax = dval->max;
873}
874
875static const EnumPropertyItem *rna_NodeTreeInterfaceSocketVector_subtype_itemf(
876 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
877{
878 return rna_subtype_filter_itemf({PROP_FACTOR,
885 PROP_XYZ,
886 PROP_NONE},
887 r_free);
888}
889
890void rna_NodeTreeInterfaceSocketVector_default_value_range(
891 PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
892{
893 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
894 bNodeSocketValueVector *dval = static_cast<bNodeSocketValueVector *>(socket->socket_data);
895
896 if (dval->max < dval->min) {
897 dval->max = dval->min;
898 }
899
900 *min = -FLT_MAX;
901 *max = FLT_MAX;
902 *softmin = dval->min;
903 *softmax = dval->max;
904}
905
906static const EnumPropertyItem *rna_NodeTreeInterfaceSocketString_subtype_itemf(
907 bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
908{
909 return rna_subtype_filter_itemf({PROP_FILEPATH, PROP_NONE}, r_free);
910}
911
912/* If the dimensions of the vector socket changed, we need to update the socket type, since each
913 * dimensions value has its own sub-type. */
914static void rna_NodeTreeInterfaceSocketVector_dimensions_update(Main *bmain,
915 Scene *scene,
917{
918
919 bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
920
921 /* Store a copy of the existing default value since it will be freed when setting the socket type
922 * below.*/
923 const bNodeSocketValueVector default_value = *static_cast<bNodeSocketValueVector *>(
924 socket->socket_data);
925
927 SOCK_VECTOR, default_value.subtype, default_value.dimensions);
928
929 socket->set_socket_type(socket_idname);
930
931 /* Restore existing default value. */
932 *static_cast<bNodeSocketValueVector *>(socket->socket_data) = default_value;
933
934 rna_NodeTreeInterfaceItem_update(bmain, scene, ptr);
935}
936
937static bool rna_NodeTreeInterfaceSocketMaterial_default_value_poll(PointerRNA * /*ptr*/,
938 PointerRNA value)
939{
940 /* Do not show grease pencil materials for now. */
941 Material *ma = static_cast<Material *>(value.data);
942 return ma->gp_style == nullptr;
943}
944
945static void rna_NodeTreeInterface_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
946{
947 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
948 if (!ntree->runtime) {
949 return;
950 }
951
952 ntree->ensure_interface_cache();
954 ptr,
955 const_cast<bNodeTreeInterfaceItem **>(ntree->interface_items().data()),
956 sizeof(bNodeTreeInterfaceItem *),
957 ntree->interface_items().size(),
958 false,
959 nullptr);
960}
961
962static int rna_NodeTreeInterface_items_length(PointerRNA *ptr)
963{
964 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
965 if (!ntree->runtime) {
966 return 0;
967 }
968
969 ntree->ensure_interface_cache();
970 return ntree->interface_items().size();
971}
972
973static bool rna_NodeTreeInterface_items_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
974{
975 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
976 if (!ntree->runtime) {
977 return false;
978 }
979
980 ntree->ensure_interface_cache();
981 if (!ntree->interface_items().index_range().contains(index)) {
982 return false;
983 }
984
986 *ptr, &RNA_NodeTreeInterfaceItem, ntree->interface_items()[index], *r_ptr);
987 return true;
988}
989
990static bool rna_NodeTreeInterface_items_lookup_string(PointerRNA *ptr,
991 const char *key,
992 PointerRNA *r_ptr)
993{
994 bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
995 if (!ntree->runtime) {
996 return false;
997 }
998
999 ntree->ensure_interface_cache();
1000 for (bNodeTreeInterfaceItem *item : ntree->interface_items()) {
1001 switch (NodeTreeInterfaceItemType(item->item_type)) {
1002 case NODE_INTERFACE_SOCKET: {
1003 bNodeTreeInterfaceSocket *socket = reinterpret_cast<bNodeTreeInterfaceSocket *>(item);
1004 if (STREQ(socket->name, key)) {
1005 rna_pointer_create_with_ancestors(*ptr, &RNA_NodeTreeInterfaceSocket, socket, *r_ptr);
1006 return true;
1007 }
1008 break;
1009 }
1010 case NODE_INTERFACE_PANEL: {
1011 bNodeTreeInterfacePanel *panel = reinterpret_cast<bNodeTreeInterfacePanel *>(item);
1012 if (STREQ(panel->name, key)) {
1013 rna_pointer_create_with_ancestors(*ptr, &RNA_NodeTreeInterfacePanel, panel, *r_ptr);
1014 return true;
1015 }
1016 break;
1017 }
1018 }
1019 }
1020 return false;
1021}
1022
1023const EnumPropertyItem *RNA_node_tree_interface_socket_menu_itemf(bContext * /*C*/,
1024 PointerRNA *ptr,
1025 PropertyRNA * /*prop*/,
1026 bool *r_free)
1027{
1028 const bNodeTreeInterfaceSocket *socket = static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
1029 if (!socket) {
1030 *r_free = false;
1032 }
1033 const bNodeSocketValueMenu *data = static_cast<bNodeSocketValueMenu *>(socket->socket_data);
1034 if (!data->enum_items) {
1035 *r_free = false;
1037 }
1038 return RNA_node_enum_definition_itemf(*data->enum_items, r_free);
1039}
1040
1041#else
1042
1044{
1045 StructRNA *srna;
1046 PropertyRNA *prop;
1047
1048 srna = RNA_def_struct(brna, "NodeTreeInterfaceItem", nullptr);
1049 RNA_def_struct_ui_text(srna, "Node Tree Interface Item", "Item in a node tree interface");
1050 RNA_def_struct_sdna(srna, "bNodeTreeInterfaceItem");
1051 RNA_def_struct_refine_func(srna, "rna_NodeTreeInterfaceItem_refine");
1052 RNA_def_struct_path_func(srna, "rna_NodeTreeInterfaceItem_path");
1053
1054 prop = RNA_def_property(srna, "item_type", PROP_ENUM, PROP_NONE);
1055 RNA_def_property_enum_sdna(prop, nullptr, "item_type");
1058 RNA_def_property_ui_text(prop, "Item Type", "Type of interface item");
1059
1060 prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
1061 RNA_def_property_struct_type(prop, "NodeTreeInterfacePanel");
1063 prop, "rna_NodeTreeInterfaceItem_parent_get", nullptr, nullptr, nullptr);
1066 RNA_def_property_ui_text(prop, "Parent", "Panel that contains the item");
1067
1068 prop = RNA_def_property(srna, "position", PROP_INT, PROP_NONE);
1069 RNA_def_property_int_funcs(prop, "rna_NodeTreeInterfaceItem_position_get", nullptr, nullptr);
1070 RNA_def_property_range(prop, -1, INT_MAX);
1072 RNA_def_property_ui_text(prop, "Position", "Position of the item in its parent panel");
1073
1074 prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
1075 RNA_def_property_int_funcs(prop, "rna_NodeTreeInterfaceItem_index_get", nullptr, nullptr);
1076 RNA_def_property_range(prop, -1, INT_MAX);
1079 prop, "Index", "Global index of the item among all items in the interface");
1080}
1081
1083{
1084 StructRNA *srna;
1085 PropertyRNA *prop;
1086 FunctionRNA *func;
1087 PropertyRNA *parm;
1088
1089 srna = RNA_def_struct(brna, "NodeTreeInterfaceSocket", "NodeTreeInterfaceItem");
1090 RNA_def_struct_ui_text(srna, "Node Tree Interface Socket", "Declaration of a node socket");
1091 RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket");
1093 "rna_NodeTreeInterfaceSocket_register",
1094 "rna_NodeTreeInterfaceSocket_unregister",
1095 nullptr);
1096 RNA_def_struct_idprops_func(srna, "rna_NodeTreeInterfaceSocket_idprops");
1097
1098 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1099 RNA_def_property_ui_text(prop, "Name", "Socket name");
1100 RNA_def_struct_name_property(srna, prop);
1101 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1102
1103 prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
1105 "rna_NodeTreeInterfaceSocket_identifier_get",
1106 "rna_NodeTreeInterfaceSocket_identifier_length",
1107 nullptr);
1109 RNA_def_property_ui_text(prop, "Identifier", "Unique identifier for mapping sockets");
1110
1111 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
1112 RNA_def_property_string_sdna(prop, nullptr, "description");
1113 RNA_def_property_ui_text(prop, "Description", "Socket description");
1114 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1115
1116 prop = RNA_def_property(srna, "socket_type", PROP_ENUM, PROP_NONE);
1119 "rna_NodeTreeInterfaceSocket_socket_type_get",
1120 "rna_NodeTreeInterfaceSocket_socket_type_set",
1121 "rna_NodeTreeInterfaceSocket_socket_type_itemf");
1124 prop, "Socket Type", "Type of the socket generated by this interface item");
1125 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1126
1127 prop = RNA_def_property(srna, "in_out", PROP_ENUM, PROP_NONE);
1128 RNA_def_property_enum_bitflag_sdna(prop, nullptr, "flag");
1131 RNA_def_property_ui_text(prop, "Input/Output Type", "Input or output socket type");
1132
1133 prop = RNA_def_property(srna, "hide_value", PROP_BOOLEAN, PROP_NONE);
1137 prop, "Hide Value", "Hide the socket input value even when the socket is not connected");
1138 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1139
1140 prop = RNA_def_property(srna, "hide_in_modifier", PROP_BOOLEAN, PROP_NONE);
1144 "Hide in Modifier",
1145 "Don't show the input value in the geometry nodes modifier interface");
1146 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1147
1148 prop = RNA_def_property(srna, "force_non_field", PROP_BOOLEAN, PROP_NONE);
1150 prop, nullptr, "flag", NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY_LEGACY);
1151 RNA_def_property_boolean_funcs(prop, nullptr, "rna_NodeTreeInterfaceSocket_force_non_field_set");
1154 prop,
1155 "Single Value",
1156 "Only allow single value inputs rather than field.\nDeprecated. Will be remove in 5.0.");
1157 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1158
1159 prop = RNA_def_property(srna, "is_inspect_output", PROP_BOOLEAN, PROP_NONE);
1163 "Is Inspect Output",
1164 "Take link out of node group to connect to root tree output node");
1165 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1166
1167 prop = RNA_def_property(srna, "is_panel_toggle", PROP_BOOLEAN, PROP_NONE);
1171 "Is Panel Toggle",
1172 "This socket is meant to be used as the toggle in its panel header");
1173 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1174
1175 prop = RNA_def_property(srna, "layer_selection_field", PROP_BOOLEAN, PROP_NONE);
1179 prop, "Layer Selection", "Take Grease Pencil Layer or Layer Group as selection field");
1180 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1181
1182 prop = RNA_def_property(srna, "menu_expanded", PROP_BOOLEAN, PROP_NONE);
1186 prop, "Menu Expanded", "Draw the menu socket as an expanded drop-down menu");
1187 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1188
1189 prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE);
1192 prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_attribute_domain_itemf");
1194 prop,
1195 "Attribute Domain",
1196 "Attribute domain used by the geometry nodes modifier to create an attribute output");
1197 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1198
1199 prop = RNA_def_property(srna, "default_attribute_name", PROP_STRING, PROP_NONE);
1200 RNA_def_property_string_sdna(prop, nullptr, "default_attribute_name");
1202 "Default Attribute",
1203 "The attribute name used by default when the node group is used by a "
1204 "geometry nodes modifier");
1205 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1206
1207 prop = RNA_def_property(srna, "structure_type", PROP_ENUM, PROP_NONE);
1210 prop,
1211 "Structure Type",
1212 "What kind of higher order types are expected to flow through this socket");
1214 prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_structure_type_itemf");
1215 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1216
1217 prop = RNA_def_property(srna, "default_input", PROP_ENUM, PROP_NONE);
1220 prop,
1221 "Default Input",
1222 "Input to use when the socket is unconnected. Requires \"Hide Value\".");
1224 prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_default_input_itemf");
1225 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1226
1227 /* Registered properties and functions for custom socket types. */
1228 prop = RNA_def_property(srna, "bl_socket_idname", PROP_STRING, PROP_NONE);
1229 RNA_def_property_string_sdna(prop, nullptr, "socket_type");
1231 RNA_def_property_ui_text(prop, "Socket Type Name", "Name of the socket type");
1232 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1233
1234 func = RNA_def_function(srna, "draw", nullptr);
1236 RNA_def_function_ui_description(func, "Draw properties of the socket interface");
1237 parm = RNA_def_pointer(func, "context", "Context", "", "");
1239 parm = RNA_def_property(func, "layout", PROP_POINTER, PROP_NONE);
1240 RNA_def_property_struct_type(parm, "UILayout");
1241 RNA_def_property_ui_text(parm, "Layout", "Layout in the UI");
1243
1244 func = RNA_def_function(srna, "init_socket", nullptr);
1245 RNA_def_function_ui_description(func, "Initialize a node socket instance");
1247 parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the socket to initialize");
1249 parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Socket to initialize");
1251 parm = RNA_def_string(
1252 func, "data_path", nullptr, 0, "Data Path", "Path to specialized socket data");
1254
1255 func = RNA_def_function(srna, "from_socket", nullptr);
1256 RNA_def_function_ui_description(func, "Setup template parameters from an existing socket");
1258 parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the original socket");
1260 parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Original socket");
1262}
1263
1265{
1266 StructRNA *srna;
1267 PropertyRNA *prop;
1268
1269 srna = RNA_def_struct(brna, "NodeTreeInterfacePanel", "NodeTreeInterfaceItem");
1270 RNA_def_struct_ui_text(srna, "Node Tree Interface Item", "Declaration of a node panel");
1271 RNA_def_struct_sdna(srna, "bNodeTreeInterfacePanel");
1272
1273 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1274 RNA_def_property_ui_text(prop, "Name", "Panel name");
1275 RNA_def_struct_name_property(srna, prop);
1276 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1277
1278 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
1279 RNA_def_property_string_sdna(prop, nullptr, "description");
1280 RNA_def_property_ui_text(prop, "Description", "Panel description");
1281 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1282
1283 prop = RNA_def_property(srna, "default_closed", PROP_BOOLEAN, PROP_NONE);
1286 RNA_def_property_ui_text(prop, "Default Closed", "Panel is closed by default on new nodes");
1287 RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
1288
1289 prop = RNA_def_property(srna, "interface_items", PROP_COLLECTION, PROP_NONE);
1290 RNA_def_property_collection_sdna(prop, nullptr, "items_array", "items_num");
1291 RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
1293 RNA_def_property_ui_text(prop, "Items", "Items in the node panel");
1294
1295 prop = RNA_def_property(srna, "persistent_uid", PROP_INT, PROP_NONE);
1296 RNA_def_property_int_sdna(prop, nullptr, "identifier");
1298 prop, "Persistent Identifier", "Unique identifier for this panel within this node tree");
1300}
1301
1303{
1304 PropertyRNA *prop;
1305 PropertyRNA *parm;
1306 FunctionRNA *func;
1307
1308 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
1309 RNA_def_property_int_sdna(prop, nullptr, "active_index");
1310 RNA_def_property_ui_text(prop, "Active Index", "Index of the active item");
1312 RNA_def_property_update(prop, NC_NODE, nullptr);
1313
1314 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1315 RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
1318 "rna_NodeTreeInterfaceItems_active_get",
1319 "rna_NodeTreeInterfaceItems_active_set",
1320 nullptr,
1321 nullptr);
1322 RNA_def_property_ui_text(prop, "Active", "Active item");
1323 RNA_def_property_update(prop, NC_NODE, nullptr);
1324
1325 func = RNA_def_function(srna, "new_socket", "rna_NodeTreeInterfaceItems_new_socket");
1326 RNA_def_function_ui_description(func, "Add a new socket to the interface");
1328 parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of the socket");
1330 RNA_def_string(func, "description", nullptr, 0, "Description", "Description of the socket");
1331 RNA_def_enum(func,
1332 "in_out",
1335 "Input/Output Type",
1336 "Create an input or output socket");
1337 parm = RNA_def_enum(func,
1338 "socket_type",
1340 0,
1341 "Socket Type",
1342 "Type of socket generated on nodes");
1343 /* NOTE: itemf callback works for the function parameter, it does not require a data pointer. */
1345 parm, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_socket_type_itemf");
1347 func, "parent", "NodeTreeInterfacePanel", "Parent", "Panel to add the socket in");
1348 /* return value */
1349 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceSocket", "Socket", "New socket");
1350 RNA_def_function_return(func, parm);
1351
1352 func = RNA_def_function(srna, "new_panel", "rna_NodeTreeInterfaceItems_new_panel");
1353 RNA_def_function_ui_description(func, "Add a new panel to the interface");
1355 parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of the new panel");
1356 RNA_def_string(func, "description", nullptr, 0, "Description", "Description of the panel");
1358 func, "default_closed", false, "Default Closed", "Panel is closed by default on new nodes");
1360 /* return value */
1361 parm = RNA_def_pointer(func, "item", "NodeTreeInterfacePanel", "Panel", "New panel");
1362 RNA_def_function_return(func, parm);
1363
1364 func = RNA_def_function(srna, "copy", "rna_NodeTreeInterfaceItems_copy");
1365 RNA_def_function_ui_description(func, "Add a copy of an item to the interface");
1367 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "Item to copy");
1369 /* return value */
1370 parm = RNA_def_pointer(
1371 func, "item_copy", "NodeTreeInterfaceItem", "Item Copy", "Copy of the item");
1372 RNA_def_function_return(func, parm);
1373
1374 func = RNA_def_function(srna, "remove", "rna_NodeTreeInterfaceItems_remove");
1375 RNA_def_function_ui_description(func, "Remove an item from the interface");
1377 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "The item to remove");
1380 func,
1381 "move_content_to_parent",
1382 true,
1383 "Move Content",
1384 "If the item is a panel, move the contents to the parent instead of deleting it");
1385
1386 func = RNA_def_function(srna, "clear", "rna_NodeTreeInterfaceItems_clear");
1387 RNA_def_function_ui_description(func, "Remove all items from the interface");
1389
1390 func = RNA_def_function(srna, "move", "rna_NodeTreeInterfaceItems_move");
1391 RNA_def_function_ui_description(func, "Move an item to another position");
1393 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "The item to move");
1395 parm = RNA_def_int(func,
1396 "to_position",
1397 -1,
1398 0,
1399 INT_MAX,
1400 "To Position",
1401 "Target position for the item in its current panel",
1402 0,
1403 10000);
1405
1406 func = RNA_def_function(srna, "move_to_parent", "rna_NodeTreeInterfaceItems_move_to_parent");
1407 RNA_def_function_ui_description(func, "Move an item to a new panel and/or position.");
1409 parm = RNA_def_pointer(func, "item", "NodeTreeInterfaceItem", "Item", "The item to move");
1411 parm = RNA_def_pointer(
1412 func, "parent", "NodeTreeInterfacePanel", "Parent", "New parent of the item");
1414 parm = RNA_def_int(func,
1415 "to_position",
1416 -1,
1417 0,
1418 INT_MAX,
1419 "To Position",
1420 "Target position for the item in the new parent panel",
1421 0,
1422 10000);
1424}
1425
1427{
1428 StructRNA *srna;
1429 PropertyRNA *prop;
1430
1431 srna = RNA_def_struct(brna, "NodeTreeInterface", nullptr);
1433 srna, "Node Tree Interface", "Declaration of sockets and ui panels of a node group");
1434 RNA_def_struct_sdna(srna, "bNodeTreeInterface");
1435
1436 prop = RNA_def_property(srna, "items_tree", PROP_COLLECTION, PROP_NONE);
1438 "rna_NodeTreeInterface_items_begin",
1439 "rna_iterator_array_next",
1440 "rna_iterator_array_end",
1441 "rna_iterator_array_dereference_get",
1442 "rna_NodeTreeInterface_items_length",
1443 "rna_NodeTreeInterface_items_lookup_int",
1444 "rna_NodeTreeInterface_items_lookup_string",
1445 nullptr);
1446 RNA_def_property_struct_type(prop, "NodeTreeInterfaceItem");
1448 RNA_def_property_ui_text(prop, "Items", "Items in the node interface");
1449
1451}
1452
1462
1463#endif
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
#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 ELEM(...)
#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_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_FIELD
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_DYNAMIC
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO
@ NTREE_GEOMETRY
eNodeSocketDatatype
@ SOCK_VECTOR
@ SOCK_CLOSURE
@ SOCK_CUSTOM
@ SOCK_BUNDLE
@ RPT_ERROR_INVALID_INPUT
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:511
@ FUNC_USE_REPORTS
Definition RNA_types.hh:805
@ FUNC_USE_MAIN
Definition RNA_types.hh:803
@ FUNC_USE_SELF_ID
Definition RNA_types.hh:792
@ FUNC_REGISTER_OPTIONAL
Definition RNA_types.hh:814
@ FUNC_ALLOW_WRITE
Definition RNA_types.hh:820
int(*)(PointerRNA *ptr, void *data, bool *have_function) StructValidateFunc
Definition RNA_types.hh:871
@ PROP_BOOLEAN
Definition RNA_types.hh:150
@ PROP_ENUM
Definition RNA_types.hh:154
@ PROP_INT
Definition RNA_types.hh:151
@ PROP_STRING
Definition RNA_types.hh:153
@ PROP_POINTER
Definition RNA_types.hh:155
@ PROP_COLLECTION
Definition RNA_types.hh:156
int(*)(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *list) StructCallbackFunc
Definition RNA_types.hh:872
void(*)(void *data) StructFreeFunc
Definition RNA_types.hh:876
@ PROPOVERRIDE_NO_COMPARISON
Definition RNA_types.hh:477
PropertyFlag
Definition RNA_types.hh:286
@ PROP_ANIMATABLE
Definition RNA_types.hh:305
@ PROP_EDITABLE
Definition RNA_types.hh:292
@ PROP_NEVER_NULL
Definition RNA_types.hh:351
@ PROP_REGISTER
Definition RNA_types.hh:385
@ PROP_TIME
Definition RNA_types.hh:241
@ PROP_DIRECTION
Definition RNA_types.hh:250
@ PROP_XYZ
Definition RNA_types.hh:257
@ PROP_DISTANCE
Definition RNA_types.hh:244
@ PROP_ACCELERATION
Definition RNA_types.hh:252
@ PROP_ANGLE
Definition RNA_types.hh:240
@ PROP_TIME_ABSOLUTE
Definition RNA_types.hh:242
@ PROP_EULER
Definition RNA_types.hh:254
@ PROP_COLOR_TEMPERATURE
Definition RNA_types.hh:278
@ PROP_NONE
Definition RNA_types.hh:221
@ PROP_PERCENTAGE
Definition RNA_types.hh:238
@ PROP_FREQUENCY
Definition RNA_types.hh:280
@ PROP_FACTOR
Definition RNA_types.hh:239
@ PROP_TRANSLATION
Definition RNA_types.hh:249
@ PROP_UNSIGNED
Definition RNA_types.hh:237
@ PROP_FILEPATH
Definition RNA_types.hh:224
@ PROP_VELOCITY
Definition RNA_types.hh:251
@ PROP_WAVELENGTH
Definition RNA_types.hh:275
#define C
Definition RandGen.cpp:29
#define NC_NODE
Definition WM_types.hh:391
#define NA_EDITED
Definition WM_types.hh:581
ReportList * reports
Definition WM_types.hh:1025
#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
#define MEM_SAFE_FREE(v)
T & get_item_as(bNodeTreeInterfaceItem &item)
Span< bNodeSocketType * > node_socket_types_get()
Definition node.cc:2789
void node_register_socket_type(bNodeSocketType &stype)
Definition node.cc:2826
bNodeSocketType * node_socket_type_find(StringRef idname)
Definition node.cc:2794
bNodeSocketType * node_socket_type_find_static(int type, int subtype=0)
Definition node.cc:2803
std::optional< StringRefNull > node_static_socket_type(int type, int subtype, std::optional< int > dimensions=std::nullopt)
Definition node.cc:3167
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)
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr, void *data, int itemsize, int length, bool free_ptr, IteratorSkipFunc skip)
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_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_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_struct_idprops_func(StructRNA *srna, const char *idproperties)
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)
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 const EnumPropertyItem node_tree_interface_socket_structure_type_items[]
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:124
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
Definition RNA_types.hh:909
StructCallbackFunc call
Definition RNA_types.hh:910
StructFreeFunc free
Definition RNA_types.hh:911
Definition DNA_ID.h:404
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:152
void(* interface_init_socket)(ID *id, const bNodeTreeInterfaceSocket *interface_socket, bNode *node, bNodeSocket *socket, StringRefNull data_path)
Definition BKE_node.hh:172
void(* free_self)(bNodeSocketType *stype)
Definition BKE_node.hh:196
void(* interface_draw)(ID *id, bNodeTreeInterfaceSocket *socket, bContext *C, uiLayout *layout)
Definition BKE_node.hh:168
eNodeSocketDatatype type
Definition BKE_node.hh:187
void(* interface_from_socket)(ID *id, bNodeTreeInterfaceSocket *interface_socket, const bNode *node, const bNodeSocket *socket)
Definition BKE_node.hh:177
bool(* valid_socket_type)(bNodeTreeType *ntreetype, bNodeSocketType *socket_type)
Definition BKE_node.hh:515
max
Definition text_draw.cc:251
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4227
uint8_t flag
Definition wm_window.cc:139