Cycles: working towards texture workflow design
[blender.git] / source / blender / editors / interface / interface_node.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Blender Foundation 2009.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/editors/interface/interface_node.c
26  *  \ingroup edinterface
27  */
28
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include <string.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_node_types.h"
36 #include "DNA_screen_types.h"
37
38 #include "BLI_listbase.h"
39 #include "BLI_string.h"
40 #include "BLI_utildefines.h"
41
42 #include "BKE_context.h"
43 #include "BKE_depsgraph.h"
44 #include "BKE_library.h"
45 #include "BKE_main.h"
46 #include "BKE_node.h"
47
48 #include "RNA_access.h"
49
50 #include "WM_api.h"
51 #include "WM_types.h"
52
53 #include "UI_interface.h"
54 #include "interface_intern.h"
55
56 #include "ED_node.h"
57
58 /************************* Node Link Menu **************************/
59
60 #define UI_NODE_LINK_ADD                0
61 #define UI_NODE_LINK_DISCONNECT -1
62 #define UI_NODE_LINK_REMOVE             -2
63
64 typedef struct NodeLinkArg {
65         bNodeTree *ntree;
66         bNode *node;
67         bNodeSocket *sock;
68
69         bNodeTree *ngroup;
70         int type;
71         int output;
72 } NodeLinkArg;
73
74 static void ui_node_tag_recursive(bNode *node)
75 {
76         bNodeSocket *input;
77
78         if(!node || (node->flag & NODE_TEST))
79                 return; /* in case of cycles */
80         
81         node->flag |= NODE_TEST;
82
83         for(input=node->inputs.first; input; input=input->next)
84                 if(input->link)
85                         ui_node_tag_recursive(input->link->fromnode);
86 }
87
88 static void ui_node_clear_recursive(bNode *node)
89 {
90         bNodeSocket *input;
91
92         if(!node || !(node->flag & NODE_TEST))
93                 return; /* in case of cycles */
94         
95         node->flag &= ~NODE_TEST;
96
97         for(input=node->inputs.first; input; input=input->next)
98                 if(input->link)
99                         ui_node_clear_recursive(input->link->fromnode);
100 }
101
102 static void ui_node_remove_linked(bNodeTree *ntree, bNode *rem_node)
103 {
104         bNode *node, *next;
105         bNodeSocket *sock;
106
107         if(!rem_node)
108                 return;
109
110         /* tag linked nodes to be removed */
111         for(node=ntree->nodes.first; node; node=node->next)
112                 node->flag &= ~NODE_TEST;
113         
114         ui_node_tag_recursive(rem_node);
115
116         /* clear tags on nodes that are still used by other nodes */
117         for(node=ntree->nodes.first; node; node=node->next)
118                 if(!(node->flag & NODE_TEST))
119                         for(sock=node->inputs.first; sock; sock=sock->next)
120                                 if(sock->link && sock->link->fromnode != rem_node)
121                                         ui_node_clear_recursive(sock->link->fromnode);
122
123         /* remove nodes */
124         for(node=ntree->nodes.first; node; node=next) {
125                 next = node->next;
126
127                 if(node->flag & NODE_TEST) {
128                         if(node->id)
129                                 node->id->us--;
130                         nodeFreeNode(ntree, node);
131                 }
132         }
133         
134         //node_tree_verify_groups(ntree);
135 }
136
137 static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR])
138 {
139         if(sock->link && sock->link->fromnode) {
140                 bNode *node = sock->link->fromnode;
141
142                 if(node->type == NODE_GROUP)
143                         BLI_strncpy(name, node->id->name+2, UI_MAX_NAME_STR);
144                 else
145                         BLI_strncpy(name, node->typeinfo->name, UI_MAX_NAME_STR);
146
147                 if(node->inputs.first == NULL &&
148                    node->outputs.first != node->outputs.last &&
149                    !(node->typeinfo->flag & NODE_OPTIONS))
150                         BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", name, sock->link->fromsock->name);
151         }
152         else if(sock->type == SOCK_CLOSURE)
153                 BLI_strncpy(name, "None", UI_MAX_NAME_STR);
154         else
155                 BLI_strncpy(name, "Default", UI_MAX_NAME_STR);
156 }
157
158 static void ui_node_link(bContext *C, void *arg_p, void *event_p)
159 {
160         NodeLinkArg *arg = (NodeLinkArg*)arg_p;
161         bNode *node_to = arg->node;
162         bNodeSocket *sock_to = arg->sock;
163         bNodeTree *ntree = arg->ntree;
164         bNode *node_from;
165         bNodeSocket *sock_from;
166         int event = GET_INT_FROM_POINTER(event_p);
167
168         if(event == UI_NODE_LINK_DISCONNECT) {
169                 /* disconnect */
170                 if(sock_to->link)
171                         nodeRemLink(ntree, sock_to->link);
172         }
173         else if(event == UI_NODE_LINK_REMOVE) {
174                 /* remove */
175                 if(sock_to->link)
176                         ui_node_remove_linked(ntree, sock_to->link->fromnode);
177         }
178         else {
179                 bNode *node_prev = NULL;
180
181                 /* unlink existing node */
182                 if(sock_to->link) {
183                         node_prev = sock_to->link->fromnode;
184                         nodeRemLink(ntree, sock_to->link);
185                 }
186
187                 /* find existing node that we can use */
188                 for(node_from=ntree->nodes.first; node_from; node_from=node_from->next)
189                         if(node_from->type == arg->type)
190                                 break;
191
192                 if(node_from)
193                         if(!(node_from->inputs.first == NULL && !(node_from->typeinfo->flag & NODE_OPTIONS)))
194                                 node_from = NULL;
195
196                 if(node_prev && node_prev->type == arg->type &&
197                         (arg->type != NODE_GROUP || node_prev->id == &arg->ngroup->id)) {
198                         /* keep the previous node if it's the same type */
199                         node_from = node_prev;
200                 }
201                 else if(!node_from) {
202                         /* add new node */
203                         if(arg->ngroup)
204                                 node_from = nodeAddNodeType(ntree, NODE_GROUP, arg->ngroup, NULL);
205                         else
206                                 node_from = nodeAddNodeType(ntree, arg->type, NULL, NULL);
207
208                         node_from->locx = node_to->locx - (node_from->typeinfo->width + 50);
209                         node_from->locy = node_to->locy;
210
211                         if(node_from->id)
212                                 id_us_plus(node_from->id);
213                 }
214
215                 nodeSetActive(ntree, node_from);
216
217                 /* add link */
218                 sock_from = BLI_findlink(&node_from->outputs, arg->output);
219                 nodeAddLink(ntree, node_from, sock_from, node_to, sock_to);
220
221                 /* copy input sockets from previous node */
222                 if(node_prev && node_from != node_prev) {
223                         bNodeSocket *sock_prev, *sock_from;
224
225                         for(sock_prev=node_prev->inputs.first; sock_prev; sock_prev=sock_prev->next) {
226                                 for(sock_from=node_from->inputs.first; sock_from; sock_from=sock_from->next) {
227                                         if(strcmp(sock_prev->name, sock_from->name) == 0 && sock_prev->type == sock_from->type) {
228                                                 bNodeLink *link = sock_prev->link;
229
230                                                 if(link && link->fromnode) {
231                                                         nodeAddLink(ntree, link->fromnode, link->fromsock, node_from, sock_from);
232                                                         nodeRemLink(ntree, link);
233                                                 }
234
235                                                 memcpy(sock_from->ns.vec, sock_prev->ns.vec, sizeof(sock_from->ns.vec));
236                                         }
237                                 }
238                         }
239
240                         /* remove node */
241                         ui_node_remove_linked(ntree, node_prev);
242                 }
243
244                 NodeTagChanged(ntree, node_from);
245         }
246
247         NodeTagChanged(ntree, node_to);
248         ntreeSolveOrder(ntree);
249
250         ED_node_generic_update(CTX_data_main(C), ntree, node_to);
251 }
252
253 static int ui_compatible_sockets(int typeA, int typeB)
254 {
255         if(typeA == SOCK_CLOSURE || typeB == SOCK_CLOSURE)
256                 return (typeA == typeB);
257         
258         return (typeA == typeB);
259 }
260
261 static bNodeSocketType *ui_node_input_socket_type(bNode *node, bNodeSocket *sock)
262 {
263         if(node->type == NODE_GROUP)
264                 return NULL;
265         
266         return &node->typeinfo->inputs[BLI_findindex(&node->inputs, sock)];
267 }
268
269 static void ui_node_menu_column(Main *bmain, NodeLinkArg *arg, uiLayout *layout, const char *cname, int nclass)
270 {
271         bNodeTree *ntree = arg->ntree;
272         bNodeSocket *sock = arg->sock;
273         uiLayout *column = NULL;
274         uiBlock *block = uiLayoutGetBlock(layout);
275         uiBut *but;
276         bNodeType *ntype;
277         bNodeTree *ngroup;
278         NodeLinkArg *argN;
279         int first = 1;
280
281         if(nclass == NODE_CLASS_GROUP) {
282                 for(ngroup=bmain->nodetree.first; ngroup; ngroup=ngroup->id.next) {
283                         bNodeSocket *gsock;
284                         char name[UI_MAX_NAME_STR];
285                         int i, j, num = 0;
286
287                         if(ngroup->type != ntree->type)
288                                 continue;
289
290                         for(gsock=ngroup->inputs.first; gsock; gsock=gsock->next)
291                                 if(ui_compatible_sockets(gsock->type, sock->type))
292                                         num++;
293
294                         for(i=0, j=0, gsock=ngroup->outputs.first; gsock; gsock=gsock->next, i++) {
295                                 if(!ui_compatible_sockets(gsock->type, sock->type))
296                                         continue;
297
298                                 if(first) {
299                                         column= uiLayoutColumn(layout, 0);
300                                         uiBlockSetCurLayout(block, column);
301
302                                         uiItemL(column, cname, ICON_NONE);
303                                         but= block->buttons.last;
304                                         but->flag= UI_TEXT_LEFT;
305
306                                         first = 0;
307                                 }
308
309                                 if(num > 1) {
310                                         if(j == 0) {
311                                                 uiItemL(column, ngroup->id.name+2, ICON_NONE);
312                                                 but= block->buttons.last;
313                                                 but->flag= UI_TEXT_LEFT;
314                                         }
315
316                                         BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", gsock->name);
317                                         j++;
318                                 }
319                                 else
320                                         BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR);
321
322                                 but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
323                                         NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");
324
325                                 argN = MEM_dupallocN(arg);
326                                 argN->ngroup = ngroup;
327                                 argN->output = i;
328                                 uiButSetNFunc(but, ui_node_link, argN, NULL);
329                         }
330                 }
331         }
332         else {
333                 for(ntype=ntree->alltypes.first; ntype; ntype=ntype->next) {
334                         bNodeSocketType *stype;
335                         char name[UI_MAX_NAME_STR];
336                         int i, j, num = 0;
337
338                         if(ntype->nclass != nclass)
339                                 continue;
340
341                         for(i=0, stype=ntype->outputs; stype && stype->type != -1; stype++, i++)
342                                 if(ui_compatible_sockets(stype->type, sock->type))
343                                         num++;
344
345                         for(i=0, j=0, stype=ntype->outputs; stype && stype->type != -1; stype++, i++) {
346                                 if(!ui_compatible_sockets(stype->type, sock->type))
347                                         continue;
348
349                                 if(first) {
350                                         column= uiLayoutColumn(layout, 0);
351                                         uiBlockSetCurLayout(block, column);
352
353                                         uiItemL(column, cname, ICON_NONE);
354                                         but= block->buttons.last;
355                                         but->flag= UI_TEXT_LEFT;
356
357                                         first = 0;
358                                 }
359
360                                 if(num > 1) {
361                                         if(j == 0) {
362                                                 uiItemL(column, ntype->name, ICON_NONE);
363                                                 but= block->buttons.last;
364                                                 but->flag= UI_TEXT_LEFT;
365                                         }
366
367                                         BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", stype->name);
368                                         j++;
369                                 }
370                                 else
371                                         BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR);
372
373                                 but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
374                                         NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");
375
376                                 argN = MEM_dupallocN(arg);
377                                 argN->type = ntype->type;
378                                 argN->output = i;
379                                 uiButSetNFunc(but, ui_node_link, argN, NULL);
380                         }
381                 }
382         }
383 }
384
385 static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_p)
386 {
387         Main *bmain= CTX_data_main(C);
388         uiBlock *block = uiLayoutGetBlock(layout);
389         uiBut *but = (uiBut*)but_p;
390         uiLayout *split, *column;
391         NodeLinkArg *arg = (NodeLinkArg*)but->func_argN;
392         bNodeSocket *sock = arg->sock;
393         
394         uiBlockSetCurLayout(block, layout);
395         split= uiLayoutSplit(layout, 0, 0);
396
397         ui_node_menu_column(bmain, arg, split, "Input", NODE_CLASS_INPUT);
398         ui_node_menu_column(bmain, arg, split, "Output", NODE_CLASS_OUTPUT);
399         ui_node_menu_column(bmain, arg, split, "Closure", NODE_CLASS_CLOSURE);
400         ui_node_menu_column(bmain, arg, split, "Texture", NODE_CLASS_TEXTURE);
401         ui_node_menu_column(bmain, arg, split, "Color", NODE_CLASS_OP_COLOR);
402         ui_node_menu_column(bmain, arg, split, "Vector", NODE_CLASS_OP_VECTOR);
403         ui_node_menu_column(bmain, arg, split, "Convertor", NODE_CLASS_CONVERTOR);
404
405         column= uiLayoutColumn(split, 0);
406         uiBlockSetCurLayout(block, column);
407
408         if(sock->link) {
409                 uiItemL(column, "Link", ICON_NONE);
410                 but= block->buttons.last;
411                 but->flag= UI_TEXT_LEFT;
412
413                 but = uiDefBut(block, BUT, 0, "Remove", 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
414                         NULL, 0.0, 0.0, 0.0, 0.0, "Remove nodes connected to the input");
415                 uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE));
416
417                 but = uiDefBut(block, BUT, 0, "Disconnect", 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
418                         NULL, 0.0, 0.0, 0.0, 0.0, "Disconnect nodes connected to the input");
419                 uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT));
420         }
421
422         ui_node_menu_column(bmain, arg, column, "Group", NODE_CLASS_GROUP);
423 }
424
425 void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSocket *sock)
426 {
427         uiBlock *block = uiLayoutGetBlock(layout);
428         NodeLinkArg *arg;
429         uiBut *but;
430         bNodeSocketType *stype = ui_node_input_socket_type(node, sock);
431
432         arg = MEM_callocN(sizeof(NodeLinkArg), "NodeLinkArg");
433         arg->ntree = ntree;
434         arg->node = node;
435         arg->sock = sock;
436         arg->type = 0;
437         arg->output = 0;
438
439         uiBlockSetCurLayout(block, layout);
440
441         if(sock->link || sock->type == SOCK_CLOSURE || (stype && (stype->flag & SOCK_NO_VALUE))) {
442                 char name[UI_MAX_NAME_STR];
443                 ui_node_sock_name(sock, name);
444                 but= uiDefMenuBut(block, ui_template_node_link_menu, NULL, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
445         }
446         else
447                 but= uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
448
449         but->type= MENU;
450         but->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK;
451         but->poin= (char*)but;
452         but->func_argN = arg;
453
454         if(sock->link && sock->link->fromnode)
455                 if(sock->link->fromnode->flag & NODE_ACTIVE_TEXTURE)
456                         but->flag |= UI_BUT_NODE_ACTIVE;
457 }
458
459 /************************* Node Tree Layout **************************/
460
461 static void ui_node_draw_input(uiLayout *layout, bContext *C,
462         bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth);
463
464 static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, int depth)
465 {
466         bNodeSocket *input;
467         uiLayout *col, *split;
468         PointerRNA nodeptr;
469
470         RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);
471
472         if(node->typeinfo->uifunc) {
473                 if(node->type != NODE_GROUP) {
474                         split = uiLayoutSplit(layout, 0.35f, 0);
475                         col = uiLayoutColumn(split, 0);
476                         col = uiLayoutColumn(split, 0);
477
478                         node->typeinfo->uifunc(col, C, &nodeptr);
479                 }
480         }
481
482         for(input=node->inputs.first; input; input=input->next)
483                 ui_node_draw_input(layout, C, ntree, node, input, depth+1);
484 }
485
486 static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth)
487 {
488         PointerRNA inputptr;
489         uiBlock *block = uiLayoutGetBlock(layout);
490         uiBut *bt;
491         uiLayout *split, *row, *col;
492         bNode *lnode;
493         char label[UI_MAX_NAME_STR];
494         int indent = (depth > 1)? 2*(depth - 1): 0;
495
496         /* to avoid eternal loops on cyclic dependencies */
497         node->flag |= NODE_TEST;
498         lnode = (input->link)? input->link->fromnode: NULL;
499
500         /* socket RNA pointer */
501         RNA_pointer_create(&ntree->id, &RNA_NodeSocket, input, &inputptr);
502
503         /* indented label */
504         memset(label, ' ', indent);
505         label[indent] = '\0';
506         BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, input->name);
507
508         /* split in label and value */
509         split = uiLayoutSplit(layout, 0.35f, 0);
510
511         row = uiLayoutRow(split, 1);
512
513         if(depth > 0) {
514                 uiBlockSetEmboss(block, UI_EMBOSSN);
515
516                 if(lnode && (lnode->inputs.first || (lnode->typeinfo->uifunc && lnode->type != NODE_GROUP))) {
517                         int icon = (input->flag & SOCK_COLLAPSED)? ICON_DISCLOSURE_TRI_RIGHT: ICON_DISCLOSURE_TRI_DOWN;
518                         uiItemR(row, &inputptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", icon);
519                 }
520                 else
521                         uiItemL(row, "", ICON_BLANK1);
522
523                 bt = block->buttons.last;
524                 bt->x2 = UI_UNIT_X/2;
525
526                 uiBlockSetEmboss(block, UI_EMBOSS);
527         }
528
529         uiItemL(row, label, ICON_NONE);
530
531         if(lnode) {
532                 /* input linked to a node */
533                 uiTemplateNodeLink(split, ntree, node, input);
534
535                 if(!(input->flag & SOCK_COLLAPSED)) {
536                         if(depth == 0)
537                                 uiItemS(layout);
538
539                         ui_node_draw_node(layout, C, ntree, lnode, depth);
540                 }
541         }
542         else {
543                 bNodeSocketType *stype = ui_node_input_socket_type(node, input);
544
545                 /* input not linked, show value */
546                 if(input->type != SOCK_CLOSURE && (!stype || !(stype->flag & SOCK_NO_VALUE))) {
547                         if(input->type == SOCK_VECTOR) {
548                                 row = uiLayoutRow(split, 0);
549                                 col = uiLayoutColumn(row, 0);
550
551                                 uiItemR(col, &inputptr, "default_value", 0, "", 0);
552                         }
553                         else {
554                                 row = uiLayoutRow(split, 1);
555                                 uiItemR(row, &inputptr, "default_value", 0, "", 0);
556                         }
557                 }
558                 else
559                         row = uiLayoutRow(split, 0);
560
561                 uiTemplateNodeLink(row, ntree, node, input);
562         }
563
564         /* clear */
565         node->flag &= ~NODE_TEST;
566 }
567
568 void uiTemplateNodeView(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input)
569 {
570         bNode *tnode;
571
572         if(!ntree)
573                 return;
574
575         /* clear for cycle check */
576         for(tnode=ntree->nodes.first; tnode; tnode=tnode->next)
577                 tnode->flag &= ~NODE_TEST;
578
579         if(input)
580                 ui_node_draw_input(layout, C, ntree, node, input, 0);
581         else
582                 ui_node_draw_node(layout, C, ntree, node, 0);
583 }
584