Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2005 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <math.h> 00034 #include <stdio.h> 00035 #include <string.h> 00036 00037 #include "BLI_blenlib.h" 00038 #include "BLI_math.h" 00039 #include "BLI_utildefines.h" 00040 00041 #include "DNA_node_types.h" 00042 #include "DNA_material_types.h" 00043 #include "DNA_object_types.h" 00044 #include "DNA_scene_types.h" 00045 #include "DNA_space_types.h" 00046 #include "DNA_screen_types.h" 00047 00048 #include "BKE_context.h" 00049 #include "BKE_curve.h" 00050 #include "BKE_global.h" 00051 #include "BKE_image.h" 00052 #include "BKE_library.h" 00053 #include "BKE_main.h" 00054 #include "BKE_node.h" 00055 00056 #include "NOD_composite.h" 00057 #include "NOD_shader.h" 00058 00059 #include "BIF_gl.h" 00060 #include "BIF_glutil.h" 00061 00062 #include "BLF_api.h" 00063 00064 #include "MEM_guardedalloc.h" 00065 00066 00067 #include "RNA_access.h" 00068 00069 #include "ED_node.h" 00070 00071 #include "WM_api.h" 00072 #include "WM_types.h" 00073 00074 #include "UI_interface.h" 00075 #include "UI_resources.h" 00076 00077 #include "IMB_imbuf.h" 00078 #include "IMB_imbuf_types.h" 00079 00080 #include "node_intern.h" 00081 00082 00083 // XXX interface.h 00084 extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); 00085 00086 /* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */ 00087 00088 static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v) 00089 { 00090 SpaceNode *snode= snode_v; 00091 00092 if(snode->treetype==NTREE_SHADER) { 00093 nodeShaderSynchronizeID(node_v, 1); 00094 // allqueue(REDRAWBUTSSHADING, 0); 00095 } 00096 } 00097 00098 static void node_socket_button_label(const bContext *UNUSED(C), uiBlock *block, 00099 bNodeTree *UNUSED(ntree), bNode *UNUSED(node), bNodeSocket *sock, 00100 const char *UNUSED(name), int x, int y, int width) 00101 { 00102 uiDefBut(block, LABEL, 0, sock->name, x, y, width, NODE_DY, NULL, 0, 0, 0, 0, ""); 00103 } 00104 00105 00106 static void node_socket_button_default(const bContext *C, uiBlock *block, 00107 bNodeTree *ntree, bNode *node, bNodeSocket *sock, 00108 const char *name, int x, int y, int width) 00109 { 00110 PointerRNA ptr; 00111 uiBut *bt; 00112 00113 RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); 00114 00115 bt = uiDefButR(block, NUM, B_NODE_EXEC, name, 00116 x, y+1, width, NODE_DY-2, 00117 &ptr, "default_value", 0, 0, 0, -1, -1, NULL); 00118 if (node) 00119 uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); 00120 } 00121 00122 typedef struct SocketComponentMenuArgs { 00123 PointerRNA ptr; 00124 int x, y, width; 00125 uiButHandleFunc cb; 00126 void *arg1, *arg2; 00127 } SocketComponentMenuArgs; 00128 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ 00129 static uiBlock *socket_component_menu(bContext *C, ARegion *ar, void *args_v) 00130 { 00131 SocketComponentMenuArgs *args= (SocketComponentMenuArgs*)args_v; 00132 uiBlock *block; 00133 uiLayout *layout; 00134 00135 block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); 00136 uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); 00137 00138 layout= uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, args->x, args->y+2, args->width, NODE_DY, UI_GetStyle()), 0); 00139 00140 uiItemR(layout, &args->ptr, "default_value", UI_ITEM_R_EXPAND, "", ICON_NONE); 00141 00142 return block; 00143 } 00144 static void node_socket_button_components(const bContext *C, uiBlock *block, 00145 bNodeTree *ntree, bNode *node, bNodeSocket *sock, 00146 const char *name, int x, int y, int width) 00147 { 00148 PointerRNA ptr; 00149 SocketComponentMenuArgs *args; 00150 00151 RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); 00152 00153 args= MEM_callocN(sizeof(SocketComponentMenuArgs), "SocketComponentMenuArgs"); 00154 00155 args->ptr = ptr; 00156 args->x = x; 00157 args->y = y; 00158 args->width = width; 00159 args->cb = node_sync_cb; 00160 args->arg1 = CTX_wm_space_node(C); 00161 args->arg2 = node; 00162 00163 uiDefBlockButN(block, socket_component_menu, args, name, x, y+1, width, NODE_DY-2, ""); 00164 } 00165 00166 static void node_socket_button_color(const bContext *C, uiBlock *block, 00167 bNodeTree *ntree, bNode *node, bNodeSocket *sock, 00168 const char *name, int x, int y, int width) 00169 { 00170 PointerRNA ptr; 00171 uiBut *bt; 00172 int labelw= width - 40; 00173 00174 RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); 00175 00176 bt=uiDefButR(block, COL, B_NODE_EXEC, "", 00177 x, y+2, (labelw>0 ? 40 : width), NODE_DY-2, 00178 &ptr, "default_value", 0, 0, 0, -1, -1, NULL); 00179 if (node) 00180 uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); 00181 00182 if (name[0]!='\0' && labelw>0) 00183 uiDefBut(block, LABEL, 0, name, x + 40, y+2, labelw, NODE_DY-2, NULL, 0, 0, 0, 0, ""); 00184 } 00185 00186 /* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */ 00187 00188 #if 0 /* UNUSED */ 00189 static void node_draw_socket_new(bNodeSocket *sock, float size) 00190 { 00191 float x=sock->locx, y=sock->locy; 00192 00193 /* 16 values of sin function */ 00194 static float si[16] = { 00195 0.00000000f, 0.39435585f,0.72479278f,0.93775213f, 00196 0.99871650f,0.89780453f,0.65137248f,0.29936312f, 00197 -0.10116832f,-0.48530196f,-0.79077573f,-0.96807711f, 00198 -0.98846832f,-0.84864425f,-0.57126821f,-0.20129852f 00199 }; 00200 /* 16 values of cos function */ 00201 static float co[16] ={ 00202 1.00000000f,0.91895781f,0.68896691f,0.34730525f, 00203 -0.05064916f,-0.44039415f,-0.75875812f,-0.95413925f, 00204 -0.99486932f,-0.87434661f,-0.61210598f,-0.25065253f, 00205 0.15142777f,0.52896401f,0.82076344f,0.97952994f, 00206 }; 00207 int a; 00208 00209 glColor3ub(180, 180, 180); 00210 00211 glBegin(GL_POLYGON); 00212 for(a=0; a<16; a++) 00213 glVertex2f(x+size*si[a], y+size*co[a]); 00214 glEnd(); 00215 00216 glColor4ub(0, 0, 0, 150); 00217 glEnable(GL_BLEND); 00218 glEnable( GL_LINE_SMOOTH ); 00219 glBegin(GL_LINE_LOOP); 00220 for(a=0; a<16; a++) 00221 glVertex2f(x+size*si[a], y+size*co[a]); 00222 glEnd(); 00223 glDisable( GL_LINE_SMOOTH ); 00224 glDisable(GL_BLEND); 00225 } 00226 #endif 00227 00228 /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */ 00229 00230 static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00231 { 00232 PointerRNA sockptr; 00233 PropertyRNA *prop; 00234 00235 /* first socket stores value */ 00236 prop = RNA_struct_find_property(ptr, "outputs"); 00237 RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr); 00238 00239 uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE); 00240 } 00241 00242 static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00243 { 00244 uiLayout *col; 00245 PointerRNA sockptr; 00246 PropertyRNA *prop; 00247 00248 /* first socket stores value */ 00249 prop = RNA_struct_find_property(ptr, "outputs"); 00250 RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr); 00251 00252 col = uiLayoutColumn(layout, 0); 00253 uiTemplateColorWheel(col, &sockptr, "default_value", 1, 0, 0, 0); 00254 uiItemR(col, &sockptr, "default_value", 0, "", ICON_NONE); 00255 } 00256 00257 static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00258 { 00259 uiLayout *row; 00260 00261 bNodeTree *ntree= (bNodeTree*)ptr->id.data; 00262 00263 row= uiLayoutRow(layout, 1); 00264 uiItemR(row, ptr, "blend_type", 0, "", ICON_NONE); 00265 if(ntree->type == NTREE_COMPOSIT) 00266 uiItemR(row, ptr, "use_alpha", 0, "", ICON_IMAGE_RGB_ALPHA); 00267 } 00268 00269 static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00270 { 00271 uiLayout *row; 00272 #if 0 00273 /* XXX no context access here .. */ 00274 bNode *node= ptr->data; 00275 CurveMapping *cumap= node->storage; 00276 00277 if(cumap) { 00278 cumap->flag |= CUMA_DRAW_CFRA; 00279 if(node->custom1<node->custom2) 00280 cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1); 00281 } 00282 #endif 00283 00284 uiTemplateCurveMapping(layout, ptr, "curve", 's', 0, 0); 00285 00286 row= uiLayoutRow(layout, 1); 00287 uiItemR(row, ptr, "frame_start", 0, "Sta", ICON_NONE); 00288 uiItemR(row, ptr, "frame_end", 0, "End", ICON_NONE); 00289 } 00290 00291 static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00292 { 00293 uiTemplateColorRamp(layout, ptr, "color_ramp", 0); 00294 } 00295 00296 static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00297 { 00298 uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0, 0); 00299 } 00300 00301 static float *_sample_col= NULL; // bad bad, 2.5 will do better? 00302 #if 0 00303 static void node_curvemap_sample(float *col) 00304 { 00305 _sample_col= col; 00306 } 00307 #endif 00308 00309 static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00310 { 00311 bNode *node= ptr->data; 00312 CurveMapping *cumap= node->storage; 00313 00314 if(_sample_col) { 00315 cumap->flag |= CUMA_DRAW_SAMPLE; 00316 copy_v3_v3(cumap->sample, _sample_col); 00317 } 00318 else 00319 cumap->flag &= ~CUMA_DRAW_SAMPLE; 00320 00321 uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0); 00322 } 00323 00324 static void node_normal_cb(bContext *C, void *ntree_v, void *node_v) 00325 { 00326 Main *bmain = CTX_data_main(C); 00327 00328 ED_node_generic_update(bmain, ntree_v, node_v); 00329 WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree_v); 00330 } 00331 00332 static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00333 { 00334 uiBlock *block= uiLayoutAbsoluteBlock(layout); 00335 bNodeTree *ntree= ptr->id.data; 00336 bNode *node= ptr->data; 00337 rctf *butr= &node->butr; 00338 bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ 00339 float *nor= ((bNodeSocketValueVector*)sock->default_value)->value; 00340 uiBut *bt; 00341 00342 bt= uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", 00343 (short)butr->xmin, (short)butr->xmin, 00344 butr->xmax-butr->xmin, butr->xmax-butr->xmin, 00345 nor, 0.0f, 1.0f, 0, 0, ""); 00346 uiButSetFunc(bt, node_normal_cb, ntree, node); 00347 } 00348 #if 0 // not used in 2.5x yet 00349 static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v) 00350 { 00351 Main *bmain= CTX_data_main(C); 00352 bNodeTree *ntree= ntree_v; 00353 bNode *node= node_v; 00354 Tex *tex; 00355 00356 if(node->menunr<1) return; 00357 00358 if(node->id) { 00359 node->id->us--; 00360 node->id= NULL; 00361 } 00362 tex= BLI_findlink(&bmain->tex, node->menunr-1); 00363 00364 node->id= &tex->id; 00365 id_us_plus(node->id); 00366 BLI_strncpy(node->name, node->id->name+2, sizeof(node->name)); 00367 00368 nodeSetActive(ntree, node); 00369 00370 if( ntree->type == NTREE_TEXTURE ) 00371 ntreeTexCheckCyclics( ntree ); 00372 00373 // allqueue(REDRAWBUTSSHADING, 0); 00374 // allqueue(REDRAWNODE, 0); 00375 NodeTagChanged(ntree, node); 00376 00377 node->menunr= 0; 00378 } 00379 #endif 00380 static void node_dynamic_update_cb(bContext *C, void *UNUSED(ntree_v), void *node_v) 00381 { 00382 Main *bmain= CTX_data_main(C); 00383 Material *ma; 00384 bNode *node= (bNode *)node_v; 00385 ID *id= node->id; 00386 int error= 0; 00387 00388 if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) error= 1; 00389 00390 /* Users only have to press the "update" button in one pynode 00391 * and we also update all others sharing the same script */ 00392 for (ma= bmain->mat.first; ma; ma= ma->id.next) { 00393 if (ma->nodetree) { 00394 bNode *nd; 00395 for (nd= ma->nodetree->nodes.first; nd; nd= nd->next) { 00396 if ((nd->type == NODE_DYNAMIC) && (nd->id == id)) { 00397 nd->custom1= 0; 00398 nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_REPARSE); 00399 nd->menunr= 0; 00400 if (error) 00401 nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_ERROR); 00402 } 00403 } 00404 } 00405 } 00406 00407 // allqueue(REDRAWBUTSSHADING, 0); 00408 // allqueue(REDRAWNODE, 0); 00409 // XXX BIF_preview_changed(ID_MA); 00410 } 00411 00412 static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00413 { 00414 bNode *node= ptr->data; 00415 00416 short multi = ( 00417 node->id && 00418 ((Tex*)node->id)->use_nodes && 00419 (node->type != CMP_NODE_TEXTURE) && 00420 (node->type != TEX_NODE_TEXTURE) 00421 ); 00422 00423 uiItemR(layout, ptr, "texture", 0, "", ICON_NONE); 00424 00425 if(multi) { 00426 /* Number Drawing not optimal here, better have a list*/ 00427 uiItemR(layout, ptr, "node_output", 0, "", ICON_NONE); 00428 } 00429 } 00430 00431 static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00432 { 00433 uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); 00434 } 00435 00436 static int node_resize_area_default(bNode *node, int x, int y) 00437 { 00438 if (node->flag & NODE_HIDDEN) { 00439 rctf totr= node->totr; 00440 /* right part of node */ 00441 totr.xmin= node->totr.xmax-20.0f; 00442 return BLI_in_rctf(&totr, x, y); 00443 } 00444 else { 00445 /* rect we're interested in is just the bottom right corner */ 00446 rctf totr= node->totr; 00447 /* bottom right corner */ 00448 totr.xmin= totr.xmax-10.0f; 00449 totr.ymax= totr.ymin+10.0f; 00450 return BLI_in_rctf(&totr, x, y); 00451 } 00452 } 00453 00454 /* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */ 00455 00456 /* width of socket columns in group display */ 00457 #define NODE_GROUP_FRAME 120 00458 00459 /* based on settings in node, sets drawing rect info. each redraw! */ 00460 /* note: this assumes only 1 group at a time is drawn (linked data) */ 00461 /* in node->totr the entire boundbox for the group is stored */ 00462 static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode) 00463 { 00464 if (!(gnode->flag & NODE_GROUP_EDIT)) { 00465 node_update_default(C, ntree, gnode); 00466 } 00467 else { 00468 bNodeTree *ngroup= (bNodeTree *)gnode->id; 00469 bNode *node; 00470 bNodeSocket *sock, *gsock; 00471 float locx, locy; 00472 rctf *rect= &gnode->totr; 00473 float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; 00474 float group_header= 26*U.dpi/72; 00475 int counter; 00476 int dy; 00477 00478 /* get "global" coords */ 00479 nodeSpaceCoords(gnode, &locx, &locy); 00480 00481 /* center them, is a bit of abuse of locx and locy though */ 00482 node_update_nodetree(C, ngroup, locx, locy); 00483 00484 rect->xmin = rect->xmax = locx; 00485 rect->ymin = rect->ymax = locy; 00486 00487 counter= 1; 00488 for(node= ngroup->nodes.first; node; node= node->next) { 00489 if(counter) { 00490 *rect= node->totr; 00491 counter= 0; 00492 } 00493 else 00494 BLI_union_rctf(rect, &node->totr); 00495 } 00496 00497 /* add some room for links to group sockets */ 00498 rect->xmin -= 4*NODE_DY; 00499 rect->xmax += 4*NODE_DY; 00500 rect->ymin-= NODE_DY; 00501 rect->ymax+= NODE_DY; 00502 00503 /* input sockets */ 00504 dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->inputs)-1); 00505 gsock=ngroup->inputs.first; 00506 sock=gnode->inputs.first; 00507 while (gsock || sock) { 00508 while (sock && !sock->groupsock) { 00509 sock->locx = rect->xmin - node_group_frame; 00510 sock->locy = dy; 00511 00512 /* prevent long socket lists from growing out of the group box */ 00513 if (dy-3*NODE_DYS < rect->ymin) 00514 rect->ymin = dy-3*NODE_DYS; 00515 if (dy+3*NODE_DYS > rect->ymax) 00516 rect->ymax = dy+3*NODE_DYS; 00517 dy -= 2*NODE_DY; 00518 00519 sock = sock->next; 00520 } 00521 while (gsock && (!sock || sock->groupsock!=gsock)) { 00522 gsock->locx = rect->xmin; 00523 gsock->locy = dy; 00524 00525 /* prevent long socket lists from growing out of the group box */ 00526 if (dy-3*NODE_DYS < rect->ymin) 00527 rect->ymin = dy-3*NODE_DYS; 00528 if (dy+3*NODE_DYS > rect->ymax) 00529 rect->ymax = dy+3*NODE_DYS; 00530 dy -= 2*NODE_DY; 00531 00532 gsock = gsock->next; 00533 } 00534 while (sock && gsock && sock->groupsock==gsock) { 00535 gsock->locx = rect->xmin; 00536 sock->locx = rect->xmin - node_group_frame; 00537 sock->locy = gsock->locy = dy; 00538 00539 /* prevent long socket lists from growing out of the group box */ 00540 if (dy-3*NODE_DYS < rect->ymin) 00541 rect->ymin = dy-3*NODE_DYS; 00542 if (dy+3*NODE_DYS > rect->ymax) 00543 rect->ymax = dy+3*NODE_DYS; 00544 dy -= 2*NODE_DY; 00545 00546 sock = sock->next; 00547 gsock = gsock->next; 00548 } 00549 } 00550 00551 /* output sockets */ 00552 dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->outputs)-1); 00553 gsock=ngroup->outputs.first; 00554 sock=gnode->outputs.first; 00555 while (gsock || sock) { 00556 while (sock && !sock->groupsock) { 00557 sock->locx = rect->xmax + node_group_frame; 00558 sock->locy = dy - NODE_DYS; 00559 00560 /* prevent long socket lists from growing out of the group box */ 00561 if (dy-3*NODE_DYS < rect->ymin) 00562 rect->ymin = dy-3*NODE_DYS; 00563 if (dy+3*NODE_DYS > rect->ymax) 00564 rect->ymax = dy+3*NODE_DYS; 00565 dy -= 2*NODE_DY; 00566 00567 sock = sock->next; 00568 } 00569 while (gsock && (!sock || sock->groupsock!=gsock)) { 00570 gsock->locx = rect->xmax; 00571 gsock->locy = dy - NODE_DYS; 00572 00573 /* prevent long socket lists from growing out of the group box */ 00574 if (dy-3*NODE_DYS < rect->ymin) 00575 rect->ymin = dy-3*NODE_DYS; 00576 if (dy+3*NODE_DYS > rect->ymax) 00577 rect->ymax = dy+3*NODE_DYS; 00578 dy -= 2*NODE_DY; 00579 00580 gsock = gsock->next; 00581 } 00582 while (sock && gsock && sock->groupsock==gsock) { 00583 gsock->locx = rect->xmax; 00584 sock->locx = rect->xmax + node_group_frame; 00585 sock->locy = gsock->locy = dy - NODE_DYS; 00586 00587 /* prevent long socket lists from growing out of the group box */ 00588 if (dy-3*NODE_DYS < rect->ymin) 00589 rect->ymin = dy-3*NODE_DYS; 00590 if (dy+3*NODE_DYS > rect->ymax) 00591 rect->ymax = dy+3*NODE_DYS; 00592 dy -= 2*NODE_DY; 00593 00594 sock = sock->next; 00595 gsock = gsock->next; 00596 } 00597 } 00598 00599 /* Set the block bounds to clip mouse events from underlying nodes. 00600 * Add margin for header and input/output columns. 00601 */ 00602 uiExplicitBoundsBlock(gnode->block, 00603 rect->xmin - node_group_frame, 00604 rect->ymin, 00605 rect->xmax + node_group_frame, 00606 rect->ymax + group_header); 00607 } 00608 } 00609 00610 static void update_group_input_cb(bContext *UNUSED(C), void *UNUSED(snode_v), void *ngroup_v) 00611 { 00612 bNodeTree *ngroup= (bNodeTree*)ngroup_v; 00613 00614 ngroup->update |= NTREE_UPDATE_GROUP_IN; 00615 ntreeUpdateTree(ngroup); 00616 } 00617 00618 static void update_group_output_cb(bContext *UNUSED(C), void *UNUSED(snode_v), void *ngroup_v) 00619 { 00620 bNodeTree *ngroup= (bNodeTree*)ngroup_v; 00621 00622 ngroup->update |= NTREE_UPDATE_GROUP_OUT; 00623 ntreeUpdateTree(ngroup); 00624 } 00625 00626 static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket *sock, int in_out, float xoffset, float yoffset) 00627 { 00628 bNodeTree *ngroup= (bNodeTree*)gnode->id; 00629 uiBut *bt; 00630 00631 if (sock->flag & SOCK_DYNAMIC) { 00632 bt = uiDefBut(gnode->block, TEX, 0, "", 00633 sock->locx+xoffset, sock->locy+1+yoffset, 72, NODE_DY, 00634 sock->name, 0, sizeof(sock->name), 0, 0, ""); 00635 if (in_out==SOCK_IN) 00636 uiButSetFunc(bt, update_group_input_cb, snode, ngroup); 00637 else 00638 uiButSetFunc(bt, update_group_output_cb, snode, ngroup); 00639 } 00640 else { 00641 uiDefBut(gnode->block, LABEL, 0, sock->name, 00642 sock->locx+xoffset, sock->locy+1+yoffset, 72, NODE_DY, 00643 NULL, 0, sizeof(sock->name), 0, 0, ""); 00644 } 00645 } 00646 00647 static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode, bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out) 00648 { 00649 bNodeTree *ngroup= (bNodeTree*)gnode->id; 00650 bNodeSocketType *stype= ntreeGetSocketType(gsock ? gsock->type : sock->type); 00651 uiBut *bt; 00652 float offset; 00653 int draw_value; 00654 float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; 00655 float socket_size= NODE_SOCKSIZE*U.dpi/72; 00656 float arrowbutw= 0.8f*UI_UNIT_X; 00657 /* layout stuff for buttons on group left frame */ 00658 float colw= 0.6f*node_group_frame; 00659 float col1= 6 - node_group_frame; 00660 float col2= col1 + colw+6; 00661 float col3= - arrowbutw - 6; 00662 /* layout stuff for buttons on group right frame */ 00663 float cor1= 6; 00664 float cor2= cor1 + arrowbutw + 6; 00665 float cor3= cor2 + arrowbutw + 6; 00666 00667 /* node and group socket circles */ 00668 if (sock) 00669 node_socket_circle_draw(ntree, sock, socket_size); 00670 if (gsock) 00671 node_socket_circle_draw(ngroup, gsock, socket_size); 00672 00673 /* socket name */ 00674 offset = (in_out==SOCK_IN ? col1 : cor3); 00675 if (!gsock) 00676 offset += (in_out==SOCK_IN ? node_group_frame : -node_group_frame); 00677 00678 /* draw both name and value button if: 00679 * 1) input: not internal 00680 * 2) output: (node type uses const outputs) and (group output is unlinked) 00681 */ 00682 draw_value = 0; 00683 switch (in_out) { 00684 case SOCK_IN: 00685 draw_value = !(gsock && (gsock->flag & SOCK_INTERNAL)); 00686 break; 00687 case SOCK_OUT: 00688 if (gnode->typeinfo->flag & NODE_CONST_OUTPUT) 00689 draw_value = !(gsock && gsock->link); 00690 break; 00691 } 00692 if (draw_value) { 00693 /* both name and value buttons */ 00694 if (gsock) { 00695 draw_group_socket_name(snode, gnode, gsock, in_out, offset, 0); 00696 if (stype->buttonfunc) 00697 stype->buttonfunc(C, gnode->block, ngroup, NULL, gsock, "", gsock->locx+offset, gsock->locy-NODE_DY, colw); 00698 } 00699 else { 00700 draw_group_socket_name(snode, gnode, sock, in_out, offset, 0); 00701 if (stype->buttonfunc) 00702 stype->buttonfunc(C, gnode->block, ngroup, NULL, sock, "", sock->locx+offset, sock->locy-NODE_DY, colw); 00703 } 00704 } 00705 else { 00706 /* only name, no value button */ 00707 if (gsock) 00708 draw_group_socket_name(snode, gnode, gsock, in_out, offset, -NODE_DYS); 00709 else 00710 draw_group_socket_name(snode, gnode, sock, in_out, offset, -NODE_DYS); 00711 } 00712 00713 if (gsock && (gsock->flag & SOCK_DYNAMIC)) { 00714 /* up/down buttons */ 00715 offset = (in_out==SOCK_IN ? col2 : cor2); 00716 uiBlockSetDirection(gnode->block, UI_TOP); 00717 uiBlockBeginAlign(gnode->block); 00718 bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_up", 0, ICON_TRIA_UP, 00719 gsock->locx+offset, gsock->locy, arrowbutw, arrowbutw, ""); 00720 if (!gsock->prev || !(gsock->prev->flag & SOCK_DYNAMIC)) 00721 uiButSetFlag(bt, UI_BUT_DISABLED); 00722 RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); 00723 RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", in_out); 00724 bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_down", 0, ICON_TRIA_DOWN, 00725 gsock->locx+offset, gsock->locy-arrowbutw, arrowbutw, arrowbutw, ""); 00726 if (!gsock->next || !(gsock->next->flag & SOCK_DYNAMIC)) 00727 uiButSetFlag(bt, UI_BUT_DISABLED); 00728 RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); 00729 RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", in_out); 00730 uiBlockEndAlign(gnode->block); 00731 uiBlockSetDirection(gnode->block, 0); 00732 00733 /* remove button */ 00734 offset = (in_out==SOCK_IN ? col3 : cor1); 00735 uiBlockSetEmboss(gnode->block, UI_EMBOSSN); 00736 bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, 00737 gsock->locx+offset, gsock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); 00738 RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); 00739 RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", in_out); 00740 uiBlockSetEmboss(gnode->block, UI_EMBOSS); 00741 } 00742 } 00743 00744 /* groups are, on creation, centered around 0,0 */ 00745 static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *gnode) 00746 { 00747 if (!(gnode->flag & NODE_GROUP_EDIT)) { 00748 node_draw_default(C, ar, snode, ntree, gnode); 00749 } 00750 else { 00751 bNodeTree *ngroup= (bNodeTree *)gnode->id; 00752 bNodeSocket *sock, *gsock; 00753 uiLayout *layout; 00754 PointerRNA ptr; 00755 rctf rect= gnode->totr; 00756 float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; 00757 float group_header= 26*U.dpi/72; 00758 00759 int index; 00760 00761 /* backdrop header */ 00762 glEnable(GL_BLEND); 00763 uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); 00764 UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); 00765 uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymax, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); 00766 00767 /* backdrop body */ 00768 UI_ThemeColorShadeAlpha(TH_BACK, -8, -70); 00769 uiSetRoundBox(UI_CNR_NONE); 00770 uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, BASIS_RAD); 00771 00772 /* input column */ 00773 UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); 00774 uiSetRoundBox(UI_CNR_BOTTOM_LEFT); 00775 uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymin, rect.xmin, rect.ymax, BASIS_RAD); 00776 00777 /* output column */ 00778 UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); 00779 uiSetRoundBox(UI_CNR_BOTTOM_RIGHT); 00780 uiDrawBox(GL_POLYGON, rect.xmax, rect.ymin, rect.xmax+node_group_frame, rect.ymax, BASIS_RAD); 00781 00782 /* input column separator */ 00783 glColor4ub(200, 200, 200, 140); 00784 glBegin(GL_LINES); 00785 glVertex2f(rect.xmin, rect.ymin); 00786 glVertex2f(rect.xmin, rect.ymax); 00787 glEnd(); 00788 00789 /* output column separator */ 00790 glColor4ub(200, 200, 200, 140); 00791 glBegin(GL_LINES); 00792 glVertex2f(rect.xmax, rect.ymin); 00793 glVertex2f(rect.xmax, rect.ymax); 00794 glEnd(); 00795 00796 /* group node outline */ 00797 uiSetRoundBox(UI_CNR_ALL); 00798 glColor4ub(200, 200, 200, 140); 00799 glEnable( GL_LINE_SMOOTH ); 00800 uiDrawBox(GL_LINE_LOOP, rect.xmin-node_group_frame, rect.ymin, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); 00801 glDisable( GL_LINE_SMOOTH ); 00802 glDisable(GL_BLEND); 00803 00804 /* backdrop title */ 00805 UI_ThemeColor(TH_TEXT_HI); 00806 00807 layout = uiBlockLayout(gnode->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, (short)(rect.xmin+15), (short)(rect.ymax+group_header), 00808 MIN2((int)(rect.xmax - rect.xmin-18.0f), node_group_frame+20), group_header, UI_GetStyle()); 00809 RNA_pointer_create(&ntree->id, &RNA_Node, gnode, &ptr); 00810 uiTemplateIDBrowse(layout, (bContext*)C, &ptr, "node_tree", NULL, NULL, NULL); 00811 uiBlockLayoutResolve(gnode->block, NULL, NULL); 00812 00813 /* draw the internal tree nodes and links */ 00814 node_draw_nodetree(C, ar, snode, ngroup); 00815 00816 /* group sockets */ 00817 gsock=ngroup->inputs.first; 00818 sock=gnode->inputs.first; 00819 index = 0; 00820 while (gsock || sock) { 00821 while (sock && !sock->groupsock) { 00822 draw_group_socket(C, snode, ntree, gnode, sock, NULL, index, SOCK_IN); 00823 sock = sock->next; 00824 } 00825 while (gsock && (!sock || sock->groupsock!=gsock)) { 00826 draw_group_socket(C, snode, ntree, gnode, NULL, gsock, index, SOCK_IN); 00827 gsock = gsock->next; 00828 ++index; 00829 } 00830 while (sock && gsock && sock->groupsock==gsock) { 00831 draw_group_socket(C, snode, ntree, gnode, sock, gsock, index, SOCK_IN); 00832 sock = sock->next; 00833 gsock = gsock->next; 00834 ++index; 00835 } 00836 } 00837 gsock=ngroup->outputs.first; 00838 sock=gnode->outputs.first; 00839 index = 0; 00840 while (gsock || sock) { 00841 while (sock && !sock->groupsock) { 00842 draw_group_socket(C, snode, ntree, gnode, sock, NULL, index, SOCK_OUT); 00843 sock = sock->next; 00844 } 00845 while (gsock && (!sock || sock->groupsock!=gsock)) { 00846 draw_group_socket(C, snode, ntree, gnode, NULL, gsock, index, SOCK_OUT); 00847 gsock = gsock->next; 00848 ++index; 00849 } 00850 while (sock && gsock && sock->groupsock==gsock) { 00851 draw_group_socket(C, snode, ntree, gnode, sock, gsock, index, SOCK_OUT); 00852 sock = sock->next; 00853 gsock = gsock->next; 00854 ++index; 00855 } 00856 } 00857 00858 uiEndBlock(C, gnode->block); 00859 uiDrawBlock(C, gnode->block); 00860 gnode->block= NULL; 00861 } 00862 } 00863 00864 void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr) 00865 { 00866 uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, NULL); 00867 } 00868 00869 static void node_common_buts_whileloop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00870 { 00871 uiItemR(layout, ptr, "max_iterations", 0, NULL, 0); 00872 } 00873 00874 static void node_update_frame(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node) 00875 { 00876 float locx, locy; 00877 00878 /* get "global" coords */ 00879 nodeSpaceCoords(node, &locx, &locy); 00880 00881 node->prvr.xmin= locx + NODE_DYS; 00882 node->prvr.xmax= locx + node->width- NODE_DYS; 00883 00884 node->totr.xmin= locx; 00885 node->totr.xmax= locx + node->width; 00886 node->totr.ymax= locy; 00887 node->totr.ymin= locy - node->height; 00888 } 00889 00890 static void node_common_set_butfunc(bNodeType *ntype) 00891 { 00892 switch(ntype->type) { 00893 case NODE_GROUP: 00894 ntype->uifunc= node_uifunc_group; 00895 ntype->drawfunc= node_draw_group; 00896 ntype->drawupdatefunc= node_update_group; 00897 break; 00898 case NODE_FORLOOP: 00899 // ntype->uifunc= node_common_buts_group; 00900 ntype->drawfunc= node_draw_group; 00901 ntype->drawupdatefunc= node_update_group; 00902 break; 00903 case NODE_WHILELOOP: 00904 ntype->uifunc= node_common_buts_whileloop; 00905 ntype->drawfunc= node_draw_group; 00906 ntype->drawupdatefunc= node_update_group; 00907 break; 00908 case NODE_FRAME: 00909 ntype->drawupdatefunc= node_update_frame; 00910 break; 00911 } 00912 } 00913 00914 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ 00915 00916 static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v) 00917 { 00918 Main *bmain= CTX_data_main(C); 00919 bNodeTree *ntree= ntree_v; 00920 bNode *node= node_v; 00921 /* ID *oldid; */ /* UNUSED */ 00922 00923 if(node->menunr<1) return; 00924 00925 if(node->id) { 00926 node->id->us--; 00927 } 00928 /* oldid= node->id; */ /* UNUSED */ 00929 node->id= BLI_findlink(&bmain->text, node->menunr-1); 00930 id_us_plus(node->id); 00931 BLI_strncpy(node->name, node->id->name+2, sizeof(node->name)); 00932 00933 node->custom1= BSET(node->custom1, NODE_DYNAMIC_NEW); 00934 00935 nodeSetActive(ntree, node); 00936 00937 // allqueue(REDRAWBUTSSHADING, 0); 00938 // allqueue(REDRAWNODE, 0); 00939 00940 node->menunr= 0; 00941 } 00942 00943 static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) 00944 { 00945 bNode *node= ptr->data; 00946 uiLayout *col; 00947 00948 uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL); 00949 00950 if(!node->id) return; 00951 00952 col= uiLayoutColumn(layout, 0); 00953 uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NONE); 00954 uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NONE); 00955 uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NONE); 00956 } 00957 00958 static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00959 { 00960 uiLayout *row; 00961 00962 uiItemL(layout, "Location:", ICON_NONE); 00963 row= uiLayoutRow(layout, 1); 00964 uiItemR(row, ptr, "location", 0, "", ICON_NONE); 00965 00966 uiItemL(layout, "Rotation:", ICON_NONE); 00967 row= uiLayoutRow(layout, 1); 00968 uiItemR(row, ptr, "rotation", 0, "", ICON_NONE); 00969 00970 uiItemL(layout, "Scale:", ICON_NONE); 00971 row= uiLayoutRow(layout, 1); 00972 uiItemR(row, ptr, "scale", 0, "", ICON_NONE); 00973 00974 row= uiLayoutRow(layout, 1); 00975 uiItemR(row, ptr, "use_min", 0, "Min", ICON_NONE); 00976 uiItemR(row, ptr, "min", 0, "", ICON_NONE); 00977 00978 row= uiLayoutRow(layout, 1); 00979 uiItemR(row, ptr, "use_max", 0, "Max", ICON_NONE); 00980 uiItemR(row, ptr, "max", 0, "", ICON_NONE); 00981 } 00982 00983 static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 00984 { 00985 uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); 00986 } 00987 00988 static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr) 00989 { 00990 PointerRNA obptr= CTX_data_pointer_get(C, "active_object"); 00991 uiLayout *col; 00992 00993 col= uiLayoutColumn(layout, 0); 00994 00995 if(obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { 00996 PointerRNA dataptr= RNA_pointer_get(&obptr, "data"); 00997 00998 uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_textures", "", ICON_NONE); 00999 uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NONE); 01000 } 01001 else { 01002 uiItemR(col, ptr, "uv_layer", 0, "UV", ICON_NONE); 01003 uiItemR(col, ptr, "color_layer", 0, "VCol", ICON_NONE); 01004 } 01005 } 01006 01007 static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01008 { 01009 uiItemR(layout, ptr, "attribute_name", 0, "Name", ICON_NONE); 01010 } 01011 01012 static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA *ptr) 01013 { 01014 uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); 01015 uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); 01016 } 01017 01018 static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01019 { 01020 uiItemR(layout, ptr, "sun_direction", 0, "", ICON_NONE); 01021 uiItemR(layout, ptr, "turbidity", 0, NULL, ICON_NONE); 01022 } 01023 01024 static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01025 { 01026 uiItemR(layout, ptr, "gradient_type", 0, "", ICON_NONE); 01027 } 01028 01029 static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01030 { 01031 uiItemR(layout, ptr, "turbulence_depth", 0, NULL, ICON_NONE); 01032 } 01033 01034 static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01035 { 01036 uiItemR(layout, ptr, "wave_type", 0, "", ICON_NONE); 01037 } 01038 01039 static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01040 { 01041 uiItemR(layout, ptr, "musgrave_type", 0, "", ICON_NONE); 01042 } 01043 01044 static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01045 { 01046 uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE); 01047 } 01048 01049 static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01050 { 01051 uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); 01052 } 01053 01054 static void node_shader_buts_dynamic(uiLayout *layout, bContext *C, PointerRNA *ptr) 01055 { 01056 Main *bmain= CTX_data_main(C); 01057 uiBlock *block= uiLayoutAbsoluteBlock(layout); 01058 bNode *node= ptr->data; 01059 bNodeTree *ntree= ptr->id.data; 01060 rctf *butr= &node->butr; 01061 uiBut *bt; 01062 // XXX SpaceNode *snode= curarea->spacedata.first; 01063 short dy= (short)butr->ymin; 01064 int xoff=0; 01065 01066 /* B_NODE_EXEC is handled in butspace.c do_node_buts */ 01067 if(!node->id) { 01068 const char *strp; 01069 IDnames_to_pupstring(&strp, NULL, "", &(bmain->text), NULL, NULL); 01070 node->menunr= 0; 01071 bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp, 01072 butr->xmin, dy, 19, 19, 01073 &node->menunr, 0, 0, 0, 0, "Browses existing choices"); 01074 uiButSetFunc(bt, node_browse_text_cb, ntree, node); 01075 xoff=19; 01076 if(strp) MEM_freeN((void *)strp); 01077 } 01078 else { 01079 bt = uiDefBut(block, BUT, B_NOP, "Update", 01080 butr->xmin+xoff, butr->ymin+20, 50, 19, 01081 &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)"); 01082 uiButSetFunc(bt, node_dynamic_update_cb, ntree, node); 01083 01084 if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { 01085 // UI_ThemeColor(TH_REDALERT); 01086 // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect); 01087 // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin); 01088 ; 01089 } 01090 } 01091 } 01092 01093 /* only once called */ 01094 static void node_shader_set_butfunc(bNodeType *ntype) 01095 { 01096 ntype->uifuncbut = NULL; 01097 switch(ntype->type) { 01098 /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ 01099 01100 case SH_NODE_MATERIAL: 01101 case SH_NODE_MATERIAL_EXT: 01102 ntype->uifunc= node_shader_buts_material; 01103 break; 01104 case SH_NODE_TEXTURE: 01105 ntype->uifunc= node_buts_texture; 01106 break; 01107 case SH_NODE_NORMAL: 01108 ntype->uifunc= node_buts_normal; 01109 break; 01110 case SH_NODE_CURVE_VEC: 01111 ntype->uifunc= node_buts_curvevec; 01112 break; 01113 case SH_NODE_CURVE_RGB: 01114 ntype->uifunc= node_buts_curvecol; 01115 break; 01116 case SH_NODE_MAPPING: 01117 ntype->uifunc= node_shader_buts_mapping; 01118 break; 01119 case SH_NODE_VALUE: 01120 ntype->uifunc= node_buts_value; 01121 break; 01122 case SH_NODE_RGB: 01123 ntype->uifunc= node_buts_rgb; 01124 break; 01125 case SH_NODE_MIX_RGB: 01126 ntype->uifunc= node_buts_mix_rgb; 01127 break; 01128 case SH_NODE_VALTORGB: 01129 ntype->uifunc= node_buts_colorramp; 01130 break; 01131 case SH_NODE_MATH: 01132 ntype->uifunc= node_buts_math; 01133 break; 01134 case SH_NODE_VECT_MATH: 01135 ntype->uifunc= node_shader_buts_vect_math; 01136 break; 01137 case SH_NODE_GEOMETRY: 01138 ntype->uifunc= node_shader_buts_geometry; 01139 break; 01140 case SH_NODE_ATTRIBUTE: 01141 ntype->uifunc= node_shader_buts_attribute; 01142 break; 01143 case SH_NODE_TEX_SKY: 01144 ntype->uifunc= node_shader_buts_tex_sky; 01145 break; 01146 case SH_NODE_TEX_IMAGE: 01147 ntype->uifunc= node_shader_buts_tex_image; 01148 break; 01149 case SH_NODE_TEX_ENVIRONMENT: 01150 ntype->uifunc= node_shader_buts_tex_image; 01151 break; 01152 case SH_NODE_TEX_GRADIENT: 01153 ntype->uifunc= node_shader_buts_tex_gradient; 01154 break; 01155 case SH_NODE_TEX_MAGIC: 01156 ntype->uifunc= node_shader_buts_tex_magic; 01157 break; 01158 case SH_NODE_TEX_WAVE: 01159 ntype->uifunc= node_shader_buts_tex_wave; 01160 break; 01161 case SH_NODE_TEX_MUSGRAVE: 01162 ntype->uifunc= node_shader_buts_tex_musgrave; 01163 break; 01164 case SH_NODE_TEX_VORONOI: 01165 ntype->uifunc= node_shader_buts_tex_voronoi; 01166 break; 01167 case SH_NODE_BSDF_GLOSSY: 01168 case SH_NODE_BSDF_GLASS: 01169 ntype->uifunc= node_shader_buts_glossy; 01170 break; 01171 case NODE_DYNAMIC: 01172 ntype->uifunc= node_shader_buts_dynamic; 01173 break; 01174 } 01175 if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; 01176 } 01177 01178 /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */ 01179 01180 static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) 01181 { 01182 uiLayout *col; 01183 bNode *node= ptr->data; 01184 PointerRNA imaptr; 01185 PropertyRNA *prop; 01186 int source; 01187 01188 uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); 01189 01190 if(!node->id) return; 01191 01192 prop = RNA_struct_find_property(ptr, "image"); 01193 if (!prop || RNA_property_type(prop) != PROP_POINTER) return; 01194 imaptr= RNA_property_pointer_get(ptr, prop); 01195 01196 col= uiLayoutColumn(layout, 0); 01197 01198 uiItemR(col, &imaptr, "source", 0, NULL, ICON_NONE); 01199 01200 source= RNA_enum_get(&imaptr, "source"); 01201 01202 if(source == IMA_SRC_SEQUENCE) { 01203 /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ 01204 Scene *scene= CTX_data_scene(C); 01205 ImageUser *iuser= node->storage; 01206 char numstr[32]; 01207 const int framenr= BKE_image_user_get_frame(iuser, CFRA, 0); 01208 BLI_snprintf(numstr, sizeof(numstr), "Frame: %d", framenr); 01209 uiItemL(layout, numstr, ICON_NONE); 01210 } 01211 01212 if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { 01213 col= uiLayoutColumn(layout, 1); 01214 uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE); 01215 uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE); 01216 uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE); 01217 uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NONE); 01218 uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE); 01219 } 01220 01221 col= uiLayoutColumn(layout, 0); 01222 01223 if (RNA_enum_get(&imaptr, "type")== IMA_TYPE_MULTILAYER) 01224 uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE); 01225 } 01226 01227 static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) 01228 { 01229 bNode *node= ptr->data; 01230 uiLayout *col, *row; 01231 PointerRNA op_ptr; 01232 PointerRNA scn_ptr; 01233 PropertyRNA *prop; 01234 const char *layer_name; 01235 char scene_name[MAX_ID_NAME-2]; 01236 01237 uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL); 01238 01239 if(!node->id) return; 01240 01241 col= uiLayoutColumn(layout, 0); 01242 row = uiLayoutRow(col, 0); 01243 uiItemR(row, ptr, "layer", 0, "", ICON_NONE); 01244 01245 prop = RNA_struct_find_property(ptr, "layer"); 01246 if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name))) 01247 return; 01248 01249 scn_ptr = RNA_pointer_get(ptr, "scene"); 01250 RNA_string_get(&scn_ptr, "name", scene_name); 01251 01252 WM_operator_properties_create(&op_ptr, "RENDER_OT_render"); 01253 RNA_string_set(&op_ptr, "layer", layer_name); 01254 RNA_string_set(&op_ptr, "scene", scene_name); 01255 uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); 01256 01257 } 01258 01259 01260 static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01261 { 01262 uiLayout *col, *row; 01263 01264 col= uiLayoutColumn(layout, 0); 01265 01266 uiItemR(col, ptr, "filter_type", 0, "", ICON_NONE); 01267 if (RNA_enum_get(ptr, "filter_type")!= R_FILTER_FAST_GAUSS) { 01268 uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE); 01269 uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NONE); 01270 } 01271 01272 uiItemR(col, ptr, "use_relative", 0, NULL, ICON_NONE); 01273 01274 if (RNA_boolean_get(ptr, "use_relative")) { 01275 uiItemL(col, "Aspect Correction", 0); 01276 row= uiLayoutRow(layout, 1); 01277 uiItemR(row, ptr, "aspect_correction", UI_ITEM_R_EXPAND, NULL, 0); 01278 01279 col= uiLayoutColumn(layout, 1); 01280 uiItemR(col, ptr, "factor_x", 0, "X", ICON_NONE); 01281 uiItemR(col, ptr, "factor_y", 0, "Y", ICON_NONE); 01282 } 01283 else { 01284 col= uiLayoutColumn(layout, 1); 01285 uiItemR(col, ptr, "size_x", 0, "X", ICON_NONE); 01286 uiItemR(col, ptr, "size_y", 0, "Y", ICON_NONE); 01287 } 01288 } 01289 01290 static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01291 { 01292 uiLayout *col; 01293 01294 uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE); 01295 uiItemR(layout, ptr, "use_wrap", 0, NULL, ICON_NONE); 01296 01297 col= uiLayoutColumn(layout, 1); 01298 uiItemL(col, "Center:", ICON_NONE); 01299 uiItemR(col, ptr, "center_x", 0, "X", ICON_NONE); 01300 uiItemR(col, ptr, "center_y", 0, "Y", ICON_NONE); 01301 01302 uiItemS(layout); 01303 01304 col= uiLayoutColumn(layout, 1); 01305 uiItemR(col, ptr, "distance", 0, NULL, ICON_NONE); 01306 uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE); 01307 01308 uiItemS(layout); 01309 01310 uiItemR(layout, ptr, "spin", 0, NULL, ICON_NONE); 01311 uiItemR(layout, ptr, "zoom", 0, NULL, ICON_NONE); 01312 } 01313 01314 static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01315 { 01316 uiLayout *col; 01317 01318 col= uiLayoutColumn(layout, 1); 01319 uiItemR(col, ptr, "iterations", 0, NULL, ICON_NONE); 01320 uiItemR(col, ptr, "sigma_color", 0, NULL, ICON_NONE); 01321 uiItemR(col, ptr, "sigma_space", 0, NULL, ICON_NONE); 01322 } 01323 01324 static void node_composit_buts_defocus(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01325 { 01326 uiLayout *sub, *col; 01327 01328 col= uiLayoutColumn(layout, 0); 01329 uiItemL(col, "Bokeh Type:", ICON_NONE); 01330 uiItemR(col, ptr, "bokeh", 0, "", ICON_NONE); 01331 uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE); 01332 01333 uiItemR(layout, ptr, "use_gamma_correction", 0, NULL, ICON_NONE); 01334 01335 col = uiLayoutColumn(layout, 0); 01336 uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer")==1); 01337 uiItemR(col, ptr, "f_stop", 0, NULL, ICON_NONE); 01338 01339 uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NONE); 01340 uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE); 01341 01342 col = uiLayoutColumn(layout, 0); 01343 uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NONE); 01344 sub = uiLayoutColumn(col, 0); 01345 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_preview")); 01346 uiItemR(sub, ptr, "samples", 0, NULL, ICON_NONE); 01347 01348 col = uiLayoutColumn(layout, 0); 01349 uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NONE); 01350 sub = uiLayoutColumn(col, 0); 01351 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer")==0); 01352 uiItemR(sub, ptr, "z_scale", 0, NULL, ICON_NONE); 01353 } 01354 01355 /* qdn: glare node */ 01356 static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01357 { 01358 uiItemR(layout, ptr, "glare_type", 0, "", ICON_NONE); 01359 uiItemR(layout, ptr, "quality", 0, "", ICON_NONE); 01360 01361 if (RNA_enum_get(ptr, "glare_type")!= 1) { 01362 uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE); 01363 01364 if (RNA_enum_get(ptr, "glare_type")!= 0) 01365 uiItemR(layout, ptr, "color_modulation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01366 } 01367 01368 uiItemR(layout, ptr, "mix", 0, NULL, ICON_NONE); 01369 uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE); 01370 01371 if (RNA_enum_get(ptr, "glare_type")== 2) { 01372 uiItemR(layout, ptr, "streaks", 0, NULL, ICON_NONE); 01373 uiItemR(layout, ptr, "angle_offset", 0, NULL, ICON_NONE); 01374 } 01375 if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) { 01376 uiItemR(layout, ptr, "fade", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01377 01378 if (RNA_enum_get(ptr, "glare_type")== 0) 01379 uiItemR(layout, ptr, "use_rotate_45", 0, NULL, ICON_NONE); 01380 } 01381 if (RNA_enum_get(ptr, "glare_type")== 1) { 01382 uiItemR(layout, ptr, "size", 0, NULL, ICON_NONE); 01383 } 01384 } 01385 01386 static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01387 { 01388 uiLayout *col; 01389 01390 col = uiLayoutColumn(layout, 0); 01391 uiItemR(col, ptr, "tonemap_type", 0, "", ICON_NONE); 01392 if (RNA_enum_get(ptr, "tonemap_type")== 0) { 01393 uiItemR(col, ptr, "key", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01394 uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE); 01395 uiItemR(col, ptr, "gamma", 0, NULL, ICON_NONE); 01396 } 01397 else { 01398 uiItemR(col, ptr, "intensity", 0, NULL, ICON_NONE); 01399 uiItemR(col, ptr, "contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01400 uiItemR(col, ptr, "adaptation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01401 uiItemR(col, ptr, "correction", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01402 } 01403 } 01404 01405 static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01406 { 01407 uiLayout *col; 01408 01409 col= uiLayoutColumn(layout, 0); 01410 uiItemR(col, ptr, "use_projector", 0, NULL, ICON_NONE); 01411 01412 col = uiLayoutColumn(col, 0); 01413 uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector")==0); 01414 uiItemR(col, ptr, "use_jitter", 0, NULL, ICON_NONE); 01415 uiItemR(col, ptr, "use_fit", 0, NULL, ICON_NONE); 01416 } 01417 01418 static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01419 { 01420 uiLayout *col; 01421 01422 col= uiLayoutColumn(layout, 0); 01423 uiItemR(col, ptr, "samples", 0, NULL, ICON_NONE); 01424 uiItemR(col, ptr, "factor", 0, "Blur", ICON_NONE); 01425 01426 col= uiLayoutColumn(layout, 1); 01427 uiItemL(col, "Speed:", ICON_NONE); 01428 uiItemR(col, ptr, "speed_min", 0, "Min", ICON_NONE); 01429 uiItemR(col, ptr, "speed_max", 0, "Max", ICON_NONE); 01430 01431 uiItemR(layout, ptr, "use_curved", 0, NULL, ICON_NONE); 01432 } 01433 01434 static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01435 { 01436 uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE); 01437 } 01438 01439 static void node_composit_buts_flip(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01440 { 01441 uiItemR(layout, ptr, "axis", 0, "", ICON_NONE); 01442 } 01443 01444 static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01445 { 01446 uiLayout *col; 01447 01448 uiItemR(layout, ptr, "use_crop_size", 0, NULL, ICON_NONE); 01449 uiItemR(layout, ptr, "relative", 0, NULL, ICON_NONE); 01450 01451 col= uiLayoutColumn(layout, 1); 01452 if (RNA_boolean_get(ptr, "relative")){ 01453 uiItemR(col, ptr, "rel_min_x", 0, "Left", ICON_NONE); 01454 uiItemR(col, ptr, "rel_max_x", 0, "Right", ICON_NONE); 01455 uiItemR(col, ptr, "rel_min_y", 0, "Up", ICON_NONE); 01456 uiItemR(col, ptr, "rel_max_y", 0, "Down", ICON_NONE); 01457 } else { 01458 uiItemR(col, ptr, "min_x", 0, "Left", ICON_NONE); 01459 uiItemR(col, ptr, "max_x", 0, "Right", ICON_NONE); 01460 uiItemR(col, ptr, "min_y", 0, "Up", ICON_NONE); 01461 uiItemR(col, ptr, "max_y", 0, "Down", ICON_NONE); 01462 } 01463 } 01464 01465 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01466 { 01467 uiLayout *row, *col; 01468 01469 col= uiLayoutColumn(layout, 0); 01470 row= uiLayoutRow(col, 0); 01471 uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01472 uiItemR(col, ptr, "factor", 0, NULL, ICON_NONE); 01473 } 01474 01475 static void node_composit_buts_double_edge_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01476 { 01477 uiLayout *col; 01478 01479 col= uiLayoutColumn(layout, 0); 01480 01481 uiItemL(col, "Inner Edge:", ICON_NONE); 01482 uiItemR(col, ptr, "inner_mode", 0, "", ICON_NONE); 01483 uiItemL(col, "Buffer Edge:", ICON_NONE); 01484 uiItemR(col, ptr, "edge_mode", 0, "", ICON_NONE); 01485 } 01486 01487 static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01488 { 01489 uiLayout *sub, *col; 01490 01491 col =uiLayoutColumn(layout, 1); 01492 uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE); 01493 uiItemR(col, ptr, "size", 0, NULL, ICON_NONE); 01494 01495 col =uiLayoutColumn(layout, 1); 01496 uiItemR(col, ptr, "use_min", 0, NULL, ICON_NONE); 01497 sub =uiLayoutColumn(col, 0); 01498 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min")); 01499 uiItemR(sub, ptr, "min", 0, "", ICON_NONE); 01500 01501 col =uiLayoutColumn(layout, 1); 01502 uiItemR(col, ptr, "use_max", 0, NULL, ICON_NONE); 01503 sub =uiLayoutColumn(col, 0); 01504 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max")); 01505 uiItemR(sub, ptr, "max", 0, "", ICON_NONE); 01506 } 01507 01508 static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01509 { 01510 uiLayout *col; 01511 01512 col =uiLayoutColumn(layout, 1); 01513 uiItemR(col, ptr, "use_premultiply", 0, NULL, ICON_NONE); 01514 uiItemR(col, ptr, "premul", 0, NULL, ICON_NONE); 01515 } 01516 01517 static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01518 { 01519 uiLayout *col; 01520 01521 col =uiLayoutColumn(layout, 1); 01522 uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE); 01523 } 01524 01525 01526 static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01527 { 01528 uiLayout *col; 01529 01530 col =uiLayoutColumn(layout, 0); 01531 uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01532 uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01533 uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01534 } 01535 01536 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01537 { 01538 uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE); 01539 } 01540 01541 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01542 { 01543 uiLayout *col; 01544 01545 col =uiLayoutColumn(layout, 1); 01546 uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01547 uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01548 } 01549 01550 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01551 { 01552 uiLayout *col; 01553 01554 col =uiLayoutColumn(layout, 1); 01555 uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01556 uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01557 } 01558 01559 static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01560 { 01561 uiLayout *row, *col; 01562 01563 uiItemL(layout, "Despill Channel:", ICON_NONE); 01564 row =uiLayoutRow(layout,0); 01565 uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01566 01567 col= uiLayoutColumn(layout, 0); 01568 uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NONE); 01569 01570 if(RNA_enum_get(ptr, "limit_method")==0) { 01571 uiItemL(col, "Limiting Channel:", ICON_NONE); 01572 row=uiLayoutRow(col,0); 01573 uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01574 } 01575 01576 uiItemR(col, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01577 uiItemR(col, ptr, "use_unspill", 0, NULL, ICON_NONE); 01578 if (RNA_boolean_get(ptr, "use_unspill")== 1) { 01579 uiItemR(col, ptr, "unspill_red", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01580 uiItemR(col, ptr, "unspill_green", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01581 uiItemR(col, ptr, "unspill_blue", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01582 } 01583 } 01584 01585 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01586 { 01587 uiLayout *col; 01588 01589 col= uiLayoutColumn(layout, 0); 01590 uiItemR(col, ptr, "tolerance", 0, NULL, ICON_NONE); 01591 uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE); 01592 01593 col= uiLayoutColumn(layout, 1); 01594 /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now */ 01595 uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01596 /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now*/ 01597 } 01598 01599 static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01600 { 01601 uiLayout *col; 01602 01603 col= uiLayoutColumn(layout, 1); 01604 uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01605 uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01606 uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01607 } 01608 01609 static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01610 { 01611 uiLayout *col, *row; 01612 01613 uiItemL(layout, "Color Space:", ICON_NONE); 01614 row= uiLayoutRow(layout, 0); 01615 uiItemR(row, ptr, "color_space", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01616 01617 col=uiLayoutColumn(layout, 0); 01618 uiItemL(col, "Key Channel:", ICON_NONE); 01619 row= uiLayoutRow(col, 0); 01620 uiItemR(row, ptr, "matte_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01621 01622 col =uiLayoutColumn(layout, 0); 01623 01624 uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NONE); 01625 if(RNA_enum_get(ptr, "limit_method")==0) { 01626 uiItemL(col, "Limiting Channel:", ICON_NONE); 01627 row=uiLayoutRow(col,0); 01628 uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01629 } 01630 01631 uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01632 uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01633 } 01634 01635 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01636 { 01637 uiLayout *col; 01638 01639 col= uiLayoutColumn(layout, 1); 01640 uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01641 uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NONE); 01642 } 01643 01644 static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01645 { 01646 uiItemR(layout, ptr, "alpha", 0, NULL, ICON_NONE); 01647 } 01648 01649 static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01650 { 01651 uiItemR(layout, ptr, "index", 0, NULL, ICON_NONE); 01652 uiItemR(layout, ptr, "use_smooth_mask", 0, NULL, ICON_NONE); 01653 } 01654 01655 static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01656 { 01657 bNode *node= ptr->data; 01658 NodeImageFile *nif= node->storage; 01659 PointerRNA imfptr; 01660 01661 uiLayout *row; 01662 01663 uiItemR(layout, ptr, "filepath", 0, "", ICON_NONE); 01664 01665 RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &nif->im_format, &imfptr); 01666 uiTemplateImageSettings(layout, &imfptr); 01667 01668 row= uiLayoutRow(layout, 1); 01669 uiItemR(row, ptr, "frame_start", 0, "Start", ICON_NONE); 01670 uiItemR(row, ptr, "frame_end", 0, "End", ICON_NONE); 01671 } 01672 01673 static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01674 { 01675 uiItemR(layout, ptr, "space", 0, "", ICON_NONE); 01676 } 01677 01678 static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01679 { 01680 uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE); 01681 } 01682 01683 static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01684 { 01685 uiLayout *col; 01686 01687 col= uiLayoutColumn(layout, 0); 01688 uiItemR(col, ptr, "invert_rgb", 0, NULL, ICON_NONE); 01689 uiItemR(col, ptr, "invert_alpha", 0, NULL, ICON_NONE); 01690 } 01691 01692 static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01693 { 01694 uiItemR(layout, ptr, "mapping", 0, "", ICON_NONE); 01695 } 01696 01697 static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01698 { 01699 uiItemR(layout, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 01700 } 01701 01702 static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01703 { 01704 uiLayout *split, *col, *row; 01705 01706 uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE); 01707 01708 if (RNA_enum_get(ptr, "correction_method")== 0) { 01709 01710 split = uiLayoutSplit(layout, 0, 0); 01711 col = uiLayoutColumn(split, 0); 01712 uiTemplateColorWheel(col, ptr, "lift", 1, 1, 0, 1); 01713 row = uiLayoutRow(col, 0); 01714 uiItemR(row, ptr, "lift", 0, NULL, ICON_NONE); 01715 01716 col = uiLayoutColumn(split, 0); 01717 uiTemplateColorWheel(col, ptr, "gamma", 1, 1, 1, 1); 01718 row = uiLayoutRow(col, 0); 01719 uiItemR(row, ptr, "gamma", 0, NULL, ICON_NONE); 01720 01721 col = uiLayoutColumn(split, 0); 01722 uiTemplateColorWheel(col, ptr, "gain", 1, 1, 1, 1); 01723 row = uiLayoutRow(col, 0); 01724 uiItemR(row, ptr, "gain", 0, NULL, ICON_NONE); 01725 01726 } else { 01727 01728 split = uiLayoutSplit(layout, 0, 0); 01729 col = uiLayoutColumn(split, 0); 01730 uiTemplateColorWheel(col, ptr, "offset", 1, 1, 0, 1); 01731 row = uiLayoutRow(col, 0); 01732 uiItemR(row, ptr, "offset", 0, NULL, ICON_NONE); 01733 01734 col = uiLayoutColumn(split, 0); 01735 uiTemplateColorWheel(col, ptr, "power", 1, 1, 0, 1); 01736 row = uiLayoutRow(col, 0); 01737 uiItemR(row, ptr, "power", 0, NULL, ICON_NONE); 01738 01739 col = uiLayoutColumn(split, 0); 01740 uiTemplateColorWheel(col, ptr, "slope", 1, 1, 0, 1); 01741 row = uiLayoutRow(col, 0); 01742 uiItemR(row, ptr, "slope", 0, NULL, ICON_NONE); 01743 } 01744 01745 } 01746 static void node_composit_buts_colorbalance_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01747 { 01748 uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE); 01749 01750 if (RNA_enum_get(ptr, "correction_method")== 0) { 01751 01752 uiTemplateColorWheel(layout, ptr, "lift", 1, 1, 0, 1); 01753 uiItemR(layout, ptr, "lift", 0, NULL, ICON_NONE); 01754 01755 uiTemplateColorWheel(layout, ptr, "gamma", 1, 1, 1, 1); 01756 uiItemR(layout, ptr, "gamma", 0, NULL, ICON_NONE); 01757 01758 uiTemplateColorWheel(layout, ptr, "gain", 1, 1, 1, 1); 01759 uiItemR(layout, ptr, "gain", 0, NULL, ICON_NONE); 01760 } else { 01761 uiTemplateColorWheel(layout, ptr, "offset", 1, 1, 0, 1); 01762 uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE); 01763 01764 uiTemplateColorWheel(layout, ptr, "power", 1, 1, 0, 1); 01765 uiItemR(layout, ptr, "power", 0, NULL, ICON_NONE); 01766 01767 uiTemplateColorWheel(layout, ptr, "slope", 1, 1, 0, 1); 01768 uiItemR(layout, ptr, "slope", 0, NULL, ICON_NONE); 01769 } 01770 } 01771 01772 01773 static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01774 { 01775 uiTemplateCurveMapping(layout, ptr, "mapping", 'h', 0, 0); 01776 } 01777 01778 static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01779 { 01780 uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); 01781 } 01782 01783 static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr) 01784 { 01785 uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); 01786 } 01787 01788 static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr) 01789 { 01790 bNode *node= ptr->data; 01791 01792 uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); 01793 01794 if(!node->id) 01795 return; 01796 01797 uiItemR(layout, ptr, "filter_type", 0, "", 0); 01798 } 01799 01800 static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01801 { 01802 uiItemR(layout, ptr, "filter_type", 0, "", 0); 01803 } 01804 01805 static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr) 01806 { 01807 bNode *node= ptr->data; 01808 01809 uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); 01810 01811 if(!node->id) 01812 return; 01813 01814 uiItemR(layout, ptr, "distortion_type", 0, "", 0); 01815 } 01816 01817 /* only once called */ 01818 static void node_composit_set_butfunc(bNodeType *ntype) 01819 { 01820 ntype->uifuncbut = NULL; 01821 switch(ntype->type) { 01822 /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ 01823 01824 case CMP_NODE_IMAGE: 01825 ntype->uifunc= node_composit_buts_image; 01826 break; 01827 case CMP_NODE_R_LAYERS: 01828 ntype->uifunc= node_composit_buts_renderlayers; 01829 break; 01830 case CMP_NODE_NORMAL: 01831 ntype->uifunc= node_buts_normal; 01832 break; 01833 case CMP_NODE_CURVE_VEC: 01834 ntype->uifunc= node_buts_curvevec; 01835 break; 01836 case CMP_NODE_CURVE_RGB: 01837 ntype->uifunc= node_buts_curvecol; 01838 break; 01839 case CMP_NODE_VALUE: 01840 ntype->uifunc= node_buts_value; 01841 break; 01842 case CMP_NODE_RGB: 01843 ntype->uifunc= node_buts_rgb; 01844 break; 01845 case CMP_NODE_FLIP: 01846 ntype->uifunc= node_composit_buts_flip; 01847 break; 01848 case CMP_NODE_SPLITVIEWER: 01849 ntype->uifunc= node_composit_buts_splitviewer; 01850 break; 01851 case CMP_NODE_MIX_RGB: 01852 ntype->uifunc= node_buts_mix_rgb; 01853 break; 01854 case CMP_NODE_VALTORGB: 01855 ntype->uifunc= node_buts_colorramp; 01856 break; 01857 case CMP_NODE_CROP: 01858 ntype->uifunc= node_composit_buts_crop; 01859 break; 01860 case CMP_NODE_BLUR: 01861 ntype->uifunc= node_composit_buts_blur; 01862 break; 01863 case CMP_NODE_DBLUR: 01864 ntype->uifunc= node_composit_buts_dblur; 01865 break; 01866 case CMP_NODE_BILATERALBLUR: 01867 ntype->uifunc= node_composit_buts_bilateralblur; 01868 break; 01869 case CMP_NODE_DEFOCUS: 01870 ntype->uifunc = node_composit_buts_defocus; 01871 break; 01872 case CMP_NODE_GLARE: 01873 ntype->uifunc = node_composit_buts_glare; 01874 break; 01875 case CMP_NODE_TONEMAP: 01876 ntype->uifunc = node_composit_buts_tonemap; 01877 break; 01878 case CMP_NODE_LENSDIST: 01879 ntype->uifunc = node_composit_buts_lensdist; 01880 break; 01881 case CMP_NODE_VECBLUR: 01882 ntype->uifunc= node_composit_buts_vecblur; 01883 break; 01884 case CMP_NODE_FILTER: 01885 ntype->uifunc= node_composit_buts_filter; 01886 break; 01887 case CMP_NODE_MAP_VALUE: 01888 ntype->uifunc= node_composit_buts_map_value; 01889 break; 01890 case CMP_NODE_TIME: 01891 ntype->uifunc= node_buts_time; 01892 break; 01893 case CMP_NODE_ALPHAOVER: 01894 ntype->uifunc= node_composit_buts_alphaover; 01895 break; 01896 case CMP_NODE_HUE_SAT: 01897 ntype->uifunc= node_composit_buts_hue_sat; 01898 break; 01899 case CMP_NODE_TEXTURE: 01900 ntype->uifunc= node_buts_texture; 01901 break; 01902 case CMP_NODE_DILATEERODE: 01903 ntype->uifunc= node_composit_buts_dilateerode; 01904 break; 01905 case CMP_NODE_OUTPUT_FILE: 01906 ntype->uifunc= node_composit_buts_file_output; 01907 break; 01908 case CMP_NODE_DIFF_MATTE: 01909 ntype->uifunc=node_composit_buts_diff_matte; 01910 break; 01911 case CMP_NODE_DIST_MATTE: 01912 ntype->uifunc=node_composit_buts_distance_matte; 01913 break; 01914 case CMP_NODE_COLOR_SPILL: 01915 ntype->uifunc=node_composit_buts_color_spill; 01916 break; 01917 case CMP_NODE_CHROMA_MATTE: 01918 ntype->uifunc=node_composit_buts_chroma_matte; 01919 break; 01920 case CMP_NODE_COLOR_MATTE: 01921 ntype->uifunc=node_composit_buts_color_matte; 01922 break; 01923 case CMP_NODE_SCALE: 01924 ntype->uifunc= node_composit_buts_scale; 01925 break; 01926 case CMP_NODE_ROTATE: 01927 ntype->uifunc=node_composit_buts_rotate; 01928 break; 01929 case CMP_NODE_CHANNEL_MATTE: 01930 ntype->uifunc= node_composit_buts_channel_matte; 01931 break; 01932 case CMP_NODE_LUMA_MATTE: 01933 ntype->uifunc= node_composit_buts_luma_matte; 01934 break; 01935 case CMP_NODE_MAP_UV: 01936 ntype->uifunc= node_composit_buts_map_uv; 01937 break; 01938 case CMP_NODE_ID_MASK: 01939 ntype->uifunc= node_composit_buts_id_mask; 01940 break; 01941 case CMP_NODE_DOUBLEEDGEMASK: 01942 ntype->uifunc= node_composit_buts_double_edge_mask; 01943 break; 01944 case CMP_NODE_MATH: 01945 ntype->uifunc= node_buts_math; 01946 break; 01947 case CMP_NODE_INVERT: 01948 ntype->uifunc= node_composit_buts_invert; 01949 break; 01950 case CMP_NODE_PREMULKEY: 01951 ntype->uifunc= node_composit_buts_premulkey; 01952 break; 01953 case CMP_NODE_VIEW_LEVELS: 01954 ntype->uifunc=node_composit_buts_view_levels; 01955 break; 01956 case CMP_NODE_COLORBALANCE: 01957 ntype->uifunc=node_composit_buts_colorbalance; 01958 ntype->uifuncbut=node_composit_buts_colorbalance_but; 01959 break; 01960 case CMP_NODE_HUECORRECT: 01961 ntype->uifunc=node_composit_buts_huecorrect; 01962 break; 01963 case CMP_NODE_ZCOMBINE: 01964 ntype->uifunc=node_composit_buts_zcombine; 01965 break; 01966 case CMP_NODE_COMBYCCA: 01967 case CMP_NODE_SEPYCCA: 01968 ntype->uifunc=node_composit_buts_ycc; 01969 break; 01970 case CMP_NODE_MOVIECLIP: 01971 ntype->uifunc= node_composit_buts_movieclip; 01972 break; 01973 case CMP_NODE_STABILIZE2D: 01974 ntype->uifunc= node_composit_buts_stabilize2d; 01975 break; 01976 case CMP_NODE_TRANSFORM: 01977 ntype->uifunc= node_composit_buts_transform; 01978 break; 01979 case CMP_NODE_MOVIEDISTORTION: 01980 ntype->uifunc= node_composit_buts_moviedistortion; 01981 break; 01982 default: 01983 ntype->uifunc= NULL; 01984 } 01985 if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; 01986 01987 } 01988 01989 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */ 01990 01991 static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 01992 { 01993 uiLayout *col; 01994 01995 col= uiLayoutColumn(layout, 1); 01996 uiItemR(col, ptr, "offset", 0, "Offset", ICON_NONE); 01997 uiItemR(col, ptr, "offset_frequency", 0, "Frequency", ICON_NONE); 01998 01999 col= uiLayoutColumn(layout, 1); 02000 uiItemR(col, ptr, "squash", 0, "Squash", ICON_NONE); 02001 uiItemR(col, ptr, "squash_frequency", 0, "Frequency", ICON_NONE); 02002 } 02003 02004 static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 02005 { 02006 PointerRNA tex_ptr; 02007 bNode *node= ptr->data; 02008 ID *id= ptr->id.data; 02009 Tex *tex = (Tex *)node->storage; 02010 uiLayout *col, *row; 02011 02012 RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr); 02013 02014 col= uiLayoutColumn(layout, 0); 02015 02016 switch( tex->type ) { 02017 case TEX_BLEND: 02018 uiItemR(col, &tex_ptr, "progression", 0, "", ICON_NONE); 02019 row= uiLayoutRow(col, 0); 02020 uiItemR(row, &tex_ptr, "use_flip_axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02021 break; 02022 02023 case TEX_MARBLE: 02024 row= uiLayoutRow(col, 0); 02025 uiItemR(row, &tex_ptr, "marble_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02026 row= uiLayoutRow(col, 0); 02027 uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02028 row= uiLayoutRow(col, 0); 02029 uiItemR(row, &tex_ptr, "noise_basis", 0, "", ICON_NONE); 02030 row= uiLayoutRow(col, 0); 02031 uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02032 break; 02033 02034 case TEX_MAGIC: 02035 uiItemR(col, &tex_ptr, "noise_depth", 0, NULL, ICON_NONE); 02036 break; 02037 02038 case TEX_STUCCI: 02039 row= uiLayoutRow(col, 0); 02040 uiItemR(row, &tex_ptr, "stucci_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02041 row= uiLayoutRow(col, 0); 02042 uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02043 uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE); 02044 break; 02045 02046 case TEX_WOOD: 02047 uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE); 02048 uiItemR(col, &tex_ptr, "wood_type", 0, "", ICON_NONE); 02049 row= uiLayoutRow(col, 0); 02050 uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02051 row= uiLayoutRow(col, 0); 02052 uiLayoutSetActive(row, !(RNA_enum_get(&tex_ptr, "wood_type")==TEX_BAND || RNA_enum_get(&tex_ptr, "wood_type")==TEX_RING)); 02053 uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02054 break; 02055 02056 case TEX_CLOUDS: 02057 uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE); 02058 row= uiLayoutRow(col, 0); 02059 uiItemR(row, &tex_ptr, "cloud_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02060 row= uiLayoutRow(col, 0); 02061 uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 02062 uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, "Depth", ICON_NONE); 02063 break; 02064 02065 case TEX_DISTNOISE: 02066 uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE); 02067 uiItemR(col, &tex_ptr, "noise_distortion", 0, "", ICON_NONE); 02068 break; 02069 02070 case TEX_MUSGRAVE: 02071 uiItemR(col, &tex_ptr, "musgrave_type", 0, "", ICON_NONE); 02072 uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE); 02073 break; 02074 case TEX_VORONOI: 02075 uiItemR(col, &tex_ptr, "distance_metric", 0, "", ICON_NONE); 02076 if(tex->vn_distm == TEX_MINKOVSKY) { 02077 uiItemR(col, &tex_ptr, "minkovsky_exponent", 0, NULL, ICON_NONE); 02078 } 02079 uiItemR(col, &tex_ptr, "color_mode", 0, "", ICON_NONE); 02080 break; 02081 } 02082 } 02083 02084 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) 02085 { 02086 uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); 02087 } 02088 02089 static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) 02090 { 02091 uiItemR(layout, ptr, "filepath", 0, "", ICON_NONE); 02092 } 02093 02094 /* only once called */ 02095 static void node_texture_set_butfunc(bNodeType *ntype) 02096 { 02097 ntype->uifuncbut = NULL; 02098 if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) { 02099 ntype->uifunc = node_texture_buts_proc; 02100 } 02101 else switch(ntype->type) { 02102 02103 case TEX_NODE_MATH: 02104 ntype->uifunc = node_buts_math; 02105 break; 02106 02107 case TEX_NODE_MIX_RGB: 02108 ntype->uifunc = node_buts_mix_rgb; 02109 break; 02110 02111 case TEX_NODE_VALTORGB: 02112 ntype->uifunc = node_buts_colorramp; 02113 break; 02114 02115 case TEX_NODE_CURVE_RGB: 02116 ntype->uifunc= node_buts_curvecol; 02117 break; 02118 02119 case TEX_NODE_CURVE_TIME: 02120 ntype->uifunc = node_buts_time; 02121 break; 02122 02123 case TEX_NODE_TEXTURE: 02124 ntype->uifunc = node_buts_texture; 02125 break; 02126 02127 case TEX_NODE_BRICKS: 02128 ntype->uifunc = node_texture_buts_bricks; 02129 break; 02130 02131 case TEX_NODE_IMAGE: 02132 ntype->uifunc = node_texture_buts_image; 02133 break; 02134 02135 case TEX_NODE_OUTPUT: 02136 ntype->uifunc = node_texture_buts_output; 02137 break; 02138 } 02139 if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; 02140 } 02141 02142 /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */ 02143 02144 void ED_init_node_butfuncs(void) 02145 { 02146 bNodeTreeType *treetype; 02147 bNodeType *ntype; 02148 bNodeSocketType *stype; 02149 int i; 02150 02151 /* node type ui functions */ 02152 for (i=0; i < NUM_NTREE_TYPES; ++i) { 02153 treetype = ntreeGetType(i); 02154 if (treetype) { 02155 for (ntype= treetype->node_types.first; ntype; ntype= ntype->next) { 02156 /* default ui functions */ 02157 ntype->drawfunc = node_draw_default; 02158 ntype->drawupdatefunc = node_update_default; 02159 ntype->uifunc = NULL; 02160 ntype->uifuncbut = NULL; 02161 ntype->resize_area_func = node_resize_area_default; 02162 02163 node_common_set_butfunc(ntype); 02164 02165 switch (i) { 02166 case NTREE_COMPOSIT: 02167 node_composit_set_butfunc(ntype); 02168 break; 02169 case NTREE_SHADER: 02170 node_shader_set_butfunc(ntype); 02171 break; 02172 case NTREE_TEXTURE: 02173 node_texture_set_butfunc(ntype); 02174 break; 02175 } 02176 } 02177 } 02178 } 02179 02180 /* socket type ui functions */ 02181 for (i=0; i < NUM_SOCKET_TYPES; ++i) { 02182 stype = ntreeGetSocketType(i); 02183 if (stype) { 02184 switch(stype->type) { 02185 case SOCK_FLOAT: 02186 case SOCK_INT: 02187 case SOCK_BOOLEAN: 02188 stype->buttonfunc = node_socket_button_default; 02189 break; 02190 case SOCK_VECTOR: 02191 stype->buttonfunc = node_socket_button_components; 02192 break; 02193 case SOCK_RGBA: 02194 stype->buttonfunc = node_socket_button_color; 02195 break; 02196 case SOCK_SHADER: 02197 stype->buttonfunc = node_socket_button_label; 02198 break; 02199 default: 02200 stype->buttonfunc = NULL; 02201 } 02202 } 02203 } 02204 } 02205 02206 /* ************** Generic drawing ************** */ 02207 02208 void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage) 02209 { 02210 02211 if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) { 02212 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); 02213 void *lock; 02214 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock); 02215 if(ibuf) { 02216 float x, y; 02217 02218 glMatrixMode(GL_PROJECTION); 02219 glPushMatrix(); 02220 glMatrixMode(GL_MODELVIEW); 02221 glPushMatrix(); 02222 02223 /* keep this, saves us from a version patch */ 02224 if(snode->zoom==0.0f) snode->zoom= 1.0f; 02225 02226 /* somehow the offset has to be calculated inverse */ 02227 02228 glaDefine2DArea(&ar->winrct); 02229 /* ortho at pixel level curarea */ 02230 wmOrtho2(-0.375, ar->winx-0.375, -0.375, ar->winy-0.375); 02231 02232 x = (ar->winx-snode->zoom*ibuf->x)/2 + snode->xof; 02233 y = (ar->winy-snode->zoom*ibuf->y)/2 + snode->yof; 02234 02235 if(!ibuf->rect) { 02236 if(color_manage) 02237 ibuf->profile = IB_PROFILE_LINEAR_RGB; 02238 else 02239 ibuf->profile = IB_PROFILE_NONE; 02240 IMB_rect_from_float(ibuf); 02241 } 02242 02243 if(ibuf->rect) { 02244 if (snode->flag & SNODE_SHOW_ALPHA) { 02245 glPixelZoom(snode->zoom, snode->zoom); 02246 /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ 02247 if(ENDIAN_ORDER == B_ENDIAN) 02248 glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); 02249 02250 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, ibuf->rect); 02251 02252 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); 02253 glPixelZoom(1.0f, 1.0f); 02254 } else if (snode->flag & SNODE_USE_ALPHA) { 02255 glEnable(GL_BLEND); 02256 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 02257 glPixelZoom(snode->zoom, snode->zoom); 02258 02259 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); 02260 02261 glPixelZoom(1.0f, 1.0f); 02262 glDisable(GL_BLEND); 02263 } else { 02264 glPixelZoom(snode->zoom, snode->zoom); 02265 02266 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); 02267 02268 glPixelZoom(1.0f, 1.0f); 02269 } 02270 } 02271 02272 glMatrixMode(GL_PROJECTION); 02273 glPopMatrix(); 02274 glMatrixMode(GL_MODELVIEW); 02275 glPopMatrix(); 02276 } 02277 02278 BKE_image_release_ibuf(ima, lock); 02279 } 02280 } 02281 02282 #if 0 02283 /* note: needs to be userpref or opengl profile option */ 02284 static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode) 02285 { 02286 02287 draw_nodespace_grid(snode); 02288 02289 if(snode->flag & SNODE_BACKDRAW) { 02290 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); 02291 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); 02292 if(ibuf) { 02293 int x, y; 02294 float zoom = 1.0; 02295 02296 glMatrixMode(GL_PROJECTION); 02297 glPushMatrix(); 02298 glMatrixMode(GL_MODELVIEW); 02299 glPushMatrix(); 02300 02301 glaDefine2DArea(&sa->winrct); 02302 02303 if(ibuf->x > sa->winx || ibuf->y > sa->winy) { 02304 float zoomx, zoomy; 02305 zoomx= (float)sa->winx/ibuf->x; 02306 zoomy= (float)sa->winy/ibuf->y; 02307 zoom = MIN2(zoomx, zoomy); 02308 } 02309 02310 x = (sa->winx-zoom*ibuf->x)/2 + snode->xof; 02311 y = (sa->winy-zoom*ibuf->y)/2 + snode->yof; 02312 02313 glPixelZoom(zoom, zoom); 02314 02315 glColor4f(1.0, 1.0, 1.0, 1.0); 02316 if(ibuf->rect) 02317 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); 02318 else if(ibuf->channels==4) 02319 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float); 02320 02321 glPixelZoom(1.0, 1.0); 02322 02323 glMatrixMode(GL_PROJECTION); 02324 glPopMatrix(); 02325 glMatrixMode(GL_MODELVIEW); 02326 glPopMatrix(); 02327 } 02328 } 02329 } 02330 #endif 02331 02332 /* if v2d not NULL, it clips and returns 0 if not visible */ 02333 int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol) 02334 { 02335 float dist, vec[4][2]; 02336 02337 /* in v0 and v3 we put begin/end points */ 02338 if(link->fromsock) { 02339 vec[0][0]= link->fromsock->locx; 02340 vec[0][1]= link->fromsock->locy; 02341 } 02342 else { 02343 if(snode==NULL) return 0; 02344 vec[0][0]= snode->mx; 02345 vec[0][1]= snode->my; 02346 } 02347 if(link->tosock) { 02348 vec[3][0]= link->tosock->locx; 02349 vec[3][1]= link->tosock->locy; 02350 } 02351 else { 02352 if(snode==NULL) return 0; 02353 vec[3][0]= snode->mx; 02354 vec[3][1]= snode->my; 02355 } 02356 02357 dist= UI_GetThemeValue(TH_NODE_CURVING)*0.10f*ABS(vec[0][0] - vec[3][0]); 02358 02359 /* check direction later, for top sockets */ 02360 vec[1][0]= vec[0][0]+dist; 02361 vec[1][1]= vec[0][1]; 02362 02363 vec[2][0]= vec[3][0]-dist; 02364 vec[2][1]= vec[3][1]; 02365 02366 if(v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax); /* clipped */ 02367 else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin); /* clipped */ 02368 else { 02369 02370 /* always do all three, to prevent data hanging around */ 02371 forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2); 02372 forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2); 02373 02374 return 1; 02375 } 02376 return 0; 02377 } 02378 02379 #define LINK_RESOL 24 02380 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 ) 02381 { 02382 float coord_array[LINK_RESOL+1][2]; 02383 02384 if(node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) { 02385 float dist, spline_step = 0.0f; 02386 int i; 02387 02388 /* store current linewidth */ 02389 float linew; 02390 glGetFloatv(GL_LINE_WIDTH, &linew); 02391 02392 /* we can reuse the dist variable here to increment the GL curve eval amount*/ 02393 dist = 1.0f/(float)LINK_RESOL; 02394 02395 glEnable(GL_LINE_SMOOTH); 02396 02397 if(do_triple) { 02398 UI_ThemeColorShadeAlpha(th_col3, -80, -120); 02399 glLineWidth(4.0f); 02400 02401 glBegin(GL_LINE_STRIP); 02402 for(i=0; i<=LINK_RESOL; i++) { 02403 glVertex2fv(coord_array[i]); 02404 } 02405 glEnd(); 02406 } 02407 02408 /* XXX using GL_LINES for shaded node lines is a workaround 02409 * for Intel hardware, this breaks with GL_LINE_STRIP and 02410 * changing color in begin/end blocks. 02411 */ 02412 glLineWidth(1.5f); 02413 if(do_shaded) { 02414 glBegin(GL_LINES); 02415 for(i=0; i<LINK_RESOL; i++) { 02416 UI_ThemeColorBlend(th_col1, th_col2, spline_step); 02417 glVertex2fv(coord_array[i]); 02418 02419 UI_ThemeColorBlend(th_col1, th_col2, spline_step+dist); 02420 glVertex2fv(coord_array[i+1]); 02421 02422 spline_step += dist; 02423 } 02424 glEnd(); 02425 } 02426 else { 02427 UI_ThemeColor(th_col1); 02428 glBegin(GL_LINE_STRIP); 02429 for(i=0; i<=LINK_RESOL; i++) { 02430 glVertex2fv(coord_array[i]); 02431 } 02432 glEnd(); 02433 } 02434 02435 glDisable(GL_LINE_SMOOTH); 02436 02437 /* restore previuos linewidth */ 02438 glLineWidth(linew); 02439 } 02440 } 02441 02442 static void node_link_straight_points(View2D *UNUSED(v2d), SpaceNode *snode, bNodeLink *link, float coord_array[][2]) 02443 { 02444 if(link->fromsock) { 02445 coord_array[0][0]= link->fromsock->locx; 02446 coord_array[0][1]= link->fromsock->locy; 02447 } 02448 else { 02449 if(snode==NULL) return; 02450 coord_array[0][0]= snode->mx; 02451 coord_array[0][1]= snode->my; 02452 } 02453 if(link->tosock) { 02454 coord_array[1][0]= link->tosock->locx; 02455 coord_array[1][1]= link->tosock->locy; 02456 } 02457 else { 02458 if(snode==NULL) return; 02459 coord_array[1][0]= snode->mx; 02460 coord_array[1][1]= snode->my; 02461 } 02462 } 02463 02464 void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ) 02465 { 02466 float coord_array[2][2]; 02467 float linew; 02468 int i; 02469 02470 node_link_straight_points(v2d, snode, link, coord_array); 02471 02472 /* store current linewidth */ 02473 glGetFloatv(GL_LINE_WIDTH, &linew); 02474 02475 glEnable(GL_LINE_SMOOTH); 02476 02477 if(do_triple) { 02478 UI_ThemeColorShadeAlpha(th_col3, -80, -120); 02479 glLineWidth(4.0f); 02480 02481 glBegin(GL_LINES); 02482 glVertex2fv(coord_array[0]); 02483 glVertex2fv(coord_array[1]); 02484 glEnd(); 02485 } 02486 02487 UI_ThemeColor(th_col1); 02488 glLineWidth(1.5f); 02489 02490 /* XXX using GL_LINES for shaded node lines is a workaround 02491 * for Intel hardware, this breaks with GL_LINE_STRIP and 02492 * changing color in begin/end blocks. 02493 */ 02494 if(do_shaded) { 02495 glBegin(GL_LINES); 02496 for (i=0; i < LINK_RESOL-1; ++i) { 02497 float t= (float)i/(float)(LINK_RESOL-1); 02498 UI_ThemeColorBlend(th_col1, th_col2, t); 02499 glVertex2f((1.0f-t)*coord_array[0][0]+t*coord_array[1][0], (1.0f-t)*coord_array[0][1]+t*coord_array[1][1]); 02500 02501 t= (float)(i+1)/(float)(LINK_RESOL-1); 02502 UI_ThemeColorBlend(th_col1, th_col2, t); 02503 glVertex2f((1.0f-t)*coord_array[0][0]+t*coord_array[1][0], (1.0f-t)*coord_array[0][1]+t*coord_array[1][1]); 02504 } 02505 glEnd(); 02506 } 02507 else { 02508 glBegin(GL_LINE_STRIP); 02509 for (i=0; i < LINK_RESOL; ++i) { 02510 float t= (float)i/(float)(LINK_RESOL-1); 02511 glVertex2f((1.0f-t)*coord_array[0][0]+t*coord_array[1][0], (1.0f-t)*coord_array[0][1]+t*coord_array[1][1]); 02512 } 02513 glEnd(); 02514 } 02515 02516 glDisable(GL_LINE_SMOOTH); 02517 02518 /* restore previuos linewidth */ 02519 glLineWidth(linew); 02520 } 02521 02522 /* note; this is used for fake links in groups too */ 02523 void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) 02524 { 02525 int do_shaded= 0, th_col1= TH_HEADER, th_col2= TH_HEADER; 02526 int do_triple= 0, th_col3= TH_WIRE; 02527 02528 if(link->fromsock==NULL && link->tosock==NULL) 02529 return; 02530 02531 /* new connection */ 02532 if(!link->fromsock || !link->tosock) { 02533 th_col1 = TH_ACTIVE; 02534 do_triple = 1; 02535 } 02536 else { 02537 /* going to give issues once... */ 02538 if(link->tosock->flag & SOCK_UNAVAIL) 02539 return; 02540 if(link->fromsock->flag & SOCK_UNAVAIL) 02541 return; 02542 02543 /* a bit ugly... but thats how we detect the internal group links */ 02544 if(!link->fromnode || !link->tonode) { 02545 UI_ThemeColorBlend(TH_BACK, TH_WIRE, 0.5f); 02546 do_shaded= 0; 02547 } 02548 else { 02549 /* check cyclic */ 02550 if((link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) && (link->flag & NODE_LINK_VALID)) { 02551 /* special indicated link, on drop-node */ 02552 if(link->flag & NODE_LINKFLAG_HILITE) { 02553 th_col1= th_col2= TH_ACTIVE; 02554 } 02555 else { 02556 /* regular link */ 02557 if(link->fromnode->flag & SELECT) 02558 th_col1= TH_EDGE_SELECT; 02559 if(link->tonode->flag & SELECT) 02560 th_col2= TH_EDGE_SELECT; 02561 } 02562 do_shaded= 1; 02563 do_triple= 1; 02564 } 02565 else { 02566 th_col1 = TH_REDALERT; 02567 } 02568 } 02569 } 02570 02571 node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); 02572 // node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); 02573 }