Blender V4.3
graph/node.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "graph/node.h"
6#include "graph/node_type.h"
7
8#include "util/foreach.h"
9#include "util/md5.h"
10#include "util/param.h"
11#include "util/transform.h"
12
14
15/* Node Type */
16
18
19Node::Node(const NodeType *type_, ustring name_) : name(name_), type(type_)
20{
21 assert(type);
22
23 owner = nullptr;
25
26 /* assign non-empty name, convenient for debugging */
27 if (name.empty()) {
28 name = type->name;
29 }
30
31 /* initialize default values */
32 foreach (const SocketType &socket, type->inputs) {
33 set_default_value(socket);
34 }
35}
36
38
39#ifndef NDEBUG
40static bool is_socket_float3(const SocketType &socket)
41{
42 return socket.type == SocketType::COLOR || socket.type == SocketType::POINT ||
43 socket.type == SocketType::VECTOR || socket.type == SocketType::NORMAL;
44}
45
46static bool is_socket_array_float3(const SocketType &socket)
47{
48 return socket.type == SocketType::COLOR_ARRAY || socket.type == SocketType::POINT_ARRAY ||
50}
51#endif
52
53/* set values */
54void Node::set(const SocketType &input, bool value)
55{
56 assert(input.type == SocketType::BOOLEAN);
57 set_if_different(input, value);
58}
59
60void Node::set(const SocketType &input, int value)
61{
62 assert((input.type == SocketType::INT || input.type == SocketType::ENUM));
63 set_if_different(input, value);
64}
65
66void Node::set(const SocketType &input, uint value)
67{
68 assert(input.type == SocketType::UINT);
69 set_if_different(input, value);
70}
71
72void Node::set(const SocketType &input, uint64_t value)
73{
74 assert(input.type == SocketType::UINT64);
75 set_if_different(input, value);
76}
77
78void Node::set(const SocketType &input, float value)
79{
80 assert(input.type == SocketType::FLOAT);
81 set_if_different(input, value);
82}
83
84void Node::set(const SocketType &input, float2 value)
85{
86 assert(input.type == SocketType::POINT2);
87 set_if_different(input, value);
88}
89
90void Node::set(const SocketType &input, float3 value)
91{
92 assert(is_socket_float3(input));
93 set_if_different(input, value);
94}
95
96void Node::set(const SocketType &input, const char *value)
97{
98 set(input, ustring(value));
99}
100
101void Node::set(const SocketType &input, ustring value)
102{
103 if (input.type == SocketType::STRING) {
104 set_if_different(input, value);
105 }
106 else if (input.type == SocketType::ENUM) {
107 const NodeEnum &enm = *input.enum_values;
108 if (enm.exists(value)) {
109 set_if_different(input, enm[value]);
110 }
111 else {
112 assert(0);
113 }
114 }
115 else {
116 assert(0);
117 }
118}
119
120void Node::set(const SocketType &input, const Transform &value)
121{
122 assert(input.type == SocketType::TRANSFORM);
123 set_if_different(input, value);
124}
125
126void Node::set(const SocketType &input, Node *value)
127{
128 assert(input.type == SocketType::NODE);
129 set_if_different(input, value);
130}
131
132/* set array values */
133void Node::set(const SocketType &input, array<bool> &value)
134{
135 assert(input.type == SocketType::BOOLEAN_ARRAY);
136 set_if_different(input, value);
137}
138
139void Node::set(const SocketType &input, array<int> &value)
140{
141 assert(input.type == SocketType::INT_ARRAY);
142 set_if_different(input, value);
143}
144
145void Node::set(const SocketType &input, array<float> &value)
146{
147 assert(input.type == SocketType::FLOAT_ARRAY);
148 set_if_different(input, value);
149}
150
151void Node::set(const SocketType &input, array<float2> &value)
152{
153 assert(input.type == SocketType::POINT2_ARRAY);
154 set_if_different(input, value);
155}
156
157void Node::set(const SocketType &input, array<float3> &value)
158{
159 assert(is_socket_array_float3(input));
160 set_if_different(input, value);
161}
162
163void Node::set(const SocketType &input, array<ustring> &value)
164{
165 assert(input.type == SocketType::STRING_ARRAY);
166 set_if_different(input, value);
167}
168
169void Node::set(const SocketType &input, array<Transform> &value)
170{
171 assert(input.type == SocketType::TRANSFORM_ARRAY);
172 set_if_different(input, value);
173}
174
175void Node::set(const SocketType &input, array<Node *> &value)
176{
177 assert(input.type == SocketType::NODE_ARRAY);
178 set_if_different(input, value);
179}
180
181/* get values */
182bool Node::get_bool(const SocketType &input) const
183{
184 assert(input.type == SocketType::BOOLEAN);
185 return get_socket_value<bool>(this, input);
186}
187
188int Node::get_int(const SocketType &input) const
189{
190 assert(input.type == SocketType::INT || input.type == SocketType::ENUM);
191 return get_socket_value<int>(this, input);
192}
193
194uint Node::get_uint(const SocketType &input) const
195{
196 assert(input.type == SocketType::UINT);
197 return get_socket_value<uint>(this, input);
198}
199
201{
202 assert(input.type == SocketType::UINT64);
203 return get_socket_value<uint64_t>(this, input);
204}
205
206float Node::get_float(const SocketType &input) const
207{
208 assert(input.type == SocketType::FLOAT);
209 return get_socket_value<float>(this, input);
210}
211
213{
214 assert(input.type == SocketType::POINT2);
215 return get_socket_value<float2>(this, input);
216}
217
219{
220 assert(is_socket_float3(input));
221 return get_socket_value<float3>(this, input);
222}
223
224ustring Node::get_string(const SocketType &input) const
225{
226 if (input.type == SocketType::STRING) {
227 return get_socket_value<ustring>(this, input);
228 }
229 else if (input.type == SocketType::ENUM) {
230 const NodeEnum &enm = *input.enum_values;
231 int intvalue = get_socket_value<int>(this, input);
232 return (enm.exists(intvalue)) ? enm[intvalue] : ustring();
233 }
234 else {
235 assert(0);
236 return ustring();
237 }
238}
239
241{
242 assert(input.type == SocketType::TRANSFORM);
243 return get_socket_value<Transform>(this, input);
244}
245
246Node *Node::get_node(const SocketType &input) const
247{
248 assert(input.type == SocketType::NODE);
249 return get_socket_value<Node *>(this, input);
250}
251
252/* get array values */
254{
255 assert(input.type == SocketType::BOOLEAN_ARRAY);
256 return get_socket_value<array<bool>>(this, input);
257}
258
259const array<int> &Node::get_int_array(const SocketType &input) const
260{
261 assert(input.type == SocketType::INT_ARRAY);
262 return get_socket_value<array<int>>(this, input);
263}
264
266{
267 assert(input.type == SocketType::FLOAT_ARRAY);
268 return get_socket_value<array<float>>(this, input);
269}
270
272{
273 assert(input.type == SocketType::POINT2_ARRAY);
274 return get_socket_value<array<float2>>(this, input);
275}
276
278{
279 assert(is_socket_array_float3(input));
280 return get_socket_value<array<float3>>(this, input);
281}
282
284{
285 assert(input.type == SocketType::STRING_ARRAY);
286 return get_socket_value<array<ustring>>(this, input);
287}
288
290{
291 assert(input.type == SocketType::TRANSFORM_ARRAY);
292 return get_socket_value<array<Transform>>(this, input);
293}
294
296{
297 assert(input.type == SocketType::NODE_ARRAY);
298 return get_socket_value<array<Node *>>(this, input);
299}
300
301/* generic value operations */
302
303bool Node::has_default_value(const SocketType &input) const
304{
305 const void *src = input.default_value;
306 void *dst = &get_socket_value<char>(this, input);
307 return memcmp(dst, src, input.size()) == 0;
308}
309
311{
312 const void *src = socket.default_value;
313 void *dst = ((char *)this) + socket.struct_offset;
314 if (socket.size() > 0) {
315 memcpy(dst, src, socket.size());
316 }
317}
318
319template<typename T>
320static void copy_array(const Node *node,
321 const SocketType &socket,
322 const Node *other,
323 const SocketType &other_socket)
324{
325 const array<T> *src = (const array<T> *)(((char *)other) + other_socket.struct_offset);
326 array<T> *dst = (array<T> *)(((char *)node) + socket.struct_offset);
327 *dst = *src;
328}
329
330void Node::copy_value(const SocketType &socket, const Node &other, const SocketType &other_socket)
331{
332 assert(socket.type == other_socket.type);
333
334 if (socket.is_array()) {
335 switch (socket.type) {
337 copy_array<bool>(this, socket, &other, other_socket);
338 break;
340 copy_array<float>(this, socket, &other, other_socket);
341 break;
343 copy_array<int>(this, socket, &other, other_socket);
344 break;
346 copy_array<float3>(this, socket, &other, other_socket);
347 break;
349 copy_array<float3>(this, socket, &other, other_socket);
350 break;
352 copy_array<float3>(this, socket, &other, other_socket);
353 break;
355 copy_array<float3>(this, socket, &other, other_socket);
356 break;
358 copy_array<float2>(this, socket, &other, other_socket);
359 break;
361 copy_array<ustring>(this, socket, &other, other_socket);
362 break;
364 copy_array<Transform>(this, socket, &other, other_socket);
365 break;
367 copy_array<void *>(this, socket, &other, other_socket);
368
369 array<Node *> &node_array = get_socket_value<array<Node *>>(this, socket);
370
371 for (Node *node : node_array) {
372 node->reference();
373 }
374
375 break;
376 }
377 default:
378 assert(0);
379 break;
380 }
381 }
382 else {
383 const void *src = ((char *)&other) + other_socket.struct_offset;
384 void *dst = ((char *)this) + socket.struct_offset;
385 memcpy(dst, src, socket.size());
386
387 if (socket.type == SocketType::NODE) {
388 Node *node = get_socket_value<Node *>(this, socket);
389
390 if (node) {
391 node->reference();
392 }
393 }
394 }
395}
396
397void Node::set_value(const SocketType &socket, const Node &other, const SocketType &other_socket)
398{
399 assert(socket.type == other_socket.type);
400 (void)other_socket;
401
402 if (socket.is_array()) {
403 switch (socket.type) {
405 set(socket, get_socket_value<array<bool>>(&other, socket));
406 break;
408 set(socket, get_socket_value<array<float>>(&other, socket));
409 break;
411 set(socket, get_socket_value<array<int>>(&other, socket));
412 break;
417 set(socket, get_socket_value<array<float3>>(&other, socket));
418 break;
420 set(socket, get_socket_value<array<float2>>(&other, socket));
421 break;
423 set(socket, get_socket_value<array<ustring>>(&other, socket));
424 break;
426 set(socket, get_socket_value<array<Transform>>(&other, socket));
427 break;
429 set(socket, get_socket_value<array<Node *>>(&other, socket));
430 break;
431 default:
432 assert(0);
433 break;
434 }
435 }
436 else {
437 switch (socket.type) {
439 set(socket, get_socket_value<bool>(&other, socket));
440 break;
442 set(socket, get_socket_value<float>(&other, socket));
443 break;
444 case SocketType::INT:
445 set(socket, get_socket_value<int>(&other, socket));
446 break;
447 case SocketType::UINT:
448 set(socket, get_socket_value<uint>(&other, socket));
449 break;
451 set(socket, get_socket_value<uint64_t>(&other, socket));
452 break;
457 set(socket, get_socket_value<float3>(&other, socket));
458 break;
460 set(socket, get_socket_value<float2>(&other, socket));
461 break;
463 set(socket, get_socket_value<ustring>(&other, socket));
464 break;
465 case SocketType::ENUM:
466 set(socket, get_socket_value<int>(&other, socket));
467 break;
469 set(socket, get_socket_value<Transform>(&other, socket));
470 break;
471 case SocketType::NODE:
472 set(socket, get_socket_value<Node *>(&other, socket));
473 break;
474 default:
475 assert(0);
476 break;
477 }
478 }
479}
480
481template<typename T>
482static bool is_array_equal(const Node *node, const Node *other, const SocketType &socket)
483{
484 const array<T> *a = (const array<T> *)(((char *)node) + socket.struct_offset);
485 const array<T> *b = (const array<T> *)(((char *)other) + socket.struct_offset);
486 return *a == *b;
487}
488
489template<typename T>
490static bool is_value_equal(const Node *node, const Node *other, const SocketType &socket)
491{
492 const T *a = (const T *)(((char *)node) + socket.struct_offset);
493 const T *b = (const T *)(((char *)other) + socket.struct_offset);
494 return *a == *b;
495}
496
497bool Node::equals_value(const Node &other, const SocketType &socket) const
498{
499 switch (socket.type) {
501 return is_value_equal<bool>(this, &other, socket);
503 return is_value_equal<float>(this, &other, socket);
504 case SocketType::INT:
505 return is_value_equal<int>(this, &other, socket);
506 case SocketType::UINT:
507 return is_value_equal<uint>(this, &other, socket);
509 return is_value_equal<uint64_t>(this, &other, socket);
511 return is_value_equal<float3>(this, &other, socket);
513 return is_value_equal<float3>(this, &other, socket);
515 return is_value_equal<float3>(this, &other, socket);
517 return is_value_equal<float3>(this, &other, socket);
519 return is_value_equal<float2>(this, &other, socket);
521 return true;
523 return is_value_equal<ustring>(this, &other, socket);
524 case SocketType::ENUM:
525 return is_value_equal<int>(this, &other, socket);
527 return is_value_equal<Transform>(this, &other, socket);
528 case SocketType::NODE:
529 return is_value_equal<void *>(this, &other, socket);
530
532 return is_array_equal<bool>(this, &other, socket);
534 return is_array_equal<float>(this, &other, socket);
536 return is_array_equal<int>(this, &other, socket);
538 return is_array_equal<float3>(this, &other, socket);
540 return is_array_equal<float3>(this, &other, socket);
542 return is_array_equal<float3>(this, &other, socket);
544 return is_array_equal<float3>(this, &other, socket);
546 return is_array_equal<float2>(this, &other, socket);
548 return is_array_equal<ustring>(this, &other, socket);
550 return is_array_equal<Transform>(this, &other, socket);
552 return is_array_equal<void *>(this, &other, socket);
553
556 return true;
557 }
558
559 return true;
560}
561
562/* equals */
563
564bool Node::equals(const Node &other) const
565{
566 assert(type == other.type);
567
568 foreach (const SocketType &socket, type->inputs) {
569 if (!equals_value(other, socket)) {
570 return false;
571 }
572 }
573
574 return true;
575}
576
577/* Hash */
578
579namespace {
580
581template<typename T> void value_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
582{
583 md5.append(((uint8_t *)node) + socket.struct_offset, socket.size());
584}
585
586void float3_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
587{
588 /* Don't compare 4th element used for padding. */
589 md5.append(((uint8_t *)node) + socket.struct_offset, sizeof(float) * 3);
590}
591
592template<typename T> void array_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
593{
594 const array<T> &a = *(const array<T> *)(((char *)node) + socket.struct_offset);
595 for (size_t i = 0; i < a.size(); i++) {
596 md5.append((uint8_t *)&a[i], sizeof(T));
597 }
598}
599
600void float3_array_hash(const Node *node, const SocketType &socket, MD5Hash &md5)
601{
602 /* Don't compare 4th element used for padding. */
603 const array<float3> &a = *(const array<float3> *)(((char *)node) + socket.struct_offset);
604 for (size_t i = 0; i < a.size(); i++) {
605 md5.append((uint8_t *)&a[i], sizeof(float) * 3);
606 }
607}
608
609} // namespace
610
612{
613 md5.append(type->name.string());
614
615 foreach (const SocketType &socket, type->inputs) {
616 md5.append(socket.name.string());
617
618 switch (socket.type) {
620 value_hash<bool>(this, socket, md5);
621 break;
623 value_hash<float>(this, socket, md5);
624 break;
625 case SocketType::INT:
626 value_hash<int>(this, socket, md5);
627 break;
628 case SocketType::UINT:
629 value_hash<uint>(this, socket, md5);
630 break;
632 value_hash<uint64_t>(this, socket, md5);
633 break;
635 float3_hash(this, socket, md5);
636 break;
638 float3_hash(this, socket, md5);
639 break;
641 float3_hash(this, socket, md5);
642 break;
644 float3_hash(this, socket, md5);
645 break;
647 value_hash<float2>(this, socket, md5);
648 break;
650 break;
652 value_hash<ustring>(this, socket, md5);
653 break;
654 case SocketType::ENUM:
655 value_hash<int>(this, socket, md5);
656 break;
658 value_hash<Transform>(this, socket, md5);
659 break;
660 case SocketType::NODE:
661 value_hash<void *>(this, socket, md5);
662 break;
663
665 array_hash<bool>(this, socket, md5);
666 break;
668 array_hash<float>(this, socket, md5);
669 break;
671 array_hash<int>(this, socket, md5);
672 break;
674 float3_array_hash(this, socket, md5);
675 break;
677 float3_array_hash(this, socket, md5);
678 break;
680 float3_array_hash(this, socket, md5);
681 break;
683 float3_array_hash(this, socket, md5);
684 break;
686 array_hash<float2>(this, socket, md5);
687 break;
689 array_hash<ustring>(this, socket, md5);
690 break;
692 array_hash<Transform>(this, socket, md5);
693 break;
695 array_hash<void *>(this, socket, md5);
696 break;
697
700 break;
701 }
702 }
703}
704
705namespace {
706
707template<typename T> size_t array_size_in_bytes(const Node *node, const SocketType &socket)
708{
709 const array<T> &a = *(const array<T> *)(((char *)node) + socket.struct_offset);
710 return a.size() * sizeof(T);
711}
712
713} // namespace
714
716{
717 size_t total_size = 0;
718 foreach (const SocketType &socket, type->inputs) {
719 switch (socket.type) {
722 case SocketType::INT:
723 case SocketType::UINT:
732 case SocketType::ENUM:
734 case SocketType::NODE:
735 total_size += socket.size();
736 break;
737
739 total_size += array_size_in_bytes<bool>(this, socket);
740 break;
742 total_size += array_size_in_bytes<float>(this, socket);
743 break;
745 total_size += array_size_in_bytes<int>(this, socket);
746 break;
748 total_size += array_size_in_bytes<float3>(this, socket);
749 break;
751 total_size += array_size_in_bytes<float3>(this, socket);
752 break;
754 total_size += array_size_in_bytes<float3>(this, socket);
755 break;
757 total_size += array_size_in_bytes<float3>(this, socket);
758 break;
760 total_size += array_size_in_bytes<float2>(this, socket);
761 break;
763 total_size += array_size_in_bytes<ustring>(this, socket);
764 break;
766 total_size += array_size_in_bytes<Transform>(this, socket);
767 break;
769 total_size += array_size_in_bytes<void *>(this, socket);
770 break;
771
774 break;
775 }
776 }
777 return total_size;
778}
779
780bool Node::is_a(const NodeType *type_)
781{
782 for (const NodeType *base = type; base; base = base->base) {
783 if (base == type_) {
784 return true;
785 }
786 }
787 return false;
788}
789
791{
792 return owner;
793}
794
795void Node::set_owner(const NodeOwner *owner_)
796{
797 assert(owner_);
798 owner = owner_;
799}
800
802{
803 foreach (const SocketType &socket, type->inputs) {
804 if (socket.type == SocketType::NODE) {
805 Node *node = get_socket_value<Node *>(this, socket);
806
807 if (node) {
808 node->dereference();
809 }
810 }
811 else if (socket.type == SocketType::NODE_ARRAY) {
812 const array<Node *> &nodes = get_socket_value<array<Node *>>(this, socket);
813
814 for (Node *node : nodes) {
815 node->dereference();
816 }
817 }
818 }
819}
820
821bool Node::socket_is_modified(const SocketType &input) const
822{
823 return (socket_modified & input.modified_flag_bit) != 0;
824}
825
827{
828 return socket_modified != 0;
829}
830
832{
833 socket_modified = ~0ull;
834}
835
837{
838 socket_modified = 0;
839}
840
841template<typename T> void Node::set_if_different(const SocketType &input, T value)
842{
843 if (get_socket_value<T>(this, input) == value) {
844 return;
845 }
846
847 get_socket_value<T>(this, input) = value;
848 socket_modified |= input.modified_flag_bit;
849}
850
851void Node::set_if_different(const SocketType &input, Node *value)
852{
853 if (get_socket_value<Node *>(this, input) == value) {
854 return;
855 }
856
857 Node *old_node = get_socket_value<Node *>(this, input);
858 if (old_node) {
859 old_node->dereference();
860 }
861
862 if (value) {
863 value->reference();
864 }
865
866 get_socket_value<Node *>(this, input) = value;
867 socket_modified |= input.modified_flag_bit;
868}
869
870template<typename T> void Node::set_if_different(const SocketType &input, array<T> &value)
871{
872 if (!socket_is_modified(input)) {
873 if (get_socket_value<array<T>>(this, input) == value) {
874 return;
875 }
876 }
877
878 get_socket_value<array<T>>(this, input).steal_data(value);
879 socket_modified |= input.modified_flag_bit;
880}
881
883{
884 if (!socket_is_modified(input)) {
885 if (get_socket_value<array<Node *>>(this, input) == value) {
886 return;
887 }
888 }
889
890 array<Node *> &old_nodes = get_socket_value<array<Node *>>(this, input);
891 for (Node *old_node : old_nodes) {
892 old_node->dereference();
893 }
894
895 for (Node *new_node : value) {
896 new_node->reference();
897 }
898
899 get_socket_value<array<Node *>>(this, input).steal_data(value);
900 socket_modified |= input.modified_flag_bit;
901}
902
904{
905 printf("Node : %s\n", name.c_str());
906 for (auto &socket : type->inputs) {
907 if (socket_is_modified(socket)) {
908 printf("-- socket modified : %s\n", socket.name.c_str());
909 }
910 }
911}
912
unsigned int uint
Definition md5.h:21
void append(const uint8_t *data, int size)
Definition md5.cpp:255
size_t size() const
local_group_size(16, 16) .push_constant(Type b
#define printf
OperationNode * node
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
static bool is_socket_array_float3(const SocketType &socket)
static bool is_array_equal(const Node *node, const Node *other, const SocketType &socket)
static bool is_value_equal(const Node *node, const Node *other, const SocketType &socket)
static bool is_socket_float3(const SocketType &socket)
static void copy_array(const Node *node, const SocketType &socket, const Node *other, const SocketType &other_socket)
#define T
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
bool exists(ustring x) const
Definition node_enum.h:29
virtual ~NodeOwner()
const NodeType * base
Definition node_type.h:124
bool has_default_value(const SocketType &input) const
const array< float3 > & get_float3_array(const SocketType &input) const
bool equals(const Node &other) const
const array< float > & get_float_array(const SocketType &input) const
const array< int > & get_int_array(const SocketType &input) const
void dereference()
Definition graph/node.h:193
const NodeOwner * owner
Definition graph/node.h:207
float get_float(const SocketType &input) const
Transform get_transform(const SocketType &input) const
void set(const SocketType &input, bool value)
uint64_t get_uint64(const SocketType &input) const
void set_value(const SocketType &input, const Node &other, const SocketType &other_input)
void dereference_all_used_nodes()
float3 get_float3(const SocketType &input) const
void set_default_value(const SocketType &input)
static T & get_socket_value(const Node *node, const SocketType &socket)
Definition graph/node.h:210
const array< bool > & get_bool_array(const SocketType &input) const
void copy_value(const SocketType &input, const Node &other, const SocketType &other_input)
const array< Node * > & get_node_array(const SocketType &input) const
size_t get_total_size_in_bytes() const
SocketModifiedFlags socket_modified
Definition graph/node.h:215
bool get_bool(const SocketType &input) const
float2 get_float2(const SocketType &input) const
void clear_modified()
const array< ustring > & get_string_array(const SocketType &input) const
const array< float2 > & get_float2_array(const SocketType &input) const
void hash(MD5Hash &md5)
bool socket_is_modified(const SocketType &input) const
ustring get_string(const SocketType &input) const
bool is_a(const NodeType *type)
void set_if_different(const SocketType &input, T value)
Node * get_node(const SocketType &input) const
virtual ~Node()=0
const NodeOwner * get_owner() const
void tag_modified()
bool is_modified() const
uint get_uint(const SocketType &input) const
Node(const NodeType *type, ustring name=ustring())
int get_int(const SocketType &input) const
const array< Transform > & get_transform_array(const SocketType &input) const
bool equals_value(const Node &other, const SocketType &input) const
void print_modified_sockets() const
void set_owner(const NodeOwner *owner_)
size_t size() const
Definition node_type.cpp:13
const void * default_value
Definition node_type.h:82
ustring name
Definition node_type.h:79
@ BOOLEAN_ARRAY
Definition node_type.h:43
@ TRANSFORM_ARRAY
Definition node_type.h:52
Type type
Definition node_type.h:80
bool is_array() const
Definition node_type.cpp:18
int struct_offset
Definition node_type.h:81