1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2007 Blender Foundation.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup nodes
22 */
23
24 #include <limits.h>
25
26 #include "DNA_node_types.h"
27
28 #include "BLI_color.hh"
29 #include "BLI_float3.hh"
30 #include "BLI_listbase.h"
31 #include "BLI_math.h"
32 #include "BLI_string.h"
33 #include "BLI_utildefines.h"
34
35 #include "BKE_lib_id.h"
36 #include "BKE_node.h"
37 #include "BKE_persistent_data_handle.hh"
38
39 #include "RNA_access.h"
40 #include "RNA_types.h"
41
42 #include "MEM_guardedalloc.h"
43
44 #include "NOD_node_tree_multi_function.hh"
45 #include "NOD_socket.h"
46
node_add_socket_from_template(struct bNodeTree * ntree,struct bNode * node,struct bNodeSocketTemplate * stemp,int in_out)47 struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree,
48 struct bNode *node,
49 struct bNodeSocketTemplate *stemp,
50 int in_out)
51 {
52 bNodeSocket *sock = nodeAddStaticSocket(
53 ntree, node, in_out, stemp->type, stemp->subtype, stemp->identifier, stemp->name);
54
55 sock->flag |= stemp->flag;
56
57 /* initialize default_value */
58 switch (stemp->type) {
59 case SOCK_FLOAT: {
60 bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)sock->default_value;
61 dval->value = stemp->val1;
62 dval->min = stemp->min;
63 dval->max = stemp->max;
64 break;
65 }
66 case SOCK_INT: {
67 bNodeSocketValueInt *dval = (bNodeSocketValueInt *)sock->default_value;
68 dval->value = (int)stemp->val1;
69 dval->min = (int)stemp->min;
70 dval->max = (int)stemp->max;
71 break;
72 }
73 case SOCK_BOOLEAN: {
74 bNodeSocketValueBoolean *dval = (bNodeSocketValueBoolean *)sock->default_value;
75 dval->value = (int)stemp->val1;
76 break;
77 }
78 case SOCK_VECTOR: {
79 bNodeSocketValueVector *dval = (bNodeSocketValueVector *)sock->default_value;
80 dval->value[0] = stemp->val1;
81 dval->value[1] = stemp->val2;
82 dval->value[2] = stemp->val3;
83 dval->min = stemp->min;
84 dval->max = stemp->max;
85 break;
86 }
87 case SOCK_RGBA: {
88 bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)sock->default_value;
89 dval->value[0] = stemp->val1;
90 dval->value[1] = stemp->val2;
91 dval->value[2] = stemp->val3;
92 dval->value[3] = stemp->val4;
93 break;
94 }
95 }
96
97 return sock;
98 }
99
verify_socket_template(bNodeTree * ntree,bNode * node,int in_out,ListBase * socklist,bNodeSocketTemplate * stemp)100 static bNodeSocket *verify_socket_template(
101 bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp)
102 {
103 bNodeSocket *sock;
104
105 for (sock = (bNodeSocket *)socklist->first; sock; sock = sock->next) {
106 if (STREQLEN(sock->name, stemp->name, NODE_MAXSTR)) {
107 break;
108 }
109 }
110 if (sock) {
111 if (sock->type != stemp->type) {
112 nodeModifySocketType(ntree, node, sock, stemp->type, stemp->subtype);
113 }
114 sock->flag |= stemp->flag;
115 }
116 else {
117 /* no socket for this template found, make a new one */
118 sock = node_add_socket_from_template(ntree, node, stemp, in_out);
119 }
120
121 /* remove the new socket from the node socket list first,
122 * will be added back after verification. */
123 BLI_remlink(socklist, sock);
124
125 return sock;
126 }
127
verify_socket_template_list(bNodeTree * ntree,bNode * node,int in_out,ListBase * socklist,bNodeSocketTemplate * stemp_first)128 static void verify_socket_template_list(bNodeTree *ntree,
129 bNode *node,
130 int in_out,
131 ListBase *socklist,
132 bNodeSocketTemplate *stemp_first)
133 {
134 bNodeSocket *sock, *nextsock;
135 bNodeSocketTemplate *stemp;
136
137 /* no inputs anymore? */
138 if (stemp_first == NULL) {
139 for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) {
140 nextsock = sock->next;
141 nodeRemoveSocket(ntree, node, sock);
142 }
143 }
144 else {
145 /* step by step compare */
146 stemp = stemp_first;
147 while (stemp->type != -1) {
148 stemp->sock = verify_socket_template(ntree, node, in_out, socklist, stemp);
149 stemp++;
150 }
151 /* leftovers are removed */
152 for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) {
153 nextsock = sock->next;
154 nodeRemoveSocket(ntree, node, sock);
155 }
156
157 /* and we put back the verified sockets */
158 stemp = stemp_first;
159 if (socklist->first) {
160 /* Some dynamic sockets left, store the list start
161 * so we can add static sockets in front of it. */
162 sock = (bNodeSocket *)socklist->first;
163 while (stemp->type != -1) {
164 /* Put static sockets in front of dynamic. */
165 BLI_insertlinkbefore(socklist, sock, stemp->sock);
166 stemp++;
167 }
168 }
169 else {
170 while (stemp->type != -1) {
171 BLI_addtail(socklist, stemp->sock);
172 stemp++;
173 }
174 }
175 }
176 }
177
node_verify_socket_templates(bNodeTree * ntree,bNode * node)178 void node_verify_socket_templates(bNodeTree *ntree, bNode *node)
179 {
180 bNodeType *ntype = node->typeinfo;
181 /* Don't try to match socket lists when there are no templates.
182 * This prevents dynamically generated sockets to be removed, like for
183 * group, image or render layer nodes. We have an explicit check for the
184 * render layer node since it still has fixed sockets too.
185 */
186 if (ntype) {
187 if (ntype->inputs && ntype->inputs[0].type >= 0) {
188 verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs);
189 }
190 if (ntype->outputs && ntype->outputs[0].type >= 0 && node->type != CMP_NODE_R_LAYERS) {
191 verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs);
192 }
193 }
194 }
195
node_socket_init_default_value(bNodeSocket * sock)196 void node_socket_init_default_value(bNodeSocket *sock)
197 {
198 int type = sock->typeinfo->type;
199 int subtype = sock->typeinfo->subtype;
200
201 if (sock->default_value) {
202 return; /* already initialized */
203 }
204
205 switch (type) {
206 case SOCK_FLOAT: {
207 bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)MEM_callocN(
208 sizeof(bNodeSocketValueFloat), "node socket value float");
209 dval->subtype = subtype;
210 dval->value = 0.0f;
211 dval->min = -FLT_MAX;
212 dval->max = FLT_MAX;
213
214 sock->default_value = dval;
215 break;
216 }
217 case SOCK_INT: {
218 bNodeSocketValueInt *dval = (bNodeSocketValueInt *)MEM_callocN(sizeof(bNodeSocketValueInt),
219 "node socket value int");
220 dval->subtype = subtype;
221 dval->value = 0;
222 dval->min = INT_MIN;
223 dval->max = INT_MAX;
224
225 sock->default_value = dval;
226 break;
227 }
228 case SOCK_BOOLEAN: {
229 bNodeSocketValueBoolean *dval = (bNodeSocketValueBoolean *)MEM_callocN(
230 sizeof(bNodeSocketValueBoolean), "node socket value bool");
231 dval->value = false;
232
233 sock->default_value = dval;
234 break;
235 }
236 case SOCK_VECTOR: {
237 static float default_value[] = {0.0f, 0.0f, 0.0f};
238 bNodeSocketValueVector *dval = (bNodeSocketValueVector *)MEM_callocN(
239 sizeof(bNodeSocketValueVector), "node socket value vector");
240 dval->subtype = subtype;
241 copy_v3_v3(dval->value, default_value);
242 dval->min = -FLT_MAX;
243 dval->max = FLT_MAX;
244
245 sock->default_value = dval;
246 break;
247 }
248 case SOCK_RGBA: {
249 static float default_value[] = {0.0f, 0.0f, 0.0f, 1.0f};
250 bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)MEM_callocN(
251 sizeof(bNodeSocketValueRGBA), "node socket value color");
252 copy_v4_v4(dval->value, default_value);
253
254 sock->default_value = dval;
255 break;
256 }
257 case SOCK_STRING: {
258 bNodeSocketValueString *dval = (bNodeSocketValueString *)MEM_callocN(
259 sizeof(bNodeSocketValueString), "node socket value string");
260 dval->subtype = subtype;
261 dval->value[0] = '\0';
262
263 sock->default_value = dval;
264 break;
265 }
266 case SOCK_OBJECT: {
267 bNodeSocketValueObject *dval = (bNodeSocketValueObject *)MEM_callocN(
268 sizeof(bNodeSocketValueObject), "node socket value object");
269 dval->value = NULL;
270
271 sock->default_value = dval;
272 break;
273 }
274 case SOCK_IMAGE: {
275 bNodeSocketValueImage *dval = (bNodeSocketValueImage *)MEM_callocN(
276 sizeof(bNodeSocketValueImage), "node socket value image");
277 dval->value = NULL;
278
279 sock->default_value = dval;
280 break;
281 }
282 }
283 }
284
node_socket_copy_default_value(bNodeSocket * to,const bNodeSocket * from)285 void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
286 {
287 /* sanity check */
288 if (to->type != from->type) {
289 return;
290 }
291
292 /* make sure both exist */
293 if (!from->default_value) {
294 return;
295 }
296 node_socket_init_default_value(to);
297
298 /* use label instead of name if it has been set */
299 if (from->label[0] != '\0') {
300 BLI_strncpy(to->name, from->label, NODE_MAXSTR);
301 }
302
303 switch (from->typeinfo->type) {
304 case SOCK_FLOAT: {
305 bNodeSocketValueFloat *toval = (bNodeSocketValueFloat *)to->default_value;
306 bNodeSocketValueFloat *fromval = (bNodeSocketValueFloat *)from->default_value;
307 *toval = *fromval;
308 break;
309 }
310 case SOCK_INT: {
311 bNodeSocketValueInt *toval = (bNodeSocketValueInt *)to->default_value;
312 bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)from->default_value;
313 *toval = *fromval;
314 break;
315 }
316 case SOCK_BOOLEAN: {
317 bNodeSocketValueBoolean *toval = (bNodeSocketValueBoolean *)to->default_value;
318 bNodeSocketValueBoolean *fromval = (bNodeSocketValueBoolean *)from->default_value;
319 *toval = *fromval;
320 break;
321 }
322 case SOCK_VECTOR: {
323 bNodeSocketValueVector *toval = (bNodeSocketValueVector *)to->default_value;
324 bNodeSocketValueVector *fromval = (bNodeSocketValueVector *)from->default_value;
325 *toval = *fromval;
326 break;
327 }
328 case SOCK_RGBA: {
329 bNodeSocketValueRGBA *toval = (bNodeSocketValueRGBA *)to->default_value;
330 bNodeSocketValueRGBA *fromval = (bNodeSocketValueRGBA *)from->default_value;
331 *toval = *fromval;
332 break;
333 }
334 case SOCK_STRING: {
335 bNodeSocketValueString *toval = (bNodeSocketValueString *)to->default_value;
336 bNodeSocketValueString *fromval = (bNodeSocketValueString *)from->default_value;
337 *toval = *fromval;
338 break;
339 }
340 case SOCK_OBJECT: {
341 bNodeSocketValueObject *toval = (bNodeSocketValueObject *)to->default_value;
342 bNodeSocketValueObject *fromval = (bNodeSocketValueObject *)from->default_value;
343 *toval = *fromval;
344 id_us_plus(&toval->value->id);
345 break;
346 }
347 case SOCK_IMAGE: {
348 bNodeSocketValueImage *toval = (bNodeSocketValueImage *)to->default_value;
349 bNodeSocketValueImage *fromval = (bNodeSocketValueImage *)from->default_value;
350 *toval = *fromval;
351 id_us_plus(&toval->value->id);
352 break;
353 }
354 }
355
356 to->flag |= (from->flag & SOCK_HIDE_VALUE);
357 }
358
node_socket_skip_reroutes(ListBase * links,bNode * node,bNodeSocket * socket,bNode ** r_node,bNodeSocket ** r_socket)359 void node_socket_skip_reroutes(
360 ListBase *links, bNode *node, bNodeSocket *socket, bNode **r_node, bNodeSocket **r_socket)
361 {
362 const int loop_limit = 100; /* Limit in case there is a connection cycle. */
363
364 if (socket->in_out == SOCK_IN) {
365 bNodeLink *first_link = (bNodeLink *)links->first;
366
367 for (int i = 0; node->type == NODE_REROUTE && i < loop_limit; i++) {
368 bNodeLink *link = first_link;
369
370 for (; link; link = link->next) {
371 if (link->fromnode == node && link->tonode != node) {
372 break;
373 }
374 }
375
376 if (link) {
377 node = link->tonode;
378 socket = link->tosock;
379 }
380 else {
381 break;
382 }
383 }
384 }
385 else {
386 for (int i = 0; node->type == NODE_REROUTE && i < loop_limit; i++) {
387 bNodeSocket *input = (bNodeSocket *)node->inputs.first;
388
389 if (input && input->link) {
390 node = input->link->fromnode;
391 socket = input->link->fromsock;
392 }
393 else {
394 break;
395 }
396 }
397 }
398
399 if (r_node) {
400 *r_node = node;
401 }
402 if (r_socket) {
403 *r_socket = socket;
404 }
405 }
406
standard_node_socket_interface_init_socket(bNodeTree * UNUSED (ntree),bNodeSocket * stemp,bNode * UNUSED (node),bNodeSocket * sock,const char * UNUSED (data_path))407 static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree),
408 bNodeSocket *stemp,
409 bNode *UNUSED(node),
410 bNodeSocket *sock,
411 const char *UNUSED(data_path))
412 {
413 /* initialize the type value */
414 sock->type = sock->typeinfo->type;
415
416 /* XXX socket interface 'type' value is not used really,
417 * but has to match or the copy function will bail out
418 */
419 stemp->type = stemp->typeinfo->type;
420 /* copy default_value settings */
421 node_socket_copy_default_value(sock, stemp);
422 }
423
424 /* copies settings that are not changed for each socket instance */
standard_node_socket_interface_verify_socket(bNodeTree * UNUSED (ntree),bNodeSocket * stemp,bNode * UNUSED (node),bNodeSocket * sock,const char * UNUSED (data_path))425 static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree),
426 bNodeSocket *stemp,
427 bNode *UNUSED(node),
428 bNodeSocket *sock,
429 const char *UNUSED(data_path))
430 {
431 /* sanity check */
432 if (sock->type != stemp->typeinfo->type) {
433 return;
434 }
435
436 /* make sure both exist */
437 if (!stemp->default_value) {
438 return;
439 }
440 node_socket_init_default_value(sock);
441
442 switch (stemp->typeinfo->type) {
443 case SOCK_FLOAT: {
444 bNodeSocketValueFloat *toval = (bNodeSocketValueFloat *)sock->default_value;
445 bNodeSocketValueFloat *fromval = (bNodeSocketValueFloat *)stemp->default_value;
446 toval->min = fromval->min;
447 toval->max = fromval->max;
448 break;
449 }
450 case SOCK_INT: {
451 bNodeSocketValueInt *toval = (bNodeSocketValueInt *)sock->default_value;
452 bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)stemp->default_value;
453 toval->min = fromval->min;
454 toval->max = fromval->max;
455 break;
456 }
457 case SOCK_VECTOR: {
458 bNodeSocketValueVector *toval = (bNodeSocketValueVector *)sock->default_value;
459 bNodeSocketValueVector *fromval = (bNodeSocketValueVector *)stemp->default_value;
460 toval->min = fromval->min;
461 toval->max = fromval->max;
462 break;
463 }
464 }
465 }
466
standard_node_socket_interface_from_socket(bNodeTree * UNUSED (ntree),bNodeSocket * stemp,bNode * UNUSED (node),bNodeSocket * sock)467 static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree),
468 bNodeSocket *stemp,
469 bNode *UNUSED(node),
470 bNodeSocket *sock)
471 {
472 /* initialize settings */
473 stemp->type = stemp->typeinfo->type;
474 node_socket_copy_default_value(stemp, sock);
475 }
476
477 extern "C" void ED_init_standard_node_socket_type(bNodeSocketType *);
478
make_standard_socket_type(int type,int subtype)479 static bNodeSocketType *make_standard_socket_type(int type, int subtype)
480 {
481 const char *socket_idname = nodeStaticSocketType(type, subtype);
482 const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype);
483 bNodeSocketType *stype;
484 StructRNA *srna;
485
486 stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type");
487 stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN;
488 BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname));
489
490 /* set the RNA type
491 * uses the exact same identifier as the socket type idname */
492 srna = stype->ext_socket.srna = RNA_struct_find(socket_idname);
493 BLI_assert(srna != NULL);
494 /* associate the RNA type with the socket type */
495 RNA_struct_blender_type_set(srna, stype);
496
497 /* set the interface RNA type */
498 srna = stype->ext_interface.srna = RNA_struct_find(interface_idname);
499 BLI_assert(srna != NULL);
500 /* associate the RNA type with the socket type */
501 RNA_struct_blender_type_set(srna, stype);
502
503 /* extra type info for standard socket types */
504 stype->type = type;
505 stype->subtype = subtype;
506
507 /* XXX bad-level call! needed for setting draw callbacks */
508 ED_init_standard_node_socket_type(stype);
509
510 stype->interface_init_socket = standard_node_socket_interface_init_socket;
511 stype->interface_from_socket = standard_node_socket_interface_from_socket;
512 stype->interface_verify_socket = standard_node_socket_interface_verify_socket;
513
514 stype->use_link_limits_of_type = true;
515 stype->input_link_limit = 1;
516 stype->output_link_limit = 0xFFF;
517
518 return stype;
519 }
520
521 extern "C" void ED_init_node_socket_type_virtual(bNodeSocketType *);
522
make_socket_type_virtual(void)523 static bNodeSocketType *make_socket_type_virtual(void)
524 {
525 const char *socket_idname = "NodeSocketVirtual";
526 bNodeSocketType *stype;
527 StructRNA *srna;
528
529 stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type");
530 stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN;
531 BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname));
532
533 /* set the RNA type
534 * uses the exact same identifier as the socket type idname */
535 srna = stype->ext_socket.srna = RNA_struct_find(socket_idname);
536 BLI_assert(srna != NULL);
537 /* associate the RNA type with the socket type */
538 RNA_struct_blender_type_set(srna, stype);
539
540 /* extra type info for standard socket types */
541 stype->type = SOCK_CUSTOM;
542
543 ED_init_node_socket_type_virtual(stype);
544
545 stype->use_link_limits_of_type = true;
546 stype->input_link_limit = 0xFFF;
547 stype->output_link_limit = 0xFFF;
548
549 return stype;
550 }
551
make_socket_type_bool()552 static bNodeSocketType *make_socket_type_bool()
553 {
554 bNodeSocketType *socktype = make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE);
555 socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<bool>(); };
556 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
557 bool value = builder.socket_default_value<bNodeSocketValueBoolean>()->value;
558 builder.set_constant_value(value);
559 };
560 return socktype;
561 }
562
make_socket_type_float(PropertySubType subtype)563 static bNodeSocketType *make_socket_type_float(PropertySubType subtype)
564 {
565 bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype);
566 socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<float>(); };
567 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
568 float value = builder.socket_default_value<bNodeSocketValueFloat>()->value;
569 builder.set_constant_value(value);
570 };
571 return socktype;
572 }
573
make_socket_type_int(PropertySubType subtype)574 static bNodeSocketType *make_socket_type_int(PropertySubType subtype)
575 {
576 bNodeSocketType *socktype = make_standard_socket_type(SOCK_INT, subtype);
577 socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<int>(); };
578 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
579 int value = builder.socket_default_value<bNodeSocketValueInt>()->value;
580 builder.set_constant_value(value);
581 };
582 return socktype;
583 }
584
make_socket_type_vector(PropertySubType subtype)585 static bNodeSocketType *make_socket_type_vector(PropertySubType subtype)
586 {
587 bNodeSocketType *socktype = make_standard_socket_type(SOCK_VECTOR, subtype);
588 socktype->get_mf_data_type = []() {
589 return blender::fn::MFDataType::ForSingle<blender::float3>();
590 };
591 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
592 blender::float3 value = builder.socket_default_value<bNodeSocketValueVector>()->value;
593 builder.set_constant_value(value);
594 };
595 return socktype;
596 }
597
make_socket_type_rgba()598 static bNodeSocketType *make_socket_type_rgba()
599 {
600 bNodeSocketType *socktype = make_standard_socket_type(SOCK_RGBA, PROP_NONE);
601 socktype->get_mf_data_type = []() {
602 return blender::fn::MFDataType::ForSingle<blender::Color4f>();
603 };
604 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
605 blender::Color4f value = builder.socket_default_value<bNodeSocketValueRGBA>()->value;
606 builder.set_constant_value(value);
607 };
608 return socktype;
609 }
610
make_socket_type_string()611 static bNodeSocketType *make_socket_type_string()
612 {
613 bNodeSocketType *socktype = make_standard_socket_type(SOCK_STRING, PROP_NONE);
614 socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<std::string>(); };
615 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
616 std::string value = builder.socket_default_value<bNodeSocketValueString>()->value;
617 builder.set_constant_value(value);
618 };
619 return socktype;
620 }
621
622 class ObjectSocketMultiFunction : public blender::fn::MultiFunction {
623 private:
624 Object *object_;
625
626 public:
ObjectSocketMultiFunction(Object * object)627 ObjectSocketMultiFunction(Object *object) : object_(object)
628 {
629 blender::fn::MFSignatureBuilder signature = this->get_builder("Object Socket");
630 signature.depends_on_context();
631 signature.single_output<blender::bke::PersistentObjectHandle>("Object");
632 }
633
call(blender::IndexMask mask,blender::fn::MFParams params,blender::fn::MFContext context) const634 void call(blender::IndexMask mask,
635 blender::fn::MFParams params,
636 blender::fn::MFContext context) const override
637 {
638 blender::MutableSpan output =
639 params.uninitialized_single_output<blender::bke::PersistentObjectHandle>(0, "Object");
640
641 /* Try to get a handle map, so that the object can be converted to a handle. */
642 const blender::bke::PersistentDataHandleMap *handle_map =
643 context.get_global_context<blender::bke::PersistentDataHandleMap>(
644 "PersistentDataHandleMap");
645
646 if (handle_map == nullptr) {
647 /* Return empty handles when there is no handle map. */
648 output.fill_indices(mask, blender::bke::PersistentObjectHandle());
649 return;
650 }
651
652 blender::bke::PersistentObjectHandle handle = handle_map->lookup(object_);
653 for (int64_t i : mask) {
654 output[i] = handle;
655 }
656 }
657 };
658
659 MAKE_CPP_TYPE(PersistentObjectHandle, blender::bke::PersistentObjectHandle);
660
make_socket_type_object()661 static bNodeSocketType *make_socket_type_object()
662 {
663 bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);
664 socktype->get_mf_data_type = []() {
665 /* Objects are not passed along as raw pointers, but as handles. */
666 return blender::fn::MFDataType::ForSingle<blender::bke::PersistentObjectHandle>();
667 };
668 socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
669 Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value;
670 builder.construct_generator_fn<ObjectSocketMultiFunction>(object);
671 };
672 return socktype;
673 }
674
register_standard_node_socket_types(void)675 void register_standard_node_socket_types(void)
676 {
677 /* draw callbacks are set in drawnode.c to avoid bad-level calls */
678
679 nodeRegisterSocketType(make_socket_type_float(PROP_NONE));
680 nodeRegisterSocketType(make_socket_type_float(PROP_UNSIGNED));
681 nodeRegisterSocketType(make_socket_type_float(PROP_PERCENTAGE));
682 nodeRegisterSocketType(make_socket_type_float(PROP_FACTOR));
683 nodeRegisterSocketType(make_socket_type_float(PROP_ANGLE));
684 nodeRegisterSocketType(make_socket_type_float(PROP_TIME));
685
686 nodeRegisterSocketType(make_socket_type_int(PROP_NONE));
687 nodeRegisterSocketType(make_socket_type_int(PROP_UNSIGNED));
688 nodeRegisterSocketType(make_socket_type_int(PROP_PERCENTAGE));
689 nodeRegisterSocketType(make_socket_type_int(PROP_FACTOR));
690
691 nodeRegisterSocketType(make_socket_type_bool());
692
693 nodeRegisterSocketType(make_socket_type_vector(PROP_NONE));
694 nodeRegisterSocketType(make_socket_type_vector(PROP_TRANSLATION));
695 nodeRegisterSocketType(make_socket_type_vector(PROP_DIRECTION));
696 nodeRegisterSocketType(make_socket_type_vector(PROP_VELOCITY));
697 nodeRegisterSocketType(make_socket_type_vector(PROP_ACCELERATION));
698 nodeRegisterSocketType(make_socket_type_vector(PROP_EULER));
699 nodeRegisterSocketType(make_socket_type_vector(PROP_XYZ));
700
701 nodeRegisterSocketType(make_socket_type_rgba());
702
703 nodeRegisterSocketType(make_socket_type_string());
704
705 nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE));
706
707 nodeRegisterSocketType(make_socket_type_object());
708
709 nodeRegisterSocketType(make_standard_socket_type(SOCK_IMAGE, PROP_NONE));
710
711 nodeRegisterSocketType(make_socket_type_virtual());
712 }
713