Merging r58475 through r58700 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / editors / space_node / node_add.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_add.c
29  *  \ingroup spnode
30  */
31
32 #include <errno.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "DNA_node_types.h"
37
38 #include "BLI_listbase.h"
39 #include "BLI_math.h"
40
41 #include "BLF_translation.h"
42
43 #include "BKE_context.h"
44 #include "BKE_image.h"
45 #include "BKE_library.h"
46 #include "BKE_main.h"
47 #include "BKE_node.h"
48 #include "BKE_report.h"
49
50 #include "ED_node.h"  /* own include */
51 #include "ED_screen.h"
52 #include "ED_render.h"
53
54 #include "RNA_access.h"
55 #include "RNA_define.h"
56 #include "RNA_enum_types.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #include "UI_view2d.h"
62
63 #include "node_intern.h"  /* own include */
64
65 /* XXX Does some additional initialization on top of nodeAddNode
66  * Can be used with both custom and static nodes, if idname==NULL the static int type will be used instead.
67  */
68 bNode *node_add_node(const bContext *C, const char *idname, int type, float locx, float locy)
69 {
70         SpaceNode *snode = CTX_wm_space_node(C);
71         Main *bmain = CTX_data_main(C);
72         bNode *node = NULL;
73         
74         node_deselect_all(snode);
75         
76         if (idname)
77                 node = nodeAddNode(C, snode->edittree, idname);
78         else
79                 node = nodeAddStaticNode(C, snode->edittree, type);
80         BLI_assert(node && node->typeinfo);
81         
82         /* generics */
83         node->locx = locx;
84         node->locy = locy + 60.0f;     /* arbitrary... so its visible, (0,0) is top of node */
85         nodeSetSelected(node, TRUE);
86         
87         /* node location is mapped */
88         locx /= UI_DPI_FAC;
89         locy /= UI_DPI_FAC;
90         
91         node->locx = locx;
92         node->locy = locy + 60.0f;
93         
94         ntreeUpdateTree(bmain, snode->edittree);
95         ED_node_set_active(bmain, snode->edittree, node);
96         
97         if (snode->flag & SNODE_USE_HIDDEN_PREVIEW)
98                 node->flag &= ~NODE_PREVIEW;
99         
100         snode_update(snode, node);
101         
102         if (snode->nodetree->type == NTREE_TEXTURE) {
103                 ntreeTexCheckCyclics(snode->edittree);
104         }
105         
106         return node;
107 }
108
109 /* ********************** Add reroute operator ***************** */
110 static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int tot, float result[2])
111 {
112         float coord_array[NODE_LINK_RESOL + 1][2];
113         int i, b;
114
115         if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
116
117                 for (i = 0; i < tot - 1; i++)
118                         for (b = 0; b < NODE_LINK_RESOL; b++)
119                                 if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
120                                         result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f;
121                                         result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f;
122                                         return 1;
123                                 }
124         }
125         return 0;
126 }
127
128 typedef struct bNodeSocketLink {
129         struct bNodeSocketLink *next, *prev;
130         
131         struct bNodeSocket *sock;
132         struct bNodeLink *link;
133         float point[2];
134 } bNodeSocketLink;
135
136 static bNodeSocketLink *add_reroute_insert_socket_link(ListBase *lb, bNodeSocket *sock, bNodeLink *link, const float point[2])
137 {
138         bNodeSocketLink *socklink, *prev;
139         
140         socklink = MEM_callocN(sizeof(bNodeSocketLink), "socket link");
141         socklink->sock = sock;
142         socklink->link = link;
143         copy_v2_v2(socklink->point, point);
144         
145         for (prev = lb->last; prev; prev = prev->prev) {
146                 if (prev->sock == sock)
147                         break;
148         }
149         BLI_insertlinkafter(lb, prev, socklink);
150         return socklink;
151 }
152
153 static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLink *socklink, int in_out)
154 {
155         SpaceNode *snode = CTX_wm_space_node(C);
156         bNodeTree *ntree = snode->edittree;
157         bNode *reroute_node = NULL;
158         bNodeSocket *cursock = socklink->sock;
159         float insert_point[2];
160         int num_links;
161         
162         zero_v2(insert_point);
163         num_links = 0;
164         
165         while (socklink && socklink->sock == cursock) {
166                 if (!(socklink->link->flag & NODE_LINK_TEST)) {
167                         socklink->link->flag |= NODE_LINK_TEST;
168                         
169                         /* create the reroute node for this cursock */
170                         if (!reroute_node) {
171                                 reroute_node = nodeAddStaticNode(C, ntree, NODE_REROUTE);
172                                 
173                                 /* add a single link to/from the reroute node to replace multiple links */
174                                 if (in_out == SOCK_OUT) {
175                                         nodeAddLink(ntree, socklink->link->fromnode, socklink->link->fromsock, reroute_node, reroute_node->inputs.first);
176                                 }
177                                 else {
178                                         nodeAddLink(ntree, reroute_node, reroute_node->outputs.first, socklink->link->tonode, socklink->link->tosock);
179                                 }
180                         }
181                         
182                         /* insert the reroute node into the link */
183                         if (in_out == SOCK_OUT) {
184                                 socklink->link->fromnode = reroute_node;
185                                 socklink->link->fromsock = reroute_node->outputs.first;
186                         }
187                         else {
188                                 socklink->link->tonode = reroute_node;
189                                 socklink->link->tosock = reroute_node->inputs.first;
190                         }
191                         
192                         add_v2_v2(insert_point, socklink->point);
193                         num_links++;
194                 }
195                 socklink = socklink->next;
196         }
197         
198         if (num_links > 0) {
199                 /* average cut point from shared links */
200                 mul_v2_fl(insert_point, 1.0f / num_links);
201                 
202                 reroute_node->locx = insert_point[0];
203                 reroute_node->locy = insert_point[1];
204         }
205         
206         return socklink;
207 }
208
209 static int add_reroute_exec(bContext *C, wmOperator *op)
210 {
211         SpaceNode *snode = CTX_wm_space_node(C);
212         ARegion *ar = CTX_wm_region(C);
213         bNodeTree *ntree = snode->edittree;
214         float mcoords[256][2];
215         int i = 0;
216         
217         /* Get the cut path */
218         RNA_BEGIN(op->ptr, itemptr, "path")
219         {
220                 float loc[2];
221
222                 RNA_float_get_array(&itemptr, "loc", loc);
223                 UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1],
224                                          &mcoords[i][0], &mcoords[i][1]);
225                 i++;
226                 if (i >= 256) break;
227         }
228         RNA_END;
229
230         if (i > 1) {
231                 ListBase output_links, input_links;
232                 bNodeLink *link;
233                 bNodeSocketLink *socklink;
234                 float insert_point[2];
235                 
236                 /* always first */
237                 ED_preview_kill_jobs(C);
238                 
239                 node_deselect_all(snode);
240                 
241                 /* Find cut links and sort them by sockets */
242                 output_links.first = output_links.last = NULL;
243                 input_links.first = input_links.last = NULL;
244                 for (link = ntree->links.first; link; link = link->next) {
245                         if (nodeLinkIsHidden(link))
246                                 continue;
247                         if (add_reroute_intersect_check(link, mcoords, i, insert_point)) {
248                                 add_reroute_insert_socket_link(&output_links, link->fromsock, link, insert_point);
249                                 add_reroute_insert_socket_link(&input_links, link->tosock, link, insert_point);
250                                 
251                                 /* Clear flag */
252                                 link->flag &= ~NODE_LINK_TEST;
253                         }
254                 }
255                 
256                 /* Create reroute nodes for intersected links.
257                  * Only one reroute if links share the same input/output socket.
258                  */
259                 socklink = output_links.first;
260                 while (socklink) {
261                         socklink = add_reroute_do_socket_section(C, socklink, SOCK_OUT);
262                 }
263                 socklink = input_links.first;
264                 while (socklink) {
265                         socklink = add_reroute_do_socket_section(C, socklink, SOCK_IN);
266                 }
267                 
268                 BLI_freelistN(&output_links);
269                 BLI_freelistN(&input_links);
270                 
271                 /* always last */
272                 ntreeUpdateTree(CTX_data_main(C), ntree);
273                 snode_notify(C, snode);
274                 snode_dag_update(C, snode);
275                 
276                 return OPERATOR_FINISHED;
277         }
278         
279         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
280 }
281
282 void NODE_OT_add_reroute(wmOperatorType *ot)
283 {
284         PropertyRNA *prop;
285
286         ot->name = "Add Reroute";
287         ot->idname = "NODE_OT_add_reroute";
288         ot->description = "Add a reroute node";
289
290         ot->invoke = WM_gesture_lines_invoke;
291         ot->modal = WM_gesture_lines_modal;
292         ot->exec = add_reroute_exec;
293         ot->cancel = WM_gesture_lines_cancel;
294
295         ot->poll = ED_operator_node_editable;
296
297         /* flags */
298         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
299
300         prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
301         RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
302         /* internal */
303         RNA_def_int(ot->srna, "cursor", BC_CROSSCURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
304 }
305
306
307 /* ****************** Add File Node Operator  ******************* */
308
309 static int node_add_file_exec(bContext *C, wmOperator *op)
310 {
311         SpaceNode *snode = CTX_wm_space_node(C);
312         bNode *node;
313         Image *ima = NULL;
314         int type = 0;
315
316         /* check input variables */
317         if (RNA_struct_property_is_set(op->ptr, "filepath")) {
318                 char path[FILE_MAX];
319                 RNA_string_get(op->ptr, "filepath", path);
320
321                 errno = 0;
322
323                 ima = BKE_image_load_exists(path);
324
325                 if (!ima) {
326                         BKE_reportf(op->reports, RPT_ERROR, "Cannot read image '%s': %s",
327                                     path, errno ? strerror(errno) : TIP_("unsupported format"));
328                         return OPERATOR_CANCELLED;
329                 }
330         }
331         else if (RNA_struct_property_is_set(op->ptr, "name")) {
332                 char name[MAX_ID_NAME - 2];
333                 RNA_string_get(op->ptr, "name", name);
334                 ima = (Image *)BKE_libblock_find_name(ID_IM, name);
335
336                 if (!ima) {
337                         BKE_reportf(op->reports, RPT_ERROR, "Image '%s' not found", name);
338                         return OPERATOR_CANCELLED;
339                 }
340         }
341
342         switch (snode->nodetree->type) {
343                 case NTREE_SHADER:
344                         type = SH_NODE_TEX_IMAGE;
345                         break;
346                 case NTREE_TEXTURE:
347                         type = TEX_NODE_IMAGE;
348                         break;
349                 case NTREE_COMPOSIT:
350                         type = CMP_NODE_IMAGE;
351                         break;
352                 default:
353                         return OPERATOR_CANCELLED;
354         }
355         
356         ED_preview_kill_jobs(C);
357         
358         node = node_add_node(C, NULL, type, snode->cursor[0], snode->cursor[1]);
359         
360         if (!node) {
361                 BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
362                 return OPERATOR_CANCELLED;
363         }
364         
365         node->id = (ID *)ima;
366         
367         BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
368         WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
369
370         snode_notify(C, snode);
371         snode_dag_update(C, snode);
372         
373         return OPERATOR_FINISHED;
374 }
375
376 static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *event)
377 {
378         ARegion *ar = CTX_wm_region(C);
379         SpaceNode *snode = CTX_wm_space_node(C);
380         
381         /* convert mouse coordinates to v2d space */
382         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
383                                  &snode->cursor[0], &snode->cursor[1]);
384         
385         if (RNA_struct_property_is_set(op->ptr, "filepath") || RNA_struct_property_is_set(op->ptr, "name"))
386                 return node_add_file_exec(C, op);
387         else
388                 return WM_operator_filesel(C, op, event);
389 }
390
391 void NODE_OT_add_file(wmOperatorType *ot)
392 {
393         /* identifiers */
394         ot->name = "Add File Node";
395         ot->description = "Add a file node to the current node editor";
396         ot->idname = "NODE_OT_add_file";
397
398         /* callbacks */
399         ot->exec = node_add_file_exec;
400         ot->invoke = node_add_file_invoke;
401         ot->poll = ED_operator_node_editable;
402
403         /* flags */
404         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
405
406         WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE,
407                                        WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);  //XXX TODO, relative_path
408         RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign");
409 }
410
411 /* ****************** Add Mask Node Operator  ******************* */
412
413 static int node_add_mask_poll(bContext *C)
414 {
415         SpaceNode *snode = CTX_wm_space_node(C);
416
417         return ED_operator_node_editable(C) && snode->nodetree->type == NTREE_COMPOSIT;
418 }
419
420 static int node_add_mask_invoke(bContext *C, wmOperator *op, const wmEvent *event)
421 {
422         ARegion *ar = CTX_wm_region(C);
423         SpaceNode *snode = CTX_wm_space_node(C);
424         bNode *node;
425         ID *mask = NULL;
426
427         /* check input variables */
428         char name[MAX_ID_NAME - 2];
429         RNA_string_get(op->ptr, "name", name);
430         mask = BKE_libblock_find_name(ID_MSK, name);
431         if (!mask) {
432                 BKE_reportf(op->reports, RPT_ERROR, "Mask '%s' not found", name);
433                 return OPERATOR_CANCELLED;
434         }
435
436         ED_preview_kill_jobs(C);
437
438         /* convert mouse coordinates to v2d space */
439         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
440                                                          &snode->cursor[0], &snode->cursor[1]);
441         node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]);
442
443         if (!node) {
444                 BKE_report(op->reports, RPT_WARNING, "Could not add a mask node");
445                 return OPERATOR_CANCELLED;
446         }
447
448         node->id = mask;
449         id_us_plus(mask);
450
451         snode_notify(C, snode);
452         snode_dag_update(C, snode);
453
454         return OPERATOR_FINISHED;
455 }
456
457 void NODE_OT_add_mask(wmOperatorType *ot)
458 {
459         /* identifiers */
460         ot->name = "Add Mask Node";
461         ot->description = "Add a mask node to the current node editor";
462         ot->idname = "NODE_OT_add_mask";
463
464         /* callbacks */
465         ot->invoke = node_add_mask_invoke;
466         ot->poll = node_add_mask_poll;
467
468         /* flags */
469         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
470
471         RNA_def_string(ot->srna, "name", "Mask", MAX_ID_NAME - 2, "Name", "Datablock name to assign");
472 }
473
474 /********************** New node tree operator *********************/
475
476 static int new_node_tree_exec(bContext *C, wmOperator *op)
477 {
478         SpaceNode *snode = CTX_wm_space_node(C);
479         Main *bmain = CTX_data_main(C);
480         bNodeTree *ntree;
481         PointerRNA ptr, idptr;
482         PropertyRNA *prop;
483         const char *idname;
484         char _treename[MAX_ID_NAME - 2];
485         char *treename = _treename;
486         
487         if (RNA_struct_property_is_set(op->ptr, "type")) {
488                 prop = RNA_struct_find_property(op->ptr, "type");
489                 RNA_property_enum_identifier(C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &idname);
490         }
491         else if (snode)
492                 idname = snode->tree_idname;
493         else
494                 return OPERATOR_CANCELLED;
495         
496         if (RNA_struct_property_is_set(op->ptr, "name")) {
497                 RNA_string_get(op->ptr, "name", treename);
498         }
499         else {
500                 treename = (char *)DATA_("NodeTree");
501         }
502         
503         if (!ntreeTypeFind(idname)) {
504                 BKE_reportf(op->reports, RPT_ERROR, "Node tree type %s undefined", idname);
505                 return OPERATOR_CANCELLED;
506         }
507         
508         ntree = ntreeAddTree(bmain, treename, idname);
509         
510         /* hook into UI */
511         uiIDContextProperty(C, &ptr, &prop);
512
513         if (prop) {
514                 /* RNA_property_pointer_set increases the user count,
515                  * fixed here as the editor is the initial user.
516                  */
517                 ntree->id.us--;
518
519                 RNA_id_pointer_create(&ntree->id, &idptr);
520                 RNA_property_pointer_set(&ptr, prop, idptr);
521                 RNA_property_update(C, &ptr, prop);
522         }
523         else if (snode) {
524                 snode->nodetree = ntree;
525                 
526                 ED_node_tree_update(C);
527         }
528         
529         return OPERATOR_FINISHED;
530 }
531
532 static EnumPropertyItem *new_node_tree_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
533 {
534         return rna_node_tree_type_itemf(NULL, NULL, free);
535 }
536
537 void NODE_OT_new_node_tree(wmOperatorType *ot)
538 {
539         PropertyRNA *prop;
540         
541         /* identifiers */
542         ot->name = "New Node Tree";
543         ot->idname = "NODE_OT_new_node_tree";
544         ot->description = "Create a new node tree";
545         
546         /* api callbacks */
547         ot->exec = new_node_tree_exec;
548         
549         /* flags */
550         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
551         
552         prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Tree Type", "");
553         RNA_def_enum_funcs(prop, new_node_tree_type_itemf);
554         RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME - 2, "Name", "");
555 }
556