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) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation, 2002-2009 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00032 #include <string.h> 00033 #include <stdio.h> 00034 00035 #include "DNA_meshdata_types.h" 00036 #include "DNA_object_types.h" 00037 #include "DNA_node_types.h" 00038 #include "DNA_scene_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_math.h" 00044 #include "BLI_editVert.h" 00045 #include "BLI_rand.h" 00046 #include "BLI_utildefines.h" 00047 00048 #include "BKE_colortools.h" 00049 #include "BKE_context.h" 00050 #include "BKE_customdata.h" 00051 #include "BKE_image.h" 00052 #include "BKE_mesh.h" 00053 #include "BKE_node.h" 00054 #include "BKE_screen.h" 00055 00056 #include "RE_pipeline.h" 00057 00058 #include "IMB_imbuf.h" 00059 #include "IMB_imbuf_types.h" 00060 00061 #include "ED_gpencil.h" 00062 #include "ED_image.h" 00063 #include "ED_screen.h" 00064 00065 #include "RNA_access.h" 00066 00067 #include "WM_api.h" 00068 #include "WM_types.h" 00069 00070 #include "UI_interface.h" 00071 #include "UI_resources.h" 00072 00073 #include "image_intern.h" 00074 00075 #define B_REDR 1 00076 #define B_IMAGECHANGED 2 00077 #define B_NOP 0 00078 #define B_TWINANIM 5 00079 #define B_SIMAGETILE 6 00080 #define B_IDNAME 10 00081 #define B_FACESEL_PAINT_TEST 11 00082 #define B_SIMA_RECORD 12 00083 #define B_SIMA_PLAY 13 00084 00085 #define B_SIMANOTHING 16 00086 #define B_SIMABRUSHCHANGE 17 00087 #define B_SIMABRUSHBROWSE 18 00088 #define B_SIMABRUSHLOCAL 19 00089 #define B_SIMABRUSHDELETE 20 00090 #define B_KEEPDATA 21 00091 #define B_SIMABTEXBROWSE 22 00092 #define B_SIMABTEXDELETE 23 00093 #define B_VPCOLSLI 24 00094 #define B_SIMACLONEBROWSE 25 00095 #define B_SIMACLONEDELETE 26 00096 00097 /* proto */ 00098 00099 static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str) 00100 { 00101 int ofs= 0; 00102 00103 str[0]= 0; 00104 00105 if(ima==NULL) return; 00106 00107 if(ibuf==NULL) { 00108 ofs+= sprintf(str, "Can't Load Image"); 00109 } 00110 else { 00111 if(ima->source==IMA_SRC_MOVIE) { 00112 ofs+= sprintf(str, "Movie"); 00113 if(ima->anim) 00114 ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN)); 00115 } 00116 else 00117 ofs+= sprintf(str, "Image"); 00118 00119 ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y); 00120 00121 if(ibuf->rect_float) { 00122 if(ibuf->channels!=4) { 00123 ofs+= sprintf(str+ofs, "%d float channel(s)", ibuf->channels); 00124 } 00125 else if(ibuf->planes == R_IMF_PLANES_RGBA) 00126 ofs+= sprintf(str+ofs, " RGBA float"); 00127 else 00128 ofs+= sprintf(str+ofs, " RGB float"); 00129 } 00130 else { 00131 if(ibuf->planes == R_IMF_PLANES_RGBA) 00132 ofs+= sprintf(str+ofs, " RGBA byte"); 00133 else 00134 ofs+= sprintf(str+ofs, " RGB byte"); 00135 } 00136 if(ibuf->zbuf || ibuf->zbuf_float) 00137 ofs+= sprintf(str+ofs, " + Z"); 00138 00139 if(ima->source==IMA_SRC_SEQUENCE) { 00140 char *file= BLI_last_slash(ibuf->name); 00141 if(file==NULL) file= ibuf->name; 00142 else file++; 00143 ofs+= sprintf(str+ofs, ", %s", file); 00144 } 00145 } 00146 00147 /* the frame number, even if we cant */ 00148 if(ima->source==IMA_SRC_SEQUENCE) { 00149 /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ 00150 const int framenr= BKE_image_user_get_frame(iuser, CFRA, 0); 00151 ofs+= sprintf(str+ofs, ", Frame: %d", framenr); 00152 } 00153 00154 (void)ofs; 00155 } 00156 00157 /* gets active viewer user */ 00158 struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree) 00159 { 00160 bNode *node; 00161 00162 if(ntree) 00163 for(node= ntree->nodes.first; node; node= node->next) 00164 if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 00165 if(node->flag & NODE_DO_OUTPUT) 00166 return node->storage; 00167 return NULL; 00168 } 00169 00170 00171 /* ************ panel stuff ************* */ 00172 00173 /* is used for both read and write... */ 00174 00175 static int image_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00176 { 00177 SpaceImage *sima= CTX_wm_space_image(C); 00178 ImBuf *ibuf; 00179 void *lock; 00180 int result; 00181 00182 ibuf= ED_space_image_acquire_buffer(sima, &lock); 00183 result= ibuf && ibuf->rect_float; 00184 ED_space_image_release_buffer(sima, lock); 00185 00186 return result; 00187 } 00188 00189 static void image_panel_curves(const bContext *C, Panel *pa) 00190 { 00191 bScreen *sc= CTX_wm_screen(C); 00192 SpaceImage *sima= CTX_wm_space_image(C); 00193 ImBuf *ibuf; 00194 PointerRNA simaptr; 00195 int levels; 00196 void *lock; 00197 00198 ibuf= ED_space_image_acquire_buffer(sima, &lock); 00199 00200 if(ibuf) { 00201 if(sima->cumap==NULL) 00202 sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); 00203 00204 /* curvemap black/white levels only works for RGBA */ 00205 levels= (ibuf->channels==4); 00206 00207 RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &simaptr); 00208 uiTemplateCurveMapping(pa->layout, &simaptr, "curve", 'c', levels, 0); 00209 } 00210 00211 ED_space_image_release_buffer(sima, lock); 00212 } 00213 00214 #if 0 00215 /* 0: disable preview 00216 otherwise refresh preview 00217 00218 XXX if you put this back, also check XXX in image_main_area_draw() */ 00219 */ 00220 void image_preview_event(int event) 00221 { 00222 int exec= 0; 00223 00224 if(event==0) { 00225 G.scene->r.scemode &= ~R_COMP_CROP; 00226 exec= 1; 00227 } 00228 else { 00229 if(image_preview_active(curarea, NULL, NULL)) { 00230 G.scene->r.scemode |= R_COMP_CROP; 00231 exec= 1; 00232 } 00233 else 00234 G.scene->r.scemode &= ~R_COMP_CROP; 00235 } 00236 00237 if(exec && G.scene->nodetree) { 00238 /* should work when no node editor in screen..., so we execute right away */ 00239 00240 ntreeCompositTagGenerators(G.scene->nodetree); 00241 00242 G.afbreek= 0; 00243 G.scene->nodetree->timecursor= set_timecursor; 00244 G.scene->nodetree->test_break= blender_test_break; 00245 00246 BIF_store_spare(); 00247 00248 ntreeCompositExecTree(G.scene->nodetree, &G.scene->r, 1); /* 1 is do_previews */ 00249 00250 G.scene->nodetree->timecursor= NULL; 00251 G.scene->nodetree->test_break= NULL; 00252 00253 scrarea_do_windraw(curarea); 00254 waitcursor(0); 00255 00256 WM_event_add_notifier(C, NC_IMAGE, ima_v); 00257 } 00258 } 00259 00260 00261 /* nothing drawn here, we use it to store values */ 00262 static void preview_cb(struct ScrArea *sa, struct uiBlock *block) 00263 { 00264 SpaceImage *sima= sa->spacedata.first; 00265 rctf dispf; 00266 rcti *disprect= &G.scene->r.disprect; 00267 int winx= (G.scene->r.size*G.scene->r.xsch)/100; 00268 int winy= (G.scene->r.size*G.scene->r.ysch)/100; 00269 int mval[2]; 00270 00271 if(G.scene->r.mode & R_BORDER) { 00272 winx*= (G.scene->r.border.xmax - G.scene->r.border.xmin); 00273 winy*= (G.scene->r.border.ymax - G.scene->r.border.ymin); 00274 } 00275 00276 /* while dragging we need to update the rects, otherwise it doesn't end with correct one */ 00277 00278 BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); 00279 ui_graphics_to_window_rct(sa->win, &dispf, disprect); 00280 00281 /* correction for gla draw */ 00282 BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); 00283 00284 calc_image_view(sima, 'p'); 00285 // printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); 00286 /* map to image space coordinates */ 00287 mval[0]= disprect->xmin; mval[1]= disprect->ymin; 00288 areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin); 00289 mval[0]= disprect->xmax; mval[1]= disprect->ymax; 00290 areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax); 00291 00292 /* map to render coordinates */ 00293 disprect->xmin= dispf.xmin; 00294 disprect->xmax= dispf.xmax; 00295 disprect->ymin= dispf.ymin; 00296 disprect->ymax= dispf.ymax; 00297 00298 CLAMP(disprect->xmin, 0, winx); 00299 CLAMP(disprect->xmax, 0, winx); 00300 CLAMP(disprect->ymin, 0, winy); 00301 CLAMP(disprect->ymax, 0, winy); 00302 // printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); 00303 00304 } 00305 00306 static int is_preview_allowed(ScrArea *cur) 00307 { 00308 SpaceImage *sima= cur->spacedata.first; 00309 ScrArea *sa; 00310 00311 /* check if another areawindow has preview set */ 00312 for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { 00313 if(sa!=cur && sa->spacetype==SPACE_IMAGE) { 00314 if(image_preview_active(sa, NULL, NULL)) 00315 return 0; 00316 } 00317 } 00318 /* check image type */ 00319 if(sima->image==NULL || sima->image->type!=IMA_TYPE_COMPOSITE) 00320 return 0; 00321 00322 return 1; 00323 } 00324 00325 00326 static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVIEW 00327 { 00328 uiBlock *block; 00329 SpaceImage *sima= sa->spacedata.first; 00330 int ofsx, ofsy; 00331 00332 if(is_preview_allowed(sa)==0) { 00333 rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW); 00334 G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */ 00335 return; 00336 } 00337 00338 block= uiBeginBlock(C, ar, __func__, UI_EMBOSS); 00339 uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); 00340 uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc 00341 00342 ofsx= -150+(sa->winx/2)/sima->blockscale; 00343 ofsy= -100+(sa->winy/2)/sima->blockscale; 00344 if(uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200)==0) return; 00345 00346 uiBlockSetDrawExtraFunc(block, preview_cb); 00347 00348 } 00349 #endif 00350 00351 00352 /* ********************* callbacks for standard image buttons *************** */ 00353 00354 static char *slot_menu(void) 00355 { 00356 char *str; 00357 int a, slot; 00358 00359 str= MEM_callocN(IMA_MAX_RENDER_SLOT*32, "menu slots"); 00360 00361 strcpy(str, "Slot %t"); 00362 a= strlen(str); 00363 00364 for(slot=0; slot<IMA_MAX_RENDER_SLOT; slot++) 00365 a += sprintf(str+a, "|Slot %d %%x%d", slot+1, slot); 00366 00367 return str; 00368 } 00369 00370 /* TODO, curlay should be removed? */ 00371 static char *layer_menu(RenderResult *rr, short *UNUSED(curlay)) 00372 { 00373 RenderLayer *rl; 00374 int len= 64 + 32*BLI_countlist(&rr->layers); 00375 short a, nr= 0; 00376 char *str= MEM_callocN(len, "menu layers"); 00377 00378 strcpy(str, "Layer %t"); 00379 a= strlen(str); 00380 00381 /* compo result */ 00382 if(rr->rectf) { 00383 a+= sprintf(str+a, "|Composite %%x0"); 00384 nr= 1; 00385 } 00386 else if(rr->rect32) { 00387 a+= sprintf(str+a, "|Sequence %%x0"); 00388 nr= 1; 00389 } 00390 for(rl= rr->layers.first; rl; rl= rl->next, nr++) { 00391 a+= sprintf(str+a, "|%s %%x%d", rl->name, nr); 00392 } 00393 00394 /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */ 00395 00396 return str; 00397 } 00398 00399 /* rl==NULL means composite result */ 00400 static char *pass_menu(RenderLayer *rl, short *curpass) 00401 { 00402 RenderPass *rpass; 00403 int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1); 00404 short a, nr= 0; 00405 char *str= MEM_callocN(len, "menu layers"); 00406 00407 strcpy(str, "Pass %t"); 00408 a= strlen(str); 00409 00410 /* rendered results don't have a Combined pass */ 00411 if(rl==NULL || rl->rectf) { 00412 a+= sprintf(str+a, "|Combined %%x0"); 00413 nr= 1; 00414 } 00415 00416 if(rl) 00417 for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++) 00418 a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr); 00419 00420 if(*curpass >= nr) 00421 *curpass= 0; 00422 00423 return str; 00424 } 00425 00426 static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v) 00427 { 00428 Scene *scene= CTX_data_scene(C); 00429 Image *ima= ima_v; 00430 ImageUser *iuser= iuser_v; 00431 00432 if(ima->anim) { 00433 iuser->frames = IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN); 00434 BKE_image_user_calc_frame(iuser, scene->r.cfra, 0); 00435 } 00436 } 00437 00438 /* 5 layer button callbacks... */ 00439 static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) 00440 { 00441 ImageUser *iuser= iuser_v; 00442 00443 BKE_image_multilayer_index(rr_v, iuser); 00444 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00445 } 00446 static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) 00447 { 00448 RenderResult *rr= rr_v; 00449 ImageUser *iuser= iuser_v; 00450 int tot= BLI_countlist(&rr->layers); 00451 00452 if(rr->rectf || rr->rect32) 00453 tot++; /* fake compo/sequencer layer */ 00454 00455 if(iuser->layer<tot-1) { 00456 iuser->layer++; 00457 BKE_image_multilayer_index(rr, iuser); 00458 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00459 } 00460 } 00461 static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) 00462 { 00463 ImageUser *iuser= iuser_v; 00464 00465 if(iuser->layer>0) { 00466 iuser->layer--; 00467 BKE_image_multilayer_index(rr_v, iuser); 00468 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00469 } 00470 } 00471 static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) 00472 { 00473 RenderResult *rr= rr_v; 00474 ImageUser *iuser= iuser_v; 00475 RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer); 00476 00477 if(rl) { 00478 int tot= BLI_countlist(&rl->passes); 00479 00480 if(rr->rectf || rr->rect32) 00481 tot++; /* fake compo/sequencer layer */ 00482 00483 if(iuser->pass<tot-1) { 00484 iuser->pass++; 00485 BKE_image_multilayer_index(rr, iuser); 00486 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00487 } 00488 } 00489 } 00490 static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) 00491 { 00492 ImageUser *iuser= iuser_v; 00493 00494 if(iuser->pass>0) { 00495 iuser->pass--; 00496 BKE_image_multilayer_index(rr_v, iuser); 00497 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00498 } 00499 } 00500 00501 #if 0 00502 static void image_freecache_cb(bContext *C, void *ima_v, void *unused) 00503 { 00504 Scene *scene= CTX_data_scene(C); 00505 BKE_image_free_anim_ibufs(ima_v, scene->r.cfra); 00506 WM_event_add_notifier(C, NC_IMAGE, ima_v); 00507 } 00508 #endif 00509 00510 #if 0 00511 static void image_user_change(bContext *C, void *iuser_v, void *unused) 00512 { 00513 Scene *scene= CTX_data_scene(C); 00514 BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0); 00515 } 00516 #endif 00517 00518 static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, short *render_slot) 00519 { 00520 uiBlock *block= uiLayoutGetBlock(layout); 00521 uiBut *but; 00522 RenderLayer *rl= NULL; 00523 int wmenu1, wmenu2, wmenu3, layer; 00524 char *strp; 00525 00526 uiLayoutRow(layout, 1); 00527 00528 /* layer menu is 1/3 larger than pass */ 00529 wmenu1= (2*w)/5; 00530 wmenu2= (3*w)/5; 00531 wmenu3= (3*w)/6; 00532 00533 /* menu buts */ 00534 if(render_slot) { 00535 strp= slot_menu(); 00536 but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, UI_UNIT_Y, render_slot, 0,0,0,0, "Select Slot"); 00537 uiButSetFunc(but, image_multi_cb, rr, iuser); 00538 MEM_freeN(strp); 00539 } 00540 00541 if(rr) { 00542 strp= layer_menu(rr, &iuser->layer); 00543 but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, UI_UNIT_Y, &iuser->layer, 0,0,0,0, "Select Layer"); 00544 uiButSetFunc(but, image_multi_cb, rr, iuser); 00545 MEM_freeN(strp); 00546 00547 layer = iuser->layer; 00548 if(rr->rectf || rr->rect32) 00549 layer--; /* fake compo/sequencer layer */ 00550 00551 rl= BLI_findlink(&rr->layers, layer); /* return NULL is meant to be */ 00552 strp= pass_menu(rl, &iuser->pass); 00553 but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, UI_UNIT_Y, &iuser->pass, 0,0,0,0, "Select Pass"); 00554 uiButSetFunc(but, image_multi_cb, rr, iuser); 00555 MEM_freeN(strp); 00556 } 00557 } 00558 00559 static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, short *render_slot) 00560 { 00561 uiBlock *block= uiLayoutGetBlock(layout); 00562 uiLayout *row; 00563 uiBut *but; 00564 const float dpi_fac= UI_DPI_FAC; 00565 00566 row= uiLayoutRow(layout, 1); 00567 00568 if(rr==NULL || iuser==NULL) 00569 return; 00570 if(rr->layers.first==NULL) { 00571 uiItemL(row, "No Layers in Render Result", ICON_NONE); 00572 return; 00573 } 00574 00575 /* decrease, increase arrows */ 00576 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Layer"); 00577 uiButSetFunc(but, image_multi_declay_cb, rr, iuser); 00578 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer"); 00579 uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); 00580 00581 uiblock_layer_pass_buttons(row, rr, iuser, 230 * dpi_fac, render_slot); 00582 00583 /* decrease, increase arrows */ 00584 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); 00585 uiButSetFunc(but, image_multi_decpass_cb, rr, iuser); 00586 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Pass"); 00587 uiButSetFunc(but, image_multi_incpass_cb, rr, iuser); 00588 00589 uiBlockEndAlign(block); 00590 } 00591 00592 // XXX HACK! 00593 // static int packdummy=0; 00594 00595 typedef struct RNAUpdateCb { 00596 PointerRNA ptr; 00597 PropertyRNA *prop; 00598 ImageUser *iuser; 00599 } RNAUpdateCb; 00600 00601 static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) 00602 { 00603 RNAUpdateCb *cb= (RNAUpdateCb*)arg_cb; 00604 00605 /* ideally this would be done by RNA itself, but there we have 00606 no image user available, so we just update this flag here */ 00607 cb->iuser->ok= 1; 00608 00609 /* we call update here on the pointer property, this way the 00610 owner of the image pointer can still define it's own update 00611 and notifier */ 00612 RNA_property_update(C, &cb->ptr, cb->prop); 00613 } 00614 00615 void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact) 00616 { 00617 PropertyRNA *prop; 00618 PointerRNA imaptr; 00619 RNAUpdateCb *cb; 00620 Image *ima; 00621 ImageUser *iuser; 00622 ImBuf *ibuf; 00623 Scene *scene= CTX_data_scene(C); 00624 uiLayout *row, *split, *col; 00625 uiBlock *block; 00626 uiBut *but; 00627 char str[128]; 00628 void *lock; 00629 00630 if(!ptr->data) 00631 return; 00632 00633 prop= RNA_struct_find_property(ptr, propname); 00634 if(!prop) { 00635 printf("%s: property not found: %s.%s\n", 00636 __func__, RNA_struct_identifier(ptr->type), propname); 00637 return; 00638 } 00639 00640 if(RNA_property_type(prop) != PROP_POINTER) { 00641 printf("%s: expected pointer property for %s.%s\n", 00642 __func__, RNA_struct_identifier(ptr->type), propname); 00643 return; 00644 } 00645 00646 block= uiLayoutGetBlock(layout); 00647 00648 imaptr= RNA_property_pointer_get(ptr, prop); 00649 ima= imaptr.data; 00650 iuser= userptr->data; 00651 00652 cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); 00653 cb->ptr= *ptr; 00654 cb->prop= prop; 00655 cb->iuser= iuser; 00656 00657 uiLayoutSetContextPointer(layout, "edit_image", &imaptr); 00658 00659 if(!compact) 00660 uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); 00661 00662 if(ima) { 00663 uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); 00664 00665 if(ima->source == IMA_SRC_VIEWER) { 00666 ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock); 00667 image_info(scene, iuser, ima, ibuf, str); 00668 BKE_image_release_ibuf(ima, lock); 00669 00670 uiItemL(layout, ima->id.name+2, ICON_NONE); 00671 uiItemL(layout, str, ICON_NONE); 00672 00673 if(ima->type==IMA_TYPE_COMPOSITE) { 00674 // XXX not working yet 00675 #if 0 00676 iuser= ntree_get_active_iuser(scene->nodetree); 00677 if(iuser) { 00678 uiBlockBeginAlign(block); 00679 uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, ""); 00680 uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, ""); 00681 but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, ""); 00682 uiButSetFunc(but, image_freecache_cb, ima, NULL); 00683 00684 if(iuser->frames) 00685 BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr); 00686 else strcpy(str, "Frames:"); 00687 uiBlockBeginAlign(block); 00688 uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use"); 00689 uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie"); 00690 } 00691 #endif 00692 } 00693 else if(ima->type==IMA_TYPE_R_RESULT) { 00694 /* browse layer/passes */ 00695 Render *re= RE_GetRender(scene->id.name); 00696 RenderResult *rr= RE_AcquireResultRead(re); 00697 uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot); 00698 RE_ReleaseResult(re); 00699 } 00700 } 00701 else { 00702 uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE); 00703 00704 if(ima->source != IMA_SRC_GENERATED) { 00705 row= uiLayoutRow(layout, 1); 00706 if (ima->packedfile) 00707 uiItemO(row, "", ICON_PACKAGE, "image.unpack"); 00708 else 00709 uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); 00710 00711 row= uiLayoutRow(row, 0); 00712 uiLayoutSetEnabled(row, ima->packedfile==NULL); 00713 uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); 00714 uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); 00715 } 00716 00717 // XXX what was this for? 00718 #if 0 00719 /* check for re-render, only buttons */ 00720 if(imagechanged==B_IMAGECHANGED) { 00721 if(iuser->flag & IMA_ANIM_REFRESHED) { 00722 iuser->flag &= ~IMA_ANIM_REFRESHED; 00723 WM_event_add_notifier(C, NC_IMAGE, ima); 00724 } 00725 } 00726 #endif 00727 00728 /* multilayer? */ 00729 if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { 00730 uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL); 00731 } 00732 else if(ima->source != IMA_SRC_GENERATED) { 00733 if(compact == 0) { 00734 ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock); 00735 image_info(scene, iuser, ima, ibuf, str); 00736 BKE_image_release_ibuf(ima, lock); 00737 uiItemL(layout, str, ICON_NONE); 00738 } 00739 } 00740 00741 if(ima->source != IMA_SRC_GENERATED) { 00742 if(compact == 0) { /* background image view doesnt need these */ 00743 uiItemS(layout); 00744 00745 split= uiLayoutSplit(layout, 0, 0); 00746 00747 col= uiLayoutColumn(split, 0); 00748 uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE); 00749 row= uiLayoutRow(col, 0); 00750 uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); 00751 uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 00752 00753 row= uiLayoutRow(layout, 0); 00754 uiItemR(row, &imaptr, "use_premultiply", 0, NULL, ICON_NONE); 00755 uiItemR(row, &imaptr, "use_color_unpremultiply", 0, NULL, ICON_NONE); 00756 } 00757 } 00758 00759 if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { 00760 uiItemS(layout); 00761 00762 split= uiLayoutSplit(layout, 0, 0); 00763 00764 col= uiLayoutColumn(split, 0); 00765 00766 BLI_snprintf(str, sizeof(str), "(%d) Frames", iuser->framenr); 00767 uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE); 00768 if(ima->anim) { 00769 block= uiLayoutGetBlock(col); 00770 but= uiDefBut(block, BUT, 0, "Match Movie Length", 0, 0, UI_UNIT_X*2, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Set the number of frames to match the movie or sequence"); 00771 uiButSetFunc(but, set_frames_cb, ima, iuser); 00772 } 00773 00774 uiItemR(col, userptr, "frame_start", 0, "Start", ICON_NONE); 00775 uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE); 00776 00777 col= uiLayoutColumn(split, 0); 00778 row= uiLayoutRow(col, 0); 00779 uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); 00780 uiItemR(row, userptr, "fields_per_frame", 0, "Fields", ICON_NONE); 00781 uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE); 00782 uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE); 00783 } 00784 else if(ima->source==IMA_SRC_GENERATED) { 00785 split= uiLayoutSplit(layout, 0, 0); 00786 00787 col= uiLayoutColumn(split, 1); 00788 uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE); 00789 uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE); 00790 uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE); 00791 00792 uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 00793 } 00794 00795 } 00796 00797 uiBlockSetNFunc(block, NULL, NULL, NULL); 00798 } 00799 00800 MEM_freeN(cb); 00801 } 00802 00803 void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr) 00804 { 00805 ImageFormatData *imf= imfptr->data; 00806 ID *id= imfptr->id.data; 00807 const int depth_ok= BKE_imtype_valid_depths(imf->imtype); 00808 /* some settings depend on this being a scene thats rendered */ 00809 const short is_render_out= (id && GS(id->name) == ID_SCE); 00810 00811 uiLayout *col, *row, *split, *sub; 00812 00813 col= uiLayoutColumn(layout, 0); 00814 00815 split= uiLayoutSplit(col, 0.5f, 0); 00816 00817 uiItemR(split, imfptr, "file_format", 0, "", ICON_NONE); 00818 sub= uiLayoutRow(split, 0); 00819 uiItemR(sub, imfptr, "color_mode", UI_ITEM_R_EXPAND, "Color", ICON_NONE); 00820 00821 /* only display depth setting if multiple depths can be used */ 00822 if((ELEM6(depth_ok, 00823 R_IMF_CHAN_DEPTH_1, 00824 R_IMF_CHAN_DEPTH_8, 00825 R_IMF_CHAN_DEPTH_12, 00826 R_IMF_CHAN_DEPTH_16, 00827 R_IMF_CHAN_DEPTH_24, 00828 R_IMF_CHAN_DEPTH_32)) == 0) 00829 { 00830 row= uiLayoutRow(col, 0); 00831 uiItemR(row, imfptr, "color_depth", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 00832 } 00833 00834 if (BKE_imtype_supports_quality(imf->imtype)) { 00835 uiItemR(col, imfptr, "quality", 0, NULL, ICON_NONE); 00836 } 00837 00838 if (BKE_imtype_supports_compress(imf->imtype)) { 00839 uiItemR(col, imfptr, "compression", 0, NULL, ICON_NONE); 00840 } 00841 00842 if (ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) { 00843 uiItemR(col, imfptr, "exr_codec", 0, NULL, ICON_NONE); 00844 } 00845 00846 row= uiLayoutRow(col, 0); 00847 if (BKE_imtype_supports_zbuf(imf->imtype)) { 00848 uiItemR(row, imfptr, "use_zbuffer", 0, NULL, ICON_NONE); 00849 } 00850 00851 if (is_render_out && (imf->imtype == R_IMF_IMTYPE_OPENEXR)) { 00852 uiItemR(row, imfptr, "use_preview", 0, NULL, ICON_NONE); 00853 } 00854 00855 if (imf->imtype == R_IMF_IMTYPE_JP2) { 00856 row= uiLayoutRow(col, 0); 00857 uiItemR(row, imfptr, "use_jpeg2k_cinema_preset", 0, NULL, ICON_NONE); 00858 uiItemR(row, imfptr, "use_jpeg2k_cinema_48", 0, NULL, ICON_NONE); 00859 00860 uiItemR(col, imfptr, "use_jpeg2k_ycc", 0, NULL, ICON_NONE); 00861 } 00862 00863 if (imf->imtype == R_IMF_IMTYPE_CINEON) { 00864 #if 1 00865 uiItemL(col, "Hard coded Non-Linear, Gamma:1.0", ICON_NONE); 00866 #else 00867 uiItemR(col, imfptr, "use_cineon_log", 0, NULL, ICON_NONE); 00868 uiItemR(col, imfptr, "cineon_black", 0, NULL, ICON_NONE); 00869 uiItemR(col, imfptr, "cineon_white", 0, NULL, ICON_NONE); 00870 uiItemR(col, imfptr, "cineon_gamma", 0, NULL, ICON_NONE); 00871 #endif 00872 } 00873 } 00874 00875 void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser) 00876 { 00877 Scene *scene= CTX_data_scene(C); 00878 RenderResult *rr; 00879 00880 /* render layers and passes */ 00881 if(ima && iuser) { 00882 const float dpi_fac= UI_DPI_FAC; 00883 rr= BKE_image_acquire_renderresult(scene, ima); 00884 uiblock_layer_pass_buttons(layout, rr, iuser, 160 * dpi_fac, (ima->type==IMA_TYPE_R_RESULT)? &ima->render_slot: NULL); 00885 BKE_image_release_renderresult(scene, ima); 00886 } 00887 } 00888 00889 void image_buttons_register(ARegionType *art) 00890 { 00891 PanelType *pt; 00892 00893 pt= MEM_callocN(sizeof(PanelType), "spacetype image panel curves"); 00894 strcpy(pt->idname, "IMAGE_PT_curves"); 00895 strcpy(pt->label, "Curves"); 00896 pt->draw= image_panel_curves; 00897 pt->poll= image_panel_poll; 00898 pt->flag |= PNL_DEFAULT_CLOSED; 00899 BLI_addtail(&art->paneltypes, pt); 00900 00901 pt= MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); 00902 strcpy(pt->idname, "IMAGE_PT_gpencil"); 00903 strcpy(pt->label, "Grease Pencil"); 00904 pt->draw= gpencil_panel_standard; 00905 BLI_addtail(&art->paneltypes, pt); 00906 } 00907 00908 static int image_properties(bContext *C, wmOperator *UNUSED(op)) 00909 { 00910 ScrArea *sa= CTX_wm_area(C); 00911 ARegion *ar= image_has_buttons_region(sa); 00912 00913 if(ar) 00914 ED_region_toggle_hidden(C, ar); 00915 00916 return OPERATOR_FINISHED; 00917 } 00918 00919 void IMAGE_OT_properties(wmOperatorType *ot) 00920 { 00921 ot->name= "Properties"; 00922 ot->idname= "IMAGE_OT_properties"; 00923 ot->description= "Toggle display properties panel"; 00924 00925 ot->exec= image_properties; 00926 ot->poll= ED_operator_image_active; 00927 00928 /* flags */ 00929 ot->flag= 0; 00930 } 00931 00932 static int image_scopes(bContext *C, wmOperator *UNUSED(op)) 00933 { 00934 ScrArea *sa= CTX_wm_area(C); 00935 ARegion *ar= image_has_scope_region(sa); 00936 00937 if(ar) 00938 ED_region_toggle_hidden(C, ar); 00939 00940 return OPERATOR_FINISHED; 00941 } 00942 00943 void IMAGE_OT_scopes(wmOperatorType *ot) 00944 { 00945 ot->name= "Scopes"; 00946 ot->idname= "IMAGE_OT_scopes"; 00947 ot->description= "Toggle display scopes panel"; 00948 00949 ot->exec= image_scopes; 00950 ot->poll= ED_operator_image_active; 00951 00952 /* flags */ 00953 ot->flag= 0; 00954 } 00955