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