Fix #35640, part 2. Check id.lib in poll functions for operators which do critical...
[blender.git] / source / blender / editors / space_node / node_relationships.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_node/node_relationships.c
29  *  \ingroup spnode
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_node_types.h"
35 #include "DNA_object_types.h"
36
37 #include "BLI_math.h"
38 #include "BLI_blenlib.h"
39
40 #include "BKE_context.h"
41 #include "BKE_global.h"
42 #include "BKE_main.h"
43 #include "BKE_node.h"
44
45 #include "ED_node.h"  /* own include */
46 #include "ED_screen.h"
47 #include "ED_render.h"
48
49 #include "RNA_access.h"
50 #include "RNA_define.h"
51
52 #include "WM_api.h"
53 #include "WM_types.h"
54
55 #include "UI_view2d.h"
56
57 #include "node_intern.h"  /* own include */
58 #include "NOD_common.h"
59
60 /* ****************** Add *********************** */
61
62
63 typedef struct bNodeListItem {
64         struct bNodeListItem *next, *prev;
65         struct bNode *node;
66 } bNodeListItem;
67
68 static int sort_nodes_locx(void *a, void *b)
69 {
70         bNodeListItem *nli1 = (bNodeListItem *)a;
71         bNodeListItem *nli2 = (bNodeListItem *)b;
72         bNode *node1 = nli1->node;
73         bNode *node2 = nli2->node;
74
75         if (node1->locx > node2->locx)
76                 return 1;
77         else
78                 return 0;
79 }
80
81 static int socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, int allow_used)
82 {
83         if (nodeSocketIsHidden(sock))
84                 return 0;
85
86         if (!allow_used && (sock->flag & SOCK_IN_USE))
87                 return 0;
88
89         return 1;
90 }
91
92 static bNodeSocket *best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, int allow_multiple)
93 {
94         bNodeSocket *sock;
95
96         /* first look for selected output */
97         for (sock = node->outputs.first; sock; sock = sock->next) {
98                 if (!socket_is_available(ntree, sock, allow_multiple))
99                         continue;
100
101                 if (sock->flag & SELECT)
102                         return sock;
103         }
104
105         /* try to find a socket with a matching name */
106         for (sock = node->outputs.first; sock; sock = sock->next) {
107                 if (!socket_is_available(ntree, sock, allow_multiple))
108                         continue;
109
110                 /* check for same types */
111                 if (sock->type == sock_target->type) {
112                         if (STREQ(sock->name, sock_target->name))
113                                 return sock;
114                 }
115         }
116
117         /* otherwise settle for the first available socket of the right type */
118         for (sock = node->outputs.first; sock; sock = sock->next) {
119
120                 if (!socket_is_available(ntree, sock, allow_multiple))
121                         continue;
122
123                 /* check for same types */
124                 if (sock->type == sock_target->type) {
125                         return sock;
126                 }
127         }
128
129         return NULL;
130 }
131
132 /* this is a bit complicated, but designed to prioritize finding
133  * sockets of higher types, such as image, first */
134 static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace)
135 {
136         bNodeSocket *sock;
137         int socktype, maxtype = 0;
138         int a = 0;
139
140         for (sock = node->inputs.first; sock; sock = sock->next) {
141                 maxtype = max_ii(sock->type, maxtype);
142         }
143
144         /* find sockets of higher 'types' first (i.e. image) */
145         for (socktype = maxtype; socktype >= 0; socktype--) {
146                 for (sock = node->inputs.first; sock; sock = sock->next) {
147
148                         if (!socket_is_available(ntree, sock, replace)) {
149                                 a++;
150                                 continue;
151                         }
152
153                         if (sock->type == socktype) {
154                                 /* increment to make sure we don't keep finding
155                                  * the same socket on every attempt running this function */
156                                 a++;
157                                 if (a > num)
158                                         return sock;
159                         }
160                 }
161         }
162
163         return NULL;
164 }
165
166 static int snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace)
167 {
168         bNodeTree *ntree = snode->edittree;
169         bNodeLink *link;
170
171         /* then we can connect */
172         if (replace)
173                 nodeRemSocketLinks(ntree, sock_to);
174
175         link = nodeAddLink(ntree, node_fr, sock_fr, node_to, sock_to);
176         /* validate the new link */
177         ntreeUpdateTree(G.main, ntree);
178         if (!(link->flag & NODE_LINK_VALID)) {
179                 nodeRemLink(ntree, link);
180                 return 0;
181         }
182
183         snode_update(snode, node_to);
184         return 1;
185 }
186
187 static void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace)
188 {
189         bNodeTree *ntree = snode->edittree;
190         ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
191         bNodeListItem *nli;
192         bNode *node;
193         int i, numlinks = 0;
194
195         for (node = ntree->nodes.first; node; node = node->next) {
196                 if (node->flag & NODE_SELECT) {
197                         nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item");
198                         nli->node = node;
199                         BLI_addtail(nodelist, nli);
200                 }
201         }
202
203         /* sort nodes left to right */
204         BLI_sortlist(nodelist, sort_nodes_locx);
205
206         for (nli = nodelist->first; nli; nli = nli->next) {
207                 bNode *node_fr, *node_to;
208                 bNodeSocket *sock_fr, *sock_to;
209                 int has_selected_inputs = 0;
210
211                 if (nli->next == NULL) break;
212
213                 node_fr = nli->node;
214                 node_to = nli->next->node;
215
216                 /* if there are selected sockets, connect those */
217                 for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) {
218                         if (sock_to->flag & SELECT) {
219                                 has_selected_inputs = 1;
220
221                                 if (!socket_is_available(ntree, sock_to, replace))
222                                         continue;
223
224                                 /* check for an appropriate output socket to connect from */
225                                 sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
226                                 if (!sock_fr)
227                                         continue;
228
229                                 if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) {
230                                         numlinks++;
231                                 }
232                         }
233                 }
234
235                 if (!has_selected_inputs) {
236                         /* no selected inputs, connect by finding suitable match */
237                         int num_inputs = BLI_countlist(&node_to->inputs);
238
239                         for (i = 0; i < num_inputs; i++) {
240
241                                 /* find the best guess input socket */
242                                 sock_to = best_socket_input(ntree, node_to, i, replace);
243                                 if (!sock_to)
244                                         continue;
245
246                                 /* check for an appropriate output socket to connect from */
247                                 sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
248                                 if (!sock_fr)
249                                         continue;
250
251                                 if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) {
252                                         numlinks++;
253                                         break;
254                                 }
255                         }
256                 }
257         }
258
259         if (numlinks > 0) {
260                 ntreeUpdateTree(G.main, ntree);
261         }
262
263         BLI_freelistN(nodelist);
264         MEM_freeN(nodelist);
265 }
266
267 /* *************************** link viewer op ******************** */
268
269 static int node_link_viewer(const bContext *C, bNode *tonode)
270 {
271         SpaceNode *snode = CTX_wm_space_node(C);
272         bNode *node;
273         bNodeLink *link;
274         bNodeSocket *sock;
275
276         /* context check */
277         if (tonode == NULL || tonode->outputs.first == NULL)
278                 return OPERATOR_CANCELLED;
279         if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
280                 return OPERATOR_CANCELLED;
281
282         /* get viewer */
283         for (node = snode->edittree->nodes.first; node; node = node->next)
284                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
285                         if (node->flag & NODE_DO_OUTPUT)
286                                 break;
287         /* no viewer, we make one active */
288         if (node == NULL) {
289                 for (node = snode->edittree->nodes.first; node; node = node->next) {
290                         if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
291                                 node->flag |= NODE_DO_OUTPUT;
292                                 break;
293                         }
294                 }
295         }
296
297         sock = NULL;
298
299         /* try to find an already connected socket to cycle to the next */
300         if (node) {
301                 link = NULL;
302                 for (link = snode->edittree->links.first; link; link = link->next)
303                         if (link->tonode == node && link->fromnode == tonode)
304                                 if (link->tosock == node->inputs.first)
305                                         break;
306                 if (link) {
307                         /* unlink existing connection */
308                         sock = link->fromsock;
309                         nodeRemLink(snode->edittree, link);
310
311                         /* find a socket after the previously connected socket */
312                         for (sock = sock->next; sock; sock = sock->next)
313                                 if (!nodeSocketIsHidden(sock))
314                                         break;
315                 }
316         }
317
318         /* find a socket starting from the first socket */
319         if (!sock) {
320                 for (sock = tonode->outputs.first; sock; sock = sock->next)
321                         if (!nodeSocketIsHidden(sock))
322                                 break;
323         }
324
325         if (sock) {
326                 /* add a new viewer if none exists yet */
327                 if (!node) {
328                         /* XXX location is a quick hack, just place it next to the linked socket */
329                         node = node_add_node(C, NULL, CMP_NODE_VIEWER, sock->locx + 100, sock->locy);
330                         if (!node)
331                                 return OPERATOR_CANCELLED;
332
333                         link = NULL;
334                 }
335                 else {
336                         /* get link to viewer */
337                         for (link = snode->edittree->links.first; link; link = link->next)
338                                 if (link->tonode == node && link->tosock == node->inputs.first)
339                                         break;
340                 }
341
342                 if (link == NULL) {
343                         nodeAddLink(snode->edittree, tonode, sock, node, node->inputs.first);
344                 }
345                 else {
346                         link->fromnode = tonode;
347                         link->fromsock = sock;
348                         /* make sure the dependency sorting is updated */
349                         snode->edittree->update |= NTREE_UPDATE_LINKS;
350                 }
351                 ntreeUpdateTree(CTX_data_main(C), snode->edittree);
352                 snode_update(snode, node);
353         }
354
355         return OPERATOR_FINISHED;
356 }
357
358
359 static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op))
360 {
361         SpaceNode *snode = CTX_wm_space_node(C);
362         bNode *node;
363
364         node = nodeGetActive(snode->edittree);
365
366         if (!node)
367                 return OPERATOR_CANCELLED;
368
369         ED_preview_kill_jobs(C);
370
371         if (node_link_viewer(C, node) == OPERATOR_CANCELLED)
372                 return OPERATOR_CANCELLED;
373
374         snode_notify(C, snode);
375
376         return OPERATOR_FINISHED;
377 }
378
379
380 void NODE_OT_link_viewer(wmOperatorType *ot)
381 {
382         /* identifiers */
383         ot->name = "Link to Viewer Node";
384         ot->description = "Link to viewer node";
385         ot->idname = "NODE_OT_link_viewer";
386
387         /* api callbacks */
388         ot->exec = node_active_link_viewer;
389         ot->poll = composite_node_editable;
390
391         /* flags */
392         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
393 }
394
395
396 /* *************************** add link op ******************** */
397
398 static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link)
399 {
400         bNodeLink *tlink;
401         bNodeSocket *sock;
402
403         if (tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) {
404
405                 for (tlink = snode->edittree->links.first; tlink; tlink = tlink->next) {
406                         if (link != tlink && tlink->tosock == link->tosock)
407                                 break;
408                 }
409                 if (tlink) {
410                         /* try to move the existing link to the next available socket */
411                         if (tlink->tonode) {
412                                 /* is there a free input socket with the target type? */
413                                 for (sock = tlink->tonode->inputs.first; sock; sock = sock->next) {
414                                         if (sock->type == tlink->tosock->type)
415                                                 if (nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
416                                                         break;
417                                 }
418                                 if (sock) {
419                                         tlink->tosock = sock;
420                                         sock->flag &= ~SOCK_HIDDEN;
421                                 }
422                                 else {
423                                         nodeRemLink(snode->edittree, tlink);
424                                 }
425                         }
426                         else
427                                 nodeRemLink(snode->edittree, tlink);
428
429                         snode->edittree->update |= NTREE_UPDATE_LINKS;
430                 }
431         }
432 }
433
434 /* loop that adds a nodelink, called by function below  */
435 /* in_out = starting socket */
436 static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
437 {
438         SpaceNode *snode = CTX_wm_space_node(C);
439         ARegion *ar = CTX_wm_region(C);
440         bNodeLinkDrag *nldrag = op->customdata;
441         bNodeTree *ntree = snode->edittree;
442         bNode *tnode;
443         bNodeSocket *tsock = NULL;
444         bNodeLink *link;
445         LinkData *linkdata;
446         int in_out;
447
448         in_out = nldrag->in_out;
449         
450         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
451                                  &snode->cursor[0], &snode->cursor[1]);
452
453         switch (event->type) {
454                 case MOUSEMOVE:
455                         
456                         if (in_out == SOCK_OUT) {
457                                 if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
458                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
459                                                 link = linkdata->data;
460                                                 
461                                                 /* skip if this is already the target socket */
462                                                 if (link->tosock == tsock)
463                                                         continue;
464                                                 /* skip if socket is on the same node as the fromsock */
465                                                 if (tnode && link->fromnode == tnode)
466                                                         continue;
467                                                 
468                                                 /* attach links to the socket */
469                                                 link->tonode = tnode;
470                                                 link->tosock = tsock;
471                                         }
472                                 }
473                                 else {
474                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
475                                                 link = linkdata->data;
476                                                 
477                                                 link->tonode = NULL;
478                                                 link->tosock = NULL;
479                                         }
480                                 }
481                         }
482                         else {
483                                 if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
484                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
485                                                 link = linkdata->data;
486                                                 
487                                                 /* skip if this is already the target socket */
488                                                 if (link->fromsock == tsock)
489                                                         continue;
490                                                 /* skip if socket is on the same node as the fromsock */
491                                                 if (tnode && link->tonode == tnode)
492                                                         continue;
493                                                 
494                                                 /* attach links to the socket */
495                                                 link->fromnode = tnode;
496                                                 link->fromsock = tsock;
497                                         }
498                                 }
499                                 else {
500                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
501                                                 link = linkdata->data;
502                                                 
503                                                 link->fromnode = NULL;
504                                                 link->fromsock = NULL;
505                                         }
506                                 }
507                         }
508                         
509                         ED_region_tag_redraw(ar);
510                         break;
511                         
512                 case LEFTMOUSE:
513                 case RIGHTMOUSE:
514                 case MIDDLEMOUSE:
515                 {
516                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
517                                 link = linkdata->data;
518                                 
519                                 if (link->tosock && link->fromsock) {
520                                         /* add link to the node tree */
521                                         BLI_addtail(&ntree->links, link);
522                                         
523                                         ntree->update |= NTREE_UPDATE_LINKS;
524                                         
525                                         /* tag tonode for update */
526                                         link->tonode->update |= NODE_UPDATE;
527                                         
528                                         /* we might need to remove a link */
529                                         if (in_out == SOCK_OUT)
530                                                 node_remove_extra_links(snode, link->tosock, link);
531                                 }
532                                 else
533                                         nodeRemLink(ntree, link);
534                         }
535                         
536                         ntreeUpdateTree(CTX_data_main(C), ntree);
537                         snode_notify(C, snode);
538                         snode_dag_update(C, snode);
539                         
540                         BLI_remlink(&snode->linkdrag, nldrag);
541                         /* links->data pointers are either held by the tree or freed already */
542                         BLI_freelistN(&nldrag->links);
543                         MEM_freeN(nldrag);
544                         
545                         return OPERATOR_FINISHED;
546                 }
547         }
548         
549         return OPERATOR_RUNNING_MODAL;
550 }
551
552 /* return 1 when socket clicked */
553 static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
554 {
555         bNode *node;
556         bNodeSocket *sock;
557         bNodeLink *link, *link_next, *oplink;
558         bNodeLinkDrag *nldrag = NULL;
559         LinkData *linkdata;
560         int num_links;
561
562         /* output indicated? */
563         if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
564                 nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
565
566                 num_links = nodeCountSocketLinks(snode->edittree, sock);
567                 if (num_links > 0 && (num_links >= sock->limit || detach)) {
568                         /* dragged links are fixed on input side */
569                         nldrag->in_out = SOCK_IN;
570                         /* detach current links and store them in the operator data */
571                         for (link = snode->edittree->links.first; link; link = link_next) {
572                                 link_next = link->next;
573                                 if (link->fromsock == sock) {
574                                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
575                                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
576                                         *oplink = *link;
577                                         oplink->next = oplink->prev = NULL;
578                                         oplink->flag |= NODE_LINK_VALID;
579                                         
580                                         BLI_addtail(&nldrag->links, linkdata);
581                                         nodeRemLink(snode->edittree, link);
582                                 }
583                         }
584                 }
585                 else {
586                         /* dragged links are fixed on output side */
587                         nldrag->in_out = SOCK_OUT;
588                         /* create a new link */
589                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
590                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
591                         oplink->fromnode = node;
592                         oplink->fromsock = sock;
593                         oplink->flag |= NODE_LINK_VALID;
594                         
595                         BLI_addtail(&nldrag->links, linkdata);
596                 }
597         }
598         /* or an input? */
599         else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
600                 nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
601
602                 num_links = nodeCountSocketLinks(snode->edittree, sock);
603                 if (num_links > 0 && (num_links >= sock->limit || detach)) {
604                         /* dragged links are fixed on output side */
605                         nldrag->in_out = SOCK_OUT;
606                         /* detach current links and store them in the operator data */
607                         for (link = snode->edittree->links.first; link; link = link_next) {
608                                 link_next = link->next;
609                                 if (link->tosock == sock) {
610                                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
611                                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
612                                         *oplink = *link;
613                                         oplink->next = oplink->prev = NULL;
614                                         oplink->flag |= NODE_LINK_VALID;
615                                         
616                                         BLI_addtail(&nldrag->links, linkdata);
617                                         nodeRemLink(snode->edittree, link);
618                                         
619                                         /* send changed event to original link->tonode */
620                                         if (node)
621                                                 snode_update(snode, node);
622                                 }
623                         }
624                 }
625                 else {
626                         /* dragged links are fixed on input side */
627                         nldrag->in_out = SOCK_IN;
628                         /* create a new link */
629                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
630                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
631                         oplink->tonode = node;
632                         oplink->tosock = sock;
633                         oplink->flag |= NODE_LINK_VALID;
634                         
635                         BLI_addtail(&nldrag->links, linkdata);
636                 }
637         }
638
639         return nldrag;
640 }
641
642 static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
643 {
644         SpaceNode *snode = CTX_wm_space_node(C);
645         ARegion *ar = CTX_wm_region(C);
646         bNodeLinkDrag *nldrag;
647         int detach = RNA_boolean_get(op->ptr, "detach");
648
649         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
650                                  &snode->cursor[0], &snode->cursor[1]);
651
652         ED_preview_kill_jobs(C);
653
654         nldrag = node_link_init(snode, detach);
655
656         if (nldrag) {
657                 op->customdata = nldrag;
658                 BLI_addtail(&snode->linkdrag, nldrag);
659
660                 /* add modal handler */
661                 WM_event_add_modal_handler(C, op);
662
663                 return OPERATOR_RUNNING_MODAL;
664         }
665         else
666                 return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
667 }
668
669 static int node_link_cancel(bContext *C, wmOperator *op)
670 {
671         SpaceNode *snode = CTX_wm_space_node(C);
672         bNodeLinkDrag *nldrag = op->customdata;
673
674         BLI_remlink(&snode->linkdrag, nldrag);
675
676         BLI_freelistN(&nldrag->links);
677         MEM_freeN(nldrag);
678
679         return OPERATOR_CANCELLED;
680 }
681
682 void NODE_OT_link(wmOperatorType *ot)
683 {
684         /* identifiers */
685         ot->name = "Link Nodes";
686         ot->idname = "NODE_OT_link";
687         ot->description = "Use the mouse to create a link between two nodes";
688
689         /* api callbacks */
690         ot->invoke = node_link_invoke;
691         ot->modal = node_link_modal;
692 //      ot->exec = node_link_exec;
693         ot->poll = ED_operator_node_editable;
694         ot->cancel = node_link_cancel;
695
696         /* flags */
697         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
698
699         RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links");
700 }
701
702 /* ********************** Make Link operator ***************** */
703
704 /* makes a link between selected output and input sockets */
705 static int node_make_link_exec(bContext *C, wmOperator *op)
706 {
707         SpaceNode *snode = CTX_wm_space_node(C);
708         int replace = RNA_boolean_get(op->ptr, "replace");
709
710         ED_preview_kill_jobs(C);
711
712         snode_autoconnect(snode, 1, replace);
713
714         /* deselect sockets after linking */
715         node_deselect_all_input_sockets(snode, 0);
716         node_deselect_all_output_sockets(snode, 0);
717
718         ntreeUpdateTree(CTX_data_main(C), snode->edittree);
719         snode_notify(C, snode);
720         snode_dag_update(C, snode);
721
722         return OPERATOR_FINISHED;
723 }
724
725 void NODE_OT_link_make(wmOperatorType *ot)
726 {
727         /* identifiers */
728         ot->name = "Make Links";
729         ot->description = "Makes a link between selected output in input sockets";
730         ot->idname = "NODE_OT_link_make";
731
732         /* callbacks */
733         ot->exec = node_make_link_exec;
734         ot->poll = ED_operator_node_editable; // XXX we need a special poll which checks that there are selected input/output sockets
735
736         /* flags */
737         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
738
739         RNA_def_boolean(ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links");
740 }
741
742 /* ********************** Cut Link operator ***************** */
743 static int cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot)
744 {
745         float coord_array[NODE_LINK_RESOL + 1][2];
746         int i, b;
747
748         if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
749
750                 for (i = 0; i < tot - 1; i++)
751                         for (b = 0; b < NODE_LINK_RESOL; b++)
752                                 if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0)
753                                         return 1;
754         }
755         return 0;
756 }
757
758 static int cut_links_exec(bContext *C, wmOperator *op)
759 {
760         SpaceNode *snode = CTX_wm_space_node(C);
761         ARegion *ar = CTX_wm_region(C);
762         float mcoords[256][2];
763         int i = 0;
764
765         RNA_BEGIN(op->ptr, itemptr, "path")
766         {
767                 float loc[2];
768
769                 RNA_float_get_array(&itemptr, "loc", loc);
770                 UI_view2d_region_to_view(&ar->v2d, (int)loc[0], (int)loc[1],
771                                          &mcoords[i][0], &mcoords[i][1]);
772                 i++;
773                 if (i >= 256) break;
774         }
775         RNA_END;
776
777         if (i > 1) {
778                 int found = FALSE;
779                 bNodeLink *link, *next;
780                 
781                 ED_preview_kill_jobs(C);
782                 
783                 for (link = snode->edittree->links.first; link; link = next) {
784                         next = link->next;
785                         if (nodeLinkIsHidden(link))
786                                 continue;
787
788                         if (cut_links_intersect(link, mcoords, i)) {
789
790                                 if (found == FALSE) {
791                                         ED_preview_kill_jobs(C);
792                                         found = TRUE;
793                                 }
794
795                                 snode_update(snode, link->tonode);
796                                 nodeRemLink(snode->edittree, link);
797                         }
798                 }
799
800                 if (found) {
801                         ntreeUpdateTree(CTX_data_main(C), snode->edittree);
802                         snode_notify(C, snode);
803                         snode_dag_update(C, snode);
804
805                         return OPERATOR_FINISHED;
806                 }
807                 else {
808                         return OPERATOR_CANCELLED;
809                 }
810
811         }
812
813         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
814 }
815
816 void NODE_OT_links_cut(wmOperatorType *ot)
817 {
818         PropertyRNA *prop;
819
820         ot->name = "Cut Links";
821         ot->idname = "NODE_OT_links_cut";
822         ot->description = "Use the mouse to cut (remove) some links";
823
824         ot->invoke = WM_gesture_lines_invoke;
825         ot->modal = WM_gesture_lines_modal;
826         ot->exec = cut_links_exec;
827         ot->cancel = WM_gesture_lines_cancel;
828
829         ot->poll = ED_operator_node_editable;
830
831         /* flags */
832         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
833
834         prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
835         RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
836         /* internal */
837         RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
838 }
839
840 /* ********************** Detach links operator ***************** */
841
842 static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
843 {
844         SpaceNode *snode = CTX_wm_space_node(C);
845         bNodeTree *ntree = snode->edittree;
846         bNode *node;
847
848         ED_preview_kill_jobs(C);
849
850         for (node = ntree->nodes.first; node; node = node->next) {
851                 if (node->flag & SELECT) {
852                         nodeInternalRelink(ntree, node);
853                 }
854         }
855
856         ntreeUpdateTree(CTX_data_main(C), ntree);
857
858         snode_notify(C, snode);
859         snode_dag_update(C, snode);
860
861         return OPERATOR_FINISHED;
862 }
863
864 void NODE_OT_links_detach(wmOperatorType *ot)
865 {
866         ot->name = "Detach Links";
867         ot->idname = "NODE_OT_links_detach";
868         ot->description = "Remove all links to selected nodes, and try to connect neighbor nodes together";
869
870         ot->exec = detach_links_exec;
871         ot->poll = ED_operator_node_editable;
872
873         /* flags */
874         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
875 }
876
877
878 /* ****************** Show Cyclic Dependencies Operator  ******************* */
879
880 static int node_show_cycles_exec(bContext *C, wmOperator *UNUSED(op))
881 {
882         SpaceNode *snode = CTX_wm_space_node(C);
883
884         /* this is just a wrapper around this call... */
885         ntreeUpdateTree(CTX_data_main(C), snode->nodetree);
886         snode_notify(C, snode);
887
888         return OPERATOR_FINISHED;
889 }
890
891 void NODE_OT_show_cyclic_dependencies(wmOperatorType *ot)
892 {
893         /* identifiers */
894         ot->name = "Show Cyclic Dependencies";
895         ot->description = "Sort the nodes and show the cyclic dependencies between the nodes";
896         ot->idname = "NODE_OT_show_cyclic_dependencies";
897
898         /* callbacks */
899         ot->exec = node_show_cycles_exec;
900         ot->poll = ED_operator_node_active;
901
902         /* flags */
903         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
904 }
905
906 /* ****************** Set Parent ******************* */
907
908 static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
909 {
910         SpaceNode *snode = CTX_wm_space_node(C);
911         bNodeTree *ntree = snode->edittree;
912         bNode *frame = nodeGetActive(ntree), *node;
913         if (!frame || frame->type != NODE_FRAME)
914                 return OPERATOR_CANCELLED;
915
916         for (node = ntree->nodes.first; node; node = node->next) {
917                 if (node == frame)
918                         continue;
919                 if (node->flag & NODE_SELECT) {
920                         nodeDetachNode(node);
921                         nodeAttachNode(node, frame);
922                 }
923         }
924
925         ED_node_sort(ntree);
926         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
927
928         return OPERATOR_FINISHED;
929 }
930
931 void NODE_OT_parent_set(wmOperatorType *ot)
932 {
933         /* identifiers */
934         ot->name = "Make Parent";
935         ot->description = "Attach selected nodes";
936         ot->idname = "NODE_OT_parent_set";
937
938         /* api callbacks */
939         ot->exec = node_parent_set_exec;
940         ot->poll = ED_operator_node_editable;
941
942         /* flags */
943         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
944 }
945
946 /* ****************** Clear Parent ******************* */
947
948 static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
949 {
950         SpaceNode *snode = CTX_wm_space_node(C);
951         bNodeTree *ntree = snode->edittree;
952         bNode *node;
953
954         for (node = ntree->nodes.first; node; node = node->next) {
955                 if (node->flag & NODE_SELECT) {
956                         nodeDetachNode(node);
957                 }
958         }
959
960         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
961
962         return OPERATOR_FINISHED;
963 }
964
965 void NODE_OT_parent_clear(wmOperatorType *ot)
966 {
967         /* identifiers */
968         ot->name = "Clear Parent";
969         ot->description = "Detach selected nodes";
970         ot->idname = "NODE_OT_parent_clear";
971
972         /* api callbacks */
973         ot->exec = node_parent_clear_exec;
974         ot->poll = ED_operator_node_editable;
975
976         /* flags */
977         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
978 }
979
980 /* ****************** Join Nodes ******************* */
981
982 /* tags for depth-first search */
983 #define NODE_JOIN_DONE          1
984 #define NODE_JOIN_IS_DESCENDANT 2
985
986 static void node_join_attach_recursive(bNode *node, bNode *frame)
987 {
988         node->done |= NODE_JOIN_DONE;
989
990         if (node == frame) {
991                 node->done |= NODE_JOIN_IS_DESCENDANT;
992         }
993         else if (node->parent) {
994                 /* call recursively */
995                 if (!(node->parent->done & NODE_JOIN_DONE))
996                         node_join_attach_recursive(node->parent, frame);
997
998                 /* in any case: if the parent is a descendant, so is the child */
999                 if (node->parent->done & NODE_JOIN_IS_DESCENDANT)
1000                         node->done |= NODE_JOIN_IS_DESCENDANT;
1001                 else if (node->flag & NODE_TEST) {
1002                         /* if parent is not an decendant of the frame, reattach the node */
1003                         nodeDetachNode(node);
1004                         nodeAttachNode(node, frame);
1005                         node->done |= NODE_JOIN_IS_DESCENDANT;
1006                 }
1007         }
1008         else if (node->flag & NODE_TEST) {
1009                 nodeAttachNode(node, frame);
1010                 node->done |= NODE_JOIN_IS_DESCENDANT;
1011         }
1012 }
1013
1014 static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
1015 {
1016         SpaceNode *snode = CTX_wm_space_node(C);
1017         bNodeTree *ntree = snode->edittree;
1018         bNode *node, *frame;
1019
1020         /* XXX save selection: node_add_node call below sets the new frame as single active+selected node */
1021         for (node = ntree->nodes.first; node; node = node->next) {
1022                 if (node->flag & NODE_SELECT)
1023                         node->flag |= NODE_TEST;
1024                 else
1025                         node->flag &= ~NODE_TEST;
1026         }
1027
1028         frame = node_add_node(C, NULL, NODE_FRAME, 0.0f, 0.0f);
1029
1030         /* reset tags */
1031         for (node = ntree->nodes.first; node; node = node->next)
1032                 node->done = 0;
1033
1034         for (node = ntree->nodes.first; node; node = node->next) {
1035                 if (!(node->done & NODE_JOIN_DONE))
1036                         node_join_attach_recursive(node, frame);
1037         }
1038
1039         /* restore selection */
1040         for (node = ntree->nodes.first; node; node = node->next) {
1041                 if (node->flag & NODE_TEST)
1042                         node->flag |= NODE_SELECT;
1043         }
1044
1045         ED_node_sort(ntree);
1046         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1047
1048         return OPERATOR_FINISHED;
1049 }
1050
1051 void NODE_OT_join(wmOperatorType *ot)
1052 {
1053         /* identifiers */
1054         ot->name = "Join Nodes";
1055         ot->description = "Attach selected nodes to a new common frame";
1056         ot->idname = "NODE_OT_join";
1057
1058         /* api callbacks */
1059         ot->exec = node_join_exec;
1060         ot->poll = ED_operator_node_editable;
1061
1062         /* flags */
1063         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1064 }
1065
1066 /* ****************** Attach ******************* */
1067
1068 static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
1069 {
1070         SpaceNode *snode = CTX_wm_space_node(C);
1071         bNodeTree *ntree = snode->edittree;
1072         bNode *frame;
1073
1074         /* check nodes front to back */
1075         for (frame = ntree->nodes.last; frame; frame = frame->prev) {
1076                 /* skip selected, those are the nodes we want to attach */
1077                 if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT))
1078                         continue;
1079                 if (BLI_rctf_isect_pt(&frame->totr, snode->cursor[0], snode->cursor[1]))
1080                         break;
1081         }
1082         if (frame) {
1083                 bNode *node, *parent;
1084                 for (node = ntree->nodes.last; node; node = node->prev) {
1085                         if (node->flag & NODE_SELECT) {
1086                                 if (node->parent == NULL) {
1087                                         /* disallow moving a parent into its child */
1088                                         if (nodeAttachNodeCheck(frame, node) == FALSE) {
1089                                                 /* attach all unparented nodes */
1090                                                 nodeAttachNode(node, frame);
1091                                         }
1092                                 }
1093                                 else {
1094                                         /* attach nodes which share parent with the frame */
1095                                         for (parent = frame->parent; parent; parent = parent->parent) {
1096                                                 if (parent == node->parent) {
1097                                                         break;
1098                                                 }
1099                                         }
1100
1101                                         if (parent) {
1102                                                 /* disallow moving a parent into its child */
1103                                                 if (nodeAttachNodeCheck(frame, node) == FALSE) {
1104                                                         nodeDetachNode(node);
1105                                                         nodeAttachNode(node, frame);
1106                                                 }
1107                                         }
1108                                 }
1109                         }
1110                 }
1111         }
1112
1113         ED_node_sort(ntree);
1114         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1115
1116         return OPERATOR_FINISHED;
1117 }
1118
1119 static int node_attach_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1120 {
1121         ARegion *ar = CTX_wm_region(C);
1122         SpaceNode *snode = CTX_wm_space_node(C);
1123
1124         /* convert mouse coordinates to v2d space */
1125         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
1126
1127         return node_attach_exec(C, op);
1128 }
1129
1130 void NODE_OT_attach(wmOperatorType *ot)
1131 {
1132         /* identifiers */
1133         ot->name = "Attach Nodes";
1134         ot->description = "Attach active node to a frame";
1135         ot->idname = "NODE_OT_attach";
1136
1137         /* api callbacks */
1138         ot->exec = node_attach_exec;
1139         ot->invoke = node_attach_invoke;
1140         ot->poll = ED_operator_node_editable;
1141
1142         /* flags */
1143         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1144 }
1145
1146 /* ****************** Detach ******************* */
1147
1148 /* tags for depth-first search */
1149 #define NODE_DETACH_DONE            1
1150 #define NODE_DETACH_IS_DESCENDANT   2
1151
1152 static void node_detach_recursive(bNode *node)
1153 {
1154         node->done |= NODE_DETACH_DONE;
1155
1156         if (node->parent) {
1157                 /* call recursively */
1158                 if (!(node->parent->done & NODE_DETACH_DONE))
1159                         node_detach_recursive(node->parent);
1160
1161                 /* in any case: if the parent is a descendant, so is the child */
1162                 if (node->parent->done & NODE_DETACH_IS_DESCENDANT)
1163                         node->done |= NODE_DETACH_IS_DESCENDANT;
1164                 else if (node->flag & NODE_SELECT) {
1165                         /* if parent is not a decendant of a selected node, detach */
1166                         nodeDetachNode(node);
1167                         node->done |= NODE_DETACH_IS_DESCENDANT;
1168                 }
1169         }
1170         else if (node->flag & NODE_SELECT) {
1171                 node->done |= NODE_DETACH_IS_DESCENDANT;
1172         }
1173 }
1174
1175
1176 /* detach the root nodes in the current selection */
1177 static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
1178 {
1179         SpaceNode *snode = CTX_wm_space_node(C);
1180         bNodeTree *ntree = snode->edittree;
1181         bNode *node;
1182
1183         /* reset tags */
1184         for (node = ntree->nodes.first; node; node = node->next)
1185                 node->done = 0;
1186         /* detach nodes recursively
1187          * relative order is preserved here!
1188          */
1189         for (node = ntree->nodes.first; node; node = node->next) {
1190                 if (!(node->done & NODE_DETACH_DONE))
1191                         node_detach_recursive(node);
1192         }
1193
1194         ED_node_sort(ntree);
1195         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1196
1197         return OPERATOR_FINISHED;
1198 }
1199
1200 void NODE_OT_detach(wmOperatorType *ot)
1201 {
1202         /* identifiers */
1203         ot->name = "Detach Nodes";
1204         ot->description = "Detach selected nodes from parents";
1205         ot->idname = "NODE_OT_detach";
1206
1207         /* api callbacks */
1208         ot->exec = node_detach_exec;
1209         ot->poll = ED_operator_node_editable;
1210
1211         /* flags */
1212         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1213 }
1214
1215 /* *********************  automatic node insert on dragging ******************* */
1216
1217
1218 /* prevent duplicate testing code below */
1219 static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select)
1220 {
1221         SpaceNode *snode = sa ? sa->spacedata.first : NULL;
1222         bNode *node;
1223         bNodeLink *link;
1224
1225         /* no unlucky accidents */
1226         if (sa == NULL || sa->spacetype != SPACE_NODE) return NULL;
1227
1228         *select = NULL;
1229
1230         for (node = snode->edittree->nodes.first; node; node = node->next) {
1231                 if (node->flag & SELECT) {
1232                         if (*select)
1233                                 break;
1234                         else
1235                                 *select = node;
1236                 }
1237         }
1238         /* only one selected */
1239         if (node || *select == NULL) return NULL;
1240
1241         /* correct node */
1242         if ((*select)->inputs.first == NULL || (*select)->outputs.first == NULL) return NULL;
1243
1244         /* test node for links */
1245         for (link = snode->edittree->links.first; link; link = link->next) {
1246                 if (nodeLinkIsHidden(link))
1247                         continue;
1248                 
1249                 if (link->tonode == *select || link->fromnode == *select)
1250                         return NULL;
1251         }
1252
1253         return snode;
1254 }
1255
1256 /* test == 0, clear all intersect flags */
1257 void ED_node_link_intersect_test(ScrArea *sa, int test)
1258 {
1259         bNode *select;
1260         SpaceNode *snode = ed_node_link_conditions(sa, &select);
1261         bNodeLink *link, *selink = NULL;
1262         float mcoords[6][2];
1263
1264         if (snode == NULL) return;
1265
1266         /* clear flags */
1267         for (link = snode->edittree->links.first; link; link = link->next)
1268                 link->flag &= ~NODE_LINKFLAG_HILITE;
1269
1270         if (test == 0) return;
1271
1272         /* okay, there's 1 node, without links, now intersect */
1273         mcoords[0][0] = select->totr.xmin;
1274         mcoords[0][1] = select->totr.ymin;
1275         mcoords[1][0] = select->totr.xmax;
1276         mcoords[1][1] = select->totr.ymin;
1277         mcoords[2][0] = select->totr.xmax;
1278         mcoords[2][1] = select->totr.ymax;
1279         mcoords[3][0] = select->totr.xmin;
1280         mcoords[3][1] = select->totr.ymax;
1281         mcoords[4][0] = select->totr.xmin;
1282         mcoords[4][1] = select->totr.ymin;
1283         mcoords[5][0] = select->totr.xmax;
1284         mcoords[5][1] = select->totr.ymax;
1285
1286         /* we only tag a single link for intersect now */
1287         /* idea; use header dist when more? */
1288         for (link = snode->edittree->links.first; link; link = link->next) {
1289                 if (nodeLinkIsHidden(link))
1290                         continue;
1291                 
1292                 if (cut_links_intersect(link, mcoords, 5)) { /* intersect code wants edges */
1293                         if (selink)
1294                                 break;
1295                         selink = link;
1296                 }
1297         }
1298
1299         if (link == NULL && selink)
1300                 selink->flag |= NODE_LINKFLAG_HILITE;
1301 }
1302
1303 /* assumes sockets in list */
1304 static bNodeSocket *socket_best_match(ListBase *sockets)
1305 {
1306         bNodeSocket *sock;
1307         int type, maxtype = 0;
1308
1309         /* find type range */
1310         for (sock = sockets->first; sock; sock = sock->next)
1311                 maxtype = max_ii(sock->type, maxtype);
1312
1313         /* try all types, starting from 'highest' (i.e. colors, vectors, values) */
1314         for (type = maxtype; type >= 0; --type) {
1315                 for (sock = sockets->first; sock; sock = sock->next) {
1316                         if (!nodeSocketIsHidden(sock) && type == sock->type) {
1317                                 return sock;
1318                         }
1319                 }
1320         }
1321
1322         /* no visible sockets, unhide first of highest type */
1323         for (type = maxtype; type >= 0; --type) {
1324                 for (sock = sockets->first; sock; sock = sock->next) {
1325                         if (type == sock->type) {
1326                                 sock->flag &= ~SOCK_HIDDEN;
1327                                 return sock;
1328                         }
1329                 }
1330         }
1331
1332         return NULL;
1333 }
1334
1335 /* assumes link with NODE_LINKFLAG_HILITE set */
1336 void ED_node_link_insert(ScrArea *sa)
1337 {
1338         bNode *node, *select;
1339         SpaceNode *snode = ed_node_link_conditions(sa, &select);
1340         bNodeLink *link;
1341         bNodeSocket *sockto;
1342
1343         if (snode == NULL) return;
1344
1345         /* get the link */
1346         for (link = snode->edittree->links.first; link; link = link->next)
1347                 if (link->flag & NODE_LINKFLAG_HILITE)
1348                         break;
1349
1350         if (link) {
1351                 bNodeSocket *best_input = socket_best_match(&select->inputs);
1352                 bNodeSocket *best_output = socket_best_match(&select->outputs);
1353                 
1354                 if (best_input && best_output) {
1355                         node = link->tonode;
1356                         sockto = link->tosock;
1357                         
1358                         link->tonode = select;
1359                         link->tosock = best_input;
1360                         node_remove_extra_links(snode, link->tosock, link);
1361                         link->flag &= ~NODE_LINKFLAG_HILITE;
1362                         
1363                         nodeAddLink(snode->edittree, select, best_output, node, sockto);
1364                         
1365                         ntreeUpdateTree(G.main, snode->edittree);   /* needed for pointers */
1366                         snode_update(snode, select);
1367                         ED_node_tag_update_id(snode->id);
1368                 }
1369         }
1370 }