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 <ctype.h>
25 #include <limits.h>
26 #include <string.h>
27
28 #include "DNA_node_types.h"
29
30 #include "BLI_listbase.h"
31 #include "BLI_string.h"
32 #include "BLI_utildefines.h"
33
34 #include "BLT_translation.h"
35
36 #include "BKE_colortools.h"
37 #include "BKE_node.h"
38
39 #include "RNA_access.h"
40 #include "RNA_enum_types.h"
41
42 #include "MEM_guardedalloc.h"
43
44 #include "node_util.h"
45
46 /**** Storage Data ****/
47
node_free_curves(bNode * node)48 void node_free_curves(bNode *node)
49 {
50 BKE_curvemapping_free(node->storage);
51 }
52
node_free_standard_storage(bNode * node)53 void node_free_standard_storage(bNode *node)
54 {
55 if (node->storage) {
56 MEM_freeN(node->storage);
57 }
58 }
59
node_copy_curves(bNodeTree * UNUSED (dest_ntree),bNode * dest_node,const bNode * src_node)60 void node_copy_curves(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
61 {
62 dest_node->storage = BKE_curvemapping_copy(src_node->storage);
63 }
64
node_copy_standard_storage(bNodeTree * UNUSED (dest_ntree),bNode * dest_node,const bNode * src_node)65 void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree),
66 bNode *dest_node,
67 const bNode *src_node)
68 {
69 dest_node->storage = MEM_dupallocN(src_node->storage);
70 }
71
node_initexec_curves(bNodeExecContext * UNUSED (context),bNode * node,bNodeInstanceKey UNUSED (key))72 void *node_initexec_curves(bNodeExecContext *UNUSED(context),
73 bNode *node,
74 bNodeInstanceKey UNUSED(key))
75 {
76 BKE_curvemapping_init(node->storage);
77 return NULL; /* unused return */
78 }
79
80 /**** Updates ****/
81
node_sock_label(bNodeSocket * sock,const char * name)82 void node_sock_label(bNodeSocket *sock, const char *name)
83 {
84 BLI_strncpy(sock->label, name, MAX_NAME);
85 }
86
node_math_update(bNodeTree * UNUSED (ntree),bNode * node)87 void node_math_update(bNodeTree *UNUSED(ntree), bNode *node)
88 {
89 bNodeSocket *sock1 = BLI_findlink(&node->inputs, 0);
90 bNodeSocket *sock2 = BLI_findlink(&node->inputs, 1);
91 bNodeSocket *sock3 = BLI_findlink(&node->inputs, 2);
92 nodeSetSocketAvailability(sock2,
93 !ELEM(node->custom1,
94 NODE_MATH_SQRT,
95 NODE_MATH_SIGN,
96 NODE_MATH_CEIL,
97 NODE_MATH_SINE,
98 NODE_MATH_ROUND,
99 NODE_MATH_FLOOR,
100 NODE_MATH_COSINE,
101 NODE_MATH_ARCSINE,
102 NODE_MATH_TANGENT,
103 NODE_MATH_ABSOLUTE,
104 NODE_MATH_RADIANS,
105 NODE_MATH_DEGREES,
106 NODE_MATH_FRACTION,
107 NODE_MATH_ARCCOSINE,
108 NODE_MATH_ARCTANGENT) &&
109 !ELEM(node->custom1,
110 NODE_MATH_INV_SQRT,
111 NODE_MATH_TRUNC,
112 NODE_MATH_EXPONENT,
113 NODE_MATH_COSH,
114 NODE_MATH_SINH,
115 NODE_MATH_TANH));
116 nodeSetSocketAvailability(sock3,
117 ELEM(node->custom1,
118 NODE_MATH_COMPARE,
119 NODE_MATH_MULTIPLY_ADD,
120 NODE_MATH_WRAP,
121 NODE_MATH_SMOOTH_MIN,
122 NODE_MATH_SMOOTH_MAX));
123
124 if (sock1->label[0] != '\0') {
125 sock1->label[0] = '\0';
126 }
127 if (sock2->label[0] != '\0') {
128 sock2->label[0] = '\0';
129 }
130 if (sock3->label[0] != '\0') {
131 sock3->label[0] = '\0';
132 }
133
134 switch (node->custom1) {
135 case NODE_MATH_WRAP:
136 node_sock_label(sock2, "Min");
137 node_sock_label(sock3, "Max");
138 break;
139 case NODE_MATH_MULTIPLY_ADD:
140 node_sock_label(sock2, "Multiplier");
141 node_sock_label(sock3, "Addend");
142 break;
143 case NODE_MATH_LESS_THAN:
144 case NODE_MATH_GREATER_THAN:
145 node_sock_label(sock2, "Threshold");
146 break;
147 case NODE_MATH_PINGPONG:
148 node_sock_label(sock2, "Scale");
149 break;
150 case NODE_MATH_SNAP:
151 node_sock_label(sock2, "Increment");
152 break;
153 case NODE_MATH_POWER:
154 node_sock_label(sock1, "Base");
155 node_sock_label(sock2, "Exponent");
156 break;
157 case NODE_MATH_LOGARITHM:
158 node_sock_label(sock2, "Base");
159 break;
160 case NODE_MATH_DEGREES:
161 node_sock_label(sock1, "Radians");
162 break;
163 case NODE_MATH_RADIANS:
164 node_sock_label(sock1, "Degrees");
165 break;
166 case NODE_MATH_COMPARE:
167 node_sock_label(sock3, "Epsilon");
168 break;
169 case NODE_MATH_SMOOTH_MAX:
170 case NODE_MATH_SMOOTH_MIN:
171 node_sock_label(sock3, "Distance");
172 break;
173 }
174 }
175
176 /**** Labels ****/
177
node_blend_label(bNodeTree * UNUSED (ntree),bNode * node,char * label,int maxlen)178 void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
179 {
180 const char *name;
181 bool enum_label = RNA_enum_name(rna_enum_ramp_blend_items, node->custom1, &name);
182 if (!enum_label) {
183 name = "Unknown";
184 }
185 BLI_strncpy(label, IFACE_(name), maxlen);
186 }
187
node_image_label(bNodeTree * UNUSED (ntree),bNode * node,char * label,int maxlen)188 void node_image_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
189 {
190 /* If there is no loaded image, return an empty string,
191 * and let nodeLabel() fill in the proper type translation. */
192 BLI_strncpy(label, (node->id) ? node->id->name + 2 : "", maxlen);
193 }
194
node_math_label(bNodeTree * UNUSED (ntree),bNode * node,char * label,int maxlen)195 void node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
196 {
197 const char *name;
198 bool enum_label = RNA_enum_name(rna_enum_node_math_items, node->custom1, &name);
199 if (!enum_label) {
200 name = "Unknown";
201 }
202 BLI_strncpy(label, IFACE_(name), maxlen);
203 }
204
node_vector_math_label(bNodeTree * UNUSED (ntree),bNode * node,char * label,int maxlen)205 void node_vector_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
206 {
207 const char *name;
208 bool enum_label = RNA_enum_name(rna_enum_node_vec_math_items, node->custom1, &name);
209 if (!enum_label) {
210 name = "Unknown";
211 }
212 BLI_strncpy(label, IFACE_(name), maxlen);
213 }
214
node_filter_label(bNodeTree * UNUSED (ntree),bNode * node,char * label,int maxlen)215 void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
216 {
217 const char *name;
218 bool enum_label = RNA_enum_name(rna_enum_node_filter_items, node->custom1, &name);
219 if (!enum_label) {
220 name = "Unknown";
221 }
222 BLI_strncpy(label, IFACE_(name), maxlen);
223 }
224
225 /*** Link Insertion ***/
226
227 /* test if two sockets are interchangeable */
node_link_socket_match(bNodeSocket * a,bNodeSocket * b)228 static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b)
229 {
230 /* check if sockets are of the same type */
231 if (a->typeinfo != b->typeinfo) {
232 return false;
233 }
234
235 /* tests if alphabetic prefix matches
236 * this allows for imperfect matches, such as numeric suffixes,
237 * like Color1/Color2
238 */
239 int prefix_len = 0;
240 char *ca = a->name, *cb = b->name;
241 for (; *ca != '\0' && *cb != '\0'; ca++, cb++) {
242 /* end of common prefix? */
243 if (*ca != *cb) {
244 /* prefix delimited by non-alphabetic char */
245 if (isalpha(*ca) || isalpha(*cb)) {
246 return false;
247 }
248 break;
249 }
250 prefix_len++;
251 }
252 return prefix_len > 0;
253 }
254
node_count_links(bNodeTree * ntree,bNodeSocket * sock)255 static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
256 {
257 bNodeLink *link;
258 int count = 0;
259 for (link = ntree->links.first; link; link = link->next) {
260 if (link->fromsock == sock) {
261 count++;
262 }
263 if (link->tosock == sock) {
264 count++;
265 }
266 }
267 return count;
268 }
269
270 /* find an eligible socket for linking */
node_find_linkable_socket(bNodeTree * ntree,bNode * node,bNodeSocket * cur)271 static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *cur)
272 {
273 /* link swapping: try to find a free slot with a matching name */
274
275 bNodeSocket *first = cur->in_out == SOCK_IN ? node->inputs.first : node->outputs.first;
276 bNodeSocket *sock;
277
278 sock = cur->next ? cur->next : first; /* wrap around the list end */
279 while (sock != cur) {
280 if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) {
281 int link_count = node_count_links(ntree, sock);
282 /* take +1 into account since we would add a new link */
283 if (link_count + 1 <= nodeSocketLinkLimit(sock)) {
284 return sock; /* found a valid free socket we can swap to */
285 }
286 }
287
288 sock = sock->next ? sock->next : first; /* wrap around the list end */
289 }
290 return NULL;
291 }
292
node_insert_link_default(bNodeTree * ntree,bNode * node,bNodeLink * link)293 void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link)
294 {
295 bNodeSocket *sock = link->tosock;
296 bNodeLink *tlink, *tlink_next;
297
298 /* inputs can have one link only, outputs can have unlimited links */
299 if (node != link->tonode) {
300 return;
301 }
302
303 for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
304 bNodeSocket *new_sock;
305 tlink_next = tlink->next;
306
307 if (sock != tlink->tosock) {
308 continue;
309 }
310
311 new_sock = node_find_linkable_socket(ntree, node, sock);
312 if (new_sock && new_sock != sock) {
313 /* redirect existing link */
314 tlink->tosock = new_sock;
315 }
316 else if (!new_sock) {
317 /* no possible replacement, remove tlink */
318 nodeRemLink(ntree, tlink);
319 tlink = NULL;
320 }
321 }
322 }
323
324 /**** Internal Links (mute and disconnect) ****/
325
326 /* common datatype priorities, works for compositor, shader and texture nodes alike
327 * defines priority of datatype connection based on output type (to):
328 * < 0 : never connect these types
329 * >= 0 : priority of connection (higher values chosen first)
330 */
node_datatype_priority(eNodeSocketDatatype from,eNodeSocketDatatype to)331 static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype to)
332 {
333 switch (to) {
334 case SOCK_RGBA:
335 switch (from) {
336 case SOCK_RGBA:
337 return 4;
338 case SOCK_FLOAT:
339 return 3;
340 case SOCK_INT:
341 return 2;
342 case SOCK_BOOLEAN:
343 return 1;
344 default:
345 return -1;
346 }
347 case SOCK_VECTOR:
348 switch (from) {
349 case SOCK_VECTOR:
350 return 4;
351 case SOCK_FLOAT:
352 return 3;
353 case SOCK_INT:
354 return 2;
355 case SOCK_BOOLEAN:
356 return 1;
357 default:
358 return -1;
359 }
360 case SOCK_FLOAT:
361 switch (from) {
362 case SOCK_FLOAT:
363 return 5;
364 case SOCK_INT:
365 return 4;
366 case SOCK_BOOLEAN:
367 return 3;
368 case SOCK_RGBA:
369 return 2;
370 case SOCK_VECTOR:
371 return 1;
372 default:
373 return -1;
374 }
375 case SOCK_INT:
376 switch (from) {
377 case SOCK_INT:
378 return 5;
379 case SOCK_FLOAT:
380 return 4;
381 case SOCK_BOOLEAN:
382 return 3;
383 case SOCK_RGBA:
384 return 2;
385 case SOCK_VECTOR:
386 return 1;
387 default:
388 return -1;
389 }
390 case SOCK_BOOLEAN:
391 switch (from) {
392 case SOCK_BOOLEAN:
393 return 5;
394 case SOCK_INT:
395 return 4;
396 case SOCK_FLOAT:
397 return 3;
398 case SOCK_RGBA:
399 return 2;
400 case SOCK_VECTOR:
401 return 1;
402 default:
403 return -1;
404 }
405 case SOCK_SHADER:
406 switch (from) {
407 case SOCK_SHADER:
408 return 1;
409 default:
410 return -1;
411 }
412 case SOCK_STRING:
413 switch (from) {
414 case SOCK_STRING:
415 return 1;
416 default:
417 return -1;
418 }
419 default:
420 return -1;
421 }
422 }
423
424 /* select a suitable input socket for an output */
select_internal_link_input(bNode * node,bNodeSocket * output)425 static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output)
426 {
427 bNodeSocket *selected = NULL, *input;
428 int i;
429 int sel_priority = -1;
430 bool sel_is_linked = false;
431
432 for (input = node->inputs.first, i = 0; input; input = input->next, i++) {
433 int priority = node_datatype_priority(input->type, output->type);
434 bool is_linked = (input->link != NULL);
435 bool preferred;
436
437 if (nodeSocketIsHidden(input) || /* ignore hidden sockets */
438 input->flag &
439 SOCK_NO_INTERNAL_LINK || /* ignore if input is not allowed for internal connections */
440 priority < 0 || /* ignore incompatible types */
441 priority < sel_priority) /* ignore if we already found a higher priority input */
442 {
443 continue;
444 }
445
446 /* determine if this input is preferred over the currently selected */
447 preferred = (priority > sel_priority) || /* prefer higher datatype priority */
448 (is_linked && !sel_is_linked); /* prefer linked over unlinked */
449
450 if (preferred) {
451 selected = input;
452 sel_is_linked = is_linked;
453 sel_priority = priority;
454 }
455 }
456
457 return selected;
458 }
459
node_update_internal_links_default(bNodeTree * ntree,bNode * node)460 void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
461 {
462 bNodeLink *link;
463 bNodeSocket *output, *input;
464
465 /* sanity check */
466 if (!ntree) {
467 return;
468 }
469
470 /* use link pointer as a tag for handled sockets (for outputs is unused anyway) */
471 for (output = node->outputs.first; output; output = output->next) {
472 output->link = NULL;
473 }
474
475 for (link = ntree->links.first; link; link = link->next) {
476 if (nodeLinkIsHidden(link)) {
477 continue;
478 }
479
480 output = link->fromsock;
481 if (link->fromnode != node || output->link) {
482 continue;
483 }
484 if (nodeSocketIsHidden(output) || output->flag & SOCK_NO_INTERNAL_LINK) {
485 continue;
486 }
487 output->link = link; /* not really used, just for tagging handled sockets */
488
489 /* look for suitable input */
490 input = select_internal_link_input(node, output);
491
492 if (input) {
493 bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link");
494 ilink->fromnode = node;
495 ilink->fromsock = input;
496 ilink->tonode = node;
497 ilink->tosock = output;
498 /* internal link is always valid */
499 ilink->flag |= NODE_LINK_VALID;
500 BLI_addtail(&node->internal_links, ilink);
501 }
502 }
503
504 /* clean up */
505 for (output = node->outputs.first; output; output = output->next) {
506 output->link = NULL;
507 }
508 }
509
510 /**** Default value RNA access ****/
511
node_socket_get_float(bNodeTree * ntree,bNode * UNUSED (node),bNodeSocket * sock)512 float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock)
513 {
514 PointerRNA ptr;
515 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
516 return RNA_float_get(&ptr, "default_value");
517 }
518
node_socket_set_float(bNodeTree * ntree,bNode * UNUSED (node),bNodeSocket * sock,float value)519 void node_socket_set_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float value)
520 {
521 PointerRNA ptr;
522 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
523 RNA_float_set(&ptr, "default_value", value);
524 }
525
node_socket_get_color(bNodeTree * ntree,bNode * UNUSED (node),bNodeSocket * sock,float * value)526 void node_socket_get_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value)
527 {
528 PointerRNA ptr;
529 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
530 RNA_float_get_array(&ptr, "default_value", value);
531 }
532
node_socket_set_color(bNodeTree * ntree,bNode * UNUSED (node),bNodeSocket * sock,const float * value)533 void node_socket_set_color(bNodeTree *ntree,
534 bNode *UNUSED(node),
535 bNodeSocket *sock,
536 const float *value)
537 {
538 PointerRNA ptr;
539 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
540 RNA_float_set_array(&ptr, "default_value", value);
541 }
542
node_socket_get_vector(bNodeTree * ntree,bNode * UNUSED (node),bNodeSocket * sock,float * value)543 void node_socket_get_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value)
544 {
545 PointerRNA ptr;
546 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
547 RNA_float_get_array(&ptr, "default_value", value);
548 }
549
node_socket_set_vector(bNodeTree * ntree,bNode * UNUSED (node),bNodeSocket * sock,const float * value)550 void node_socket_set_vector(bNodeTree *ntree,
551 bNode *UNUSED(node),
552 bNodeSocket *sock,
553 const float *value)
554 {
555 PointerRNA ptr;
556 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
557 RNA_float_set_array(&ptr, "default_value", value);
558 }
559