4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2005 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges
27 * ***** END GPL LICENSE BLOCK *****
34 #include "BLI_blenlib.h"
38 #include "DNA_node_types.h"
39 #include "DNA_image_types.h"
40 #include "DNA_material_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_action_types.h"
43 #include "DNA_color_types.h"
44 #include "DNA_customdata_types.h"
45 #include "DNA_gpencil_types.h"
46 #include "DNA_ipo_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_space_types.h"
50 #include "DNA_screen_types.h"
51 #include "DNA_texture_types.h"
52 #include "DNA_text_types.h"
53 #include "DNA_userdef_types.h"
55 #include "BKE_context.h"
56 #include "BKE_curve.h"
57 #include "BKE_global.h"
58 #include "BKE_image.h"
59 #include "BKE_library.h"
61 #include "BKE_material.h"
63 #include "BKE_object.h"
64 #include "BKE_texture.h"
66 #include "BKE_utildefines.h"
72 #include "BIF_glutil.h"
74 #include "MEM_guardedalloc.h"
77 #include "ED_space_api.h"
78 #include "ED_screen.h"
81 #include "RNA_access.h"
82 #include "RNA_define.h"
87 #include "UI_view2d.h"
88 #include "UI_interface.h"
89 #include "UI_resources.h"
91 #include "RE_pipeline.h"
92 #include "IMB_imbuf.h"
93 #include "IMB_imbuf_types.h"
95 #include "node_intern.h"
97 /* ****************** GENERAL CALLBACKS FOR NODES ***************** */
99 static void node_ID_title_cb(bContext *C, void *node_v, void *unused_v)
104 test_idbutton(node->id->name+2); /* library.c, verifies unique name */
105 BLI_strncpy(node->name, node->id->name+2, 21);
110 /* XXX not used yet, make compiler happy :) */
111 static void node_group_alone_cb(bContext *C, void *node_v, void *unused_v)
117 // allqueue(REDRAWNODE, 0);
120 /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
122 static void node_buts_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
124 uiBlock *block= uiLayoutAbsoluteBlock(layout);
125 bNode *node= ptr->data;
126 rctf *butr= &node->butr;
132 uiBlockBeginAlign(block);
135 width= (short)(butr->xmax-butr->xmin - (node->id->us>1?19.0f:0.0f));
136 bt= uiDefBut(block, TEX, B_NOP, "NT:",
137 (short)butr->xmin, (short)butr->ymin, width, 19,
138 node->id->name+2, 0.0, 19.0, 0, 0, "NodeTree name");
139 uiButSetFunc(bt, node_ID_title_cb, node, NULL);
144 sprintf(str1, "%d", node->id->us);
145 bt= uiDefBut(block, BUT, B_NOP, str1,
146 (short)butr->xmax-19, (short)butr->ymin, 19, 19,
147 NULL, 0, 0, 0, 0, "Displays number of users.");
148 uiButSetFunc(bt, node_group_alone_cb, node, NULL);
151 uiBlockEndAlign(block);
156 static void node_buts_value(uiLayout *layout, bContext *C, PointerRNA *ptr)
161 /* first socket stores value */
162 prop = RNA_struct_find_property(ptr, "outputs");
163 RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
165 uiItemR(layout, "", 0, &sockptr, "default_value", 0);
168 static void node_buts_rgb(uiLayout *layout, bContext *C, PointerRNA *ptr)
174 /* first socket stores value */
175 prop = RNA_struct_find_property(ptr, "outputs");
176 RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
178 col = uiLayoutColumn(layout, 0);
179 uiItemR(col, "", 0, &sockptr, "default_value", 0);
182 static void node_buts_mix_rgb(uiLayout *layout, bContext *C, PointerRNA *ptr)
186 bNodeTree *ntree= (bNodeTree*)ptr->id.data;
188 row= uiLayoutRow(layout, 1);
189 uiItemR(row, "", 0, ptr, "blend_type", 0);
190 if(ntree->type == NTREE_COMPOSIT)
191 uiItemR(row, "", ICON_IMAGE_RGB_ALPHA, ptr, "alpha", 0);
194 static void node_buts_time(uiLayout *layout, bContext *C, PointerRNA *ptr)
198 /* XXX no context access here .. */
199 bNode *node= ptr->data;
200 CurveMapping *cumap= node->storage;
203 cumap->flag |= CUMA_DRAW_CFRA;
204 if(node->custom1<node->custom2)
205 cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
209 uiTemplateCurveMapping(layout, ptr, "curve", 's', 0);
211 row= uiLayoutRow(layout, 1);
212 uiItemR(row, "Sta", 0, ptr, "start", 0);
213 uiItemR(row, "End", 0, ptr, "end", 0);
216 static void node_buts_colorramp(uiLayout *layout, bContext *C, PointerRNA *ptr)
218 uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
221 static void node_buts_curvevec(uiLayout *layout, bContext *C, PointerRNA *ptr)
223 uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0);
226 static float *_sample_col= NULL; // bad bad, 2.5 will do better?
227 void node_curvemap_sample(float *col)
232 static void node_buts_curvecol(uiLayout *layout, bContext *C, PointerRNA *ptr)
234 bNode *node= ptr->data;
235 CurveMapping *cumap= node->storage;
238 cumap->flag |= CUMA_DRAW_SAMPLE;
239 VECCOPY(cumap->sample, _sample_col);
242 cumap->flag &= ~CUMA_DRAW_SAMPLE;
244 uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0);
247 static void node_buts_normal(uiLayout *layout, bContext *C, PointerRNA *ptr)
249 uiBlock *block= uiLayoutAbsoluteBlock(layout);
250 bNode *node= ptr->data;
251 rctf *butr= &node->butr;
252 bNodeSocket *sock= node->outputs.first; /* first socket stores normal */
254 uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "",
255 (short)butr->xmin, (short)butr->xmin, butr->xmax-butr->xmin, butr->xmax-butr->xmin,
256 sock->ns.vec, 0.0f, 1.0f, 0, 0, "");
258 #if 0 // not used in 2.5x yet
259 static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
261 bNodeTree *ntree= ntree_v;
265 if(node->menunr<1) return;
271 tex= BLI_findlink(&G.main->tex, node->menunr-1);
274 id_us_plus(node->id);
275 BLI_strncpy(node->name, node->id->name+2, 21);
277 nodeSetActive(ntree, node);
279 if( ntree->type == NTREE_TEXTURE )
280 ntreeTexCheckCyclics( ntree );
282 // allqueue(REDRAWBUTSSHADING, 0);
283 // allqueue(REDRAWNODE, 0);
284 NodeTagChanged(ntree, node);
289 static void node_dynamic_update_cb(bContext *C, void *ntree_v, void *node_v)
292 bNode *node= (bNode *)node_v;
296 if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) error= 1;
298 /* Users only have to press the "update" button in one pynode
299 * and we also update all others sharing the same script */
300 for (ma= G.main->mat.first; ma; ma= ma->id.next) {
303 for (nd= ma->nodetree->nodes.first; nd; nd= nd->next) {
304 if ((nd->type == NODE_DYNAMIC) && (nd->id == id)) {
306 nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_REPARSE);
309 nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_ERROR);
315 // allqueue(REDRAWBUTSSHADING, 0);
316 // allqueue(REDRAWNODE, 0);
317 // XXX BIF_preview_changed(ID_MA);
320 static void node_buts_texture(uiLayout *layout, bContext *C, PointerRNA *ptr)
322 bNode *node= ptr->data;
326 ((Tex*)node->id)->use_nodes &&
327 (node->type != CMP_NODE_TEXTURE) &&
328 (node->type != TEX_NODE_TEXTURE)
331 uiItemR(layout, "", 0, ptr, "texture", 0);
334 /* Number Drawing not optimal here, better have a list*/
335 uiItemR(layout, "", 0, ptr, "node_output", 0);
339 static void node_buts_math(uiLayout *layout, bContext *C, PointerRNA *ptr)
341 uiItemR(layout, "", 0, ptr, "operation", 0);
344 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
346 static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v)
348 bNodeTree *ntree= ntree_v;
352 if(node->menunr<1) return;
358 node->id= BLI_findlink(&G.main->text, node->menunr-1);
359 id_us_plus(node->id);
360 BLI_strncpy(node->name, node->id->name+2, 21); /* huh? why 21? */
362 node->custom1= BSET(node->custom1, NODE_DYNAMIC_NEW);
364 nodeSetActive(ntree, node);
366 // allqueue(REDRAWBUTSSHADING, 0);
367 // allqueue(REDRAWNODE, 0);
372 static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
374 bNode *node= ptr->data;
377 uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL);
379 if(!node->id) return;
381 col= uiLayoutColumn(layout, 0);
382 uiItemR(col, NULL, 0, ptr, "diffuse", 0);
383 uiItemR(col, NULL, 0, ptr, "specular", 0);
384 uiItemR(col, NULL, 0, ptr, "invert_normal", 0);
387 static void node_shader_buts_mapping(uiLayout *layout, bContext *C, PointerRNA *ptr)
391 uiItemL(layout, "Location:", 0);
392 row= uiLayoutRow(layout, 1);
393 uiItemR(row, "", 0, ptr, "location", 0);
395 uiItemL(layout, "Rotation:", 0);
396 row= uiLayoutRow(layout, 1);
397 uiItemR(row, "", 0, ptr, "rotation", 0);
399 uiItemL(layout, "Scale:", 0);
400 row= uiLayoutRow(layout, 1);
401 uiItemR(row, "", 0, ptr, "scale", 0);
403 row= uiLayoutRow(layout, 1);
404 uiItemR(row, "Min", 0, ptr, "clamp_minimum", 0);
405 uiItemR(row, "", 0, ptr, "minimum", 0);
407 row= uiLayoutRow(layout, 1);
408 uiItemR(row, "Max", 0, ptr, "clamp_maximum", 0);
409 uiItemR(row, "", 0, ptr, "maximum", 0);
413 static void node_shader_buts_vect_math(uiLayout *layout, bContext *C, PointerRNA *ptr)
415 uiItemR(layout, "", 0, ptr, "operation", 0);
418 static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr)
422 col= uiLayoutColumn(layout, 0);
423 uiItemR(col, "UV", 0, ptr, "uv_layer", 0);
424 uiItemR(col, "VCol", 0, ptr, "color_layer", 0);
427 static void node_shader_buts_dynamic(uiLayout *layout, bContext *C, PointerRNA *ptr)
429 uiBlock *block= uiLayoutAbsoluteBlock(layout);
430 bNode *node= ptr->data;
431 bNodeTree *ntree= ptr->id.data;
432 rctf *butr= &node->butr;
434 // XXX SpaceNode *snode= curarea->spacedata.first;
435 short dy= (short)butr->ymin;
438 /* B_NODE_EXEC is handled in butspace.c do_node_buts */
441 IDnames_to_pupstring(&strp, NULL, "", &(G.main->text), NULL, NULL);
443 bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp,
444 butr->xmin, dy, 19, 19,
445 &node->menunr, 0, 0, 0, 0, "Browses existing choices");
446 uiButSetFunc(bt, node_browse_text_cb, ntree, node);
448 if(strp) MEM_freeN(strp);
451 bt = uiDefBut(block, BUT, B_NOP, "Update",
452 butr->xmin+xoff, butr->ymin+20, 50, 19,
453 &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)");
454 uiButSetFunc(bt, node_dynamic_update_cb, ntree, node);
456 if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
457 // UI_ThemeColor(TH_REDALERT);
458 // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect);
459 // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin);
465 /* only once called */
466 static void node_shader_set_butfunc(bNodeType *ntype)
468 switch(ntype->type) {
469 /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */
471 case SH_NODE_MATERIAL:
472 case SH_NODE_MATERIAL_EXT:
473 ntype->uifunc= node_shader_buts_material;
475 case SH_NODE_TEXTURE:
476 ntype->uifunc= node_buts_texture;
479 ntype->uifunc= node_buts_normal;
481 case SH_NODE_CURVE_VEC:
482 ntype->uifunc= node_buts_curvevec;
484 case SH_NODE_CURVE_RGB:
485 ntype->uifunc= node_buts_curvecol;
487 case SH_NODE_MAPPING:
488 ntype->uifunc= node_shader_buts_mapping;
491 ntype->uifunc= node_buts_value;
494 ntype->uifunc= node_buts_rgb;
496 case SH_NODE_MIX_RGB:
497 ntype->uifunc= node_buts_mix_rgb;
499 case SH_NODE_VALTORGB:
500 ntype->uifunc= node_buts_colorramp;
503 ntype->uifunc= node_buts_math;
505 case SH_NODE_VECT_MATH:
506 ntype->uifunc= node_shader_buts_vect_math;
508 case SH_NODE_GEOMETRY:
509 ntype->uifunc= node_shader_buts_geometry;
512 ntype->uifunc= node_shader_buts_dynamic;
519 /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
521 static void node_browse_image_cb(bContext *C, void *ntree_v, void *node_v)
523 bNodeTree *ntree= ntree_v;
526 nodeSetActive(ntree, node);
528 if(node->menunr<1) return;
529 if(node->menunr==32767) { /* code for Load New */
530 /// addqueue(curarea->win, UI_BUT_EVENT, B_NODE_LOADIMAGE); XXX
533 if(node->id) node->id->us--;
534 node->id= BLI_findlink(&G.main->image, node->menunr-1);
535 id_us_plus(node->id);
537 BLI_strncpy(node->name, node->id->name+2, 21);
539 NodeTagChanged(ntree, node);
540 BKE_image_signal((Image *)node->id, node->storage, IMA_SIGNAL_USER_NEW_IMAGE);
541 // addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC); XXX
546 static void node_active_cb(bContext *C, void *ntree_v, void *node_v)
548 nodeSetActive(ntree_v, node_v);
551 static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
554 bNode *node= ptr->data;
558 uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
560 if(!node->id) return;
562 prop = RNA_struct_find_property(ptr, "image");
563 if (!prop || RNA_property_type(prop) != PROP_POINTER) return;
564 imaptr= RNA_property_pointer_get(ptr, prop);
566 col= uiLayoutColumn(layout, 0);
568 uiItemR(col, NULL, 0, &imaptr, "source", 0);
570 if (ELEM(RNA_enum_get(&imaptr, "source"), IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
571 col= uiLayoutColumn(layout, 1);
572 uiItemR(col, NULL, 0, ptr, "frames", 0);
573 uiItemR(col, NULL, 0, ptr, "start", 0);
574 uiItemR(col, NULL, 0, ptr, "offset", 0);
575 uiItemR(col, NULL, 0, ptr, "cyclic", 0);
576 uiItemR(col, NULL, 0, ptr, "auto_refresh", UI_ITEM_R_ICON_ONLY);
579 col= uiLayoutColumn(layout, 0);
581 if (RNA_enum_get(&imaptr, "type")== IMA_TYPE_MULTILAYER)
582 uiItemR(col, NULL, 0, ptr, "layer", 0);
585 static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
587 bNode *node= ptr->data;
590 uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
592 if(!node->id) return;
594 col= uiLayoutColumn(layout, 0);
595 uiItemR(col, "", 0, ptr, "layer", 0);
597 /* XXX Missing 're-render this layer' button - needs completely new implementation */
601 static void node_composit_buts_blur(uiLayout *layout, bContext *C, PointerRNA *ptr)
605 col= uiLayoutColumn(layout, 0);
607 uiItemR(col, "", 0, ptr, "filter_type", 0);
608 if (RNA_enum_get(ptr, "filter_type")!= R_FILTER_FAST_GAUSS) {
609 uiItemR(col, NULL, 0, ptr, "bokeh", 0);
610 uiItemR(col, NULL, 0, ptr, "gamma", 0);
613 uiItemR(col, NULL, 0, ptr, "relative", 0);
614 col= uiLayoutColumn(layout, 1);
615 if (RNA_boolean_get(ptr, "relative")) {
616 uiItemR(col, "X", 0, ptr, "factor_x", 0);
617 uiItemR(col, "Y", 0, ptr, "factor_y", 0);
620 uiItemR(col, "X", 0, ptr, "sizex", 0);
621 uiItemR(col, "Y", 0, ptr, "sizey", 0);
625 static void node_composit_buts_dblur(uiLayout *layout, bContext *C, PointerRNA *ptr)
629 uiItemR(layout, NULL, 0, ptr, "iterations", 0);
630 uiItemR(layout, NULL, 0, ptr, "wrap", 0);
632 col= uiLayoutColumn(layout, 1);
633 uiItemL(col, "Center:", 0);
634 uiItemR(col, "X", 0, ptr, "center_x", 0);
635 uiItemR(col, "Y", 0, ptr, "center_y", 0);
639 col= uiLayoutColumn(layout, 1);
640 uiItemR(col, NULL, 0, ptr, "distance", 0);
641 uiItemR(col, NULL, 0, ptr, "angle", 0);
645 uiItemR(layout, NULL, 0, ptr, "spin", 0);
646 uiItemR(layout, NULL, 0, ptr, "zoom", 0);
649 static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *C, PointerRNA *ptr)
653 col= uiLayoutColumn(layout, 1);
654 uiItemR(col, NULL, 0, ptr, "iterations", 0);
655 uiItemR(col, NULL, 0, ptr, "sigma_color", 0);
656 uiItemR(col, NULL, 0, ptr, "sigma_space", 0);
659 static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA *ptr)
663 col= uiLayoutColumn(layout, 0);
664 uiItemL(col, "Bokeh Type:", 0);
665 uiItemR(col, "", 0, ptr, "bokeh", 0);
666 uiItemR(col, NULL, 0, ptr, "angle", 0);
668 uiItemR(layout, NULL, 0, ptr, "gamma_correction", 0);
670 col = uiLayoutColumn(layout, 0);
671 uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer")==0);
672 uiItemR(col, NULL, 0, ptr, "f_stop", 0);
674 uiItemR(layout, NULL, 0, ptr, "max_blur", 0);
675 uiItemR(layout, NULL, 0, ptr, "threshold", 0);
677 col = uiLayoutColumn(layout, 0);
678 uiItemR(col, NULL, 0, ptr, "preview", 0);
679 sub = uiLayoutColumn(col, 0);
680 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "preview"));
681 uiItemR(sub, NULL, 0, ptr, "samples", 0);
683 col = uiLayoutColumn(layout, 0);
684 uiItemR(col, NULL, 0, ptr, "use_zbuffer", 0);
685 sub = uiLayoutColumn(col, 0);
686 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer"));
687 uiItemR(sub, NULL, 0, ptr, "z_scale", 0);
690 /* qdn: glare node */
691 static void node_composit_buts_glare(uiLayout *layout, bContext *C, PointerRNA *ptr)
693 uiItemR(layout, "", 0, ptr, "glare_type", 0);
694 uiItemR(layout, "", 0, ptr, "quality", 0);
696 if (RNA_enum_get(ptr, "glare_type")!= 1) {
697 uiItemR(layout, NULL, 0, ptr, "iterations", 0);
699 if (RNA_enum_get(ptr, "glare_type")!= 0)
700 uiItemR(layout, NULL, 0, ptr, "color_modulation", UI_ITEM_R_SLIDER);
703 uiItemR(layout, NULL, 0, ptr, "mix", 0);
704 uiItemR(layout, NULL, 0, ptr, "threshold", 0);
706 if (RNA_enum_get(ptr, "glare_type")== 2) {
707 uiItemR(layout, NULL, 0, ptr, "streaks", 0);
708 uiItemR(layout, NULL, 0, ptr, "angle_offset", 0);
710 if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) {
711 uiItemR(layout, NULL, 0, ptr, "fade", UI_ITEM_R_SLIDER);
713 if (RNA_enum_get(ptr, "glare_type")== 0)
714 uiItemR(layout, NULL, 0, ptr, "rotate_45", 0);
716 if (RNA_enum_get(ptr, "glare_type")== 1) {
717 uiItemR(layout, NULL, 0, ptr, "size", 0);
721 static void node_composit_buts_tonemap(uiLayout *layout, bContext *C, PointerRNA *ptr)
725 col = uiLayoutColumn(layout, 0);
726 uiItemR(col, "", 0, ptr, "tonemap_type", 0);
727 if (RNA_enum_get(ptr, "tonemap_type")== 0) {
728 uiItemR(col, NULL, 0, ptr, "key", UI_ITEM_R_SLIDER);
729 uiItemR(col, NULL, 0, ptr, "offset", 0);
730 uiItemR(col, NULL, 0, ptr, "gamma", 0);
733 uiItemR(col, NULL, 0, ptr, "intensity", 0);
734 uiItemR(col, NULL, 0, ptr, "contrast", UI_ITEM_R_SLIDER);
735 uiItemR(col, NULL, 0, ptr, "adaptation", UI_ITEM_R_SLIDER);
736 uiItemR(col, NULL, 0, ptr, "correction", UI_ITEM_R_SLIDER);
740 static void node_composit_buts_lensdist(uiLayout *layout, bContext *C, PointerRNA *ptr)
744 col= uiLayoutColumn(layout, 0);
745 uiItemR(col, NULL, 0, ptr, "projector", 0);
747 col = uiLayoutColumn(col, 0);
748 uiLayoutSetActive(col, RNA_boolean_get(ptr, "projector")==0);
749 uiItemR(col, NULL, 0, ptr, "jitter", 0);
750 uiItemR(col, NULL, 0, ptr, "fit", 0);
753 static void node_composit_buts_vecblur(uiLayout *layout, bContext *C, PointerRNA *ptr)
757 col= uiLayoutColumn(layout, 0);
758 uiItemR(col, NULL, 0, ptr, "samples", 0);
759 uiItemR(col, "Blur", 0, ptr, "factor", 0);
761 col= uiLayoutColumn(layout, 1);
762 uiItemL(col, "Speed:", 0);
763 uiItemR(col, "Min", 0, ptr, "min_speed", 0);
764 uiItemR(col, "Max", 0, ptr, "max_speed", 0);
766 uiItemR(layout, NULL, 0, ptr, "curved", 0);
769 static void node_composit_buts_filter(uiLayout *layout, bContext *C, PointerRNA *ptr)
771 uiItemR(layout, "", 0, ptr, "filter_type", 0);
774 static void node_composit_buts_flip(uiLayout *layout, bContext *C, PointerRNA *ptr)
776 uiItemR(layout, "", 0, ptr, "axis", 0);
779 static void node_composit_buts_crop(uiLayout *layout, bContext *C, PointerRNA *ptr)
783 uiItemR(layout, NULL, 0, ptr, "crop_size", 0);
785 col= uiLayoutColumn(layout, 1);
786 uiItemR(col, "Left", 0, ptr, "x1", 0);
787 uiItemR(col, "Right", 0, ptr, "x2", 0);
788 uiItemR(col, "Up", 0, ptr, "y1", 0);
789 uiItemR(col, "Down", 0, ptr, "y2", 0);
792 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *C, PointerRNA *ptr)
796 col= uiLayoutColumn(layout, 0);
797 row= uiLayoutRow(col, 0);
798 uiItemR(row, NULL, 0, ptr, "axis", UI_ITEM_R_EXPAND);
799 uiItemR(col, NULL, 0, ptr, "factor", 0);
802 static void node_composit_buts_map_value(uiLayout *layout, bContext *C, PointerRNA *ptr)
806 col =uiLayoutColumn(layout, 1);
807 uiItemR(col, NULL, 0, ptr, "offset", 0);
808 uiItemR(col, NULL, 0, ptr, "size", 0);
810 col =uiLayoutColumn(layout, 1);
811 uiItemR(col, NULL, 0, ptr, "use_min", 0);
812 sub =uiLayoutColumn(col, 0);
813 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
814 uiItemR(sub, "", 0, ptr, "min", 0);
816 col =uiLayoutColumn(layout, 1);
817 uiItemR(col, NULL, 0, ptr, "use_max", 0);
818 sub =uiLayoutColumn(col, 0);
819 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
820 uiItemR(sub, "", 0, ptr, "max", 0);
823 static void node_composit_buts_alphaover(uiLayout *layout, bContext *C, PointerRNA *ptr)
827 col =uiLayoutColumn(layout, 1);
828 uiItemR(col, NULL, 0, ptr, "convert_premul", 0);
829 uiItemR(col, NULL, 0, ptr, "premul", 0);
832 static void node_composit_buts_hue_sat(uiLayout *layout, bContext *C, PointerRNA *ptr)
836 col =uiLayoutColumn(layout, 0);
837 uiItemR(col, NULL, 0, ptr, "hue", UI_ITEM_R_SLIDER);
838 uiItemR(col, NULL, 0, ptr, "sat", UI_ITEM_R_SLIDER);
839 uiItemR(col, NULL, 0, ptr, "val", UI_ITEM_R_SLIDER);
842 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *C, PointerRNA *ptr)
844 uiItemR(layout, NULL, 0, ptr, "distance", 0);
847 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
851 col =uiLayoutColumn(layout, 1);
852 uiItemR(col, NULL, 0, ptr, "tolerance", UI_ITEM_R_SLIDER);
853 uiItemR(col, NULL, 0, ptr, "falloff", UI_ITEM_R_SLIDER);
856 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
860 col =uiLayoutColumn(layout, 1);
861 uiItemR(col, NULL, 0, ptr, "tolerance", UI_ITEM_R_SLIDER);
862 uiItemR(col, NULL, 0, ptr, "falloff", UI_ITEM_R_SLIDER);
865 static void node_composit_buts_color_spill(uiLayout *layout, bContext *C, PointerRNA *ptr)
869 col =uiLayoutColumn(layout, 0);
870 uiItemR(col, NULL, 0, ptr, "factor", 0);
871 row= uiLayoutRow(col, 0);
872 uiItemR(row, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND);
875 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
879 col= uiLayoutColumn(layout, 0);
880 uiItemR(col, NULL, 0, ptr, "acceptance", 0);
881 uiItemR(col, NULL, 0, ptr, "cutoff", 0);
883 col= uiLayoutColumn(layout, 1);
884 uiItemR(col, NULL, 0, ptr, "lift", UI_ITEM_R_SLIDER);
885 uiItemR(col, NULL, 0, ptr, "gain", UI_ITEM_R_SLIDER);
886 uiItemR(col, NULL, 0, ptr, "shadow_adjust", UI_ITEM_R_SLIDER);
889 static void node_composit_buts_color_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
893 col= uiLayoutColumn(layout, 1);
894 uiItemR(col, NULL, 0, ptr, "h", UI_ITEM_R_SLIDER);
895 uiItemR(col, NULL, 0, ptr, "s", UI_ITEM_R_SLIDER);
896 uiItemR(col, NULL, 0, ptr, "v", UI_ITEM_R_SLIDER);
899 static void node_composit_buts_channel_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
903 row= uiLayoutRow(layout, 0);
904 uiItemR(row, NULL, 0, ptr, "color_space", UI_ITEM_R_EXPAND);
906 row= uiLayoutRow(layout, 0);
907 uiItemR(row, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND);
909 col =uiLayoutColumn(layout, 1);
910 uiItemR(col, NULL, 0, ptr, "high", UI_ITEM_R_SLIDER);
911 uiItemR(col, NULL, 0, ptr, "low", UI_ITEM_R_SLIDER);
914 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
918 col= uiLayoutColumn(layout, 1);
919 uiItemR(col, NULL, 0, ptr, "high", UI_ITEM_R_SLIDER);
920 uiItemR(col, NULL, 0, ptr, "low", UI_ITEM_R_SLIDER);
923 static void node_composit_buts_map_uv(uiLayout *layout, bContext *C, PointerRNA *ptr)
925 uiItemR(layout, NULL, 0, ptr, "alpha", 0);
928 static void node_composit_buts_id_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
930 uiItemR(layout, NULL, 0, ptr, "index", 0);
933 static void node_composit_buts_file_output(uiLayout *layout, bContext *C, PointerRNA *ptr)
937 col= uiLayoutColumn(layout, 0);
938 uiItemR(col, "", 0, ptr, "filename", 0);
939 uiItemR(col, "", 0, ptr, "image_type", 0);
941 row= uiLayoutRow(layout, 0);
942 if (RNA_enum_get(ptr, "image_type")== R_OPENEXR) {
943 uiItemR(row, NULL, 0, ptr, "exr_half", 0);
944 uiItemR(row, "", 0, ptr, "exr_codec", 0);
946 else if (RNA_enum_get(ptr, "image_type")== R_JPEG90) {
947 uiItemR(row, NULL, 0, ptr, "quality", UI_ITEM_R_SLIDER);
950 row= uiLayoutRow(layout, 1);
951 uiItemR(row, "Start", 0, ptr, "start_frame", 0);
952 uiItemR(row, "End", 0, ptr, "end_frame", 0);
955 static void node_composit_buts_scale(uiLayout *layout, bContext *C, PointerRNA *ptr)
957 uiItemR(layout, "", 0, ptr, "space", 0);
960 static void node_composit_buts_invert(uiLayout *layout, bContext *C, PointerRNA *ptr)
964 col= uiLayoutColumn(layout, 0);
965 uiItemR(col, NULL, 0, ptr, "rgb", 0);
966 uiItemR(col, NULL, 0, ptr, "alpha", 0);
969 static void node_composit_buts_premulkey(uiLayout *layout, bContext *C, PointerRNA *ptr)
971 uiItemR(layout, "", 0, ptr, "mapping", 0);
974 static void node_composit_buts_view_levels(uiLayout *layout, bContext *C, PointerRNA *ptr)
976 uiItemR(layout, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND);
979 /* only once called */
980 static void node_composit_set_butfunc(bNodeType *ntype)
982 switch(ntype->type) {
983 /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */
986 ntype->uifunc= node_composit_buts_image;
988 case CMP_NODE_R_LAYERS:
989 ntype->uifunc= node_composit_buts_renderlayers;
991 case CMP_NODE_NORMAL:
992 ntype->uifunc= node_buts_normal;
994 case CMP_NODE_CURVE_VEC:
995 ntype->uifunc= node_buts_curvevec;
997 case CMP_NODE_CURVE_RGB:
998 ntype->uifunc= node_buts_curvecol;
1000 case CMP_NODE_VALUE:
1001 ntype->uifunc= node_buts_value;
1004 ntype->uifunc= node_buts_rgb;
1007 ntype->uifunc= node_composit_buts_flip;
1009 case CMP_NODE_SPLITVIEWER:
1010 ntype->uifunc= node_composit_buts_splitviewer;
1012 case CMP_NODE_MIX_RGB:
1013 ntype->uifunc= node_buts_mix_rgb;
1015 case CMP_NODE_VALTORGB:
1016 ntype->uifunc= node_buts_colorramp;
1019 ntype->uifunc= node_composit_buts_crop;
1022 ntype->uifunc= node_composit_buts_blur;
1024 case CMP_NODE_DBLUR:
1025 ntype->uifunc= node_composit_buts_dblur;
1027 case CMP_NODE_BILATERALBLUR:
1028 ntype->uifunc= node_composit_buts_bilateralblur;
1030 case CMP_NODE_DEFOCUS:
1031 ntype->uifunc = node_composit_buts_defocus;
1033 case CMP_NODE_GLARE:
1034 ntype->uifunc = node_composit_buts_glare;
1036 case CMP_NODE_TONEMAP:
1037 ntype->uifunc = node_composit_buts_tonemap;
1039 case CMP_NODE_LENSDIST:
1040 ntype->uifunc = node_composit_buts_lensdist;
1042 case CMP_NODE_VECBLUR:
1043 ntype->uifunc= node_composit_buts_vecblur;
1045 case CMP_NODE_FILTER:
1046 ntype->uifunc= node_composit_buts_filter;
1048 case CMP_NODE_MAP_VALUE:
1049 ntype->uifunc= node_composit_buts_map_value;
1052 ntype->uifunc= node_buts_time;
1054 case CMP_NODE_ALPHAOVER:
1055 ntype->uifunc= node_composit_buts_alphaover;
1057 case CMP_NODE_HUE_SAT:
1058 ntype->uifunc= node_composit_buts_hue_sat;
1060 case CMP_NODE_TEXTURE:
1061 ntype->uifunc= node_buts_texture;
1063 case CMP_NODE_DILATEERODE:
1064 ntype->uifunc= node_composit_buts_dilateerode;
1066 case CMP_NODE_OUTPUT_FILE:
1067 ntype->uifunc= node_composit_buts_file_output;
1069 case CMP_NODE_DIFF_MATTE:
1070 ntype->uifunc=node_composit_buts_diff_matte;
1072 case CMP_NODE_DIST_MATTE:
1073 ntype->uifunc=node_composit_buts_distance_matte;
1075 case CMP_NODE_COLOR_SPILL:
1076 ntype->uifunc=node_composit_buts_color_spill;
1078 case CMP_NODE_CHROMA_MATTE:
1079 ntype->uifunc=node_composit_buts_chroma_matte;
1081 case CMP_NODE_COLOR_MATTE:
1082 ntype->uifunc=node_composit_buts_color_matte;
1084 case CMP_NODE_SCALE:
1085 ntype->uifunc= node_composit_buts_scale;
1087 case CMP_NODE_CHANNEL_MATTE:
1088 ntype->uifunc= node_composit_buts_channel_matte;
1090 case CMP_NODE_LUMA_MATTE:
1091 ntype->uifunc= node_composit_buts_luma_matte;
1093 case CMP_NODE_MAP_UV:
1094 ntype->uifunc= node_composit_buts_map_uv;
1096 case CMP_NODE_ID_MASK:
1097 ntype->uifunc= node_composit_buts_id_mask;
1100 ntype->uifunc= node_buts_math;
1102 case CMP_NODE_INVERT:
1103 ntype->uifunc= node_composit_buts_invert;
1105 case CMP_NODE_PREMULKEY:
1106 ntype->uifunc= node_composit_buts_premulkey;
1108 case CMP_NODE_VIEW_LEVELS:
1109 ntype->uifunc=node_composit_buts_view_levels;
1112 ntype->uifunc= NULL;
1116 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
1118 static void node_texture_buts_bricks(uiLayout *layout, bContext *C, PointerRNA *ptr)
1122 col= uiLayoutColumn(layout, 1);
1123 uiItemR(col, "Offset", 0, ptr, "offset", 0);
1124 uiItemR(col, "Frequency", 0, ptr, "offset_frequency", 0);
1126 col= uiLayoutColumn(layout, 1);
1127 uiItemR(col, "Squash", 0, ptr, "squash", 0);
1128 uiItemR(col, "Frequency", 0, ptr, "squash_frequency", 0);
1131 /* Copied from buttons_shading.c -- needs unifying */
1132 static char* noisebasis_menu()
1134 static char nbmenu[256];
1135 sprintf(nbmenu, "Noise Basis %%t|Blender Original %%x%d|Original Perlin %%x%d|Improved Perlin %%x%d|Voronoi F1 %%x%d|Voronoi F2 %%x%d|Voronoi F3 %%x%d|Voronoi F4 %%x%d|Voronoi F2-F1 %%x%d|Voronoi Crackle %%x%d|CellNoise %%x%d", TEX_BLENDER, TEX_STDPERLIN, TEX_NEWPERLIN, TEX_VORONOI_F1, TEX_VORONOI_F2, TEX_VORONOI_F3, TEX_VORONOI_F4, TEX_VORONOI_F2F1, TEX_VORONOI_CRACKLE, TEX_CELLNOISE);
1139 static void node_texture_buts_proc(uiLayout *layout, bContext *C, PointerRNA *ptr)
1141 uiBlock *block= uiLayoutAbsoluteBlock(layout);
1142 bNode *node= ptr->data;
1143 rctf *butr= &node->butr;
1144 Tex *tex = (Tex *)node->storage;
1152 switch( tex->type ) {
1154 uiBlockBeginAlign( block );
1155 uiDefButS( block, MENU, B_NODE_EXEC,
1156 "Linear %x0|Quad %x1|Ease %x2|Diag %x3|Sphere %x4|Halo %x5|Radial %x6",
1157 x, y+20, w, 20, &tex->stype, 0, 1, 0, 0, "Blend Type" );
1158 uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_NODE_EXEC, "Flip XY", x, y, w, 20,
1159 &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees");
1160 uiBlockEndAlign( block );
1164 uiBlockBeginAlign(block);
1166 uiDefButS(block, ROW, B_NODE_EXEC, "Soft", 0*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble");
1167 uiDefButS(block, ROW, B_NODE_EXEC, "Sharp", 1*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble");
1168 uiDefButS(block, ROW, B_NODE_EXEC, "Sharper", 2*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble");
1170 uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
1171 uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
1173 uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands.");
1174 uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands");
1175 uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands");
1177 uiBlockEndAlign(block);
1181 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+64, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
1183 uiBlockBeginAlign(block);
1184 uiDefButS(block, ROW, B_TEXPRV, "Bands", x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Uses standard noise");
1185 uiDefButS(block, ROW, B_TEXPRV, "Rings", w/2+x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Lets Noise return RGB value");
1187 uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands.");
1188 uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands");
1189 uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands");
1191 uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
1192 uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
1193 uiBlockEndAlign(block);
1197 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+60, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
1199 uiBlockBeginAlign(block);
1200 uiDefButS(block, ROW, B_TEXPRV, "B/W", x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise");
1201 uiDefButS(block, ROW, B_TEXPRV, "Color", w/2+x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value");
1202 uiDefButS(block, ROW, B_TEXPRV, "Soft", x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
1203 uiDefButS(block, ROW, B_TEXPRV, "Hard", w/2+x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
1204 uiBlockEndAlign(block);
1206 uiDefButS(block, NUM, B_TEXPRV, "Depth:", x, y, w, 18, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation");
1210 uiBlockBeginAlign(block);
1211 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+18, w, 18, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort");
1212 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion");
1213 uiBlockEndAlign(block);
1218 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
1220 uiBlock *block= uiLayoutAbsoluteBlock(layout);
1221 bNode *node= ptr->data;
1222 bNodeTree *ntree= ptr->id.data;
1223 rctf *butr= &node->butr;
1227 uiBlockBeginAlign(block);
1230 IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL);
1232 bt= uiDefButS(block, MENU, B_NOP, strp,
1233 butr->xmin, butr->ymin, 19, 19,
1234 &node->menunr, 0, 0, 0, 0, "Browses existing choices");
1235 uiButSetFunc(bt, node_browse_image_cb, ntree, node);
1236 if(strp) MEM_freeN(strp);
1238 /* Add New button */
1239 if(node->id==NULL) {
1240 bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New",
1241 butr->xmin+19, butr->ymin, (short)(butr->xmax-butr->xmin-19.0f), 19,
1242 NULL, 0.0, 0.0, 0, 0, "Add new Image");
1243 uiButSetFunc(bt, node_active_cb, ntree, node);
1247 short xmin= (short)butr->xmin, xmax= (short)butr->xmax;
1248 short width= xmax - xmin - 19;
1250 bt= uiDefBut(block, TEX, B_NOP, "IM:",
1251 xmin+19, butr->ymin, width, 19,
1252 node->id->name+2, 0.0, 19.0, 0, 0, "Image name");
1253 uiButSetFunc(bt, node_ID_title_cb, node, NULL);
1257 static void node_texture_buts_output(uiLayout *layout, bContext *C, PointerRNA *ptr)
1259 uiItemR(layout, "", 0, ptr, "output_name", 0);
1262 /* only once called */
1263 static void node_texture_set_butfunc(bNodeType *ntype)
1265 if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) {
1266 ntype->uifunc = node_texture_buts_proc;
1268 else switch(ntype->type) {
1271 ntype->uifunc = node_buts_math;
1274 case TEX_NODE_MIX_RGB:
1275 ntype->uifunc = node_buts_mix_rgb;
1278 case TEX_NODE_VALTORGB:
1279 ntype->uifunc = node_buts_colorramp;
1282 case TEX_NODE_CURVE_RGB:
1283 ntype->uifunc= node_buts_curvecol;
1286 case TEX_NODE_CURVE_TIME:
1287 ntype->uifunc = node_buts_time;
1290 case TEX_NODE_TEXTURE:
1291 ntype->uifunc = node_buts_texture;
1294 case TEX_NODE_BRICKS:
1295 ntype->uifunc = node_texture_buts_bricks;
1298 case TEX_NODE_IMAGE:
1299 ntype->uifunc = node_texture_buts_image;
1302 case TEX_NODE_OUTPUT:
1303 ntype->uifunc = node_texture_buts_output;
1307 ntype->uifunc= NULL;
1311 /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */
1313 void ED_init_node_butfuncs(void)
1318 ntype= node_all_shaders.first;
1320 node_shader_set_butfunc(ntype);
1323 /* composit nodes */
1324 ntype= node_all_composit.first;
1326 node_composit_set_butfunc(ntype);
1329 ntype = node_all_textures.first;
1331 node_texture_set_butfunc(ntype);
1336 /* ************** Generic drawing ************** */
1339 void node_rename_but(char *s)
1342 ListBase listb={0, 0};
1343 int dy, x1, y1, sizex=80, sizey=30;
1344 short pivot[2], mval[2], ret=0;
1346 getmouseco_sc(mval);
1348 pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30);
1349 pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10);
1351 if (pivot[0]!=mval[0] || pivot[1]!=mval[1])
1352 warp_pointer(pivot[0], pivot[1]);
1354 mywinset(G.curscreen->mainwin);
1356 x1= pivot[0]-sizex+10;
1357 y1= pivot[1]-sizey/2;
1360 block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1361 uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK);
1363 /* buttons have 0 as return event, to prevent menu to close on hotkeys */
1364 uiBlockBeginAlign(block);
1366 uiDefBut(block, TEX, B_NOP, "Name: ", (short)(x1),(short)(y1+dy), 150, 19, s, 0.0, 19.0, 0, 0, "Node user name");
1368 uiBlockEndAlign(block);
1370 uiDefBut(block, BUT, 32767, "OK", (short)(x1+150), (short)(y1+dy), 29, 19, NULL, 0, 0, 0, 0, "");
1372 uiBoundsBlock(block, 2);
1374 ret= uiDoBlocks(&listb, 0, 0);
1379 void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage)
1382 if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) {
1383 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1385 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
1391 /* somehow the offset has to be calculated inverse */
1393 glaDefine2DArea(&ar->winrct);
1394 /* ortho at pixel level curarea */
1395 wmOrtho2(-0.375, ar->winx-0.375, -0.375, ar->winy-0.375);
1397 x = (ar->winx-ibuf->x)/2 + snode->xof;
1398 y = (ar->winy-ibuf->y)/2 + snode->yof;
1402 ibuf->profile= IB_PROFILE_SRGB;
1404 ibuf->profile = IB_PROFILE_NONE;
1405 IMB_rect_from_float(ibuf);
1409 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1414 BKE_image_release_ibuf(ima, lock);
1419 /* note: needs to be userpref or opengl profile option */
1420 static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
1423 draw_nodespace_grid(snode);
1425 if(snode->flag & SNODE_BACKDRAW) {
1426 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1427 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1432 glMatrixMode(GL_PROJECTION);
1434 glMatrixMode(GL_MODELVIEW);
1437 glaDefine2DArea(&sa->winrct);
1439 if(ibuf->x > sa->winx || ibuf->y > sa->winy) {
1441 zoomx= (float)sa->winx/ibuf->x;
1442 zoomy= (float)sa->winy/ibuf->y;
1443 zoom = MIN2(zoomx, zoomy);
1446 x = (sa->winx-zoom*ibuf->x)/2 + snode->xof;
1447 y = (sa->winy-zoom*ibuf->y)/2 + snode->yof;
1449 glPixelZoom(zoom, zoom);
1451 glColor4f(1.0, 1.0, 1.0, 1.0);
1453 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
1454 else if(ibuf->channels==4)
1455 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float);
1457 glPixelZoom(1.0, 1.0);
1459 glMatrixMode(GL_PROJECTION);
1461 glMatrixMode(GL_MODELVIEW);
1468 /* if v2d not NULL, it clips and returns 0 if not visible */
1469 int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
1471 float dist, vec[4][2];
1473 /* in v0 and v3 we put begin/end points */
1474 if(link->fromsock) {
1475 vec[0][0]= link->fromsock->locx;
1476 vec[0][1]= link->fromsock->locy;
1479 if(snode==NULL) return 0;
1480 vec[0][0]= snode->mx;
1481 vec[0][1]= snode->my;
1484 vec[3][0]= link->tosock->locx;
1485 vec[3][1]= link->tosock->locy;
1488 if(snode==NULL) return 0;
1489 vec[3][0]= snode->mx;
1490 vec[3][1]= snode->my;
1493 dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
1495 /* check direction later, for top sockets */
1496 vec[1][0]= vec[0][0]+dist;
1497 vec[1][1]= vec[0][1];
1499 vec[2][0]= vec[3][0]-dist;
1500 vec[2][1]= vec[3][1];
1502 if(v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax); /* clipped */
1503 else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin); /* clipped */
1506 /* always do all three, to prevent data hanging around */
1507 forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2);
1508 forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2);
1515 #define LINK_RESOL 24
1516 void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int do_shaded)
1518 float coord_array[LINK_RESOL+1][2];
1520 if(node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
1521 float dist, spline_step = 0.0f;
1524 /* we can reuse the dist variable here to increment the GL curve eval amount*/
1525 dist = 1.0f/(float)LINK_RESOL;
1527 glBegin(GL_LINE_STRIP);
1528 for(i=0; i<=LINK_RESOL; i++) {
1530 UI_ThemeColorBlend(th_col1, th_col2, spline_step);
1531 spline_step += dist;
1533 glVertex2fv(coord_array[i]);
1539 /* note; this is used for fake links in groups too */
1540 void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
1542 int do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
1544 if(link->fromnode==NULL && link->tonode==NULL)
1547 if(link->fromnode==NULL || link->tonode==NULL) {
1548 UI_ThemeColor(TH_WIRE);
1552 /* going to give issues once... */
1553 if(link->tosock->flag & SOCK_UNAVAIL)
1555 if(link->fromsock->flag & SOCK_UNAVAIL)
1558 /* a bit ugly... but thats how we detect the internal group links */
1559 if(link->fromnode==link->tonode) {
1560 UI_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
1565 if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
1566 if(link->fromnode->flag & SELECT)
1567 th_col1= TH_EDGE_SELECT;
1568 if(link->tonode->flag & SELECT)
1569 th_col2= TH_EDGE_SELECT;
1572 UI_ThemeColor(TH_REDALERT);
1578 node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, do_shaded);