Got rid of some dead code
[blender-staging.git] / source / blender / editors / space_image / space_image.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_image_types.h"
33 #include "DNA_mesh_types.h"
34 #include "DNA_meshdata_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_space_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_screen_types.h"
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_math.h"
44 #include "BLI_editVert.h"
45 #include "BLI_rand.h"
46
47 #include "BKE_colortools.h"
48 #include "BKE_context.h"
49 #include "BKE_image.h"
50 #include "BKE_mesh.h"
51 #include "BKE_screen.h"
52 #include "BKE_utildefines.h"
53
54 #include "IMB_imbuf.h"
55 #include "IMB_imbuf_types.h"
56
57 #include "ED_gpencil.h"
58 #include "ED_image.h"
59 #include "ED_mesh.h"
60 #include "ED_space_api.h"
61 #include "ED_screen.h"
62 #include "ED_uvedit.h"
63
64 #include "BIF_gl.h"
65 #include "BIF_glutil.h"
66
67 #include "RNA_access.h"
68
69 #include "WM_api.h"
70 #include "WM_types.h"
71
72 #include "UI_interface.h"
73 #include "UI_resources.h"
74 #include "UI_view2d.h"
75
76 #include "image_intern.h"
77
78 /* ******************** manage regions ********************* */
79
80 ARegion *image_has_buttons_region(ScrArea *sa)
81 {
82         ARegion *ar, *arnew;
83         
84         for(ar= sa->regionbase.first; ar; ar= ar->next)
85                 if(ar->regiontype==RGN_TYPE_UI)
86                         return ar;
87         
88         /* add subdiv level; after header */
89         for(ar= sa->regionbase.first; ar; ar= ar->next)
90                 if(ar->regiontype==RGN_TYPE_HEADER)
91                         break;
92         
93         /* is error! */
94         if(ar==NULL) return NULL;
95         
96         arnew= MEM_callocN(sizeof(ARegion), "buttons for image");
97         
98         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
99         arnew->regiontype= RGN_TYPE_UI;
100         arnew->alignment= RGN_ALIGN_LEFT;
101         
102         arnew->flag = RGN_FLAG_HIDDEN;
103         
104         return arnew;
105 }
106
107 /* ******************** default callbacks for image space ***************** */
108
109 static SpaceLink *image_new(const bContext *C)
110 {
111         ARegion *ar;
112         SpaceImage *simage;
113         
114         simage= MEM_callocN(sizeof(SpaceImage), "initimage");
115         simage->spacetype= SPACE_IMAGE;
116         simage->zoom= 1;
117         simage->lock= 1;
118         
119         simage->iuser.ok= 1;
120         simage->iuser.fie_ima= 2;
121         simage->iuser.frames= 100;
122
123         /* header */
124         ar= MEM_callocN(sizeof(ARegion), "header for image");
125         
126         BLI_addtail(&simage->regionbase, ar);
127         ar->regiontype= RGN_TYPE_HEADER;
128         ar->alignment= RGN_ALIGN_BOTTOM;
129         
130         /* buttons/list view */
131         ar= MEM_callocN(sizeof(ARegion), "buttons for image");
132         
133         BLI_addtail(&simage->regionbase, ar);
134         ar->regiontype= RGN_TYPE_UI;
135         ar->alignment= RGN_ALIGN_LEFT;
136         ar->flag = RGN_FLAG_HIDDEN;
137         
138         /* main area */
139         ar= MEM_callocN(sizeof(ARegion), "main area for image");
140         
141         BLI_addtail(&simage->regionbase, ar);
142         ar->regiontype= RGN_TYPE_WINDOW;
143         
144         return (SpaceLink *)simage;
145 }
146
147 /* not spacelink itself */
148 static void image_free(SpaceLink *sl)
149 {       
150         SpaceImage *simage= (SpaceImage*) sl;
151         
152         if(simage->cumap)
153                 curvemapping_free(simage->cumap);
154 //      if(simage->gpd)
155 // XXX          free_gpencil_data(simage->gpd);
156         
157 }
158
159
160 /* spacetype; init callback */
161 static void image_init(struct wmWindowManager *wm, ScrArea *sa)
162 {
163
164 }
165
166 static SpaceLink *image_duplicate(SpaceLink *sl)
167 {
168         SpaceImage *simagen= MEM_dupallocN(sl);
169         
170         /* clear or remove stuff from old */
171         if(simagen->cumap)
172                 simagen->cumap= curvemapping_copy(simagen->cumap);
173         
174         return (SpaceLink *)simagen;
175 }
176
177 void image_operatortypes(void)
178 {
179         WM_operatortype_append(IMAGE_OT_view_all);
180         WM_operatortype_append(IMAGE_OT_view_pan);
181         WM_operatortype_append(IMAGE_OT_view_selected);
182         WM_operatortype_append(IMAGE_OT_view_zoom);
183         WM_operatortype_append(IMAGE_OT_view_zoom_in);
184         WM_operatortype_append(IMAGE_OT_view_zoom_out);
185         WM_operatortype_append(IMAGE_OT_view_zoom_ratio);
186
187         WM_operatortype_append(IMAGE_OT_new);
188         WM_operatortype_append(IMAGE_OT_open);
189         WM_operatortype_append(IMAGE_OT_replace);
190         WM_operatortype_append(IMAGE_OT_reload);
191         WM_operatortype_append(IMAGE_OT_save);
192         WM_operatortype_append(IMAGE_OT_save_as);
193         WM_operatortype_append(IMAGE_OT_save_sequence);
194         WM_operatortype_append(IMAGE_OT_pack);
195         WM_operatortype_append(IMAGE_OT_unpack);
196
197         WM_operatortype_append(IMAGE_OT_sample);
198         WM_operatortype_append(IMAGE_OT_curves_point_set);
199
200         WM_operatortype_append(IMAGE_OT_record_composite);
201
202         WM_operatortype_append(IMAGE_OT_toolbox);
203         WM_operatortype_append(IMAGE_OT_properties);
204 }
205
206 void image_keymap(struct wmKeyConfig *keyconf)
207 {
208         wmKeyMap *keymap= WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0);
209         
210         WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
211         WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
212         WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
213         WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
214         WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
215         WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
216         
217         keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
218         
219         WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
220         WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
221         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
222
223         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
224         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
225         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
226         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
227         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
228
229         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
230         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
231         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
232         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
233         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
234         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
235         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
236
237         WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0);
238
239         WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
240         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
241         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
242
243         WM_keymap_add_item(keymap, "IMAGE_OT_toolbox", SPACEKEY, KM_PRESS, 0, 0);
244 }
245
246 static void image_refresh(const bContext *C, ScrArea *sa)
247 {
248         SpaceImage *sima= CTX_wm_space_image(C);
249         Object *obedit= CTX_data_edit_object(C);
250         Image *ima;
251
252         ima= ED_space_image(sima);
253
254         /* check if we have to set the image from the editmesh */
255         if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
256         else if(obedit && obedit->type == OB_MESH) {
257                 Mesh *me= (Mesh*)obedit->data;
258                 EditMesh *em= BKE_mesh_get_editmesh(me);
259                 MTFace *tf;
260                 
261                 if(em && EM_texFaceCheck(em)) {
262                         sima->image= ima= NULL;
263                         
264                         tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
265                         
266                         if(tf && (tf->mode & TF_TEX)) {
267                                 /* don't need to check for pin here, see above */
268                                 sima->image= ima= tf->tpage;
269                                 
270                                 if(sima->flag & SI_EDITTILE);
271                                 else sima->curtile= tf->tile;
272                         }
273                 }
274
275                 BKE_mesh_end_editmesh(obedit->data, em);
276         }
277 }
278
279 static void image_listener(ScrArea *sa, wmNotifier *wmn)
280 {
281         /* context changes */
282         switch(wmn->category) {
283                 case NC_SCENE:
284                         switch(wmn->data) {
285                                 case ND_MODE:
286                                 case ND_RENDER_RESULT:
287                                 case ND_COMPO_RESULT:
288                                         ED_area_tag_refresh(sa);
289                                         ED_area_tag_redraw(sa);
290                                         break;
291                         }
292                         break;
293                 case NC_IMAGE:  
294                         ED_area_tag_redraw(sa);
295                         break;
296                 case NC_SPACE:  
297                         if(wmn->data == ND_SPACE_IMAGE)
298                                 ED_area_tag_redraw(sa);
299                         break;
300                 case NC_GEOM:
301                         switch(wmn->data) {
302                                 case ND_DATA:
303                                 case ND_SELECT:
304                                         ED_area_tag_refresh(sa);
305                                         ED_area_tag_redraw(sa);
306                                         break;
307                         }
308         }
309 }
310
311 static int image_context(const bContext *C, const char *member, bContextDataResult *result)
312 {
313         SpaceImage *sima= CTX_wm_space_image(C);
314
315         if(CTX_data_dir(member)) {
316                 static const char *dir[] = {"edit_image", NULL};
317                 CTX_data_dir_set(result, dir);
318         }
319         else if(CTX_data_equals(member, "edit_image")) {
320                 CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
321                 return 1;
322         }
323
324         return 0;
325 }
326
327 /************************** main region ***************************/
328
329 /* sets up the fields of the View2D from zoom and offset */
330 static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar)
331 {
332         Image *ima= ED_space_image(sima);
333         float x1, y1, w, h;
334         int width, height, winx, winy;
335         
336 #if 0
337         if(image_preview_active(curarea, &width, &height));
338         else
339 #endif
340         ED_space_image_size(sima, &width, &height);
341
342         w= width;
343         h= height;
344         
345         if(ima)
346                 h *= ima->aspy/ima->aspx;
347
348         winx= ar->winrct.xmax - ar->winrct.xmin + 1;
349         winy= ar->winrct.ymax - ar->winrct.ymin + 1;
350                 
351         ar->v2d.tot.xmin= 0;
352         ar->v2d.tot.ymin= 0;
353         ar->v2d.tot.xmax= w;
354         ar->v2d.tot.ymax= h;
355         
356         ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0;
357         ar->v2d.mask.xmax= winx;
358         ar->v2d.mask.ymax= winy;
359
360         /* which part of the image space do we see? */
361         x1= ar->winrct.xmin+(winx-sima->zoom*w)/2.0f;
362         y1= ar->winrct.ymin+(winy-sima->zoom*h)/2.0f;
363
364         x1-= sima->zoom*sima->xof;
365         y1-= sima->zoom*sima->yof;
366         
367         /* relative display right */
368         ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sima->zoom);
369         ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sima->zoom);
370         
371         /* relative display left */
372         ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sima->zoom);
373         ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sima->zoom);
374         
375         /* normalize 0.0..1.0 */
376         ar->v2d.cur.xmin /= w;
377         ar->v2d.cur.xmax /= w;
378         ar->v2d.cur.ymin /= h;
379         ar->v2d.cur.ymax /= h;
380 }
381
382 /* add handlers, stuff you only do once or on area/region changes */
383 static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
384 {
385         wmKeyMap *keymap;
386         
387         // image space manages own v2d
388         // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
389
390         /* image paint polls for mode */
391         keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
392         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
393
394         keymap= WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0);
395         WM_event_add_keymap_handler(&ar->handlers, keymap);
396         
397         /* own keymaps */
398         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
399         WM_event_add_keymap_handler(&ar->handlers, keymap);
400         keymap= WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0);
401         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
402 }
403
404 static void image_main_area_draw(const bContext *C, ARegion *ar)
405 {
406         /* draw entirely, view changes should be handled here */
407         SpaceImage *sima= CTX_wm_space_image(C);
408         Object *obedit= CTX_data_edit_object(C);
409         Scene *scene= CTX_data_scene(C);
410         View2D *v2d= &ar->v2d;
411         //View2DScrollers *scrollers;
412         float col[3];
413         
414         /* clear and setup matrix */
415         UI_GetThemeColor3fv(TH_BACK, col);
416         glClearColor(col[0], col[1], col[2], 0.0);
417         glClear(GL_COLOR_BUFFER_BIT);
418
419         /* put scene context variable in iuser */
420         sima->iuser.scene= scene;
421
422         /* we set view2d from own zoom and offset each time */
423         image_main_area_set_view2d(sima, ar);
424         
425         /* we draw image in pixelspace */
426         draw_image_main(sima, ar, scene);
427
428         /* and uvs in 0.0-1.0 space */
429         UI_view2d_view_ortho(C, v2d);
430         draw_uvedit_main(sima, ar, scene, obedit);
431
432         ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
433                 
434         /* Grease Pencil too (in addition to UV's) */
435         draw_image_grease_pencil((bContext *)C, 1); 
436
437         UI_view2d_view_restore(C);
438
439         /* draw Grease Pencil - screen space only */
440         draw_image_grease_pencil((bContext *)C, 0);
441
442         ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_PIXEL);
443         
444         /* scrollers? */
445         /*scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
446         UI_view2d_scrollers_draw(C, v2d, scrollers);
447         UI_view2d_scrollers_free(scrollers);*/
448 }
449
450 static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
451 {
452         /* context changes */
453         switch(wmn->category) {
454                 /* nothing yet */
455         }
456 }
457
458 /* *********************** buttons region ************************ */
459
460 /* add handlers, stuff you only do once or on area/region changes */
461 static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
462 {
463         wmKeyMap *keymap;
464
465         ED_region_panels_init(wm, ar);
466         
467         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
468         WM_event_add_keymap_handler(&ar->handlers, keymap);
469 }
470
471 static void image_buttons_area_draw(const bContext *C, ARegion *ar)
472 {
473         ED_region_panels(C, ar, 1, NULL, -1);
474 }
475
476 static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
477 {
478         /* context changes */
479         switch(wmn->category) {
480                 case NC_BRUSH:
481                         if(wmn->action==NA_EDITED)
482                                 ED_region_tag_redraw(ar);
483                         break;
484         }
485 }
486
487 /************************* header region **************************/
488
489 /* add handlers, stuff you only do once or on area/region changes */
490 static void image_header_area_init(wmWindowManager *wm, ARegion *ar)
491 {
492         ED_region_header_init(ar);
493 }
494
495 static void image_header_area_draw(const bContext *C, ARegion *ar)
496 {
497         ED_region_header(C, ar);
498 }
499
500 /**************************** spacetype *****************************/
501
502 /* only called once, from space/spacetypes.c */
503 void ED_spacetype_image(void)
504 {
505         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype image");
506         ARegionType *art;
507         
508         st->spaceid= SPACE_IMAGE;
509         strncpy(st->name, "Image", BKE_ST_MAXNAME);
510         
511         st->new= image_new;
512         st->free= image_free;
513         st->init= image_init;
514         st->duplicate= image_duplicate;
515         st->operatortypes= image_operatortypes;
516         st->keymap= image_keymap;
517         st->refresh= image_refresh;
518         st->listener= image_listener;
519         st->context= image_context;
520         
521         /* regions: main window */
522         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
523         art->regionid = RGN_TYPE_WINDOW;
524         art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL;
525         art->init= image_main_area_init;
526         art->draw= image_main_area_draw;
527         art->listener= image_main_area_listener;
528
529         BLI_addhead(&st->regiontypes, art);
530         
531         /* regions: listview/buttons */
532         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
533         art->regionid = RGN_TYPE_UI;
534         art->minsizex= 220; // XXX
535         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
536         art->listener= image_buttons_area_listener;
537         art->init= image_buttons_area_init;
538         art->draw= image_buttons_area_draw;
539         BLI_addhead(&st->regiontypes, art);
540
541         image_buttons_register(art);
542
543         /* regions: header */
544         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
545         art->regionid = RGN_TYPE_HEADER;
546         art->minsizey= HEADERY;
547         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
548         art->init= image_header_area_init;
549         art->draw= image_header_area_draw;
550         
551         BLI_addhead(&st->regiontypes, art);
552         
553         BKE_spacetype_register(st);
554 }
555
556 /**************************** common state *****************************/
557
558 /* note; image_panel_properties() uses pointer to sima->image directly */
559 Image *ED_space_image(SpaceImage *sima)
560 {
561         return sima->image;
562 }
563
564 /* called to assign images to UV faces */
565 void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
566 {
567         ED_uvedit_assign_image(scene, obedit, ima, sima->image);
568
569         /* change the space ima after because uvedit_face_visible uses the space ima
570          * to check if the face is displayed in UV-localview */
571         sima->image= ima;
572
573         if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
574                 sima->flag &= ~SI_DRAWTOOL;
575
576         if(sima->image)
577                 BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
578
579         if(sima->image && sima->image->id.us==0)
580                 sima->image->id.us= 1;
581
582         if(C) {
583                 if(obedit)
584                         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
585
586                 ED_area_tag_redraw(CTX_wm_area(C));
587         }
588 }
589
590 ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
591 {
592         ImBuf *ibuf;
593
594         if(sima && sima->image) {
595 #if 0
596                 if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
597                         return BIF_render_spare_imbuf();
598                 else
599 #endif
600                         ibuf= BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
601
602                 if(ibuf && (ibuf->rect || ibuf->rect_float))
603                         return ibuf;
604         }
605
606         return NULL;
607 }
608
609 void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
610 {
611         if(sima && sima->image)
612                 BKE_image_release_ibuf(sima->image, lock);
613 }
614
615 int ED_space_image_has_buffer(SpaceImage *sima)
616 {
617         ImBuf *ibuf;
618         void *lock;
619         int has_buffer;
620
621         ibuf= ED_space_image_acquire_buffer(sima, &lock);
622         has_buffer= (ibuf != NULL);
623         ED_space_image_release_buffer(sima, lock);
624
625         return has_buffer;
626 }
627
628 void ED_image_size(Image *ima, int *width, int *height)
629 {
630         ImBuf *ibuf= NULL;
631         void *lock;
632
633         if(ima)
634                 ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
635
636         if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
637                 *width= ibuf->x;
638                 *height= ibuf->y;
639         }
640         else {
641                 *width= 256;
642                 *height= 256;
643         }
644
645         if(ima)
646                 BKE_image_release_ibuf(ima, lock);
647 }
648
649 void ED_space_image_size(SpaceImage *sima, int *width, int *height)
650 {
651         Scene *scene= sima->iuser.scene;
652         ImBuf *ibuf;
653         void *lock;
654
655         ibuf= ED_space_image_acquire_buffer(sima, &lock);
656
657         if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
658                 *width= ibuf->x;
659                 *height= ibuf->y;
660         }
661         else if(sima->image && sima->image->type==IMA_TYPE_R_RESULT && scene) {
662                 /* not very important, just nice */
663                 *width= (scene->r.xsch*scene->r.size)/100;
664                 *height= (scene->r.ysch*scene->r.size)/100;
665         }
666         /* I know a bit weak... but preview uses not actual image size */
667         // XXX else if(image_preview_active(sima, width, height));
668         else {
669                 *width= 256;
670                 *height= 256;
671         }
672
673         ED_space_image_release_buffer(sima, lock);
674 }
675
676 void ED_image_aspect(Image *ima, float *aspx, float *aspy)
677 {
678         *aspx= *aspy= 1.0;
679
680         if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
681            (ima->aspx==0.0 || ima->aspy==0.0))
682                 return;
683
684         /* x is always 1 */
685         *aspy = ima->aspy/ima->aspx;
686 }
687
688 void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy)
689 {
690         ED_image_aspect(ED_space_image(sima), aspx, aspy);
691 }
692
693 void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
694 {
695         int width, height;
696
697         ED_space_image_size(sima, &width, &height);
698
699         *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
700         *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
701 }
702
703 void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
704 {
705         int w, h;
706
707         ED_space_image_aspect(sima, aspx, aspy);
708         ED_space_image_size(sima, &w, &h);
709
710         *aspx *= (float)w/256.0f;
711         *aspy *= (float)h/256.0f;
712 }
713
714 void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy)
715 {
716         int w, h;
717
718         ED_image_aspect(ima, aspx, aspy);
719         ED_image_size(ima, &w, &h);
720
721         *aspx *= (float)w;
722         *aspy *= (float)h;
723 }
724
725 int ED_space_image_show_render(SpaceImage *sima)
726 {
727         return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
728 }
729
730 int ED_space_image_show_paint(SpaceImage *sima)
731 {
732         if(ED_space_image_show_render(sima))
733                 return 0;
734
735         return (sima->flag & SI_DRAWTOOL);
736 }
737
738 int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
739 {
740         if(ED_space_image_show_render(sima))
741                 return 0;
742         if(ED_space_image_show_paint(sima))
743                 return 0;
744
745         if(obedit && obedit->type == OB_MESH) {
746                 EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
747                 int ret;
748         
749                 ret = EM_texFaceCheck(em);
750
751                 BKE_mesh_end_editmesh(obedit->data, em);
752                 return ret;
753         }
754
755         return 0;
756 }
757
758 int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
759 {
760         if(ED_space_image_show_render(sima))
761                 return 0;
762
763         if(ED_space_image_show_paint(sima))
764                 if(obedit && obedit->type == OB_MESH) {
765                         EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
766                         int ret;
767
768                         ret = EM_texFaceCheck(em);
769
770                         BKE_mesh_end_editmesh(obedit->data, em);
771                         return ret;
772                 }
773
774         return 0;
775 }
776