Blender V4.5
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
8
9#include <algorithm>
10#include <cstddef>
11#include <cstring>
12
13#include "BLI_listbase.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/* -------------------------------------------------------------------- */
39
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
124
125/* -------------------------------------------------------------------- */
128
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 sizex = std::max(sizex, 320);
150 sizey = std::max(sizey, 256);
151
152 const rcti window_rect = {
153 /*xmin*/ mx,
154 /*xmax*/ mx + sizex,
155 /*ymin*/ my,
156 /*ymax*/ my + sizey,
157 };
158
159 /* changes context! */
160 if (WM_window_open(C,
161 IFACE_("Blender Render"),
162 &window_rect,
164 true,
165 false,
166 true,
168 nullptr,
169 nullptr) == nullptr)
170 {
171 BKE_report(reports, RPT_ERROR, "Failed to open window!");
172 return nullptr;
173 }
174
175 area = CTX_wm_area(C);
176 if (BLI_listbase_is_single(&area->spacedata) == false) {
177 sima = static_cast<SpaceImage *>(area->spacedata.first);
178 sima->flag |= SI_PREVSPACE;
179 }
180 }
181 else if (U.render_display_type == USER_RENDER_DISPLAY_SCREEN) {
182 area = CTX_wm_area(C);
183
184 /* If the active screen is already in full-screen mode, skip this and
185 * unset the area, so that the full-screen area is just changed later. */
186 if (area && area->full) {
187 area = nullptr;
188 }
189 else {
190 if (area && area->spacetype == SPACE_IMAGE) {
191 area_was_image = true;
192 }
193
194 /* this function returns with changed context */
196 }
197 }
198
199 if (!area) {
200 wmWindow *win_show = nullptr;
201 area = find_area_showing_render_result(C, scene, &win_show);
202 if (area == nullptr) {
203 /* No need to set `win_show` as the area selected will be from the active window. */
204 area = find_area_image_empty(C);
205 }
206
207 /* if area found in other window, we make that one show in front */
208 if (win_show && win_show != CTX_wm_window(C)) {
209 wm_window_raise(win_show);
210 }
211
212 if (area == nullptr) {
213 /* find largest open non-image area */
215 if (area) {
216 ED_area_newspace(C, area, SPACE_IMAGE, true);
217 sima = static_cast<SpaceImage *>(area->spacedata.first);
218
219 /* Makes "Escape" go back to previous space. */
220 sima->flag |= SI_PREVSPACE;
221
222 /* We already had a full-screen here -> mark new space as a stacked full-screen. */
223 if (area->full) {
225 }
226 }
227 else {
228 /* use any area of decent size */
230 if (area->spacetype != SPACE_IMAGE) {
231 // XXX newspace(area, SPACE_IMAGE);
232 sima = static_cast<SpaceImage *>(area->spacedata.first);
233
234 /* Makes "Escape" go back to previous space. */
235 sima->flag |= SI_PREVSPACE;
236 }
237 }
238 }
239 }
240 sima = static_cast<SpaceImage *>(area->spacedata.first);
242
243 /* get the correct image, and scale it */
244 sima->image = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
245
246 /* If we're rendering to full screen, set appropriate hints on image editor
247 * so it can restore properly on pressing escape. */
248 if (area->full) {
249 sima->flag |= SI_FULLWINDOW;
250
251 /* Tell the image editor to revert to previous space in space list on close
252 * _only_ if it wasn't already an image editor when the render was invoked */
253 if (area_was_image == 0) {
254 sima->flag |= SI_PREVSPACE;
255 }
256 else {
257 /* Leave it alone so the image editor will just go back from
258 * full screen to the original tiled setup */
259 }
260 }
261
262 if ((sima->flag & SI_PREVSPACE) && sima->next) {
263 SpaceLink *old_sl = sima->next;
265 }
266
267 return area;
268}
269
271
272/* -------------------------------------------------------------------- */
275
277{
278 wmWindow *win = CTX_wm_window(C);
279 ScrArea *area = CTX_wm_area(C);
280 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
281
282 /* ensure image editor full-screen and area full-screen states are in sync */
283 if ((sima->flag & SI_FULLWINDOW) && !area->full) {
284 sima->flag &= ~SI_FULLWINDOW;
285 }
286
287 /* determine if render already shows */
288 if (sima->flag & SI_PREVSPACE) {
289 sima->flag &= ~SI_PREVSPACE;
290
291 if (sima->flag & SI_FULLWINDOW) {
292 sima->flag &= ~SI_FULLWINDOW;
294 }
295 else {
296 ED_area_prevspace(C, area);
297 }
298
299 return OPERATOR_FINISHED;
300 }
301 if (sima->flag & SI_FULLWINDOW) {
302 sima->flag &= ~SI_FULLWINDOW;
304 return OPERATOR_FINISHED;
305 }
306 if (WM_window_is_temp_screen(win)) {
308 return OPERATOR_FINISHED;
309 }
310
312}
313
315{
316 /* identifiers */
317 ot->name = "Cancel Render View";
318 ot->description = "Cancel show render view";
319 ot->idname = "RENDER_OT_view_cancel";
320
321 /* API callbacks. */
324}
325
327
328/* -------------------------------------------------------------------- */
331
333{
334 wmWindow *wincur = CTX_wm_window(C);
335
336 /* test if we have currently a temp screen active */
337 if (WM_window_is_temp_screen(wincur)) {
338 wm_window_lower(wincur);
339 }
340 else {
341 wmWindow *win_show = nullptr;
343
344 /* is there another window on current scene showing result? */
345 LISTBASE_FOREACH (wmWindow *, win, &CTX_wm_manager(C)->windows) {
346 const bScreen *screen = WM_window_get_active_screen(win);
347
348 if ((WM_window_is_temp_screen(win) &&
349 ((ScrArea *)screen->areabase.first)->spacetype == SPACE_IMAGE) ||
350 (win == win_show && win_show != wincur))
351 {
352 wm_window_raise(win);
353 return OPERATOR_FINISHED;
354 }
355 }
356
357 /* determine if render already shows */
358 if (area) {
359 /* but don't close it when rendering */
360 if (G.is_rendering == false) {
361 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
362
363 if (sima->flag & SI_PREVSPACE) {
364 sima->flag &= ~SI_PREVSPACE;
365
366 if (sima->flag & SI_FULLWINDOW) {
367 sima->flag &= ~SI_FULLWINDOW;
369 }
370 else {
371 ED_area_prevspace(C, area);
372 }
373 }
374 }
375 }
376 else {
377 render_view_open(C, event->xy[0], event->xy[1], op->reports);
378 }
379 }
380
381 return OPERATOR_FINISHED;
382}
383
385{
386 /* identifiers */
387 ot->name = "Show/Hide Render View";
388 ot->description = "Toggle show render view";
389 ot->idname = "RENDER_OT_view_show";
390
391 /* API callbacks. */
392 ot->invoke = render_view_show_invoke;
394}
395
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:126
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2927
ScrArea * BKE_screen_find_big_area(const bScreen *screen, int spacetype, short min)
Definition screen.cc:938
#define LISTBASE_FOREACH(type, var, list)
void void BLI_INLINE bool BLI_listbase_is_single(const 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
#define UI_SCALE_FAC
@ USER_RENDER_DISPLAY_NONE
@ USER_RENDER_DISPLAY_SCREEN
@ USER_RENDER_DISPLAY_WINDOW
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
void ED_area_newspace(bContext *C, ScrArea *area, int type, bool skip_region_exit)
Definition area.cc:2693
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:2860
void ED_screen_full_prevspace(bContext *C, ScrArea *area)
#define C
Definition RandGen.cpp:29
@ WIN_ALIGN_LOCATION_CENTER
Definition WM_api.hh:362
ReportList * reports
Definition WM_types.hh:1025
#define U
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define G(x, y, z)
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 wmOperatorStatus render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static ScrArea * find_area_image_empty(bContext *C)
static wmOperatorStatus render_view_cancel_exec(bContext *C, wmOperator *)
static ScrArea * biggest_non_image_area(bContext *C)
void RENDER_OT_view_cancel(wmOperatorType *ot)
void * first
struct RenderData r
ListBase spacedata
bScreen * full
struct ScrArea * next
SpaceLink * next
struct Image * image
ListBase areabase
int xy[2]
Definition WM_types.hh:758
struct ReportList * reports
wmOperatorType * ot
Definition wm_files.cc:4225
void wm_window_raise(wmWindow *win)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
Definition wm_window.cc:433
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)
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)