Blender V4.3
render_view.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstddef>
10#include <cstring>
11
12#include "BLI_listbase.h"
13#include "BLI_utildefines.h"
14
15#include "DNA_scene_types.h"
16#include "DNA_userdef_types.h"
17
18#include "BKE_context.hh"
19#include "BKE_global.hh"
20#include "BKE_image.hh"
21#include "BKE_report.hh"
22#include "BKE_scene.hh"
23#include "BKE_screen.hh"
24
25#include "BLT_translation.hh"
26
27#include "WM_api.hh"
28#include "WM_types.hh"
29
30#include "ED_screen.hh"
31
32#include "wm_window.hh"
33
34#include "render_intern.hh"
35
36/* -------------------------------------------------------------------- */
46{
47 bScreen *screen = CTX_wm_screen(C);
48 ScrArea *big = nullptr;
49 int size, maxsize = 0, bwmaxsize = 0;
50 short foundwin = 0;
51
52 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
53 if (area->winx > 30 && area->winy > 30) {
54 size = area->winx * area->winy;
55 if (!area->full && area->spacetype == SPACE_PROPERTIES) {
56 if (foundwin == 0 && size > bwmaxsize) {
57 bwmaxsize = size;
58 big = area;
59 }
60 }
61 else if (area->spacetype != SPACE_IMAGE && size > maxsize) {
62 maxsize = size;
63 big = area;
64 foundwin = 1;
65 }
66 }
67 }
68
69 return big;
70}
71
73{
75 ScrArea *area_render = nullptr;
76 wmWindow *win_render = nullptr;
77
78 /* find an image-window showing render result */
79 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
80 if (WM_window_get_active_scene(win) != scene) {
81 continue;
82 }
83
84 const bScreen *screen = WM_window_get_active_screen(win);
85 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
86 if (area->spacetype == SPACE_IMAGE) {
87 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
88 if (sima->image && sima->image->type == IMA_TYPE_R_RESULT) {
89 area_render = area;
90 win_render = win;
91 break;
92 }
93 }
94 }
95 if (area_render) {
96 break;
97 }
98 }
99
100 *r_win = win_render;
101 return area_render;
102}
103
105{
106 bScreen *screen = CTX_wm_screen(C);
107 ScrArea *area;
108 SpaceImage *sima;
109
110 /* find an image-window showing render result */
111 for (area = static_cast<ScrArea *>(screen->areabase.first); area; area = area->next) {
112 if (area->spacetype == SPACE_IMAGE) {
113 sima = static_cast<SpaceImage *>(area->spacedata.first);
114 if ((sima->mode == SI_MODE_VIEW) && !sima->image) {
115 break;
116 }
117 }
118 }
119
120 return area;
121}
122
125/* -------------------------------------------------------------------- */
129ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
130{
131 Main *bmain = CTX_data_main(C);
132 Scene *scene = CTX_data_scene(C);
133 ScrArea *area = nullptr;
134 SpaceImage *sima;
135 bool area_was_image = false;
136
137 if (U.render_display_type == USER_RENDER_DISPLAY_NONE) {
138 return nullptr;
139 }
140
141 if (U.render_display_type == USER_RENDER_DISPLAY_WINDOW) {
142 int sizex, sizey;
143 BKE_render_resolution(&scene->r, false, &sizex, &sizey);
144
145 sizex += 30 * UI_SCALE_FAC;
146 sizey += 60 * UI_SCALE_FAC;
147
148 /* arbitrary... miniature image window views don't make much sense */
149 if (sizex < 320) {
150 sizex = 320;
151 }
152 if (sizey < 256) {
153 sizey = 256;
154 }
155
156 const rcti window_rect = {
157 /*xmin*/ mx,
158 /*xmax*/ mx + sizex,
159 /*ymin*/ my,
160 /*ymax*/ my + sizey,
161 };
162
163 /* changes context! */
164 if (WM_window_open(C,
165 IFACE_("Blender Render"),
166 &window_rect,
168 true,
169 false,
170 true,
172 nullptr,
173 nullptr) == nullptr)
174 {
175 BKE_report(reports, RPT_ERROR, "Failed to open window!");
176 return nullptr;
177 }
178
179 area = CTX_wm_area(C);
180 if (BLI_listbase_is_single(&area->spacedata) == false) {
181 sima = static_cast<SpaceImage *>(area->spacedata.first);
182 sima->flag |= SI_PREVSPACE;
183 }
184 }
185 else if (U.render_display_type == USER_RENDER_DISPLAY_SCREEN) {
186 area = CTX_wm_area(C);
187
188 /* If the active screen is already in full-screen mode, skip this and
189 * unset the area, so that the full-screen area is just changed later. */
190 if (area && area->full) {
191 area = nullptr;
192 }
193 else {
194 if (area && area->spacetype == SPACE_IMAGE) {
195 area_was_image = true;
196 }
197
198 /* this function returns with changed context */
199 area = ED_screen_full_newspace(C, area, SPACE_IMAGE);
200 }
201 }
202
203 if (!area) {
204 wmWindow *win_show = nullptr;
205 area = find_area_showing_render_result(C, scene, &win_show);
206 if (area == nullptr) {
207 /* No need to set `win_show` as the area selected will be from the active window. */
208 area = find_area_image_empty(C);
209 }
210
211 /* if area found in other window, we make that one show in front */
212 if (win_show && win_show != CTX_wm_window(C)) {
213 wm_window_raise(win_show);
214 }
215
216 if (area == nullptr) {
217 /* find largest open non-image area */
218 area = biggest_non_image_area(C);
219 if (area) {
220 ED_area_newspace(C, area, SPACE_IMAGE, true);
221 sima = static_cast<SpaceImage *>(area->spacedata.first);
222
223 /* Makes "Escape" go back to previous space. */
224 sima->flag |= SI_PREVSPACE;
225
226 /* We already had a full-screen here -> mark new space as a stacked full-screen. */
227 if (area->full) {
228 area->flag |= AREA_FLAG_STACKED_FULLSCREEN;
229 }
230 }
231 else {
232 /* use any area of decent size */
234 if (area->spacetype != SPACE_IMAGE) {
235 // XXX newspace(area, SPACE_IMAGE);
236 sima = static_cast<SpaceImage *>(area->spacedata.first);
237
238 /* Makes "Escape" go back to previous space. */
239 sima->flag |= SI_PREVSPACE;
240 }
241 }
242 }
243 }
244 sima = static_cast<SpaceImage *>(area->spacedata.first);
246
247 /* get the correct image, and scale it */
248 sima->image = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
249
250 /* If we're rendering to full screen, set appropriate hints on image editor
251 * so it can restore properly on pressing escape. */
252 if (area->full) {
253 sima->flag |= SI_FULLWINDOW;
254
255 /* Tell the image editor to revert to previous space in space list on close
256 * _only_ if it wasn't already an image editor when the render was invoked */
257 if (area_was_image == 0) {
258 sima->flag |= SI_PREVSPACE;
259 }
260 else {
261 /* Leave it alone so the image editor will just go back from
262 * full screen to the original tiled setup */
263 }
264 }
265
266 if ((sima->flag & SI_PREVSPACE) && sima->next) {
267 SpaceLink *old_sl = sima->next;
269 }
270
271 return area;
272}
273
276/* -------------------------------------------------------------------- */
281{
282 wmWindow *win = CTX_wm_window(C);
283 ScrArea *area = CTX_wm_area(C);
284 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
285
286 /* ensure image editor full-screen and area full-screen states are in sync */
287 if ((sima->flag & SI_FULLWINDOW) && !area->full) {
288 sima->flag &= ~SI_FULLWINDOW;
289 }
290
291 /* determine if render already shows */
292 if (sima->flag & SI_PREVSPACE) {
293 sima->flag &= ~SI_PREVSPACE;
294
295 if (sima->flag & SI_FULLWINDOW) {
296 sima->flag &= ~SI_FULLWINDOW;
298 }
299 else {
300 ED_area_prevspace(C, area);
301 }
302
303 return OPERATOR_FINISHED;
304 }
305 if (sima->flag & SI_FULLWINDOW) {
306 sima->flag &= ~SI_FULLWINDOW;
308 return OPERATOR_FINISHED;
309 }
310 if (WM_window_is_temp_screen(win)) {
312 return OPERATOR_FINISHED;
313 }
314
316}
317
319{
320 /* identifiers */
321 ot->name = "Cancel Render View";
322 ot->description = "Cancel show render view";
323 ot->idname = "RENDER_OT_view_cancel";
324
325 /* api callbacks */
328}
329
332/* -------------------------------------------------------------------- */
336static int render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
337{
338 wmWindow *wincur = CTX_wm_window(C);
339
340 /* test if we have currently a temp screen active */
341 if (WM_window_is_temp_screen(wincur)) {
342 wm_window_lower(wincur);
343 }
344 else {
345 wmWindow *win_show = nullptr;
347
348 /* is there another window on current scene showing result? */
349 LISTBASE_FOREACH (wmWindow *, win, &CTX_wm_manager(C)->windows) {
350 const bScreen *screen = WM_window_get_active_screen(win);
351
352 if ((WM_window_is_temp_screen(win) &&
353 ((ScrArea *)screen->areabase.first)->spacetype == SPACE_IMAGE) ||
354 (win == win_show && win_show != wincur))
355 {
356 wm_window_raise(win);
357 return OPERATOR_FINISHED;
358 }
359 }
360
361 /* determine if render already shows */
362 if (area) {
363 /* but don't close it when rendering */
364 if (G.is_rendering == false) {
365 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
366
367 if (sima->flag & SI_PREVSPACE) {
368 sima->flag &= ~SI_PREVSPACE;
369
370 if (sima->flag & SI_FULLWINDOW) {
371 sima->flag &= ~SI_FULLWINDOW;
373 }
374 else {
375 ED_area_prevspace(C, area);
376 }
377 }
378 }
379 }
380 else {
381 render_view_open(C, event->xy[0], event->xy[1], op->reports);
382 }
383 }
384
385 return OPERATOR_FINISHED;
386}
387
389{
390 /* identifiers */
391 ot->name = "Show/Hide Render View";
392 ot->description = "Toggle show render view";
393 ot->idname = "RENDER_OT_view_show";
394
395 /* api callbacks */
398}
399
bScreen * CTX_wm_screen(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
Image * BKE_image_ensure_viewer(Main *bmain, int type, const char *name)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2877
ScrArea * BKE_screen_find_big_area(const bScreen *screen, int spacetype, short min)
Definition screen.cc:903
#define LISTBASE_FOREACH(type, var, list)
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
#define IFACE_(msgid)
@ IMA_TYPE_R_RESULT
@ SCREENMAXIMIZED
@ AREA_FLAG_STACKED_FULLSCREEN
@ SI_FULLWINDOW
@ SI_PREVSPACE
@ SPACE_PROPERTIES
@ SPACE_IMAGE
@ SPACE_FLAG_TYPE_WAS_ACTIVE
@ SPACE_FLAG_TYPE_TEMPORARY
@ SI_MODE_VIEW
#define SPACE_TYPE_ANY
@ USER_RENDER_DISPLAY_NONE
@ USER_RENDER_DISPLAY_SCREEN
@ USER_RENDER_DISPLAY_WINDOW
#define UI_SCALE_FAC
@ OPERATOR_PASS_THROUGH
void ED_area_newspace(bContext *C, ScrArea *area, int type, bool skip_region_exit)
Definition area.cc:2592
bool ED_operator_screenactive(bContext *C)
ScrArea * ED_screen_full_newspace(bContext *C, ScrArea *area, int type)
bool ED_operator_image_active(bContext *C)
ScrArea * ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, short state)
void ED_area_prevspace(bContext *C, ScrArea *area)
Definition area.cc:2742
void ED_screen_full_prevspace(bContext *C, ScrArea *area)
@ WIN_ALIGN_LOCATION_CENTER
Definition WM_api.hh:340
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
unsigned int U
Definition btGjkEpa3.h:78
#define G(x, y, z)
static int render_view_cancel_exec(bContext *C, wmOperator *)
void RENDER_OT_view_show(wmOperatorType *ot)
static ScrArea * find_area_showing_render_result(bContext *C, Scene *scene, wmWindow **r_win)
ScrArea * render_view_open(bContext *C, int mx, int my, ReportList *reports)
static ScrArea * find_area_image_empty(bContext *C)
static int render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static ScrArea * biggest_non_image_area(bContext *C)
void RENDER_OT_view_cancel(wmOperatorType *ot)
SpaceLink * next
struct Image * image
int xy[2]
Definition WM_types.hh:726
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
struct ReportList * reports
wmOperatorType * ot
Definition wm_files.cc:4125
void wm_window_raise(wmWindow *win)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
Definition wm_window.cc:429
wmWindow * WM_window_open(bContext *C, const char *title, const rcti *rect_unscaled, int space_type, bool toplevel, bool dialog, bool temp, eWindowAlignment alignment, void(*area_setup_fn)(bScreen *screen, ScrArea *area, void *user_data), void *area_setup_user_data)
Definition wm_window.cc:950
bool WM_window_is_temp_screen(const wmWindow *win)
Scene * WM_window_get_active_scene(const wmWindow *win)
void wm_window_lower(wmWindow *win)
bScreen * WM_window_get_active_screen(const wmWindow *win)