doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / blender / editors / space_node / drawnode.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "BLI_blenlib.h"
35 #include "BLI_math.h"
36 #include "BLI_utildefines.h"
37
38 #include "DNA_node_types.h"
39 #include "DNA_material_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42 #include "DNA_space_types.h"
43 #include "DNA_screen_types.h"
44
45 #include "BKE_context.h"
46 #include "BKE_curve.h"
47 #include "BKE_global.h"
48 #include "BKE_image.h"
49 #include "BKE_library.h"
50 #include "BKE_main.h"
51
52 #include "CMP_node.h"
53 #include "SHD_node.h"
54
55 #include "BIF_gl.h"
56 #include "BIF_glutil.h"
57
58 #include "BLF_api.h"
59
60 #include "MEM_guardedalloc.h"
61
62
63 #include "RNA_access.h"
64
65 #include "ED_node.h"
66
67 #include "WM_api.h"
68 #include "WM_types.h"
69
70 #include "UI_interface.h"
71 #include "UI_resources.h"
72
73 #include "IMB_imbuf.h"
74 #include "IMB_imbuf_types.h"
75
76 #include "node_intern.h"
77
78
79 /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
80
81 static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
82 {
83         PointerRNA sockptr;
84         PropertyRNA *prop;
85         
86         /* first socket stores value */
87         prop = RNA_struct_find_property(ptr, "outputs");
88         RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
89         
90         uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NULL);
91 }
92
93 static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
94 {
95         uiLayout *col;
96         PointerRNA sockptr;
97         PropertyRNA *prop;
98         
99         /* first socket stores value */
100         prop = RNA_struct_find_property(ptr, "outputs");
101         RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
102         
103         col = uiLayoutColumn(layout, 0);
104         uiTemplateColorWheel(col, &sockptr, "default_value", 1, 0, 0, 0);
105         uiItemR(col, &sockptr, "default_value", 0, "", ICON_NULL);
106 }
107
108 static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
109 {       
110         uiLayout *row;
111
112         bNodeTree *ntree= (bNodeTree*)ptr->id.data;
113
114         row= uiLayoutRow(layout, 1);
115         uiItemR(row, ptr, "blend_type", 0, "", ICON_NULL);
116         if(ntree->type == NTREE_COMPOSIT)
117                 uiItemR(row, ptr, "use_alpha", 0, "", ICON_IMAGE_RGB_ALPHA);
118 }
119
120 static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
121 {
122         uiLayout *row;
123 #if 0
124         /* XXX no context access here .. */
125         bNode *node= ptr->data;
126         CurveMapping *cumap= node->storage;
127         
128         if(cumap) {
129                 cumap->flag |= CUMA_DRAW_CFRA;
130                 if(node->custom1<node->custom2)
131                         cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
132         }
133 #endif
134
135         uiTemplateCurveMapping(layout, ptr, "curve", 's', 0, 0);
136
137         row= uiLayoutRow(layout, 1);
138         uiItemR(row, ptr, "frame_start", 0, "Sta", ICON_NULL);
139         uiItemR(row, ptr, "frame_end", 0, "End", ICON_NULL);
140 }
141
142 static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
143 {
144         uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
145 }
146
147 static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
148 {
149         uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0, 0);
150 }
151
152 static float *_sample_col= NULL;        // bad bad, 2.5 will do better?
153 #if 0
154 static void node_curvemap_sample(float *col)
155 {
156         _sample_col= col;
157 }
158 #endif
159
160 static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
161 {
162         bNode *node= ptr->data;
163         CurveMapping *cumap= node->storage;
164
165         if(_sample_col) {
166                 cumap->flag |= CUMA_DRAW_SAMPLE;
167                 VECCOPY(cumap->sample, _sample_col);
168         }
169         else 
170                 cumap->flag &= ~CUMA_DRAW_SAMPLE;
171
172         uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0);
173 }
174
175 static void node_normal_cb(bContext *C, void *ntree_v, void *node_v)
176 {
177         Main *bmain = CTX_data_main(C);
178
179         ED_node_generic_update(bmain, ntree_v, node_v);
180         WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree_v);
181 }
182
183 static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
184 {
185         uiBlock *block= uiLayoutAbsoluteBlock(layout);
186         bNodeTree *ntree= ptr->id.data;
187         bNode *node= ptr->data;
188         rctf *butr= &node->butr;
189         bNodeSocket *sock= node->outputs.first;         /* first socket stores normal */
190         uiBut *bt;
191         
192         bt= uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", 
193                           (short)butr->xmin, (short)butr->xmin, butr->xmax-butr->xmin, butr->xmax-butr->xmin, 
194                           sock->ns.vec, 0.0f, 1.0f, 0, 0, "");
195         uiButSetFunc(bt, node_normal_cb, ntree, node);
196 }
197 #if 0 // not used in 2.5x yet
198 static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
199 {
200         Main *bmain= CTX_data_main(C);
201         bNodeTree *ntree= ntree_v;
202         bNode *node= node_v;
203         Tex *tex;
204         
205         if(node->menunr<1) return;
206         
207         if(node->id) {
208                 node->id->us--;
209                 node->id= NULL;
210         }
211         tex= BLI_findlink(&bmain->tex, node->menunr-1);
212
213         node->id= &tex->id;
214         id_us_plus(node->id);
215         BLI_strncpy(node->name, node->id->name+2, sizeof(node->name));
216         
217         nodeSetActive(ntree, node);
218         
219         if( ntree->type == NTREE_TEXTURE )
220                 ntreeTexCheckCyclics( ntree );
221         
222         // allqueue(REDRAWBUTSSHADING, 0);
223         // allqueue(REDRAWNODE, 0);
224         NodeTagChanged(ntree, node); 
225         
226         node->menunr= 0;
227 }
228 #endif
229 static void node_dynamic_update_cb(bContext *C, void *UNUSED(ntree_v), void *node_v)
230 {
231         Main *bmain= CTX_data_main(C);
232         Material *ma;
233         bNode *node= (bNode *)node_v;
234         ID *id= node->id;
235         int error= 0;
236
237         if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) error= 1;
238
239         /* Users only have to press the "update" button in one pynode
240          * and we also update all others sharing the same script */
241         for (ma= bmain->mat.first; ma; ma= ma->id.next) {
242                 if (ma->nodetree) {
243                         bNode *nd;
244                         for (nd= ma->nodetree->nodes.first; nd; nd= nd->next) {
245                                 if ((nd->type == NODE_DYNAMIC) && (nd->id == id)) {
246                                         nd->custom1= 0;
247                                         nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_REPARSE);
248                                         nd->menunr= 0;
249                                         if (error)
250                                                 nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_ERROR);
251                                 }
252                         }
253                 }
254         }
255
256         // allqueue(REDRAWBUTSSHADING, 0);
257         // allqueue(REDRAWNODE, 0);
258         // XXX BIF_preview_changed(ID_MA);
259 }
260
261 static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
262 {
263         bNode *node= ptr->data;
264
265         short multi = (
266                 node->id &&
267                 ((Tex*)node->id)->use_nodes &&
268                 (node->type != CMP_NODE_TEXTURE) &&
269                 (node->type != TEX_NODE_TEXTURE)
270         );
271         
272         uiItemR(layout, ptr, "texture", 0, "", ICON_NULL);
273         
274         if(multi) {
275                 /* Number Drawing not optimal here, better have a list*/
276                 uiItemR(layout, ptr, "node_output", 0, "", ICON_NULL);
277         }
278 }
279
280 static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
281
282         uiItemR(layout, ptr, "operation", 0, "", ICON_NULL);
283 }
284
285 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
286
287 static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v)
288 {
289         Main *bmain= CTX_data_main(C);
290         bNodeTree *ntree= ntree_v;
291         bNode *node= node_v;
292         ID *oldid;
293         
294         if(node->menunr<1) return;
295         
296         if(node->id) {
297                 node->id->us--;
298         }
299         oldid= node->id;
300         node->id= BLI_findlink(&bmain->text, node->menunr-1);
301         id_us_plus(node->id);
302         BLI_strncpy(node->name, node->id->name+2, sizeof(node->name));
303
304         node->custom1= BSET(node->custom1, NODE_DYNAMIC_NEW);
305         
306         nodeSetActive(ntree, node);
307
308         // allqueue(REDRAWBUTSSHADING, 0);
309         // allqueue(REDRAWNODE, 0);
310
311         node->menunr= 0;
312 }
313
314 static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
315 {
316         bNode *node= ptr->data;
317         uiLayout *col;
318         
319         uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL);
320         
321         if(!node->id) return;
322         
323         col= uiLayoutColumn(layout, 0);
324         uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NULL);
325         uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NULL);
326         uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NULL);
327 }
328
329 static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
330 {
331         uiLayout *row;
332         
333         uiItemL(layout, "Location:", ICON_NULL);
334         row= uiLayoutRow(layout, 1);
335         uiItemR(row, ptr, "location", 0, "", ICON_NULL);
336         
337         uiItemL(layout, "Rotation:", ICON_NULL);
338         row= uiLayoutRow(layout, 1);
339         uiItemR(row, ptr, "rotation", 0, "", ICON_NULL);
340         
341         uiItemL(layout, "Scale:", ICON_NULL);
342         row= uiLayoutRow(layout, 1);
343         uiItemR(row, ptr, "scale", 0, "", ICON_NULL);
344         
345         row= uiLayoutRow(layout, 1);
346         uiItemR(row, ptr, "use_min", 0, "Min", ICON_NULL);
347         uiItemR(row, ptr, "min", 0, "", ICON_NULL);
348         
349         row= uiLayoutRow(layout, 1);
350         uiItemR(row, ptr, "use_max", 0, "Max", ICON_NULL);
351         uiItemR(row, ptr, "max", 0, "", ICON_NULL);
352         
353 }
354
355 static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
356
357         uiItemR(layout, ptr, "operation", 0, "", ICON_NULL);
358 }
359
360 static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr)
361 {
362         PointerRNA obptr= CTX_data_pointer_get(C, "active_object");
363         uiLayout *col;
364
365         col= uiLayoutColumn(layout, 0);
366
367         if(obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
368                 PointerRNA dataptr= RNA_pointer_get(&obptr, "data");
369
370                 uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_textures", "", ICON_NULL);
371                 uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NULL);
372         }
373         else {
374                 uiItemR(col, ptr, "uv_layer", 0, "UV", ICON_NULL);
375                 uiItemR(col, ptr, "color_layer", 0, "VCol", ICON_NULL);
376         }
377 }
378
379 static void node_shader_buts_dynamic(uiLayout *layout, bContext *C, PointerRNA *ptr)
380
381         Main *bmain= CTX_data_main(C);
382         uiBlock *block= uiLayoutAbsoluteBlock(layout);
383         bNode *node= ptr->data;
384         bNodeTree *ntree= ptr->id.data;
385         rctf *butr= &node->butr;
386         uiBut *bt;
387         // XXX SpaceNode *snode= curarea->spacedata.first;
388         short dy= (short)butr->ymin;
389         int xoff=0;
390
391         /* B_NODE_EXEC is handled in butspace.c do_node_buts */
392         if(!node->id) {
393                         const char *strp;
394                         IDnames_to_pupstring(&strp, NULL, "", &(bmain->text), NULL, NULL);
395                         node->menunr= 0;
396                         bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp, 
397                                                         butr->xmin, dy, 19, 19, 
398                                                         &node->menunr, 0, 0, 0, 0, "Browses existing choices");
399                         uiButSetFunc(bt, node_browse_text_cb, ntree, node);
400                         xoff=19;
401                         if(strp) MEM_freeN((void *)strp);
402         }
403         else {
404                 bt = uiDefBut(block, BUT, B_NOP, "Update",
405                                 butr->xmin+xoff, butr->ymin+20, 50, 19,
406                                 &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)");
407                 uiButSetFunc(bt, node_dynamic_update_cb, ntree, node);
408
409                 if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
410                         // UI_ThemeColor(TH_REDALERT);
411                         // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect);
412                         // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin);
413                         ;
414                 }
415         }
416 }
417
418 /* only once called */
419 static void node_shader_set_butfunc(bNodeType *ntype)
420 {
421         switch(ntype->type) {
422                 /* case NODE_GROUP:      note, typeinfo for group is generated... see "XXX ugly hack" */
423
424                 case SH_NODE_MATERIAL:
425                 case SH_NODE_MATERIAL_EXT:
426                         ntype->uifunc= node_shader_buts_material;
427                         break;
428                 case SH_NODE_TEXTURE:
429                         ntype->uifunc= node_buts_texture;
430                         break;
431                 case SH_NODE_NORMAL:
432                         ntype->uifunc= node_buts_normal;
433                         break;
434                 case SH_NODE_CURVE_VEC:
435                         ntype->uifunc= node_buts_curvevec;
436                         break;
437                 case SH_NODE_CURVE_RGB:
438                         ntype->uifunc= node_buts_curvecol;
439                         break;
440                 case SH_NODE_MAPPING:
441                         ntype->uifunc= node_shader_buts_mapping;
442                         break;
443                 case SH_NODE_VALUE:
444                         ntype->uifunc= node_buts_value;
445                         break;
446                 case SH_NODE_RGB:
447                         ntype->uifunc= node_buts_rgb;
448                         break;
449                 case SH_NODE_MIX_RGB:
450                         ntype->uifunc= node_buts_mix_rgb;
451                         break;
452                 case SH_NODE_VALTORGB:
453                         ntype->uifunc= node_buts_colorramp;
454                         break;
455                 case SH_NODE_MATH: 
456                         ntype->uifunc= node_buts_math;
457                         break; 
458                 case SH_NODE_VECT_MATH: 
459                         ntype->uifunc= node_shader_buts_vect_math;
460                         break; 
461                 case SH_NODE_GEOMETRY:
462                         ntype->uifunc= node_shader_buts_geometry;
463                         break;
464                 case NODE_DYNAMIC:
465                         ntype->uifunc= node_shader_buts_dynamic;
466                         break;
467                 default:
468                         ntype->uifunc= NULL;
469         }
470 }
471
472 /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
473
474 static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
475 {
476         uiLayout *col;
477         bNode *node= ptr->data;
478         PointerRNA imaptr;
479         PropertyRNA *prop;
480         
481         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
482         
483         if(!node->id) return;
484         
485         prop = RNA_struct_find_property(ptr, "image");
486         if (!prop || RNA_property_type(prop) != PROP_POINTER) return;
487         imaptr= RNA_property_pointer_get(ptr, prop);
488         
489         col= uiLayoutColumn(layout, 0);
490         
491         uiItemR(col, &imaptr, "source", 0, NULL, ICON_NULL);
492         
493         if (ELEM(RNA_enum_get(&imaptr, "source"), IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
494                 col= uiLayoutColumn(layout, 1);
495                 uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NULL);
496                 uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NULL);
497                 uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NULL);
498                 uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NULL);
499                 uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NULL);
500         }
501
502         col= uiLayoutColumn(layout, 0);
503         
504         if (RNA_enum_get(&imaptr, "type")== IMA_TYPE_MULTILAYER)
505                 uiItemR(col, ptr, "layer", 0, NULL, ICON_NULL);
506 }
507
508 static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
509 {
510         bNode *node= ptr->data;
511         uiLayout *col, *row;
512         PointerRNA op_ptr;
513         PointerRNA scn_ptr;
514         PropertyRNA *prop;
515         const char *layer_name;
516         char scene_name[19];
517         
518         uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
519         
520         if(!node->id) return;
521
522         col= uiLayoutColumn(layout, 0);
523         row = uiLayoutRow(col, 0);
524         uiItemR(row, ptr, "layer", 0, "", ICON_NULL);
525         
526         prop = RNA_struct_find_property(ptr, "layer");
527         if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name)))
528                 return;
529         
530         scn_ptr = RNA_pointer_get(ptr, "scene");
531         RNA_string_get(&scn_ptr, "name", scene_name);
532         
533         WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
534         RNA_string_set(&op_ptr, "layer", layer_name);
535         RNA_string_set(&op_ptr, "scene", scene_name);
536         uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
537
538 }
539
540
541 static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
542 {
543         uiLayout *col, *row;
544         
545         col= uiLayoutColumn(layout, 0);
546         
547         uiItemR(col, ptr, "filter_type", 0, "", ICON_NULL);
548         if (RNA_enum_get(ptr, "filter_type")!= R_FILTER_FAST_GAUSS) {
549                 uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NULL);
550                 uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NULL);
551         }
552         
553         uiItemR(col, ptr, "use_relative", 0, NULL, ICON_NULL);
554         
555         if (RNA_boolean_get(ptr, "use_relative")) {
556                 uiItemL(col, "Aspect Correction", 0);
557                 row= uiLayoutRow(layout, 1);
558                 uiItemR(row, ptr, "aspect_correction", UI_ITEM_R_EXPAND, NULL, 0);
559                 
560                 col= uiLayoutColumn(layout, 1);
561                 uiItemR(col, ptr, "factor_x", 0, "X", ICON_NULL);
562                 uiItemR(col, ptr, "factor_y", 0, "Y", ICON_NULL);
563         }
564         else {
565                 col= uiLayoutColumn(layout, 1);
566                 uiItemR(col, ptr, "size_x", 0, "X", ICON_NULL);
567                 uiItemR(col, ptr, "size_y", 0, "Y", ICON_NULL);
568         }
569 }
570
571 static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
572 {
573         uiLayout *col;
574         
575         uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NULL);
576         uiItemR(layout, ptr, "use_wrap", 0, NULL, ICON_NULL);
577         
578         col= uiLayoutColumn(layout, 1);
579         uiItemL(col, "Center:", ICON_NULL);
580         uiItemR(col, ptr, "center_x", 0, "X", ICON_NULL);
581         uiItemR(col, ptr, "center_y", 0, "Y", ICON_NULL);
582         
583         uiItemS(layout);
584         
585         col= uiLayoutColumn(layout, 1);
586         uiItemR(col, ptr, "distance", 0, NULL, ICON_NULL);
587         uiItemR(col, ptr, "angle", 0, NULL, ICON_NULL);
588         
589         uiItemS(layout);
590         
591         uiItemR(layout, ptr, "spin", 0, NULL, ICON_NULL);
592         uiItemR(layout, ptr, "zoom", 0, NULL, ICON_NULL);
593 }
594
595 static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
596 {       
597         uiLayout *col;
598         
599         col= uiLayoutColumn(layout, 1);
600         uiItemR(col, ptr, "iterations", 0, NULL, ICON_NULL);
601         uiItemR(col, ptr, "sigma_color", 0, NULL, ICON_NULL);
602         uiItemR(col, ptr, "sigma_space", 0, NULL, ICON_NULL);
603 }
604
605 static void node_composit_buts_defocus(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
606 {
607         uiLayout *sub, *col;
608         
609         col= uiLayoutColumn(layout, 0);
610         uiItemL(col, "Bokeh Type:", ICON_NULL);
611         uiItemR(col, ptr, "bokeh", 0, "", ICON_NULL);
612         uiItemR(col, ptr, "angle", 0, NULL, ICON_NULL);
613
614         uiItemR(layout, ptr, "use_gamma_correction", 0, NULL, ICON_NULL);
615
616         col = uiLayoutColumn(layout, 0);
617         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer")==1);
618         uiItemR(col, ptr, "f_stop", 0, NULL, ICON_NULL);
619
620         uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NULL);
621         uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NULL);
622
623         col = uiLayoutColumn(layout, 0);
624         uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NULL);
625         sub = uiLayoutColumn(col, 0);
626         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_preview"));
627         uiItemR(sub, ptr, "samples", 0, NULL, ICON_NULL);
628         
629         col = uiLayoutColumn(layout, 0);
630         uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NULL);
631         sub = uiLayoutColumn(col, 0);
632         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer")==0);
633         uiItemR(sub, ptr, "z_scale", 0, NULL, ICON_NULL);
634 }
635
636 /* qdn: glare node */
637 static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
638 {       
639         uiItemR(layout, ptr, "glare_type", 0, "", ICON_NULL);
640         uiItemR(layout, ptr, "quality", 0, "", ICON_NULL);
641
642         if (RNA_enum_get(ptr, "glare_type")!= 1) {
643                 uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NULL);
644         
645                 if (RNA_enum_get(ptr, "glare_type")!= 0) 
646                         uiItemR(layout, ptr, "color_modulation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
647         }
648         
649         uiItemR(layout, ptr, "mix", 0, NULL, ICON_NULL);
650         uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NULL);
651
652         if (RNA_enum_get(ptr, "glare_type")== 2) {
653                 uiItemR(layout, ptr, "streaks", 0, NULL, ICON_NULL);
654                 uiItemR(layout, ptr, "angle_offset", 0, NULL, ICON_NULL);
655         }
656         if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) {
657                 uiItemR(layout, ptr, "fade", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
658                 
659                 if (RNA_enum_get(ptr, "glare_type")== 0) 
660                         uiItemR(layout, ptr, "use_rotate_45", 0, NULL, ICON_NULL);
661         }
662         if (RNA_enum_get(ptr, "glare_type")== 1) {
663                 uiItemR(layout, ptr, "size", 0, NULL, ICON_NULL);
664         }
665 }
666
667 static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
668 {       
669         uiLayout *col;
670
671         col = uiLayoutColumn(layout, 0);
672         uiItemR(col, ptr, "tonemap_type", 0, "", ICON_NULL);
673         if (RNA_enum_get(ptr, "tonemap_type")== 0) {
674                 uiItemR(col, ptr, "key", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
675                 uiItemR(col, ptr, "offset", 0, NULL, ICON_NULL);
676                 uiItemR(col, ptr, "gamma", 0, NULL, ICON_NULL);
677         }
678         else {
679                 uiItemR(col, ptr, "intensity", 0, NULL, ICON_NULL);
680                 uiItemR(col, ptr, "contrast", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
681                 uiItemR(col, ptr, "adaptation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
682                 uiItemR(col, ptr, "correction", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
683         }
684 }
685
686 static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
687 {
688         uiLayout *col;
689
690         col= uiLayoutColumn(layout, 0);
691         uiItemR(col, ptr, "use_projector", 0, NULL, ICON_NULL);
692
693         col = uiLayoutColumn(col, 0);
694         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector")==0);
695         uiItemR(col, ptr, "use_jitter", 0, NULL, ICON_NULL);
696         uiItemR(col, ptr, "use_fit", 0, NULL, ICON_NULL);
697 }
698
699 static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
700 {
701         uiLayout *col;
702         
703         col= uiLayoutColumn(layout, 0);
704         uiItemR(col, ptr, "samples", 0, NULL, ICON_NULL);
705         uiItemR(col, ptr, "factor", 0, "Blur", ICON_NULL);
706         
707         col= uiLayoutColumn(layout, 1);
708         uiItemL(col, "Speed:", ICON_NULL);
709         uiItemR(col, ptr, "speed_min", 0, "Min", ICON_NULL);
710         uiItemR(col, ptr, "speed_max", 0, "Max", ICON_NULL);
711
712         uiItemR(layout, ptr, "use_curved", 0, NULL, ICON_NULL);
713 }
714
715 static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
716 {
717         uiItemR(layout, ptr, "filter_type", 0, "", ICON_NULL);
718 }
719
720 static void node_composit_buts_flip(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
721 {
722         uiItemR(layout, ptr, "axis", 0, "", ICON_NULL);
723 }
724
725 static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
726 {
727         uiLayout *col;
728         
729         uiItemR(layout, ptr, "use_crop_size", 0, NULL, ICON_NULL);
730    uiItemR(layout, ptr, "relative", 0, NULL, ICON_NULL);
731
732         col= uiLayoutColumn(layout, 1);
733    if (RNA_boolean_get(ptr, "relative")){
734       uiItemR(col, ptr, "rel_min_x", 0, "Left", ICON_NULL);
735       uiItemR(col, ptr, "rel_max_x", 0, "Right", ICON_NULL);
736       uiItemR(col, ptr, "rel_min_y", 0, "Up", ICON_NULL);
737       uiItemR(col, ptr, "rel_max_y", 0, "Down", ICON_NULL);
738    } else {
739       uiItemR(col, ptr, "min_x", 0, "Left", ICON_NULL);
740       uiItemR(col, ptr, "max_x", 0, "Right", ICON_NULL);
741       uiItemR(col, ptr, "min_y", 0, "Up", ICON_NULL);
742       uiItemR(col, ptr, "max_y", 0, "Down", ICON_NULL);
743    }
744 }
745
746 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
747 {
748         uiLayout *row, *col;
749         
750         col= uiLayoutColumn(layout, 0);
751         row= uiLayoutRow(col, 0);
752         uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
753         uiItemR(col, ptr, "factor", 0, NULL, ICON_NULL);
754 }
755
756 static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
757 {
758         uiLayout *sub, *col;
759         
760         col =uiLayoutColumn(layout, 1);
761         uiItemR(col, ptr, "offset", 0, NULL, ICON_NULL);
762         uiItemR(col, ptr, "size", 0, NULL, ICON_NULL);
763         
764         col =uiLayoutColumn(layout, 1);
765         uiItemR(col, ptr, "use_min", 0, NULL, ICON_NULL);
766         sub =uiLayoutColumn(col, 0);
767         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
768         uiItemR(sub, ptr, "min", 0, "", ICON_NULL);
769         
770         col =uiLayoutColumn(layout, 1);
771         uiItemR(col, ptr, "use_max", 0, NULL, ICON_NULL);
772         sub =uiLayoutColumn(col, 0);
773         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
774         uiItemR(sub, ptr, "max", 0, "", ICON_NULL);
775 }
776
777 static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
778 {       
779         uiLayout *col;
780         
781         col =uiLayoutColumn(layout, 1);
782         uiItemR(col, ptr, "use_premultiply", 0, NULL, ICON_NULL);
783         uiItemR(col, ptr, "premul", 0, NULL, ICON_NULL);
784 }
785
786 static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
787 {       
788         uiLayout *col;
789         
790         col =uiLayoutColumn(layout, 1);
791         uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NULL);
792 }
793
794
795 static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
796 {
797         uiLayout *col;
798         
799         col =uiLayoutColumn(layout, 0);
800         uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
801         uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
802         uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
803 }
804
805 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
806 {
807         uiItemR(layout, ptr, "distance", 0, NULL, ICON_NULL);
808 }
809
810 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
811 {
812         uiLayout *col;
813         
814         col =uiLayoutColumn(layout, 1);
815         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
816         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
817 }
818
819 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
820 {
821         uiLayout *col;
822         
823         col =uiLayoutColumn(layout, 1);
824         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
825         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
826 }
827
828 static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
829 {
830         uiLayout *row, *col;
831         
832    uiItemL(layout, "Despill Channel:", ICON_NULL);
833    row =uiLayoutRow(layout,0);
834         uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
835
836    col= uiLayoutColumn(layout, 0);
837    uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NULL);
838
839    if(RNA_enum_get(ptr, "limit_method")==0) {
840           uiItemL(col, "Limiting Channel:", ICON_NULL);
841           row=uiLayoutRow(col,0);
842           uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
843    }
844
845    uiItemR(col, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
846    uiItemR(col, ptr, "use_unspill", 0, NULL, ICON_NULL);
847    if (RNA_enum_get(ptr, "use_unspill")== 1) {
848           uiItemR(col, ptr, "unspill_red", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
849           uiItemR(col, ptr, "unspill_green", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
850           uiItemR(col, ptr, "unspill_blue", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
851    }
852 }
853
854 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
855 {
856         uiLayout *col;
857         
858         col= uiLayoutColumn(layout, 0);
859         uiItemR(col, ptr, "tolerance", 0, NULL, ICON_NULL);
860         uiItemR(col, ptr, "threshold", 0, NULL, ICON_NULL);
861         
862         col= uiLayoutColumn(layout, 1);
863    /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NULL);  Removed for now */
864         uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
865    /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NULL);  Removed for now*/
866 }
867
868 static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
869 {
870         uiLayout *col;
871         
872         col= uiLayoutColumn(layout, 1);
873         uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
874         uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
875         uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
876 }
877
878 static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
879 {       
880         uiLayout *col, *row;
881
882    uiItemL(layout, "Color Space:", ICON_NULL);
883         row= uiLayoutRow(layout, 0);
884         uiItemR(row, ptr, "color_space", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
885
886    col=uiLayoutColumn(layout, 0);  
887    uiItemL(col, "Key Channel:", ICON_NULL);
888         row= uiLayoutRow(col, 0);
889         uiItemR(row, ptr, "matte_channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
890
891         col =uiLayoutColumn(layout, 0);
892
893    uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NULL);
894    if(RNA_enum_get(ptr, "limit_method")==0) {
895           uiItemL(col, "Limiting Channel:", ICON_NULL);
896           row=uiLayoutRow(col,0);
897           uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
898    }
899    
900         uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
901         uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
902 }
903
904 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
905 {
906         uiLayout *col;
907         
908         col= uiLayoutColumn(layout, 1);
909         uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
910         uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
911 }
912
913 static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
914 {
915         uiItemR(layout, ptr, "alpha", 0, NULL, ICON_NULL);
916 }
917
918 static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
919 {
920         uiItemR(layout, ptr, "index", 0, NULL, ICON_NULL);
921 }
922
923 static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
924 {
925         uiLayout *col, *row;
926
927         col= uiLayoutColumn(layout, 0);
928         uiItemR(col, ptr, "filepath", 0, "", ICON_NULL);
929         uiItemR(col, ptr, "image_type", 0, "", ICON_NULL);
930         
931         row= uiLayoutRow(layout, 0);
932         if (RNA_enum_get(ptr, "image_type")== R_OPENEXR) {
933                 uiItemR(row, ptr, "use_exr_half", 0, NULL, ICON_NULL);
934                 uiItemR(row, ptr, "exr_codec", 0, "", ICON_NULL);
935         }
936         else if (RNA_enum_get(ptr, "image_type")== R_JPEG90) {
937                 uiItemR(row, ptr, "quality", UI_ITEM_R_SLIDER, "Quality", ICON_NULL);
938         }
939         else if (RNA_enum_get(ptr, "image_type")== R_PNG) {
940                 uiItemR(row, ptr, "quality", UI_ITEM_R_SLIDER, "Compression", ICON_NULL);
941         }
942         
943         row= uiLayoutRow(layout, 1);
944         uiItemR(row, ptr, "frame_start", 0, "Start", ICON_NULL);
945         uiItemR(row, ptr, "frame_end", 0, "End", ICON_NULL);
946 }
947
948 static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
949 {
950         uiItemR(layout, ptr, "space", 0, "", ICON_NULL);
951 }
952
953 static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
954 {
955    uiItemR(layout, ptr, "filter_type", 0, "", ICON_NULL);
956 }
957
958 static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
959 {
960         uiLayout *col;
961         
962         col= uiLayoutColumn(layout, 0);
963         uiItemR(col, ptr, "invert_rgb", 0, NULL, ICON_NULL);
964         uiItemR(col, ptr, "invert_alpha", 0, NULL, ICON_NULL);
965 }
966
967 static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
968 {
969         uiItemR(layout, ptr, "mapping", 0, "", ICON_NULL);
970 }
971
972 static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
973 {
974         uiItemR(layout, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
975 }
976
977 static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
978 {
979         uiLayout *split, *col, *row;
980         
981         uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NULL);
982         
983         if (RNA_enum_get(ptr, "correction_method")== 0) {
984         
985                 split = uiLayoutSplit(layout, 0, 0);
986                 col = uiLayoutColumn(split, 0);
987                 uiTemplateColorWheel(col, ptr, "lift", 1, 1, 0, 1);
988                 row = uiLayoutRow(col, 0);
989                 uiItemR(row, ptr, "lift", 0, NULL, ICON_NULL);
990                 
991                 col = uiLayoutColumn(split, 0);
992                 uiTemplateColorWheel(col, ptr, "gamma", 1, 1, 1, 1);
993                 row = uiLayoutRow(col, 0);
994                 uiItemR(row, ptr, "gamma", 0, NULL, ICON_NULL);
995                 
996                 col = uiLayoutColumn(split, 0);
997                 uiTemplateColorWheel(col, ptr, "gain", 1, 1, 1, 1);
998                 row = uiLayoutRow(col, 0);
999                 uiItemR(row, ptr, "gain", 0, NULL, ICON_NULL);
1000
1001         } else {
1002                 
1003                 split = uiLayoutSplit(layout, 0, 0);
1004                 col = uiLayoutColumn(split, 0);
1005                 uiTemplateColorWheel(col, ptr, "offset", 1, 1, 0, 1);
1006                 row = uiLayoutRow(col, 0);
1007                 uiItemR(row, ptr, "offset", 0, NULL, ICON_NULL);
1008                 
1009                 col = uiLayoutColumn(split, 0);
1010                 uiTemplateColorWheel(col, ptr, "power", 1, 1, 0, 1);
1011                 row = uiLayoutRow(col, 0);
1012                 uiItemR(row, ptr, "power", 0, NULL, ICON_NULL);
1013                 
1014                 col = uiLayoutColumn(split, 0);
1015                 uiTemplateColorWheel(col, ptr, "slope", 1, 1, 0, 1);
1016                 row = uiLayoutRow(col, 0);
1017                 uiItemR(row, ptr, "slope", 0, NULL, ICON_NULL);
1018         }
1019
1020 }
1021
1022 static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1023 {
1024         uiTemplateCurveMapping(layout, ptr, "mapping", 'h', 0, 0);
1025 }
1026
1027 static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1028
1029         uiItemR(layout, ptr, "mode", 0, "", ICON_NULL);
1030 }
1031
1032 /* only once called */
1033 static void node_composit_set_butfunc(bNodeType *ntype)
1034 {
1035         switch(ntype->type) {
1036                 /* case NODE_GROUP:      note, typeinfo for group is generated... see "XXX ugly hack" */
1037
1038                 case CMP_NODE_IMAGE:
1039                         ntype->uifunc= node_composit_buts_image;
1040                         break;
1041                 case CMP_NODE_R_LAYERS:
1042                         ntype->uifunc= node_composit_buts_renderlayers;
1043                         break;
1044                 case CMP_NODE_NORMAL:
1045                         ntype->uifunc= node_buts_normal;
1046                         break;
1047                 case CMP_NODE_CURVE_VEC:
1048                         ntype->uifunc= node_buts_curvevec;
1049                         break;
1050                 case CMP_NODE_CURVE_RGB:
1051                         ntype->uifunc= node_buts_curvecol;
1052                         break;
1053                 case CMP_NODE_VALUE:
1054                         ntype->uifunc= node_buts_value;
1055                         break;
1056                 case CMP_NODE_RGB:
1057                         ntype->uifunc= node_buts_rgb;
1058                         break;
1059                 case CMP_NODE_FLIP:
1060                         ntype->uifunc= node_composit_buts_flip;
1061                         break;
1062                 case CMP_NODE_SPLITVIEWER:
1063                         ntype->uifunc= node_composit_buts_splitviewer;
1064                         break;
1065                 case CMP_NODE_MIX_RGB:
1066                         ntype->uifunc= node_buts_mix_rgb;
1067                         break;
1068                 case CMP_NODE_VALTORGB:
1069                         ntype->uifunc= node_buts_colorramp;
1070                         break;
1071                 case CMP_NODE_CROP:
1072                         ntype->uifunc= node_composit_buts_crop;
1073                         break;
1074                 case CMP_NODE_BLUR:
1075                         ntype->uifunc= node_composit_buts_blur;
1076                         break;
1077                 case CMP_NODE_DBLUR:
1078                         ntype->uifunc= node_composit_buts_dblur;
1079                         break;
1080                 case CMP_NODE_BILATERALBLUR:
1081                         ntype->uifunc= node_composit_buts_bilateralblur;
1082                         break;
1083                 case CMP_NODE_DEFOCUS:
1084                         ntype->uifunc = node_composit_buts_defocus;
1085                         break;
1086                 case CMP_NODE_GLARE:
1087                         ntype->uifunc = node_composit_buts_glare;
1088                         break;
1089                 case CMP_NODE_TONEMAP:
1090                         ntype->uifunc = node_composit_buts_tonemap;
1091                         break;
1092                 case CMP_NODE_LENSDIST:
1093                         ntype->uifunc = node_composit_buts_lensdist;
1094                         break;
1095                 case CMP_NODE_VECBLUR:
1096                         ntype->uifunc= node_composit_buts_vecblur;
1097                         break;
1098                 case CMP_NODE_FILTER:
1099                         ntype->uifunc= node_composit_buts_filter;
1100                         break;
1101                 case CMP_NODE_MAP_VALUE:
1102                         ntype->uifunc= node_composit_buts_map_value;
1103                         break;
1104                 case CMP_NODE_TIME:
1105                         ntype->uifunc= node_buts_time;
1106                         break;
1107                 case CMP_NODE_ALPHAOVER:
1108                         ntype->uifunc= node_composit_buts_alphaover;
1109                         break;
1110                 case CMP_NODE_HUE_SAT:
1111                         ntype->uifunc= node_composit_buts_hue_sat;
1112                         break;
1113                 case CMP_NODE_TEXTURE:
1114                         ntype->uifunc= node_buts_texture;
1115                         break;
1116                 case CMP_NODE_DILATEERODE:
1117                         ntype->uifunc= node_composit_buts_dilateerode;
1118                         break;
1119                 case CMP_NODE_OUTPUT_FILE:
1120                         ntype->uifunc= node_composit_buts_file_output;
1121                         break;  
1122                 case CMP_NODE_DIFF_MATTE:
1123                         ntype->uifunc=node_composit_buts_diff_matte;
1124                         break;
1125                 case CMP_NODE_DIST_MATTE:
1126                         ntype->uifunc=node_composit_buts_distance_matte;
1127                         break;
1128                 case CMP_NODE_COLOR_SPILL:
1129                         ntype->uifunc=node_composit_buts_color_spill;
1130                         break;
1131                 case CMP_NODE_CHROMA_MATTE:
1132                         ntype->uifunc=node_composit_buts_chroma_matte;
1133                         break;
1134                 case CMP_NODE_COLOR_MATTE:
1135                         ntype->uifunc=node_composit_buts_color_matte;
1136                         break;
1137                 case CMP_NODE_SCALE:
1138                         ntype->uifunc= node_composit_buts_scale;
1139                         break;
1140           case CMP_NODE_ROTATE:
1141                  ntype->uifunc=node_composit_buts_rotate;
1142                  break;
1143                 case CMP_NODE_CHANNEL_MATTE:
1144                         ntype->uifunc= node_composit_buts_channel_matte;
1145                         break;
1146                 case CMP_NODE_LUMA_MATTE:
1147                         ntype->uifunc= node_composit_buts_luma_matte;
1148                         break;
1149                 case CMP_NODE_MAP_UV:
1150                         ntype->uifunc= node_composit_buts_map_uv;
1151                         break;
1152                 case CMP_NODE_ID_MASK:
1153                         ntype->uifunc= node_composit_buts_id_mask;
1154                         break;
1155                 case CMP_NODE_MATH:
1156                         ntype->uifunc= node_buts_math;
1157                         break;
1158                 case CMP_NODE_INVERT:
1159                         ntype->uifunc= node_composit_buts_invert;
1160                         break;
1161                 case CMP_NODE_PREMULKEY:
1162                         ntype->uifunc= node_composit_buts_premulkey;
1163                         break;
1164                 case CMP_NODE_VIEW_LEVELS:
1165                         ntype->uifunc=node_composit_buts_view_levels;
1166                          break;
1167                 case CMP_NODE_COLORBALANCE:
1168                         ntype->uifunc=node_composit_buts_colorbalance;
1169                          break;
1170                 case CMP_NODE_HUECORRECT:
1171                         ntype->uifunc=node_composit_buts_huecorrect;
1172                          break;
1173                 case CMP_NODE_ZCOMBINE:
1174                         ntype->uifunc=node_composit_buts_zcombine;
1175                          break;
1176                 case CMP_NODE_COMBYCCA:
1177                 case CMP_NODE_SEPYCCA:
1178                         ntype->uifunc=node_composit_buts_ycc;
1179                         break;
1180                 default:
1181                         ntype->uifunc= NULL;
1182         }
1183 }
1184
1185 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
1186
1187 static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1188 {
1189         uiLayout *col;
1190         
1191         col= uiLayoutColumn(layout, 1);
1192         uiItemR(col, ptr, "offset", 0, "Offset", ICON_NULL);
1193         uiItemR(col, ptr, "offset_frequency", 0, "Frequency", ICON_NULL);
1194         
1195         col= uiLayoutColumn(layout, 1);
1196         uiItemR(col, ptr, "squash", 0, "Squash", ICON_NULL);
1197         uiItemR(col, ptr, "squash_frequency", 0, "Frequency", ICON_NULL);
1198 }
1199
1200 static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1201 {
1202         PointerRNA tex_ptr;
1203         bNode *node= ptr->data;
1204         ID *id= ptr->id.data;
1205         Tex *tex = (Tex *)node->storage;
1206         uiLayout *col, *row;
1207         
1208         RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
1209
1210         col= uiLayoutColumn(layout, 0);
1211
1212         switch( tex->type ) {
1213                 case TEX_BLEND:
1214                         uiItemR(col, &tex_ptr, "progression", 0, "", ICON_NULL);
1215                         row= uiLayoutRow(col, 0);
1216                         uiItemR(row, &tex_ptr, "use_flip_axis", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1217                         break;
1218
1219                 case TEX_MARBLE:
1220                         row= uiLayoutRow(col, 0);
1221                         uiItemR(row, &tex_ptr, "marble_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1222                         row= uiLayoutRow(col, 0);
1223                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1224                         row= uiLayoutRow(col, 0);
1225                         uiItemR(row, &tex_ptr, "noisebasis_2", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1226                         break;
1227
1228                 case TEX_WOOD:
1229                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NULL);
1230                         uiItemR(col, &tex_ptr, "wood_type", 0, "", ICON_NULL);
1231                         row= uiLayoutRow(col, 0);
1232                         uiItemR(row, &tex_ptr, "noisebasis_2", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1233                         row= uiLayoutRow(col, 0);
1234                         uiLayoutSetActive(row, !(RNA_enum_get(&tex_ptr, "wood_type")==TEX_BAND || RNA_enum_get(&tex_ptr, "wood_type")==TEX_RING)); 
1235                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1236                         break;
1237                         
1238                 case TEX_CLOUDS:
1239                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NULL);
1240                         row= uiLayoutRow(col, 0);
1241                         uiItemR(row, &tex_ptr, "cloud_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1242                         row= uiLayoutRow(col, 0);
1243                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1244                         uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, "Depth", ICON_NULL);
1245                         break;
1246                         
1247                 case TEX_DISTNOISE:
1248                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NULL);
1249                         uiItemR(col, &tex_ptr, "noise_distortion", 0, "", ICON_NULL);
1250                         break;
1251         }
1252 }
1253
1254 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
1255 {
1256         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
1257 }
1258
1259 static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1260 {
1261         uiItemR(layout, ptr, "filepath", 0, "", ICON_NULL);
1262 }
1263
1264 /* only once called */
1265 static void node_texture_set_butfunc(bNodeType *ntype)
1266 {
1267         if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) {
1268                 ntype->uifunc = node_texture_buts_proc;
1269         }
1270         else switch(ntype->type) {
1271                 
1272                 case TEX_NODE_MATH:
1273                         ntype->uifunc = node_buts_math;
1274                         break;
1275                 
1276                 case TEX_NODE_MIX_RGB:
1277                         ntype->uifunc = node_buts_mix_rgb;
1278                         break;
1279                         
1280                 case TEX_NODE_VALTORGB:
1281                         ntype->uifunc = node_buts_colorramp;
1282                         break;
1283                         
1284                 case TEX_NODE_CURVE_RGB:
1285                         ntype->uifunc= node_buts_curvecol;
1286                         break;
1287                         
1288                 case TEX_NODE_CURVE_TIME:
1289                         ntype->uifunc = node_buts_time;
1290                         break;
1291                         
1292                 case TEX_NODE_TEXTURE:
1293                         ntype->uifunc = node_buts_texture;
1294                         break;
1295                         
1296                 case TEX_NODE_BRICKS:
1297                         ntype->uifunc = node_texture_buts_bricks;
1298                         break;
1299                         
1300                 case TEX_NODE_IMAGE:
1301                         ntype->uifunc = node_texture_buts_image;
1302                         break;
1303                         
1304                 case TEX_NODE_OUTPUT:
1305                         ntype->uifunc = node_texture_buts_output;
1306                         break;
1307                         
1308                 default:
1309                         ntype->uifunc= NULL;
1310         }
1311 }
1312
1313 /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */
1314
1315 void ED_init_node_butfuncs(void)
1316 {
1317         bNodeType *ntype;
1318         
1319         /* shader nodes */
1320         ntype= node_all_shaders.first;
1321         while(ntype) {
1322                 node_shader_set_butfunc(ntype);
1323                 ntype= ntype->next;
1324         }
1325         /* composit nodes */
1326         ntype= node_all_composit.first;
1327         while(ntype) {
1328                 node_composit_set_butfunc(ntype);
1329                 ntype= ntype->next;
1330         }
1331         ntype = node_all_textures.first;
1332         while(ntype) {
1333                 node_texture_set_butfunc(ntype);
1334                 ntype= ntype->next;
1335         }
1336 }
1337
1338 /* ************** Generic drawing ************** */
1339
1340 void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage)
1341 {
1342         
1343         if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) {
1344                 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1345                 void *lock;
1346                 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
1347                 if(ibuf) {
1348                         float x, y; 
1349                         
1350                         glMatrixMode(GL_PROJECTION);
1351                         glPushMatrix();
1352                         glMatrixMode(GL_MODELVIEW);
1353                         glPushMatrix();
1354
1355                         /* keep this, saves us from a version patch */
1356                         if(snode->zoom==0.0f) snode->zoom= 1.0f;
1357                         
1358                         /* somehow the offset has to be calculated inverse */
1359                         
1360                         glaDefine2DArea(&ar->winrct);
1361                         /* ortho at pixel level curarea */
1362                         wmOrtho2(-0.375, ar->winx-0.375, -0.375, ar->winy-0.375);
1363                         
1364                         x = (ar->winx-snode->zoom*ibuf->x)/2 + snode->xof;
1365                         y = (ar->winy-snode->zoom*ibuf->y)/2 + snode->yof;
1366                         
1367                         if(!ibuf->rect) {
1368                                 if(color_manage)
1369                                         ibuf->profile = IB_PROFILE_LINEAR_RGB;
1370                                 else
1371                                         ibuf->profile = IB_PROFILE_NONE;
1372                                 IMB_rect_from_float(ibuf);
1373                         }
1374
1375                         if(ibuf->rect) {
1376                                 if (snode->flag & SNODE_SHOW_ALPHA) {
1377                                         glPixelZoom(snode->zoom, snode->zoom);
1378                                         /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
1379                                         if(ENDIAN_ORDER == B_ENDIAN)
1380                                                 glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
1381                                         
1382                                         glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, ibuf->rect);
1383                                         
1384                                         glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
1385                                         glPixelZoom(1.0f, 1.0f);
1386                                 } else if (snode->flag & SNODE_USE_ALPHA) {
1387                                         glEnable(GL_BLEND);
1388                                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1389                                         glPixelZoom(snode->zoom, snode->zoom);
1390                                         
1391                                         glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1392                                         
1393                                         glPixelZoom(1.0f, 1.0f);
1394                                         glDisable(GL_BLEND);
1395                                 } else {
1396                                         glPixelZoom(snode->zoom, snode->zoom);
1397                                         
1398                                         glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1399                                         
1400                                         glPixelZoom(1.0f, 1.0f);
1401                                 }
1402                         }
1403                         
1404                         glMatrixMode(GL_PROJECTION);
1405                         glPopMatrix();
1406                         glMatrixMode(GL_MODELVIEW);
1407                         glPopMatrix();
1408                 }
1409
1410                 BKE_image_release_ibuf(ima, lock);
1411         }
1412 }
1413
1414 void draw_nodespace_color_info(ARegion *ar, int channels, int x, int y, char *cp, float *fp)
1415 {
1416         char str[256];
1417         int ofs;
1418         
1419         ofs= sprintf(str, "X: %4d Y: %4d ", x, y);
1420
1421         if(channels==4) {
1422                 if(cp)
1423                         ofs+= sprintf(str+ofs, "| R: %3d G: %3d B: %3d A: %3d ", cp[0], cp[1], cp[2], cp[3]);
1424                 if (fp)
1425                         ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
1426         }
1427         else if(channels==1) {
1428                 if(cp)
1429                         ofs+= sprintf(str+ofs, "| Val: %3d ", cp[0]);
1430                 if (fp)
1431                         ofs+= sprintf(str+ofs, "| Val: %.3f ", fp[0]);
1432         }
1433         else if(channels==3) {
1434                 if(cp)
1435                         ofs+= sprintf(str+ofs, "| R: %3d G: %3d B: %3d ", cp[0], cp[1], cp[2]);
1436                 if (fp)
1437                         ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f ", fp[0], fp[1], fp[2]);
1438         }
1439
1440         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1441         glEnable(GL_BLEND);
1442         
1443         glColor4f(.0,.0,.0,.25);
1444         glRecti(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 20);
1445         glDisable(GL_BLEND);
1446         
1447         glColor3ub(255, 255, 255);
1448         
1449         // UI_DrawString(6, 6, str); // works ok but fixed width is nicer.
1450         BLF_size(blf_mono_font, 11, 72);
1451         BLF_position(blf_mono_font, 6, 6, 0);
1452         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
1453 }
1454
1455 #if 0
1456 /* note: needs to be userpref or opengl profile option */
1457 static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
1458 {
1459
1460         draw_nodespace_grid(snode);
1461         
1462         if(snode->flag & SNODE_BACKDRAW) {
1463                 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1464                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1465                 if(ibuf) {
1466                         int x, y;
1467                         float zoom = 1.0;
1468
1469                         glMatrixMode(GL_PROJECTION);
1470                         glPushMatrix();
1471                         glMatrixMode(GL_MODELVIEW);
1472                         glPushMatrix();
1473                         
1474                         glaDefine2DArea(&sa->winrct);
1475
1476                         if(ibuf->x > sa->winx || ibuf->y > sa->winy) {
1477                                 float zoomx, zoomy;
1478                                 zoomx= (float)sa->winx/ibuf->x;
1479                                 zoomy= (float)sa->winy/ibuf->y;
1480                                 zoom = MIN2(zoomx, zoomy);
1481                         }
1482                         
1483                         x = (sa->winx-zoom*ibuf->x)/2 + snode->xof;
1484                         y = (sa->winy-zoom*ibuf->y)/2 + snode->yof;
1485
1486                         glPixelZoom(zoom, zoom);
1487
1488                         glColor4f(1.0, 1.0, 1.0, 1.0);
1489                         if(ibuf->rect)
1490                                 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
1491                         else if(ibuf->channels==4)
1492                                 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float);
1493
1494                         glPixelZoom(1.0, 1.0);
1495
1496                         glMatrixMode(GL_PROJECTION);
1497                         glPopMatrix();
1498                         glMatrixMode(GL_MODELVIEW);
1499                         glPopMatrix();
1500                 }
1501         }
1502 }
1503 #endif
1504
1505 /* if v2d not NULL, it clips and returns 0 if not visible */
1506 int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
1507 {
1508         float dist, vec[4][2];
1509         
1510         /* in v0 and v3 we put begin/end points */
1511         if(link->fromsock) {
1512                 vec[0][0]= link->fromsock->locx;
1513                 vec[0][1]= link->fromsock->locy;
1514         }
1515         else {
1516                 if(snode==NULL) return 0;
1517                 vec[0][0]= snode->mx;
1518                 vec[0][1]= snode->my;
1519         }
1520         if(link->tosock) {
1521                 vec[3][0]= link->tosock->locx;
1522                 vec[3][1]= link->tosock->locy;
1523         }
1524         else {
1525                 if(snode==NULL) return 0;
1526                 vec[3][0]= snode->mx;
1527                 vec[3][1]= snode->my;
1528         }
1529         
1530         dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
1531         
1532         /* check direction later, for top sockets */
1533         vec[1][0]= vec[0][0]+dist;
1534         vec[1][1]= vec[0][1];
1535         
1536         vec[2][0]= vec[3][0]-dist;
1537         vec[2][1]= vec[3][1];
1538         
1539         if(v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax); /* clipped */      
1540         else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin); /* clipped */
1541         else {
1542                 
1543                 /* always do all three, to prevent data hanging around */
1544                 forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2);
1545                 forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2);
1546                 
1547                 return 1;
1548         }
1549         return 0;
1550 }
1551
1552 #define LINK_RESOL      24
1553 void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 )
1554 {
1555         float coord_array[LINK_RESOL+1][2];
1556         
1557         if(node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
1558                 float dist, spline_step = 0.0f;
1559                 int i;
1560                 
1561                 /* store current linewidth */
1562                 float linew;
1563                 glGetFloatv(GL_LINE_WIDTH, &linew);
1564                 
1565                 /* we can reuse the dist variable here to increment the GL curve eval amount*/
1566                 dist = 1.0f/(float)LINK_RESOL;
1567                 
1568                 glEnable(GL_LINE_SMOOTH);
1569                 
1570                 if(do_triple) {
1571                         UI_ThemeColorShadeAlpha(th_col3, -80, -120);
1572                         glLineWidth(4.0f);
1573                         
1574                         glBegin(GL_LINE_STRIP);
1575                         for(i=0; i<=LINK_RESOL; i++) {
1576                                 glVertex2fv(coord_array[i]);
1577                         }
1578                         glEnd();
1579                 }
1580                 
1581                 UI_ThemeColor(th_col1);
1582                 glLineWidth(1.5f);
1583                 
1584                 glBegin(GL_LINE_STRIP);
1585                 for(i=0; i<=LINK_RESOL; i++) {
1586                         if(do_shaded) {
1587                                 UI_ThemeColorBlend(th_col1, th_col2, spline_step);
1588                                 spline_step += dist;
1589                         }
1590                         glVertex2fv(coord_array[i]);
1591                 }
1592                 glEnd();
1593                 
1594                 glDisable(GL_LINE_SMOOTH);
1595                 
1596                 /* restore previuos linewidth */
1597                 glLineWidth(linew);
1598         }
1599 }
1600
1601 /* note; this is used for fake links in groups too */
1602 void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
1603 {
1604         int do_shaded= 0, th_col1= TH_HEADER, th_col2= TH_HEADER;
1605         int do_triple= 0, th_col3= TH_WIRE;
1606         
1607         if(link->fromsock==NULL && link->tosock==NULL)
1608                 return;
1609         
1610         /* new connection */
1611         if(!link->fromsock || !link->tosock) {
1612                 th_col1 = TH_ACTIVE;
1613                 do_triple = 1;
1614         }
1615         else {
1616                 /* going to give issues once... */
1617                 if(link->tosock->flag & SOCK_UNAVAIL)
1618                         return;
1619                 if(link->fromsock->flag & SOCK_UNAVAIL)
1620                         return;
1621                 
1622                 /* a bit ugly... but thats how we detect the internal group links */
1623                 if(!link->fromnode || !link->tonode) {
1624                         UI_ThemeColorBlend(TH_BACK, TH_WIRE, 0.5f);
1625                         do_shaded= 0;
1626                 }
1627                 else {
1628                         /* check cyclic */
1629                         if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
1630                                 if(link->fromnode->flag & SELECT)
1631                                         th_col1= TH_EDGE_SELECT;
1632                                 if(link->tonode->flag & SELECT)
1633                                         th_col2= TH_EDGE_SELECT;
1634                                 do_shaded= 1;
1635                                 do_triple= 1;
1636                         }                               
1637                         else {
1638                                 th_col1 = TH_REDALERT;
1639                         }
1640                 }
1641         }
1642         
1643         node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
1644 }
1645
1646