Blender V5.0
node_socket.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2007 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <climits>
10
11#include "DNA_node_types.h"
12
13#include "BLI_color.hh"
14#include "BLI_listbase.h"
15#include "BLI_math_euler.hh"
17#include "BLI_math_vector.h"
19#include "BLI_string.h"
20#include "BLI_string_utf8.h"
21#include "BLI_utildefines.h"
22
23#include "BKE_geometry_set.hh"
24#include "BKE_lib_id.hh"
25#include "BKE_node.hh"
27#include "BKE_node_runtime.hh"
30
32#include "DNA_material_types.h"
33
34#include "RNA_access.hh"
35
36#include "MEM_guardedalloc.h"
37
40#include "NOD_menu_value.hh"
42#include "NOD_socket.hh"
43
44using namespace blender;
47
49 bNode *node,
51 eNodeSocketInOut in_out)
52{
54 *ntree, *node, in_out, stemp->type, stemp->subtype, stemp->identifier, stemp->name);
55
56 sock->flag |= stemp->flag;
57
58 /* initialize default_value */
59 switch (stemp->type) {
60 case SOCK_FLOAT: {
62 dval->value = stemp->val1;
63 dval->min = stemp->min;
64 dval->max = stemp->max;
65 break;
66 }
67 case SOCK_INT: {
69 dval->value = int(stemp->val1);
70 dval->min = int(stemp->min);
71 dval->max = int(stemp->max);
72 break;
73 }
74 case SOCK_BOOLEAN: {
76 dval->value = int(stemp->val1);
77 break;
78 }
79 case SOCK_VECTOR: {
81 dval->value[0] = stemp->val1;
82 dval->value[1] = stemp->val2;
83 dval->value[2] = stemp->val3;
84 dval->dimensions = 3;
85 dval->min = stemp->min;
86 dval->max = stemp->max;
87 break;
88 }
89 case SOCK_RGBA: {
91 dval->value[0] = stemp->val1;
92 dval->value[1] = stemp->val2;
93 dval->value[2] = stemp->val3;
94 dval->value[3] = stemp->val4;
95 break;
96 }
97 }
98
99 return sock;
100}
101
103 bNode *node,
104 eNodeSocketInOut in_out,
105 ListBase *socklist,
107{
108 bNodeSocket *sock;
109
110 for (sock = (bNodeSocket *)socklist->first; sock; sock = sock->next) {
111 if (STREQLEN(sock->name, stemp->name, NODE_MAXSTR)) {
112 break;
113 }
114 }
115 if (sock) {
116 if (sock->type != stemp->type) {
117 bke::node_modify_socket_type_static(ntree, node, sock, stemp->type, stemp->subtype);
118 }
119 sock->flag |= stemp->flag;
120 }
121 else {
122 /* no socket for this template found, make a new one */
123 sock = node_add_socket_from_template(ntree, node, stemp, in_out);
124 }
125
126 /* remove the new socket from the node socket list first,
127 * will be added back after verification. */
128 BLI_remlink(socklist, sock);
129
130 return sock;
131}
132
134 bNode *node,
135 eNodeSocketInOut in_out,
136 ListBase *socklist,
137 bke::bNodeSocketTemplate *stemp_first)
138{
139 bNodeSocket *sock, *nextsock;
141
142 /* no inputs anymore? */
143 if (stemp_first == nullptr) {
144 for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) {
145 nextsock = sock->next;
146 bke::node_remove_socket(*ntree, *node, *sock);
147 }
148 }
149 else {
150 /* step by step compare */
151 stemp = stemp_first;
152 while (stemp->type != -1) {
153 stemp->sock = verify_socket_template(ntree, node, in_out, socklist, stemp);
154 stemp++;
155 }
156 /* leftovers are removed */
157 for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) {
158 nextsock = sock->next;
159 bke::node_remove_socket(*ntree, *node, *sock);
160 }
161
162 /* and we put back the verified sockets */
163 stemp = stemp_first;
164 if (socklist->first) {
165 /* Some dynamic sockets left, store the list start
166 * so we can add static sockets in front of it. */
167 sock = (bNodeSocket *)socklist->first;
168 while (stemp->type != -1) {
169 /* Put static sockets in front of dynamic. */
170 BLI_insertlinkbefore(socklist, sock, stemp->sock);
171 stemp++;
172 }
173 }
174 else {
175 while (stemp->type != -1) {
176 BLI_addtail(socklist, stemp->sock);
177 stemp++;
178 }
179 }
180 }
181}
182
183namespace blender::nodes {
184
186 bNode &node,
187 const SocketDeclaration &socket_decl,
188 Vector<bNodeSocket *> &old_sockets,
189 VectorSet<bNodeSocket *> &new_sockets,
190 const bool hide_new_sockets)
191{
192 /* Try to find a socket that corresponds to the declaration. */
193 bNodeSocket *old_socket_with_same_identifier = nullptr;
194 for (const int i : old_sockets.index_range()) {
195 bNodeSocket &old_socket = *old_sockets[i];
196 if (old_socket.identifier == socket_decl.identifier) {
197 old_sockets.remove_and_reorder(i);
198 old_socket_with_same_identifier = &old_socket;
199 break;
200 }
201 }
202 bNodeSocket *new_socket = nullptr;
203 if (old_socket_with_same_identifier == nullptr) {
204 /* Create a completely new socket. */
205 new_socket = &socket_decl.build(ntree, node);
206 SET_FLAG_FROM_TEST(new_socket->flag, hide_new_sockets, SOCK_HIDDEN);
207 }
208 else {
209 STRNCPY_UTF8(old_socket_with_same_identifier->name, socket_decl.name.c_str());
210 if (socket_decl.matches(*old_socket_with_same_identifier)) {
211 /* The existing socket matches exactly, just use it. */
212 new_socket = old_socket_with_same_identifier;
213 }
214 else {
215 /* Clear out identifier to avoid name collisions when a new socket is created. */
216 old_socket_with_same_identifier->identifier[0] = '\0';
217 new_socket = &socket_decl.update_or_build(ntree, node, *old_socket_with_same_identifier);
218
219 if (new_socket == old_socket_with_same_identifier) {
220 /* The existing socket has been updated, set the correct identifier again. */
221 STRNCPY_UTF8(new_socket->identifier, socket_decl.identifier.c_str());
222 }
223 else {
224 /* Move links to new socket with same identifier. */
225 LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
226 if (link->fromsock == old_socket_with_same_identifier) {
227 link->fromsock = new_socket;
228 }
229 else if (link->tosock == old_socket_with_same_identifier) {
230 link->tosock = new_socket;
231 }
232 }
233 for (bNodeLink &internal_link : node.runtime->internal_links) {
234 if (internal_link.fromsock == old_socket_with_same_identifier) {
235 internal_link.fromsock = new_socket;
236 }
237 else if (internal_link.tosock == old_socket_with_same_identifier) {
238 internal_link.tosock = new_socket;
239 }
240 }
241 }
242 }
244 new_socket->flag, old_socket_with_same_identifier->is_user_hidden(), SOCK_HIDDEN);
245 }
246 new_sockets.add_new(new_socket);
247 BKE_ntree_update_tag_socket_new(&ntree, new_socket);
248}
249
250static void refresh_node_panel(const PanelDeclaration &panel_decl,
251 Vector<bNodePanelState> &old_panels,
252 bNodePanelState &new_panel)
253{
254 /* Try to find a panel that corresponds to the declaration. */
255 bNodePanelState *old_panel_with_same_identifier = nullptr;
256 for (const int i : old_panels.index_range()) {
257 bNodePanelState &old_panel = old_panels[i];
258 if (old_panel.identifier == panel_decl.identifier) {
259 /* Panel is removed after copying to #new_panel. */
260 old_panel_with_same_identifier = &old_panel;
261 break;
262 }
263 }
264
265 if (old_panel_with_same_identifier == nullptr) {
266 /* Create a completely new panel. */
267 panel_decl.build(new_panel);
268 }
269 else {
270 if (panel_decl.matches(*old_panel_with_same_identifier)) {
271 /* The existing socket matches exactly, just use it. */
272 new_panel = *old_panel_with_same_identifier;
273 }
274 else {
275 /* Clear out identifier to avoid name collisions when a new panel is created. */
276 old_panel_with_same_identifier->identifier = -1;
277 panel_decl.update_or_build(*old_panel_with_same_identifier, new_panel);
278 }
279
280 /* Remove from old panels. */
281 const int64_t old_panel_index = old_panel_with_same_identifier - old_panels.begin();
282 old_panels.remove_and_reorder(old_panel_index);
283 }
284}
285
286static const char *get_identifier_from_decl(const char *identifier_prefix,
287 const bNodeSocket &socket,
288 const Span<const SocketDeclaration *> socket_decls)
289{
290 if (!BLI_str_startswith(socket.identifier, identifier_prefix)) {
291 return nullptr;
292 }
293 for (const SocketDeclaration *socket_decl : socket_decls) {
294 if (BLI_str_startswith(socket_decl->identifier.c_str(), identifier_prefix)) {
295 if (socket.type == socket_decl->socket_type) {
296 return socket_decl->identifier.c_str();
297 }
298 }
299 }
300 return nullptr;
301}
302
303static const char *get_identifier_from_decl(const Span<const char *> identifier_prefixes,
304 const bNodeSocket &socket,
305 const Span<const SocketDeclaration *> socket_decls)
306{
307 for (const char *identifier_prefix : identifier_prefixes) {
308 if (const char *identifier = get_identifier_from_decl(identifier_prefix, socket, socket_decls))
309 {
310 return identifier;
311 }
312 }
313 return nullptr;
314}
315
329 const bNode &node,
330 const bNodeSocket &socket,
331 const Span<const SocketDeclaration *> socket_decls)
332{
333 switch (node.type_legacy) {
335 return get_identifier_from_decl({"Min", "Max", "Value"}, socket, socket_decls);
336 }
337 case SH_NODE_MIX: {
338 return get_identifier_from_decl({"A", "B", "Result"}, socket, socket_decls);
339 }
340 case FN_NODE_COMPARE: {
341 if (STREQ(socket.identifier, "Angle")) {
342 return nullptr;
343 }
344 return get_identifier_from_decl({"A", "B"}, socket, socket_decls);
345 }
346 case SH_NODE_MAP_RANGE: {
347 if (socket.type == SOCK_VECTOR) {
348 if (STREQ(socket.identifier, "Value")) {
349 return "Vector";
350 }
351 if (STREQ(socket.identifier, "From Min")) {
352 return "From_Min_FLOAT3";
353 }
354 if (STREQ(socket.identifier, "From Max")) {
355 return "From_Max_FLOAT3";
356 }
357 if (STREQ(socket.identifier, "To Min")) {
358 return "To_Min_FLOAT3";
359 }
360 if (STREQ(socket.identifier, "To Max")) {
361 return "To_Max_FLOAT3";
362 }
363 if (STREQ(socket.identifier, "Steps")) {
364 return "Steps_FLOAT3";
365 }
366 if (STREQ(socket.identifier, "Result")) {
367 return "Vector";
368 }
369 }
370 return nullptr;
371 }
372 }
373 return nullptr;
374}
375
379static void do_forward_compat_versioning(bNode &node, const NodeDeclaration &node_decl)
380{
381 LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
382 if (socket->is_available()) {
383 if (const char *new_identifier = get_current_socket_identifier_for_future_socket(
384 node, *socket, node_decl.inputs))
385 {
386 STRNCPY_UTF8(socket->identifier, new_identifier);
387 }
388 }
389 }
390 LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
391 if (socket->is_available()) {
392 if (const char *new_identifier = get_current_socket_identifier_for_future_socket(
393 node, *socket, node_decl.outputs))
394 {
395 STRNCPY_UTF8(socket->identifier, new_identifier);
396 }
397 }
398 }
399}
400
405static bool hide_new_group_input_sockets(const bNode &node)
406{
407 BLI_assert(node.is_group_input());
408 /* Check needed to handle newly added group input nodes. */
409 if (const bNodeSocket *extension_socket = static_cast<bNodeSocket *>(node.outputs.last)) {
410 return extension_socket->is_user_hidden();
411 }
412 return false;
413}
414
416 bNode &node,
417 const NodeDeclaration &node_decl,
418 const bool do_id_user)
419{
420 if (!node.runtime->forward_compatible_versioning_done) {
421 do_forward_compat_versioning(node, node_decl);
422 node.runtime->forward_compatible_versioning_done = true;
423 }
424
425 /* Count panels */
426 int new_num_panels = 0;
427 for (const ItemDeclarationPtr &item_decl : node_decl.all_items) {
428 if (dynamic_cast<const PanelDeclaration *>(item_decl.get())) {
429 ++new_num_panels;
430 }
431 }
432
433 Vector<bNodeSocket *> old_inputs;
434 LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
435 old_inputs.append(socket);
436 }
437
438 Vector<bNodeSocket *> old_outputs;
439 LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
440 old_outputs.append(socket);
441 }
442
443 const bool hide_new_sockets = node.is_group_input() ? hide_new_group_input_sockets(node) : false;
444
445 Vector<bNodePanelState> old_panels = Vector<bNodePanelState>(node.panel_states());
446
447 /* New panel states buffer. */
449 node.num_panel_states = new_num_panels;
450 node.panel_states_array = MEM_calloc_arrayN<bNodePanelState>(new_num_panels, __func__);
451
452 /* Find list of sockets to add, mixture of old and new sockets. */
453 VectorSet<bNodeSocket *> new_inputs;
454 VectorSet<bNodeSocket *> new_outputs;
455 bNodePanelState *new_panel = node.panel_states_array;
456 for (const ItemDeclarationPtr &item_decl : node_decl.all_items) {
457 if (const SocketDeclaration *socket_decl = dynamic_cast<const SocketDeclaration *>(
458 item_decl.get()))
459 {
460 if (socket_decl->in_out == SOCK_IN) {
461 refresh_node_socket(ntree, node, *socket_decl, old_inputs, new_inputs, hide_new_sockets);
462 }
463 else {
464 refresh_node_socket(ntree, node, *socket_decl, old_outputs, new_outputs, hide_new_sockets);
465 }
466 }
467 else if (const PanelDeclaration *panel_decl = dynamic_cast<const PanelDeclaration *>(
468 item_decl.get()))
469 {
470 refresh_node_panel(*panel_decl, old_panels, *new_panel);
471 ++new_panel;
472 }
473 }
474
475 /* Destroy any remaining sockets that are no longer in the declaration. */
476 LISTBASE_FOREACH_MUTABLE (bNodeSocket *, old_socket, &node.inputs) {
477 if (!new_inputs.contains(old_socket)) {
478 blender::bke::node_remove_socket_ex(ntree, node, *old_socket, do_id_user);
479 }
480 }
481 LISTBASE_FOREACH_MUTABLE (bNodeSocket *, old_socket, &node.outputs) {
482 if (!new_outputs.contains(old_socket)) {
483 blender::bke::node_remove_socket_ex(ntree, node, *old_socket, do_id_user);
484 }
485 }
486
487 /* Clear and reinsert sockets in the new order. */
490 for (bNodeSocket *socket : new_inputs) {
491 BLI_addtail(&node.inputs, socket);
492 }
493 for (bNodeSocket *socket : new_outputs) {
494 BLI_addtail(&node.outputs, socket);
495 }
496}
497
498static void refresh_node(bNodeTree &ntree,
499 bNode &node,
501 bool do_id_user)
502{
503 if (node_decl.skip_updating_sockets) {
504 return;
505 }
506 if (!node_decl.matches(node)) {
507 refresh_node_sockets_and_panels(ntree, node, node_decl, do_id_user);
508 }
510}
511
513{
514 if (node.typeinfo->declare) {
515 if (node.typeinfo->static_declaration->is_context_dependent) {
516 if (!node.runtime->declaration) {
517 node.runtime->declaration = new NodeDeclaration();
518 }
519 build_node_declaration(*node.typeinfo, *node.runtime->declaration, &ntree, &node);
520 }
521 }
522 refresh_node(ntree, node, *node.runtime->declaration, true);
523}
524
526{
527 return ELEM(socket_type,
530 SOCK_RGBA,
532 SOCK_INT,
534 SOCK_MENU,
536}
537
539{
540 return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_INT, SOCK_BOOLEAN);
541}
542
544{
545 switch (socket_type) {
546 case SOCK_OBJECT:
547 case SOCK_IMAGE:
548 case SOCK_GEOMETRY:
549 case SOCK_COLLECTION:
550 case SOCK_TEXTURE:
551 case SOCK_MATERIAL:
552 case SOCK_CLOSURE:
553 case SOCK_BUNDLE:
554 case SOCK_STRING:
555 return true;
556 case SOCK_CUSTOM:
557 case SOCK_FLOAT:
558 case SOCK_VECTOR:
559 case SOCK_RGBA:
560 case SOCK_SHADER:
561 case SOCK_BOOLEAN:
562 case SOCK_INT:
563 case SOCK_ROTATION:
564 case SOCK_MENU:
565 case SOCK_MATRIX:
566 return false;
567 }
568 return false;
569}
570
571} // namespace blender::nodes
572
573void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
574{
575 blender::bke::bNodeType *ntype = node->typeinfo;
576 if (ntype == nullptr) {
577 return;
578 }
579 if (ntype->declare) {
581 refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user);
582 return;
583 }
584 /* Don't try to match socket lists when there are no templates.
585 * This prevents dynamically generated sockets to be removed, like for
586 * group, image or render layer nodes. We have an explicit check for the
587 * render layer node since it still has fixed sockets too.
588 */
589 if (ntype) {
590 if (ntype->inputs && ntype->inputs[0].type >= 0) {
591 verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs);
592 }
593 if (ntype->outputs && ntype->outputs[0].type >= 0 && node->type_legacy != CMP_NODE_R_LAYERS) {
594 verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs);
595 }
596 }
597}
598
600{
601 if (!data) {
602 return;
603 }
604
605 switch (datatype) {
606 case SOCK_FLOAT: {
607 bNodeSocketValueFloat *dval = MEM_callocN<bNodeSocketValueFloat>("node socket value float");
608 dval->subtype = subtype;
609 dval->value = 0.0f;
610 dval->min = -FLT_MAX;
611 dval->max = FLT_MAX;
612
613 *data = dval;
614 break;
615 }
616 case SOCK_INT: {
617 bNodeSocketValueInt *dval = MEM_callocN<bNodeSocketValueInt>("node socket value int");
618 dval->subtype = subtype;
619 dval->value = 0;
620 dval->min = INT_MIN;
621 dval->max = INT_MAX;
622
623 *data = dval;
624 break;
625 }
626 case SOCK_BOOLEAN: {
628 "node socket value bool");
629 dval->value = false;
630
631 *data = dval;
632 break;
633 }
634 case SOCK_ROTATION: {
636 *data = dval;
637 break;
638 }
639 case SOCK_VECTOR: {
640 static float default_value[] = {0.0f, 0.0f, 0.0f};
642 "node socket value vector");
643 dval->subtype = subtype;
644 dval->dimensions = 3;
645 copy_v3_v3(dval->value, default_value);
646 dval->min = -FLT_MAX;
647 dval->max = FLT_MAX;
648
649 *data = dval;
650 break;
651 }
652 case SOCK_RGBA: {
653 static float default_value[] = {0.0f, 0.0f, 0.0f, 1.0f};
654 bNodeSocketValueRGBA *dval = MEM_callocN<bNodeSocketValueRGBA>("node socket value color");
655 copy_v4_v4(dval->value, default_value);
656
657 *data = dval;
658 break;
659 }
660 case SOCK_STRING: {
662 "node socket value string");
663 dval->subtype = subtype;
664 dval->value[0] = '\0';
665
666 *data = dval;
667 break;
668 }
669 case SOCK_MENU: {
670 bNodeSocketValueMenu *dval = MEM_callocN<bNodeSocketValueMenu>("node socket value menu");
671 dval->value = -1;
672
673 *data = dval;
674 break;
675 }
676 case SOCK_OBJECT: {
678 "node socket value object");
679 dval->value = nullptr;
680
681 *data = dval;
682 break;
683 }
684 case SOCK_IMAGE: {
685 bNodeSocketValueImage *dval = MEM_callocN<bNodeSocketValueImage>("node socket value image");
686 dval->value = nullptr;
687
688 *data = dval;
689 break;
690 }
691 case SOCK_COLLECTION: {
693 "node socket value object");
694 dval->value = nullptr;
695
696 *data = dval;
697 break;
698 }
699 case SOCK_TEXTURE: {
701 "node socket value texture");
702 dval->value = nullptr;
703
704 *data = dval;
705 break;
706 }
707 case SOCK_MATERIAL: {
709 "node socket value material");
710 dval->value = nullptr;
711
712 *data = dval;
713 break;
714 }
715
716 case SOCK_CUSTOM:
717 case SOCK_GEOMETRY:
718 case SOCK_MATRIX:
719 case SOCK_SHADER:
720 case SOCK_BUNDLE:
721 case SOCK_CLOSURE:
722 break;
723 }
724}
725
726void node_socket_copy_default_value_data(eNodeSocketDatatype datatype, void *to, const void *from)
727{
728 if (!to || !from) {
729 return;
730 }
731
732 switch (datatype) {
733 case SOCK_FLOAT: {
736 *toval = *fromval;
737 break;
738 }
739 case SOCK_INT: {
741 bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)from;
742 *toval = *fromval;
743 break;
744 }
745 case SOCK_BOOLEAN: {
748 *toval = *fromval;
749 break;
750 }
751 case SOCK_VECTOR: {
754 *toval = *fromval;
755 break;
756 }
757 case SOCK_RGBA: {
760 *toval = *fromval;
761 break;
762 }
763 case SOCK_ROTATION: {
766 *toval = *fromval;
767 break;
768 }
769 case SOCK_STRING: {
772 *toval = *fromval;
773 break;
774 }
775 case SOCK_MENU: {
778 *toval = *fromval;
779 break;
780 }
781 case SOCK_OBJECT: {
784 *toval = *fromval;
785 id_us_plus(reinterpret_cast<ID *>(toval->value));
786 break;
787 }
788 case SOCK_IMAGE: {
791 *toval = *fromval;
792 id_us_plus(reinterpret_cast<ID *>(toval->value));
793 break;
794 }
795 case SOCK_COLLECTION: {
798 *toval = *fromval;
799 id_us_plus(reinterpret_cast<ID *>(toval->value));
800 break;
801 }
802 case SOCK_TEXTURE: {
805 *toval = *fromval;
806 id_us_plus(reinterpret_cast<ID *>(toval->value));
807 break;
808 }
809 case SOCK_MATERIAL: {
812 *toval = *fromval;
813 id_us_plus(reinterpret_cast<ID *>(toval->value));
814 break;
815 }
816
817 case SOCK_CUSTOM:
818 case SOCK_GEOMETRY:
819 case SOCK_MATRIX:
820 case SOCK_SHADER:
821 case SOCK_BUNDLE:
822 case SOCK_CLOSURE:
823 break;
824 }
825}
826
828{
829 if (sock->default_value) {
830 return; /* already initialized */
831 }
832
834 sock->typeinfo->type, PropertySubType(sock->typeinfo->subtype), &sock->default_value);
835}
836
838{
839 /* sanity check */
840 if (to->type != from->type) {
841 return;
842 }
843
844 /* make sure both exist */
845 if (!from->default_value) {
846 return;
847 }
849
850 /* use label instead of name if it has been set */
851 if (from->label[0] != '\0') {
852 STRNCPY_UTF8(to->name, from->label);
853 }
854
856
857 to->flag |= (from->flag & SOCK_HIDE_VALUE);
858}
859
861 ID * /*id*/,
862 const bNodeTreeInterfaceSocket *interface_socket,
863 bNode * /*node*/,
864 bNodeSocket *sock,
865 StringRefNull /*data_path*/)
866{
867 /* initialize the type value */
868 sock->type = sock->typeinfo->type;
869
871 eNodeSocketDatatype(sock->type), sock->typeinfo->subtype, &sock->default_value);
873 eNodeSocketDatatype(sock->type), sock->default_value, interface_socket->socket_data);
874}
875
878 const bNode * /*node*/,
879 const bNodeSocket *sock)
880{
881 /* initialize settings */
882 iosock->init_from_socket_instance(sock);
883}
884
886
888 const eNodeSocketDatatype type, int subtype, std::optional<int> dimensions = std::nullopt)
889{
890 const StringRefNull socket_idname = *bke::node_static_socket_type(type, subtype, dimensions);
892 type, subtype, dimensions);
893 const StringRefNull socket_label = *bke::node_static_socket_label(type, subtype);
894 const StringRefNull socket_subtype_label = blender::bke::node_socket_sub_type_label(subtype);
896 StructRNA *srna;
897
898 stype = MEM_new<bke::bNodeSocketType>(__func__);
899 stype->free_self = [](bke::bNodeSocketType *type) { MEM_delete(type); };
900 stype->idname = socket_idname;
901 stype->label = socket_label;
902 stype->subtype_label = socket_subtype_label;
903
904 /* set the RNA type
905 * uses the exact same identifier as the socket type idname */
906 srna = stype->ext_socket.srna = RNA_struct_find(socket_idname.c_str());
907 BLI_assert(srna != nullptr);
908 /* associate the RNA type with the socket type */
909 RNA_struct_blender_type_set(srna, stype);
910
911 /* set the interface RNA type */
912 srna = stype->ext_interface.srna = RNA_struct_find(interface_idname.c_str());
913 BLI_assert(srna != nullptr);
914 /* associate the RNA type with the socket type */
915 RNA_struct_blender_type_set(srna, stype);
916
917 /* extra type info for standard socket types */
918 stype->type = type;
919 stype->subtype = subtype;
920
921 /* XXX bad-level call! needed for setting draw callbacks */
923
926
927 stype->use_link_limits_of_type = true;
928 stype->input_link_limit = 1;
929 stype->output_link_limit = 0xFFF;
930
931 return stype;
932}
933
935
937{
938 const char *socket_idname = "NodeSocketVirtual";
940 StructRNA *srna;
941
942 stype = MEM_new<bke::bNodeSocketType>(__func__);
943 stype->free_self = [](bke::bNodeSocketType *type) { MEM_delete(type); };
944 stype->idname = socket_idname;
945
946 /* set the RNA type
947 * uses the exact same identifier as the socket type idname */
948 srna = stype->ext_socket.srna = RNA_struct_find(socket_idname);
949 BLI_assert(srna != nullptr);
950 /* associate the RNA type with the socket type */
951 RNA_struct_blender_type_set(srna, stype);
952
953 /* extra type info for standard socket types */
954 stype->type = SOCK_CUSTOM;
955
957
958 stype->use_link_limits_of_type = true;
959 stype->input_link_limit = 0xFFF;
960 stype->output_link_limit = 0xFFF;
961
962 return stype;
963}
964
966{
969 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
970 *(bool *)r_value = ((bNodeSocketValueBoolean *)socket_value)->value;
971 };
972 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
973 const bool value = ((bNodeSocketValueBoolean *)socket_value)->value;
974 return SocketValueVariant(value);
975 };
976 static SocketValueVariant default_value{false};
977 socktype->geometry_nodes_default_value = &default_value;
978 return socktype;
979}
980
982{
985 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
986 const auto &typed_value = *(bNodeSocketValueRotation *)socket_value;
987 const math::EulerXYZ euler(float3(typed_value.value_euler));
988 *static_cast<math::Quaternion *>(r_value) = math::to_quaternion(euler);
989 };
990 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
991 const auto &typed_value = *(bNodeSocketValueRotation *)socket_value;
992 const math::EulerXYZ euler(float3(typed_value.value_euler));
993 const math::Quaternion value = math::to_quaternion(euler);
994 return SocketValueVariant(value);
995 };
996 static SocketValueVariant default_value{math::Quaternion::identity()};
997 socktype->geometry_nodes_default_value = &default_value;
998 return socktype;
999}
1000
1002{
1005 socktype->get_base_cpp_value = [](const void * /*socket_value*/, void *r_value) {
1006 *static_cast<float4x4 *>(r_value) = float4x4::identity();
1007 };
1008 socktype->get_geometry_nodes_cpp_value = [](const void * /*socket_value*/) {
1010 };
1011 static SocketValueVariant default_value{float4x4::identity()};
1012 socktype->geometry_nodes_default_value = &default_value;
1013 return socktype;
1014}
1015
1017{
1020 socktype->get_base_cpp_value = [](const void * /*socket_value*/, void *r_value) {
1021 new (r_value) nodes::BundlePtr();
1022 };
1023 socktype->get_geometry_nodes_cpp_value = [](const void * /*socket_value*/) {
1025 };
1027 socktype->geometry_nodes_default_value = &default_value;
1028 return socktype;
1029}
1030
1032{
1035 socktype->get_base_cpp_value = [](const void * /*socket_value*/, void *r_value) {
1036 new (r_value) nodes::ClosurePtr();
1037 };
1038 socktype->get_geometry_nodes_cpp_value = [](const void * /*socket_value*/) {
1040 };
1042 socktype->geometry_nodes_default_value = &default_value;
1043 return socktype;
1044}
1045
1047{
1050 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1051 *(float *)r_value = ((bNodeSocketValueFloat *)socket_value)->value;
1052 };
1053 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1054 const float value = ((bNodeSocketValueFloat *)socket_value)->value;
1055 return SocketValueVariant(value);
1056 };
1057 static SocketValueVariant default_value{0.0f};
1058 socktype->geometry_nodes_default_value = &default_value;
1059 return socktype;
1060}
1061
1063{
1066 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1067 *(int *)r_value = ((bNodeSocketValueInt *)socket_value)->value;
1068 };
1069 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1070 const int value = ((bNodeSocketValueInt *)socket_value)->value;
1071 return SocketValueVariant(value);
1072 };
1073 static SocketValueVariant default_value{0};
1074 socktype->geometry_nodes_default_value = &default_value;
1075 return socktype;
1076}
1077
1079{
1080 bke::bNodeSocketType *socktype = make_standard_socket_type(SOCK_VECTOR, subtype, dimensions);
1082 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1083 *(blender::float3 *)r_value = ((bNodeSocketValueVector *)socket_value)->value;
1084 };
1085 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1086 const blender::float3 value = ((bNodeSocketValueVector *)socket_value)->value;
1087 return SocketValueVariant(value);
1088 };
1089 static SocketValueVariant default_value{blender::float3(0, 0, 0)};
1090 socktype->geometry_nodes_default_value = &default_value;
1091 return socktype;
1092}
1093
1095{
1098 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1099 *(blender::ColorGeometry4f *)r_value = ((bNodeSocketValueRGBA *)socket_value)->value;
1100 };
1101 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1102 const blender::ColorGeometry4f value = ((bNodeSocketValueRGBA *)socket_value)->value;
1103 return SocketValueVariant(value);
1104 };
1105 static SocketValueVariant default_value{blender::ColorGeometry4f(0, 0, 0, 0)};
1106 socktype->geometry_nodes_default_value = &default_value;
1107 return socktype;
1108}
1109
1111{
1114 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1115 new (r_value) std::string(((bNodeSocketValueString *)socket_value)->value);
1116 };
1117 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1118 std::string value = ((bNodeSocketValueString *)socket_value)->value;
1119 return SocketValueVariant(value);
1120 };
1121 static SocketValueVariant default_value{std::string()};
1122 socktype->geometry_nodes_default_value = &default_value;
1123 return socktype;
1124}
1125
1127{
1130 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1131 new (r_value) nodes::MenuValue(((bNodeSocketValueMenu *)socket_value)->value);
1132 };
1133 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1134 const nodes::MenuValue value{((bNodeSocketValueMenu *)socket_value)->value};
1135 return SocketValueVariant::From(value);
1136 };
1138 socktype->geometry_nodes_default_value = &default_value;
1139 return socktype;
1140}
1141
1143{
1146 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1147 *(Object **)r_value = ((bNodeSocketValueObject *)socket_value)->value;
1148 };
1149 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1150 Object *object = static_cast<const bNodeSocketValueObject *>(socket_value)->value;
1151 return SocketValueVariant::From(object);
1152 };
1153 static SocketValueVariant default_value = SocketValueVariant::From(
1154 static_cast<Object *>(nullptr));
1155 socktype->geometry_nodes_default_value = &default_value;
1156 return socktype;
1157}
1158
1160{
1163 socktype->get_base_cpp_value = [](const void * /*socket_value*/, void *r_value) {
1164 new (r_value) blender::bke::GeometrySet();
1165 };
1166 socktype->get_geometry_nodes_cpp_value = [](const void * /*socket_value*/) {
1168 };
1170 socktype->geometry_nodes_default_value = &default_value;
1171 return socktype;
1172}
1173
1175{
1178 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1179 *(Collection **)r_value = ((bNodeSocketValueCollection *)socket_value)->value;
1180 };
1181 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1182 Collection *collection = static_cast<const bNodeSocketValueCollection *>(socket_value)->value;
1183 return SocketValueVariant::From(collection);
1184 };
1185 static SocketValueVariant default_value = SocketValueVariant::From(
1186 static_cast<Collection *>(nullptr));
1187 socktype->geometry_nodes_default_value = &default_value;
1188 return socktype;
1189}
1190
1192{
1195 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1196 *(Tex **)r_value = ((bNodeSocketValueTexture *)socket_value)->value;
1197 };
1198 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1199 Tex *texture = static_cast<const bNodeSocketValueTexture *>(socket_value)->value;
1201 };
1202 static SocketValueVariant default_value = SocketValueVariant::From(static_cast<Tex *>(nullptr));
1203 socktype->geometry_nodes_default_value = &default_value;
1204 return socktype;
1205}
1206
1208{
1211 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1212 *(Image **)r_value = ((bNodeSocketValueImage *)socket_value)->value;
1213 };
1214 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1215 Image *image = static_cast<const bNodeSocketValueImage *>(socket_value)->value;
1216 return SocketValueVariant::From(image);
1217 };
1218 static SocketValueVariant default_value = SocketValueVariant::From(
1219 static_cast<Image *>(nullptr));
1220 socktype->geometry_nodes_default_value = &default_value;
1221 return socktype;
1222}
1223
1225{
1228 socktype->get_base_cpp_value = [](const void *socket_value, void *r_value) {
1229 *(Material **)r_value = ((bNodeSocketValueMaterial *)socket_value)->value;
1230 };
1231 socktype->get_geometry_nodes_cpp_value = [](const void *socket_value) {
1232 Material *material = static_cast<const bNodeSocketValueMaterial *>(socket_value)->value;
1233 return SocketValueVariant::From(material);
1234 };
1235 static SocketValueVariant default_value = SocketValueVariant::From(
1236 static_cast<Material *>(nullptr));
1237 socktype->geometry_nodes_default_value = &default_value;
1238 return socktype;
1239}
1240
1242{
1243 /* Draw callbacks are set in `drawnode.cc` to avoid bad-level calls. */
1244
1256
1261
1263
1273
1283
1293
1297
1300
1302
1304
1306
1308
1310
1312
1314
1316
1319
1321}
void id_us_plus(ID *id)
Definition lib_id.cc:358
#define FN_NODE_RANDOM_VALUE
#define SH_NODE_MAP_RANGE
#define FN_NODE_COMPARE
#define SH_NODE_MIX
#define CMP_NODE_R_LAYERS
void BKE_ntree_update_tag_socket_new(bNodeTree *ntree, bNodeSocket *socket)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:371
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
int bool BLI_str_startswith(const char *__restrict str, const char *__restrict start) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define STREQLEN(a, b, n)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define STREQ(a, b)
Object groups, one object can be in many groups at once.
#define NODE_MAXSTR
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDE_VALUE
@ SOCK_HIDDEN
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_TEXTURE
@ SOCK_VECTOR
@ SOCK_CLOSURE
@ SOCK_BOOLEAN
@ SOCK_MATERIAL
@ SOCK_SHADER
@ SOCK_MATRIX
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_CUSTOM
@ SOCK_BUNDLE
@ SOCK_GEOMETRY
@ SOCK_ROTATION
@ SOCK_OBJECT
@ SOCK_STRING
@ SOCK_RGBA
@ SOCK_MENU
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
PropertySubType
Definition RNA_types.hh:232
@ 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
BMesh const char void * data
long long int int64_t
static SocketValueVariant From(T &&value)
static const CPPType & get()
constexpr const char * c_str() const
bool contains(const Key &key) const
void add_new(const Key &key)
void remove_and_reorder(const int64_t index)
void append(const T &value)
IndexRange index_range() const
Vector< SocketDeclaration * > inputs
bool matches(const bNode &node) const
Vector< SocketDeclaration * > outputs
Vector< ItemDeclarationPtr > all_items
void update_or_build(const bNodePanelState &old_panel, bNodePanelState &new_panel) const
bool matches(const bNodePanelState &panel) const
void build(bNodePanelState &panel) const
virtual bool matches(const bNodeSocket &socket) const =0
virtual bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const
virtual bNodeSocket & build(bNodeTree &ntree, bNode &node) const =0
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_socket_declarations_update(bNode *node)
Definition node.cc:4786
void node_modify_socket_type_static(bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
Definition node.cc:2791
void node_remove_socket(bNodeTree &ntree, bNode &node, bNodeSocket &sock)
Definition node.cc:3243
std::optional< StringRefNull > node_static_socket_interface_type_new(int type, int subtype, std::optional< int > dimensions=std::nullopt)
Definition node.cc:2995
bool node_declaration_ensure_on_outdated_node(bNodeTree &ntree, bNode &node)
Definition node.cc:4798
void node_register_socket_type(bNodeSocketType &stype)
Definition node.cc:2494
bNodeSocket * node_add_static_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out, int type, int subtype, StringRefNull identifier, StringRefNull name)
Definition node.cc:3197
void node_remove_socket_ex(bNodeTree &ntree, bNode &node, bNodeSocket &sock, bool do_id_user)
Definition node.cc:3248
std::optional< StringRefNull > node_static_socket_label(int type, int subtype)
Definition node.cc:3152
std::optional< StringRefNull > node_static_socket_type(int type, int subtype, std::optional< int > dimensions=std::nullopt)
Definition node.cc:2835
StringRefNull node_socket_sub_type_label(int subtype)
Definition node.cc:2523
QuaternionBase< float > Quaternion
QuaternionBase< T > to_quaternion(const AxisAngleBase< T, AngleT > &axis_angle)
EulerXYZBase< float > EulerXYZ
ImplicitSharingPtr< Bundle > BundlePtr
std::unique_ptr< SocketDeclaration > SocketDeclarationPtr
void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node)
void build_node_declaration(const bke::bNodeType &typeinfo, NodeDeclaration &r_declaration, const bNodeTree *ntree, const bNode *node)
std::unique_ptr< ItemDeclaration > ItemDeclarationPtr
static void do_forward_compat_versioning(bNode &node, const NodeDeclaration &node_decl)
static void refresh_node_sockets_and_panels(bNodeTree &ntree, bNode &node, const NodeDeclaration &node_decl, const bool do_id_user)
static void refresh_node_socket(bNodeTree &ntree, bNode &node, const SocketDeclaration &socket_decl, Vector< bNodeSocket * > &old_sockets, VectorSet< bNodeSocket * > &new_sockets, const bool hide_new_sockets)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
static bool hide_new_group_input_sockets(const bNode &node)
ImplicitSharingPtr< Closure > ClosurePtr
static void refresh_node_panel(const PanelDeclaration &panel_decl, Vector< bNodePanelState > &old_panels, bNodePanelState &new_panel)
static const char * get_identifier_from_decl(const char *identifier_prefix, const bNodeSocket &socket, const Span< const SocketDeclaration * > socket_decls)
bool socket_type_supports_grids(const eNodeSocketDatatype socket_type)
static const char * get_current_socket_identifier_for_future_socket(const bNode &node, const bNodeSocket &socket, const Span< const SocketDeclaration * > socket_decls)
bool socket_type_always_single(const eNodeSocketDatatype socket_type)
static void refresh_node(bNodeTree &ntree, bNode &node, blender::nodes::NodeDeclaration &node_decl, bool do_id_user)
MatBase< float, 4, 4 > float4x4
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
static bke::bNodeSocketType * make_socket_type_matrix()
static bke::bNodeSocketType * make_socket_type_rotation()
static void verify_socket_template_list(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, ListBase *socklist, bke::bNodeSocketTemplate *stemp_first)
void node_socket_init_default_value(bNodeSocket *sock)
static bke::bNodeSocketType * make_socket_type_float(PropertySubType subtype)
static bke::bNodeSocketType * make_socket_type_texture()
static bke::bNodeSocketType * make_socket_type_object()
void ED_init_standard_node_socket_type(bke::bNodeSocketType *)
Definition drawnode.cc:1493
bNodeSocket * node_add_socket_from_template(bNodeTree *ntree, bNode *node, bke::bNodeSocketTemplate *stemp, eNodeSocketInOut in_out)
static bNodeSocket * verify_socket_template(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, ListBase *socklist, bke::bNodeSocketTemplate *stemp)
void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
static bke::bNodeSocketType * make_socket_type_rgba()
static bke::bNodeSocketType * make_standard_socket_type(const eNodeSocketDatatype type, int subtype, std::optional< int > dimensions=std::nullopt)
static bke::bNodeSocketType * make_socket_type_int(PropertySubType subtype)
static void standard_node_socket_interface_from_socket(ID *, bNodeTreeInterfaceSocket *iosock, const bNode *, const bNodeSocket *sock)
static bke::bNodeSocketType * make_socket_type_geometry()
static void standard_node_socket_interface_init_socket(ID *, const bNodeTreeInterfaceSocket *interface_socket, bNode *, bNodeSocket *sock, StringRefNull)
static bke::bNodeSocketType * make_socket_type_menu()
static bke::bNodeSocketType * make_socket_type_image()
static bke::bNodeSocketType * make_socket_type_collection()
void ED_init_node_socket_type_virtual(bke::bNodeSocketType *)
Definition drawnode.cc:1502
static bke::bNodeSocketType * make_socket_type_bundle()
static bke::bNodeSocketType * make_socket_type_vector(PropertySubType subtype, const int dimensions)
static bke::bNodeSocketType * make_socket_type_closure()
void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
static bke::bNodeSocketType * make_socket_type_material()
static bke::bNodeSocketType * make_socket_type_bool()
void register_standard_node_socket_types()
void node_socket_init_default_value_data(eNodeSocketDatatype datatype, int subtype, void **data)
static bke::bNodeSocketType * make_socket_type_string(PropertySubType subtype)
void node_socket_copy_default_value_data(eNodeSocketDatatype datatype, void *to, const void *from)
static bke::bNodeSocketType * make_socket_type_virtual()
StructRNA * RNA_struct_find(const char *identifier)
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
#define FLT_MAX
Definition stdcycles.h:14
StructRNA * srna
Definition DNA_ID.h:414
void * last
void * first
struct Collection * value
bNodeSocketTypeHandle * typeinfo
struct bNodeSocket * next
void * default_value
char identifier[64]
ListBase links
bNodeTypeHandle * typeinfo
ListBase inputs
int num_panel_states
bNodePanelState * panel_states_array
int16_t type_legacy
bNodeRuntimeHandle * runtime
ListBase outputs
Compact definition of a node socket.
Definition BKE_node.hh:99
Defines a socket type.
Definition BKE_node.hh:158
SocketGetCPPValueFunction get_base_cpp_value
Definition BKE_node.hh:207
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
eNodeSocketDatatype type
Definition BKE_node.hh:193
SocketGetGeometryNodesCPPValueFunction get_geometry_nodes_cpp_value
Definition BKE_node.hh:209
const SocketValueVariant * geometry_nodes_default_value
Definition BKE_node.hh:211
const blender::CPPType * base_cpp_type
Definition BKE_node.hh:205
void(* interface_from_socket)(ID *id, bNodeTreeInterfaceSocket *interface_socket, const bNode *node, const bNodeSocket *socket)
Definition BKE_node.hh:183
Defines a node type.
Definition BKE_node.hh:238
bNodeSocketTemplate * inputs
Definition BKE_node.hh:254
bNodeSocketTemplate * outputs
Definition BKE_node.hh:254
NodeDeclareFunction declare
Definition BKE_node.hh:362
i
Definition text_draw.cc:230