Merging r49463 through r49478 from trunk into soc-2011-tomato
[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_relationships.c
29  *  \ingroup spnode
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <math.h>
35 #include <string.h>
36 #include <errno.h>
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_ID.h"
41 #include "DNA_lamp_types.h"
42 #include "DNA_material_types.h"
43 #include "DNA_node_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_particle_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_world_types.h"
48 #include "DNA_action_types.h"
49 #include "DNA_anim_types.h"
50
51 #include "BLI_math.h"
52 #include "BLI_blenlib.h"
53 #include "BLI_utildefines.h"
54
55 #include "BKE_action.h"
56 #include "BKE_animsys.h"
57 #include "BKE_context.h"
58 #include "BKE_depsgraph.h"
59 #include "BKE_global.h"
60 #include "BKE_image.h"
61 #include "BKE_library.h"
62 #include "BKE_main.h"
63 #include "BKE_node.h"
64 #include "BKE_material.h"
65 #include "BKE_modifier.h"
66 #include "BKE_paint.h"
67 #include "BKE_scene.h"
68 #include "BKE_screen.h"
69 #include "BKE_texture.h"
70 #include "BKE_report.h"
71
72 #include "RE_pipeline.h"
73
74 #include "IMB_imbuf_types.h"
75
76 #include "ED_node.h"
77 #include "ED_image.h"
78 #include "ED_screen.h"
79 #include "ED_space_api.h"
80 #include "ED_render.h"
81
82 #include "RNA_access.h"
83 #include "RNA_define.h"
84 #include "RNA_enum_types.h"
85
86 #include "WM_api.h"
87 #include "WM_types.h"
88
89 #include "UI_interface.h"
90 #include "UI_resources.h"
91 #include "UI_view2d.h"
92
93 #include "IMB_imbuf.h"
94
95 #include "RNA_enum_types.h"
96
97 #include "GPU_material.h"
98
99 #include "node_intern.h"
100 #include "NOD_socket.h"
101
102
103 /* can be called from menus too, but they should do own undopush and redraws */
104 bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene,
105                      bNodeTemplate *ntemp, float locx, float locy)
106 {
107         bNode *node = NULL, *gnode;
108
109         node_deselect_all(snode);
110
111         node = nodeAddNode(snode->edittree, ntemp);
112
113         /* generics */
114         if (node) {
115                 node_select(node);
116
117                 gnode = node_tree_get_editgroup(snode->nodetree);
118                 // arbitrary y offset of 60 so its visible
119                 if (gnode) {
120                         nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy);
121                 }
122                 else {
123                         node->locx = locx;
124                         node->locy = locy + 60.0f;
125                 }
126
127                 ntreeUpdateTree(snode->edittree);
128                 ED_node_set_active(bmain, snode->edittree, node);
129
130                 if (snode->nodetree->type == NTREE_COMPOSIT) {
131                         if (ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) {
132                                 node->id = &scene->id;
133                         }
134                         else if (ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) {
135                                 node->id = (ID *)scene->clip;
136                         }
137
138                         ntreeCompositForceHidden(snode->edittree, scene);
139                 }
140
141                 if (node->id)
142                         id_us_plus(node->id);
143
144
145                 if (snode->flag & SNODE_USE_HIDDEN_PREVIEW)
146                         node->flag &= ~NODE_PREVIEW;
147
148                 snode_update(snode, node);
149         }
150
151         if (snode->nodetree->type == NTREE_TEXTURE) {
152                 ntreeTexCheckCyclics(snode->edittree);
153         }
154
155         return node;
156 }
157
158 /* ********************** Add reroute operator ***************** */
159 static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int tot, float result[2])
160 {
161         float coord_array[NODE_LINK_RESOL + 1][2];
162         int i, b;
163
164         if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
165
166                 for (i = 0; i < tot - 1; i++)
167                         for (b = 0; b < NODE_LINK_RESOL; b++)
168                                 if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
169                                         result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f;
170                                         result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f;
171                                         return 1;
172                                 }
173         }
174         return 0;
175 }
176
177 static int add_reroute_exec(bContext *C, wmOperator *op)
178 {
179         SpaceNode *snode = CTX_wm_space_node(C);
180         ARegion *ar = CTX_wm_region(C);
181         bNode *gnode = node_tree_get_editgroup(snode->nodetree);
182         float mcoords[256][2];
183         int i = 0;
184
185         RNA_BEGIN(op->ptr, itemptr, "path")
186         {
187                 float loc[2];
188
189                 RNA_float_get_array(&itemptr, "loc", loc);
190                 UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1],
191                                          &mcoords[i][0], &mcoords[i][1]);
192                 i++;
193                 if (i >= 256) break;
194         }
195         RNA_END;
196
197         if (i > 1) {
198                 bNodeLink *link;
199                 float insertPoint[2];
200
201                 ED_preview_kill_jobs(C);
202
203                 for (link = snode->edittree->links.first; link; link = link->next) {
204                         if (add_reroute_intersect_check(link, mcoords, i, insertPoint)) {
205                                 bNodeTemplate ntemp;
206                                 bNode *rerouteNode;
207
208                                 node_deselect_all(snode);
209
210                                 ntemp.type = NODE_REROUTE;
211                                 rerouteNode = nodeAddNode(snode->edittree, &ntemp);
212                                 if (gnode) {
213                                         nodeFromView(gnode, insertPoint[0], insertPoint[1], &rerouteNode->locx, &rerouteNode->locy);
214                                 }
215                                 else {
216                                         rerouteNode->locx = insertPoint[0];
217                                         rerouteNode->locy = insertPoint[1];
218                                 }
219
220                                 nodeAddLink(snode->edittree, link->fromnode, link->fromsock, rerouteNode, rerouteNode->inputs.first);
221                                 link->fromnode = rerouteNode;
222                                 link->fromsock = rerouteNode->outputs.first;
223
224                                 break; // add one reroute at the time.
225                         }
226                 }
227
228                 ntreeUpdateTree(snode->edittree);
229                 snode_notify(C, snode);
230                 snode_dag_update(C, snode);
231
232                 return OPERATOR_FINISHED;
233         }
234
235         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
236 }
237
238 void NODE_OT_add_reroute(wmOperatorType *ot)
239 {
240         PropertyRNA *prop;
241
242         ot->name = "Add reroute";
243         ot->idname = "NODE_OT_add_reroute";
244
245         ot->invoke = WM_gesture_lines_invoke;
246         ot->modal = WM_gesture_lines_modal;
247         ot->exec = add_reroute_exec;
248         ot->cancel = WM_gesture_lines_cancel;
249
250         ot->poll = ED_operator_node_active;
251
252         /* flags */
253         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
254
255         prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
256         RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
257         /* internal */
258         RNA_def_int(ot->srna, "cursor", BC_CROSSCURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
259 }
260
261
262 /* ****************** Add File Node Operator  ******************* */
263
264 static int node_add_file_exec(bContext *C, wmOperator *op)
265 {
266         Main *bmain = CTX_data_main(C);
267         Scene *scene = CTX_data_scene(C);
268         SpaceNode *snode = CTX_wm_space_node(C);
269         bNode *node;
270         Image *ima = NULL;
271         bNodeTemplate ntemp;
272
273         /* check input variables */
274         if (RNA_struct_property_is_set(op->ptr, "filepath")) {
275                 char path[FILE_MAX];
276                 RNA_string_get(op->ptr, "filepath", path);
277
278                 errno = 0;
279
280                 ima = BKE_image_load_exists(path);
281
282                 if (!ima) {
283                         BKE_reportf(op->reports, RPT_ERROR, "Can't read image: \"%s\", %s", path, errno ? strerror(errno) : "Unsupported format");
284                         return OPERATOR_CANCELLED;
285                 }
286         }
287         else if (RNA_struct_property_is_set(op->ptr, "name")) {
288                 char name[MAX_ID_NAME - 2];
289                 RNA_string_get(op->ptr, "name", name);
290                 ima = (Image *)BKE_libblock_find_name(ID_IM, name);
291
292                 if (!ima) {
293                         BKE_reportf(op->reports, RPT_ERROR, "Image named \"%s\", not found", name);
294                         return OPERATOR_CANCELLED;
295                 }
296         }
297
298         node_deselect_all(snode);
299
300         switch (snode->nodetree->type) {
301                 case NTREE_SHADER:
302                         ntemp.type = SH_NODE_TEX_IMAGE;
303                         break;
304                 case NTREE_TEXTURE:
305                         ntemp.type = TEX_NODE_IMAGE;
306                         break;
307                 case NTREE_COMPOSIT:
308                         ntemp.type = CMP_NODE_IMAGE;
309                         break;
310                 default:
311                         return OPERATOR_CANCELLED;
312         }
313
314         ED_preview_kill_jobs(C);
315
316         node = node_add_node(snode, bmain, scene, &ntemp, snode->mx, snode->my);
317
318         if (!node) {
319                 BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
320                 return OPERATOR_CANCELLED;
321         }
322
323         node->id = (ID *)ima;
324         id_us_plus(node->id);
325
326         snode_notify(C, snode);
327         snode_dag_update(C, snode);
328
329         return OPERATOR_FINISHED;
330 }
331
332 static int node_add_file_invoke(bContext *C, wmOperator *op, wmEvent *event)
333 {
334         ARegion *ar = CTX_wm_region(C);
335         SpaceNode *snode = CTX_wm_space_node(C);
336
337         /* convert mouse coordinates to v2d space */
338         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
339                                  &snode->mx, &snode->my);
340
341         if (RNA_struct_property_is_set(op->ptr, "filepath") || RNA_struct_property_is_set(op->ptr, "name"))
342                 return node_add_file_exec(C, op);
343         else
344                 return WM_operator_filesel(C, op, event);
345 }
346
347 void NODE_OT_add_file(wmOperatorType *ot)
348 {
349         /* identifiers */
350         ot->name = "Add File Node";
351         ot->description = "Add a file node to the current node editor";
352         ot->idname = "NODE_OT_add_file";
353
354         /* callbacks */
355         ot->exec = node_add_file_exec;
356         ot->invoke = node_add_file_invoke;
357         ot->poll = ED_operator_node_active;
358
359         /* flags */
360         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
361
362         WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);  //XXX TODO, relative_path
363         RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign");
364 }
365
366
367 /********************** New node tree operator *********************/
368
369 static int new_node_tree_exec(bContext *C, wmOperator *op)
370 {
371         SpaceNode *snode;
372         bNodeTree *ntree;
373         PointerRNA ptr, idptr;
374         PropertyRNA *prop;
375         int treetype;
376         char treename[MAX_ID_NAME - 2] = "NodeTree";
377
378         /* retrieve state */
379         snode = CTX_wm_space_node(C);
380
381         if (RNA_struct_property_is_set(op->ptr, "type"))
382                 treetype = RNA_enum_get(op->ptr, "type");
383         else
384                 treetype = snode->treetype;
385
386         if (RNA_struct_property_is_set(op->ptr, "name"))
387                 RNA_string_get(op->ptr, "name", treename);
388
389         ntree = ntreeAddTree(treename, treetype, 0);
390         if (!ntree)
391                 return OPERATOR_CANCELLED;
392
393         /* hook into UI */
394         uiIDContextProperty(C, &ptr, &prop);
395
396         if (prop) {
397                 RNA_id_pointer_create(&ntree->id, &idptr);
398                 RNA_property_pointer_set(&ptr, prop, idptr);
399                 /* RNA_property_pointer_set increases the user count,
400                  * fixed here as the editor is the initial user.
401                  */
402                 --ntree->id.us;
403                 RNA_property_update(C, &ptr, prop);
404         }
405         else if (snode) {
406                 Scene *scene = CTX_data_scene(C);
407                 snode->nodetree = ntree;
408
409                 ED_node_tree_update(snode, scene);
410         }
411
412         return OPERATOR_FINISHED;
413 }
414
415 void NODE_OT_new_node_tree(wmOperatorType *ot)
416 {
417         /* identifiers */
418         ot->name = "New Node Tree";
419         ot->idname = "NODE_OT_new_node_tree";
420         ot->description = "Create a new node tree";
421
422         /* api callbacks */
423         ot->exec = new_node_tree_exec;
424         ot->poll = ED_operator_node_active;
425
426         /* flags */
427         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
428
429         RNA_def_enum(ot->srna, "type", nodetree_type_items, NTREE_COMPOSIT, "Tree Type", "");
430         RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME - 2, "Name", "");
431 }