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