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