diff options
author | Ton Roosendaal <ton@blender.org> | 2006-02-09 14:07:04 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-02-09 14:07:04 +0300 |
commit | 3291adc99758e09857b9046ba47ab098293a0190 (patch) | |
tree | 323fa37dcc58c5814e41c6b09a03106ddbfcf665 | |
parent | 6ca0a74b86fcbf2c859b262798fe16a4bc68380f (diff) |
Compositing workflow upgrade;
You now can set a Preview panel in the Image window, to define a sub-rect
of an image to be processed. Works like the preview in 3D Window. Just
press SHIFT+P to get it activated. Very nice speedup!
This is how it works:
- The compositor still uses the scene image size (including % setting) for
Viewer or Composite output size
- If a preview exists, it calculates the cropped rect from its position
in the Image window, and stores that in the Scene render data
- On composite execute, it copies only this part from the 'generator nodes',
right now Images or Render Results. That makes the entire composite tree
only using small rects, so it will execute fast.
- Also the render window will only display the cropped rect, and on F12
only the cropped part is being executed
- On rendering in background mode, the cropping is ignored though.
Usability notes:
- translating or zooming view will automatically invoke a recalculation
- if you zoom in on details, the calculated rect will even become smaller
- only one Imagewindow can have this Preview Panel, to prevent conflicts of
what the cropped area should be. Compositing is on Scene level, not local
per image window. (Note; 3D Previews are local per window!)
- Closing the preview panel will invoke a full-size recalculation
- All passes/layers from rendering are nicely cropped, including Z and
vectors.
The work to make the compositor do cropping was simple, but getting the
Image window displaying correctly and get all events OK was a lot of work...
indeed, we need to refactor Image Window usage once. Sorry for making the
mess even bigger now. :) I've tried not to interfere with UV edit or Paint
though... only when you're in compositing mode the panel will work.
BUG fix:
3D Preview render didn't work when multiple layers were set in the current
scene.
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_composite.c | 256 | ||||
-rw-r--r-- | source/blender/include/BIF_drawimage.h | 1 | ||||
-rw-r--r-- | source/blender/include/BIF_space.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 2 | ||||
-rw-r--r-- | source/blender/src/drawimage.c | 184 | ||||
-rw-r--r-- | source/blender/src/interface_panel.c | 13 | ||||
-rw-r--r-- | source/blender/src/space.c | 35 |
10 files changed, 383 insertions, 118 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 27ddc005a37..19c8af94404 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -227,6 +227,7 @@ extern bNodeType *node_all_composit[]; struct CompBuf; void ntreeCompositTagRender(struct bNodeTree *ntree); void ntreeCompositTagAnimated(struct bNodeTree *ntree); +void ntreeCompositTagGenerators(struct bNodeTree *ntree); void free_compbuf(struct CompBuf *cbuf); /* internal...*/ diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 7150e99e932..f1228831940 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1852,6 +1852,10 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) ntreeBeginExecTree(ntree); + /* prevent unlucky accidents */ + if(G.background) + rd->scemode &= ~R_COMP_CROP; + /* setup callerdata for thread callback */ thdata.rd= rd; thdata.stack= ntree->stack; diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c index 2c78db7c405..ab1e21d9fb9 100644 --- a/source/blender/blenkernel/intern/node_composite.c +++ b/source/blender/blenkernel/intern/node_composite.c @@ -121,6 +121,27 @@ void print_compbuf(char *str, CompBuf *cbuf) } +static CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type) +{ + CompBuf *cbuf; + rcti disprect= *drect; + float *outfp; + int dx, y; + + if(disprect.xmax>rectx) disprect.xmax= rectx; + if(disprect.ymax>recty) disprect.ymax= recty; + if(disprect.xmin>= disprect.xmax) return NULL; + if(disprect.ymin>= disprect.ymax) return NULL; + + cbuf= alloc_compbuf(disprect.xmax-disprect.xmin, disprect.ymax-disprect.ymin, type, 1); + outfp= cbuf->rect; + rectf += type*(disprect.ymin*rectx + disprect.xmin); + dx= type*cbuf->x; + for(y=cbuf->y; y>0; y--, outfp+=dx, rectf+=type*rectx) + memcpy(outfp, rectf, type*dx); + + return cbuf; +} #if 0 @@ -466,60 +487,53 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, /* stack order input sockets: col, alpha, z */ if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ + RenderData *rd= data; Image *ima= (Image *)node->id; CompBuf *cbuf, *inbuf= in[0]->data; int rectx, recty; - - /* scene size? */ - if(1) { - RenderData *rd= data; - /* re-create output, derive size from scene */ - rectx= (rd->size*rd->xsch)/100; - recty= (rd->size*rd->ysch)/100; - - if(ima->ibuf) IMB_freeImBuf(ima->ibuf); - ima->ibuf= IMB_allocImBuf(rectx, recty, 32, IB_rectfloat, 0); // do alloc + /* re-create output, derive size from scene */ +// rectx= (rd->size*rd->xsch)/100; +// recty= (rd->size*rd->ysch)/100; + if(inbuf==NULL) { + rectx= 320; recty= 256; + } + else { + rectx= inbuf->x; + recty= inbuf->y; + } + + if(ima->ibuf) IMB_freeImBuf(ima->ibuf); + ima->ibuf= IMB_allocImBuf(rectx, recty, 32, IB_rectfloat, 0); // do alloc + + cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc + cbuf->rect= ima->ibuf->rect_float; + + /* when no alpha, we can simply copy */ + if(in[1]->data==NULL) { + void (*func)(bNode *, float *, float *); - cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc - cbuf->rect= ima->ibuf->rect_float; - - /* when no alpha, we can simply copy */ - if(in[1]->data==NULL) { - void (*func)(bNode *, float *, float *); - - if(inbuf==NULL || inbuf->type==CB_RGBA) func= do_copy_rgba; - else if(inbuf->type==CB_VEC3) func= do_copy_rgb; - else if(inbuf->type==CB_VEC2) func= do_copy_rg; - else func= do_copy_value; - - composit1_pixel_processor(node, cbuf, inbuf, in[0]->vec, func); - } - else - composit2_pixel_processor(node, cbuf, inbuf, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba); + if(inbuf==NULL || inbuf->type==CB_RGBA) func= do_copy_rgba; + else if(inbuf->type==CB_VEC3) func= do_copy_rgb; + else if(inbuf->type==CB_VEC2) func= do_copy_rg; + else func= do_copy_value; - if(in[2]->data) { - CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 0); - addzbuffloatImBuf(ima->ibuf); - zbuf->rect= ima->ibuf->zbuf_float; - composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value); - free_compbuf(zbuf); - } - - generate_preview(node, cbuf); - free_compbuf(cbuf); + composit1_pixel_processor(node, cbuf, inbuf, in[0]->vec, func); } - else { /* test */ - if(ima->ibuf) IMB_freeImBuf(ima->ibuf); - ima->ibuf= IMB_allocImBuf(rectx, recty, 32, 0, 0); // do alloc - ima->ibuf->mall= IB_rectfloat; - cbuf= in[0]->data; - ima->ibuf->rect_float= cbuf->rect; - ima->ibuf->x= cbuf->x; - ima->ibuf->y= cbuf->y; - cbuf->rect= NULL; + else + composit2_pixel_processor(node, cbuf, inbuf, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba); + + if(in[2]->data) { + CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 0); + addzbuffloatImBuf(ima->ibuf); + zbuf->rect= ima->ibuf->zbuf_float; + composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value); + free_compbuf(zbuf); } + generate_preview(node, cbuf); + free_compbuf(cbuf); + } /* lets make only previews when not done yet, so activating doesnt update */ else if(in[0]->data && node->preview && node->preview->rect==NULL) { CompBuf *cbuf, *inbuf= in[0]->data; @@ -715,54 +729,80 @@ static void animated_image(bNode *node, int cfra) } } - -static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +static CompBuf *node_composit_get_image(bNode *node, RenderData *rd) { - RenderData *rd= data; + Image *ima; + CompBuf *stackbuf; - /* image assigned to output */ - /* stack order input sockets: col, alpha */ - if(node->id) { - Image *ima; - CompBuf *stackbuf; - - /* animated image? */ - if(node->storage) - animated_image(node, rd->cfra); - - ima= (Image *)node->id; - - /* test if image is OK */ - if(ima->ok==0) return; + /* animated image? */ + if(node->storage) + animated_image(node, rd->cfra); + + ima= (Image *)node->id; + + /* test if image is OK */ + if(ima->ok==0) return NULL; + + if(ima->ibuf==NULL) { + load_image(ima, IB_rect, G.sce, rd->cfra); /* G.sce is current .blend path */ if(ima->ibuf==NULL) { - - load_image(ima, IB_rect, G.sce, rd->cfra); /* G.sce is current .blend path */ - if(ima->ibuf==NULL) { - ima->ok= 0; - return; - } + ima->ok= 0; + return NULL; } - if(ima->ibuf->rect_float==NULL) - IMB_float_from_rect(ima->ibuf); - + } + if(ima->ibuf->rect_float==NULL) + IMB_float_from_rect(ima->ibuf); + + if(rd->scemode & R_COMP_CROP) { + stackbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->rect_float, ima->ibuf->x, ima->ibuf->y, CB_RGBA); + } + else { /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ stackbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_RGBA, 0); stackbuf->rect= ima->ibuf->rect_float; + } + + return stackbuf; +} + +static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) +{ + Image *ima= (Image *)node->id; + CompBuf *zbuf= NULL; + + if(ima->ibuf && ima->ibuf->zbuf_float) { + if(rd->scemode & R_COMP_CROP) { + zbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->zbuf_float, ima->ibuf->x, ima->ibuf->y, CB_VAL); + } + else { + zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0); + zbuf->rect= ima->ibuf->zbuf_float; + } + } + return zbuf; +} + +static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + + /* image assigned to output */ + /* stack order input sockets: col, alpha */ + if(node->id) { + CompBuf *stackbuf= node_composit_get_image(node, data); /* put ibuf on stack */ out[0]->data= stackbuf; - if(out[1]->hasoutput) - out[1]->data= alphabuf_from_rgbabuf(stackbuf); - - if(out[2]->hasoutput && ima->ibuf->zbuf_float) { - CompBuf *zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0); - zbuf->rect= ima->ibuf->zbuf_float; - out[2]->data= zbuf; + if(stackbuf) { + if(out[1]->hasoutput) + out[1]->data= alphabuf_from_rgbabuf(stackbuf); + + if(out[2]->hasoutput) + out[2]->data= node_composit_get_zimage(node, data); + + generate_preview(node, stackbuf); } - - generate_preview(node, stackbuf); } } @@ -810,7 +850,8 @@ static bNodeSocketType cmp_node_rresult_out[]= { { -1, 0, "" } }; -static CompBuf *compbuf_from_pass(RenderLayer *rl, int rectx, int recty, int passcode) + +static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode) { float *fp= RE_RenderLayerGetPass(rl, passcode); if(fp) { @@ -823,9 +864,13 @@ static CompBuf *compbuf_from_pass(RenderLayer *rl, int rectx, int recty, int pas buftype= CB_VEC4; else if(passcode==SCE_PASS_RGBA) buftype= CB_RGBA; - - buf= alloc_compbuf(rectx, recty, buftype, 0); - buf->rect= fp; + + if(rd->scemode & R_COMP_CROP) + buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype); + else { + buf= alloc_compbuf(rectx, recty, buftype, 0); + buf->rect= fp; + } return buf; } return NULL; @@ -833,6 +878,7 @@ static CompBuf *compbuf_from_pass(RenderLayer *rl, int rectx, int recty, int pas static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { + RenderData *rd= data; RenderResult *rr; if(node->id && node->id!=&G.scene->id) @@ -846,8 +892,12 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, CompBuf *stackbuf; /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */ - stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); - stackbuf->rect= rl->rectf; + if(rd->scemode & R_COMP_CROP) + stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA); + else { + stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); + stackbuf->rect= rl->rectf; + } /* put on stack */ out[RRES_OUT_IMAGE]->data= stackbuf; @@ -855,24 +905,24 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, if(out[RRES_OUT_ALPHA]->hasoutput) out[RRES_OUT_ALPHA]->data= alphabuf_from_rgbabuf(stackbuf); if(out[RRES_OUT_Z]->hasoutput) - out[RRES_OUT_Z]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_Z); + out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_Z); if(out[RRES_OUT_VEC]->hasoutput) - out[RRES_OUT_VEC]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_VECTOR); + out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_VECTOR); if(out[RRES_OUT_NOR]->hasoutput) - out[RRES_OUT_NOR]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_NORMAL); + out[RRES_OUT_NOR]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_NORMAL); /* if(out[RRES_OUT_COL]->hasoutput) - out[RRES_OUT_COL]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_RGBA); + out[RRES_OUT_COL]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RGBA); if(out[RRES_OUT_DIFF]->hasoutput) - out[RRES_OUT_DIFF]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE); + out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE); if(out[RRES_OUT_SPEC]->hasoutput) - out[RRES_OUT_SPEC]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_SPEC); + out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SPEC); if(out[RRES_OUT_SHAD]->hasoutput) - out[RRES_OUT_SHAD]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_SHADOW); + out[RRES_OUT_SHAD]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SHADOW); if(out[RRES_OUT_AO]->hasoutput) - out[RRES_OUT_AO]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_AO); + out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_AO); if(out[RRES_OUT_RAY]->hasoutput) - out[RRES_OUT_RAY]->data= compbuf_from_pass(rl, rr->rectx, rr->recty, SCE_PASS_RAY); + out[RRES_OUT_RAY]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RAY); */ generate_preview(node, stackbuf); } @@ -2255,3 +2305,19 @@ void ntreeCompositTagAnimated(bNodeTree *ntree) NodeTagChanged(ntree, node); } } + + +/* called from image window preview */ +void ntreeCompositTagGenerators(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if( ELEM(node->type, CMP_NODE_R_RESULT, CMP_NODE_IMAGE)) + NodeTagChanged(ntree, node); + } +} + + diff --git a/source/blender/include/BIF_drawimage.h b/source/blender/include/BIF_drawimage.h index f1ab908cdbf..0435522025b 100644 --- a/source/blender/include/BIF_drawimage.h +++ b/source/blender/include/BIF_drawimage.h @@ -48,6 +48,7 @@ void image_viewcentre(void); void uvco_to_areaco(float *vec, short *mval); void uvco_to_areaco_noclip(float *vec, int *mval); void what_image(struct SpaceImage *sima); +void image_preview_event(int event); #endif diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h index 3585e46c0aa..d5dc65a2b3c 100644 --- a/source/blender/include/BIF_space.h +++ b/source/blender/include/BIF_space.h @@ -62,6 +62,7 @@ struct SpaceOops; #define IMAGE_HANDLER_PROPERTIES 30 #define IMAGE_HANDLER_PAINT 31 #define IMAGE_HANDLER_CURVES 32 +#define IMAGE_HANDLER_PREVIEW 33 /* action handler codes */ #define ACTION_HANDLER_PROPERTIES 40 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 0cef85afc4e..e2c9484bec1 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -254,8 +254,9 @@ typedef struct RenderData { * identical materials with this number.*/ short same_mat_redux; - /* safety and border rect */ + /* safety, border and display rect */ rctf safety, border; + rcti disprect; /* information on different layers to be rendered */ ListBase layers; @@ -442,6 +443,7 @@ typedef struct Scene { #define R_EXTENSION 0x0010 #define R_NODE_PREVIEW 0x0020 #define R_DOCOMP 0x0040 +#define R_COMP_CROP 0x0080 /* alphamode */ #define R_ADDSKY 0 diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 76b2a5acc34..a632b824a51 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -278,6 +278,8 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop) rl->lay= (1<<20) -1; rl->layflag= 0x7FFF; /* solid ztra halo strand */ rl->passflag= SCE_PASS_COMBINED; + + re->r.actlay= 0; } /* display active layer */ diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 154d12e38f1..8840a9672bf 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -67,6 +67,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_node.h" #include "BKE_image.h" #include "BKE_DerivedMesh.h" #include "BKE_displist.h" @@ -89,6 +90,7 @@ #include "BIF_screen.h" #include "BIF_transform.h" +#include "BSE_drawipo.h" #include "BSE_headerbuttons.h" #include "BSE_trans_types.h" #include "BSE_view.h" @@ -98,6 +100,8 @@ #include "blendef.h" #include "butspace.h" // event codes +#include "interface.h" /* bad.... but preview code needs UI info. Will solve... (ton) */ + static unsigned char *alloc_alpha_clone_image(int *width, int *height) { unsigned int size, alpha; @@ -144,6 +148,22 @@ static void setcloneimage() } } +static int image_preview_active(ScrArea *sa, float *xim, float *yim) +{ + SpaceImage *sima= sa->spacedata.first; + short a; + + for(a=0; a<SPACE_MAXHANDLER; a+=2) { + if(sima->blockhandler[a] == IMAGE_HANDLER_PREVIEW) { + if(xim) *xim= (G.scene->r.size*G.scene->r.xsch)/100; + if(yim) *yim= (G.scene->r.size*G.scene->r.ysch)/100; + return 1; + } + } + return 0; +} + + /** * Sets up the fields of the View2D member of the SpaceImage struct * This routine can be called in two modes: @@ -161,11 +181,12 @@ void calc_image_view(SpaceImage *sima, char mode) float x1, y1; float zoom; - if(sima->image && sima->image->ibuf) { + if(image_preview_active(curarea, &xim, &yim)); + else if(sima->image && sima->image->ibuf) { xim= sima->image->ibuf->x; yim= sima->image->ibuf->y; } - + sima->v2d.tot.xmin= 0; sima->v2d.tot.ymin= 0; sima->v2d.tot.xmax= xim; @@ -996,6 +1017,117 @@ static int image_curves_active(ScrArea *sa) return 0; } +void image_preview_event(int event) +{ + int exec= 0; + + + if(event==0) { + G.scene->r.scemode &= ~R_COMP_CROP; + exec= 1; + } + else if(event==2 || (G.scene->r.scemode & R_COMP_CROP)==0) { + if(image_preview_active(curarea, NULL, NULL)) { + G.scene->r.scemode |= R_COMP_CROP; + exec= 1; + } + } + + if(exec) { + ScrArea *sa; + + ntreeCompositTagGenerators(G.scene->nodetree); + + for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { + if(sa->spacetype==SPACE_NODE) { + addqueue(sa->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); + break; + } + } + } +} + + +/* nothing drawn here, we use it to store values */ +static void preview_cb(struct ScrArea *sa, struct uiBlock *block) +{ + rctf dispf; + rcti *disprect= &G.scene->r.disprect; + int winx= (G.scene->r.size*G.scene->r.xsch)/100; + int winy= (G.scene->r.size*G.scene->r.ysch)/100; + short mval[2]; + + /* while dragging we don't update the rects */ + if(block->panel->flag & PNL_SELECT) + return; + if(get_mbut() & M_MOUSE) + return; + + BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); + ui_graphics_to_window_rct(sa->win, &dispf, disprect); + + /* correction for gla draw */ + BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); + + calc_image_view(G.sima, 'p'); +// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); + /* map to image space coordinates */ + mval[0]= disprect->xmin; mval[1]= disprect->ymin; + areamouseco_to_ipoco(G.v2d, mval, &dispf.xmin, &dispf.ymin); + mval[0]= disprect->xmax; mval[1]= disprect->ymax; + areamouseco_to_ipoco(G.v2d, mval, &dispf.xmax, &dispf.ymax); + + /* map to render coordinates */ + disprect->xmin= dispf.xmin; + disprect->xmax= dispf.xmax; + disprect->ymin= dispf.ymin; + disprect->ymax= dispf.ymax; + + CLAMP(disprect->xmin, 0, winx); + CLAMP(disprect->xmax, 0, winx); + CLAMP(disprect->ymin, 0, winy); + CLAMP(disprect->ymax, 0, winy); +// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); + + image_preview_event(1); +} + +static int is_preview_allowed(ScrArea *cur) +{ + ScrArea *sa; + + for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { + if(sa!=cur && sa->spacetype==SPACE_IMAGE) { + if(image_preview_active(sa, NULL, NULL)) + return 0; + } + } + return 1; +} + +static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVIEW +{ + uiBlock *block; + SpaceImage *sima= sa->spacedata.first; + int ofsx, ofsy; + + if(is_preview_allowed(sa)==0) { + rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW); + return; + } + + block= uiNewBlock(&sa->uiblocks, "image_panel_preview", UI_EMBOSS, UI_HELV, sa->win); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); + uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc + + ofsx= -150+(sa->winx/2)/sima->blockscale; + ofsy= -100+(sa->winy/2)/sima->blockscale; + if(uiNewPanel(sa, block, "Preview", "Image", ofsx, ofsy, 300, 200)==0) return; + + uiBlockSetDrawExtraFunc(block, preview_cb); + +} + static void image_blockhandlers(ScrArea *sa) { SpaceImage *sima= sa->spacedata.first; @@ -1016,6 +1148,9 @@ static void image_blockhandlers(ScrArea *sa) case IMAGE_HANDLER_CURVES: image_panel_curves(sima->blockhandler[a+1]); break; + case IMAGE_HANDLER_PREVIEW: + image_panel_preview(sa, sima->blockhandler[a+1]); + break; } /* clear action value for event */ sima->blockhandler[a+1]= 0; @@ -1248,9 +1383,24 @@ void drawimagespace(ScrArea *sa, void *spacedata) draw_tfaces(); } else { + float xim, yim, xoffs=0.0f, yoffs= 0.0f; + + if(image_preview_active(curarea, &xim, &yim)) { + xoffs= G.scene->r.disprect.xmin; + yoffs= G.scene->r.disprect.ymin; + glColor3ub(0,0,0); + calc_image_view(sima, 'f'); + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); + glRectf(0.0f, 0.0f, 1.0f, 1.0f); + glLoadIdentity(); + } + else { + xim= ibuf->x; yim= ibuf->y; + } + /* calc location */ - x1= (curarea->winx-sima->zoom*ibuf->x)/2; - y1= (curarea->winy-sima->zoom*ibuf->y)/2; + x1= sima->zoom*xoffs + (curarea->winx-sima->zoom*xim)/2; + y1= sima->zoom*yoffs + (curarea->winy-sima->zoom*yim)/2; x1-= sima->zoom*sima->xof; y1-= sima->zoom*sima->yof; @@ -1432,8 +1582,16 @@ static void image_zoom_set_factor(float zoomfac) height= 256; if (sima->image) { if (sima->image->ibuf) { - width= sima->image->ibuf->x; - height= sima->image->ibuf->y; + float xim, yim; + /* I know a bit weak... but preview uses not actual image size */ + if(image_preview_active(curarea, &xim, &yim)) { + width= (int) xim; + height= (int) yim; + } + else { + width= sima->image->ibuf->x; + height= sima->image->ibuf->y; + } } } width *= sima->zoom; @@ -1479,6 +1637,12 @@ void image_viewmove(int mode) } else BIF_wait_for_statechange(); } + + if(image_preview_active(curarea, NULL, NULL)) { + /* recalculates new preview rect */ + scrarea_do_windraw(curarea); + image_preview_event(2); + } } void image_viewzoom(unsigned short event, int invert) @@ -1497,8 +1661,12 @@ void image_viewzoom(unsigned short event, int invert) sima->zoom= (invert)? 4.0: 0.25; else if(event==PAD8) sima->zoom= (invert)? 8.0: 0.125; - else - return; + + if(image_preview_active(curarea, NULL, NULL)) { + /* recalculates new preview rect */ + scrarea_do_windraw(curarea); + image_preview_event(2); + } } /** diff --git a/source/blender/src/interface_panel.c b/source/blender/src/interface_panel.c index d1ba75a5036..805b555f5a4 100644 --- a/source/blender/src/interface_panel.c +++ b/source/blender/src/interface_panel.c @@ -72,6 +72,7 @@ #include "BIF_keyval.h" #include "BIF_mainqueue.h" +#include "BIF_drawimage.h" #include "BIF_previewrender.h" #include "BIF_screen.h" #include "BIF_toolbox.h" @@ -1042,12 +1043,15 @@ void ui_draw_panel(uiBlock *block) uiSetRoundBox(3); uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8); - // blend now for panels in 3d window, test... glEnable(GL_BLEND); BIF_ThemeColor4(TH_PANEL); - + uiSetRoundBox(12); - uiRoundBox(block->minx, block->miny, block->maxx, block->maxy, 8); + /* bad code... but its late :) */ + if(strcmp(block->name, "image_panel_preview")==0) + uiRoundRect(block->minx, block->miny, block->maxx, block->maxy, 8); + else + uiRoundBox(block->minx, block->miny, block->maxx, block->maxy, 8); // glRectf(block->minx, block->miny, block->maxx, block->maxy); @@ -1623,7 +1627,8 @@ static void ui_drag_panel(uiBlock *block, int doscale) /* exception handling, 3d window preview panel */ if(block->drawextra==BIF_view3d_previewdraw) BIF_view3d_previewrender_signal(curarea, PR_DISPRECT); - + else if(strcmp(block->name, "image_panel_preview")==0) + image_preview_event(2); } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 5319969e9ab..dae28297f5b 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -202,6 +202,10 @@ void rem_blockhandler(ScrArea *sa, short eventcode) for(a=0; a<SPACE_MAXHANDLER; a+=2) { if( sl->blockhandler[a]==eventcode) { sl->blockhandler[a]= 0; + + /* specific free calls */ + if(eventcode==IMAGE_HANDLER_PREVIEW) + image_preview_event(0); break; } } @@ -220,6 +224,8 @@ void toggle_blockhandler(ScrArea *sa, short eventcode, short val) /* specific free calls */ if(eventcode==VIEW3D_HANDLER_PREVIEW) BIF_view3d_previewrender_free(sa->spacedata.first); + else if(eventcode==IMAGE_HANDLER_PREVIEW) + image_preview_event(0); addnew= 0; } @@ -1608,8 +1614,6 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) else if(G.qual==LR_ALTKEY) clear_parent(); else if((G.qual==0)) { - //toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0); - //doredraw= 1; start_game(); } break; @@ -3918,7 +3922,10 @@ void free_soundspace(SpaceSound *ssound) /* ******************** SPACE: IMAGE ********************** */ -/* extern void drawimagespace(ScrArea *sa, void *spacedata); BIF_drawimage.h */ +static void changeimagepace(ScrArea *sa, void *spacedata) +{ + image_preview_event(2); +} static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) { @@ -4038,12 +4045,20 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) } break; case PKEY: - if(G.qual==LR_SHIFTKEY) - select_pinned_tface_uv(); - else if(G.qual==LR_ALTKEY) - pin_tface_uv(0); - else - pin_tface_uv(1); + if(G.f & G_FACESELECT) { + if(G.qual==LR_SHIFTKEY) + select_pinned_tface_uv(); + else if(G.qual==LR_ALTKEY) + pin_tface_uv(0); + else + pin_tface_uv(1); + } + else { + if(G.qual==LR_SHIFTKEY) { + toggle_blockhandler(curarea, IMAGE_HANDLER_PREVIEW, 0); + scrarea_queue_winredraw(curarea); + } + } break; case RKEY: if((G.qual==0) && is_uv_tface_editing_allowed()) { @@ -5223,7 +5238,7 @@ SpaceType *spaceimage_get_type(void) if (!st) { st= spacetype_new("Image"); - spacetype_set_winfuncs(st, drawimagespace, NULL, winqreadimagespace); + spacetype_set_winfuncs(st, drawimagespace, changeimagepace, winqreadimagespace); } return st; |