Blender V4.3
view3d_draw.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 <cmath>
10
11#include "BLI_listbase.h"
12#include "BLI_math_half.hh"
13#include "BLI_math_matrix.h"
14#include "BLI_math_rotation.h"
15#include "BLI_rect.h"
16#include "BLI_string.h"
17#include "BLI_string_utils.hh"
18#include "BLI_threads.h"
19
20#include "BKE_armature.hh"
21#include "BKE_camera.h"
22#include "BKE_collection.hh"
23#include "BKE_context.hh"
24#include "BKE_customdata.hh"
25#include "BKE_global.hh"
26#include "BKE_image.hh"
27#include "BKE_key.hh"
28#include "BKE_layer.hh"
29#include "BKE_main.hh"
30#include "BKE_object.hh"
31#include "BKE_paint.hh"
32#include "BKE_scene.hh"
33#include "BKE_unit.hh"
34
35#include "BLF_api.hh"
36
37#include "BLT_translation.hh"
38
39#include "DNA_armature_types.h"
40#include "DNA_camera_types.h"
41#include "DNA_key_types.h"
42#include "DNA_object_types.h"
43#include "DNA_view3d_types.h"
45
46#include "DRW_engine.hh"
47#include "DRW_select_buffer.hh"
48
49#include "ED_gpencil_legacy.hh"
50#include "ED_info.hh"
51#include "ED_keyframing.hh"
52#include "ED_scene.hh"
53#include "ED_screen.hh"
55#include "ED_viewer_path.hh"
56
58
60
61#include "GPU_batch.hh"
62#include "GPU_framebuffer.hh"
63#include "GPU_immediate.hh"
64#include "GPU_immediate_util.hh"
65#include "GPU_material.hh"
66#include "GPU_matrix.hh"
67#include "GPU_state.hh"
68#include "GPU_viewport.hh"
69
70#include "MEM_guardedalloc.h"
71
72#include "UI_interface.hh"
73#include "UI_resources.hh"
74
75#include "RE_engine.h"
76
77#include "WM_api.hh"
78#include "WM_types.hh"
79
80#include "IMB_imbuf.hh"
81#include "IMB_imbuf_types.hh"
82
83#include "view3d_intern.hh" /* own include */
84
85using blender::float4;
86
87#define M_GOLDEN_RATIO_CONJUGATE 0.618033988749895f
88
89#define VIEW3D_OVERLAY_LINEHEIGHT (UI_style_get()->widget.points * UI_SCALE_FAC * 1.6f)
90
91/* -------------------------------------------------------------------- */
95void ED_view3d_update_viewmat(const Depsgraph *depsgraph,
96 const Scene *scene,
97 View3D *v3d,
98 ARegion *region,
99 const float viewmat[4][4],
100 const float winmat[4][4],
101 const rcti *rect,
102 bool offscreen)
103{
104 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
105
106 /* setup window matrices */
107 if (winmat) {
108 copy_m4_m4(rv3d->winmat, winmat);
109 }
110 else {
111 view3d_winmatrix_set(depsgraph, region, v3d, rect);
112 }
113
114 /* setup view matrix */
115 if (viewmat) {
116 copy_m4_m4(rv3d->viewmat, viewmat);
117 }
118 else {
119 float rect_scale[2];
120 if (rect) {
121 rect_scale[0] = float(BLI_rcti_size_x(rect)) / float(region->winx);
122 rect_scale[1] = float(BLI_rcti_size_y(rect)) / float(region->winy);
123 }
124 /* NOTE: calls BKE_object_where_is_calc for camera... */
125 view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : nullptr);
126 }
127 /* update utility matrices */
128 mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
129 invert_m4_m4(rv3d->persinv, rv3d->persmat);
130 invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
131
132 /* calculate GLSL view dependent values */
133
134 /* store window coordinates scaling/offset */
135 if (!offscreen && rv3d->persp == RV3D_CAMOB && v3d->camera) {
136 rctf cameraborder;
137 ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, false, &cameraborder);
138 rv3d->viewcamtexcofac[0] = float(region->winx) / BLI_rctf_size_x(&cameraborder);
139 rv3d->viewcamtexcofac[1] = float(region->winy) / BLI_rctf_size_y(&cameraborder);
140
141 rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / float(region->winx);
142 rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / float(region->winy);
143 }
144 else {
145 rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
146 rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
147 }
148
149 /* Calculate pixel-size factor once, this is used for lights and object-centers. */
150 {
151 /* NOTE: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
152 * because of float point precision problems at large values #23908. */
153 float v1[3], v2[3];
154 float len_px, len_sc;
155
156 v1[0] = rv3d->persmat[0][0];
157 v1[1] = rv3d->persmat[1][0];
158 v1[2] = rv3d->persmat[2][0];
159
160 v2[0] = rv3d->persmat[0][1];
161 v2[1] = rv3d->persmat[1][1];
162 v2[2] = rv3d->persmat[2][1];
163
164 len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
165
166 if (rect) {
167 len_sc = float(max_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)));
168 }
169 else {
170 len_sc = float(std::max(region->winx, region->winy));
171 }
172
173 rv3d->pixsize = len_px / len_sc;
174 }
175}
176
178 Scene *scene,
179 View3D *v3d,
180 ARegion *region,
181 const float viewmat[4][4],
182 const float winmat[4][4],
183 const rcti *rect)
184{
185 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
186
187 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, rect, false);
188
189 /* set for opengl */
191 GPU_matrix_set(rv3d->viewmat);
192}
193
195 const Scene *scene,
196 View3D *v3d,
197 ARegion *region,
198 const float viewmat[4][4],
199 const float winmat[4][4])
200{
201 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
202 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, nullptr, true);
203
204 /* set for opengl */
206 GPU_matrix_set(rv3d->viewmat);
207}
208
210 const Scene *scene,
211 View3D *v3d,
212 RegionView3D *rv3d)
213{
214 if ((scene->r.scemode & R_MULTIVIEW) == 0) {
215 return false;
216 }
217
218 if ((v3d->camera == nullptr) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
219 return false;
220 }
221
222 switch (v3d->stereo3d_camera) {
223 case STEREO_MONO_ID:
224 return false;
225 break;
226 case STEREO_3D_ID:
227 /* win will be nullptr when calling this from the selection or draw loop. */
228 if ((win == nullptr) || (WM_stereo3d_enabled(win, true) == false)) {
229 return false;
230 }
231 if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
233 {
234 return false;
235 }
236 break;
237 /* We always need the stereo calculation for left and right cameras. */
238 case STEREO_LEFT_ID:
239 case STEREO_RIGHT_ID:
240 default:
241 break;
242 }
243 return true;
244}
245
246/* setup the view and win matrices for the multiview cameras
247 *
248 * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
249 * we have no winmatrix (i.e., projection matrix) defined at that time.
250 * Since the camera and the camera shift are needed for the winmat calculation
251 * we do a small hack to replace it temporarily so we don't need to change the
252 * view3d)main_region_setup_view() code to account for that.
253 */
255 Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *region, const rcti *rect)
256{
257 bool is_left;
258 const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
259 const char *viewname;
260
261 /* show only left or right camera */
262 if (v3d->stereo3d_camera != STEREO_3D_ID) {
263 v3d->multiview_eye = v3d->stereo3d_camera;
264 }
265
267 viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
268
269 /* update the viewport matrices with the new camera */
270 if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
271 Camera *data, *data_eval;
272 float viewmat[4][4];
273 float shiftx;
274
275 data = (Camera *)v3d->camera->data;
276 data_eval = (Camera *)DEG_get_evaluated_id(depsgraph, &data->id);
277
278 shiftx = data_eval->shiftx;
279
281 data_eval->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
282
283 BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
284 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
285
286 data_eval->shiftx = shiftx;
288 }
289 else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
290 float viewmat[4][4];
291 Object *view_ob = v3d->camera;
292 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
293
295 v3d->camera = camera;
296
297 BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
298 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
299
300 v3d->camera = view_ob;
302 }
303}
304
305#ifdef WITH_XR_OPENXR
306static void view3d_xr_mirror_setup(const wmWindowManager *wm,
307 Depsgraph *depsgraph,
308 Scene *scene,
309 View3D *v3d,
310 ARegion *region,
311 const rcti *rect)
312{
313 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
314 float viewmat[4][4];
315 const float lens_old = v3d->lens;
316
317 if (!WM_xr_session_state_viewer_pose_matrix_info_get(&wm->xr, viewmat, &v3d->lens)) {
318 /* Can't get info from XR session, use fallback values. */
319 copy_m4_m4(viewmat, rv3d->viewmat);
320 v3d->lens = lens_old;
321 }
322 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
323
324 /* Set draw flags. */
330 0,
332 /* Hide navigation gizmo since it gets distorted if the view matrix has a scale factor. */
334
335 /* Reset overridden View3D data. */
336 v3d->lens = lens_old;
337}
338#endif /* WITH_XR_OPENXR */
339
341 wmWindow *win,
342 Depsgraph *depsgraph,
343 Scene *scene,
344 ARegion *region,
345 View3D *v3d,
346 const float viewmat[4][4],
347 const float winmat[4][4],
348 const rcti *rect)
349{
350 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
351
352#ifdef WITH_XR_OPENXR
353 /* Setup the view matrix. */
354 if (ED_view3d_is_region_xr_mirror_active(wm, v3d, region)) {
355 view3d_xr_mirror_setup(wm, depsgraph, scene, v3d, region, rect);
356 }
357 else
358#endif
359 if (view3d_stereo3d_active(win, scene, v3d, rv3d))
360 {
361 view3d_stereo3d_setup(depsgraph, scene, v3d, region, rect);
362 }
363 else {
364 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, winmat, rect);
365 }
366
367#ifndef WITH_XR_OPENXR
368 UNUSED_VARS(wm);
369#endif
370}
371
374/* -------------------------------------------------------------------- */
378static void view3d_camera_border(const Scene *scene,
379 const Depsgraph *depsgraph,
380 const ARegion *region,
381 const View3D *v3d,
382 const RegionView3D *rv3d,
383 rctf *r_viewborder,
384 const bool no_shift,
385 const bool no_zoom)
386{
388 rctf rect_view, rect_camera;
389 Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
390
391 /* get viewport viewplane */
394 if (no_zoom) {
395 params.zoom = 1.0f;
396 }
397 BKE_camera_params_compute_viewplane(&params, region->winx, region->winy, 1.0f, 1.0f);
398 rect_view = params.viewplane;
399
400 /* get camera viewplane */
402 /* fallback for non camera objects */
403 params.clip_start = v3d->clip_start;
404 params.clip_end = v3d->clip_end;
406 if (no_shift) {
407 params.shiftx = 0.0f;
408 params.shifty = 0.0f;
409 }
411 &params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
412 rect_camera = params.viewplane;
413
414 /* get camera border within viewport */
415 r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) *
416 region->winx;
417 r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) *
418 region->winx;
419 r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) *
420 region->winy;
421 r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) *
422 region->winy;
423}
424
426 Depsgraph *depsgraph,
427 const ARegion *region,
428 const View3D *v3d,
429 const RegionView3D *rv3d,
430 float r_size[2])
431{
432 rctf viewborder;
433
434 view3d_camera_border(scene, depsgraph, region, v3d, rv3d, &viewborder, true, true);
435 r_size[0] = BLI_rctf_size_x(&viewborder);
436 r_size[1] = BLI_rctf_size_y(&viewborder);
437}
438
440 const Depsgraph *depsgraph,
441 const ARegion *region,
442 const View3D *v3d,
443 const RegionView3D *rv3d,
444 const bool no_shift,
445 rctf *r_viewborder)
446{
447 view3d_camera_border(scene, depsgraph, region, v3d, rv3d, r_viewborder, no_shift, false);
448}
449
450static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, float y2, float fac)
451{
452 float x3, y3, x4, y4;
453
454 x3 = x1 + fac * (x2 - x1);
455 y3 = y1 + fac * (y2 - y1);
456 x4 = x1 + (1.0f - fac) * (x2 - x1);
457 y4 = y1 + (1.0f - fac) * (y2 - y1);
458
460
461 immVertex2f(shdr_pos, x1, y3);
462 immVertex2f(shdr_pos, x2, y3);
463
464 immVertex2f(shdr_pos, x1, y4);
465 immVertex2f(shdr_pos, x2, y4);
466
467 immVertex2f(shdr_pos, x3, y1);
468 immVertex2f(shdr_pos, x3, y2);
469
470 immVertex2f(shdr_pos, x4, y1);
471 immVertex2f(shdr_pos, x4, y2);
472
473 immEnd();
474}
475
476/* harmonious triangle */
478 uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
479{
480 float ofs;
481 float w = x2 - x1;
482 float h = y2 - y1;
483
485
486 if (w > h) {
487 if (golden) {
488 ofs = w * (1.0f - M_GOLDEN_RATIO_CONJUGATE);
489 }
490 else {
491 ofs = h * (h / w);
492 }
493 if (dir == 'B') {
494 std::swap(y1, y2);
495 }
496
497 immVertex2f(shdr_pos, x1, y1);
498 immVertex2f(shdr_pos, x2, y2);
499
500 immVertex2f(shdr_pos, x2, y1);
501 immVertex2f(shdr_pos, x1 + (w - ofs), y2);
502
503 immVertex2f(shdr_pos, x1, y2);
504 immVertex2f(shdr_pos, x1 + ofs, y1);
505 }
506 else {
507 if (golden) {
508 ofs = h * (1.0f - M_GOLDEN_RATIO_CONJUGATE);
509 }
510 else {
511 ofs = w * (w / h);
512 }
513 if (dir == 'B') {
514 std::swap(x1, x2);
515 }
516
517 immVertex2f(shdr_pos, x1, y1);
518 immVertex2f(shdr_pos, x2, y2);
519
520 immVertex2f(shdr_pos, x2, y1);
521 immVertex2f(shdr_pos, x1, y1 + ofs);
522
523 immVertex2f(shdr_pos, x1, y2);
524 immVertex2f(shdr_pos, x2, y1 + (h - ofs));
525 }
526
527 immEnd();
528}
529
530static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, View3D *v3d)
531{
532 float x1, x2, y1, y2;
533 float x1i, x2i, y1i, y2i;
534
535 rctf viewborder;
536 Camera *ca = nullptr;
537 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
538
539 if (v3d->camera == nullptr) {
540 return;
541 }
542 if (v3d->camera->type == OB_CAMERA) {
543 ca = static_cast<Camera *>(v3d->camera->data);
544 }
545
546 ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, false, &viewborder);
547 /* the offsets */
548 x1 = viewborder.xmin;
549 y1 = viewborder.ymin;
550 x2 = viewborder.xmax;
551 y2 = viewborder.ymax;
552
553 GPU_line_width(1.0f);
554
555 /* apply offsets so the real 3D camera shows through */
556
557 /* NOTE: quite un-scientific but without this bit extra
558 * 0.0001 on the lower left the 2D border sometimes
559 * obscures the 3D camera border */
560 /* NOTE: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
561 * but keep it here in case we need to remove the workaround */
562 x1i = int(x1 - 1.0001f);
563 y1i = int(y1 - 1.0001f);
564 x2i = int(x2 + (1.0f - 0.0001f));
565 y2i = int(y2 + (1.0f - 0.0001f));
566
567 uint shdr_pos = GPU_vertformat_attr_add(
569
570 /* First, solid lines. */
571 {
573
574 /* passepartout, specified in camera edit buttons */
575 if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f &&
577 {
578 const float winx = (region->winx + 1);
579 const float winy = (region->winy + 1);
580
581 float alpha = 1.0f;
582
583 if (ca->passepartalpha != 1.0f) {
585 alpha = ca->passepartalpha;
586 }
587
589
590 if (x1i > 0.0f) {
591 immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f);
592 }
593 if (x2i < winx) {
594 immRectf(shdr_pos, x2i, winy, winx, 0.0f);
595 }
596 if (y2i < winy) {
597 immRectf(shdr_pos, x1i, winy, x2i, y2i);
598 }
599 if (y2i > 0.0f) {
600 immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
601 }
602
605 imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
606 }
607
608#ifdef VIEW3D_CAMERA_BORDER_HACK
609 if (view3d_camera_border_hack_test == true) {
611 imm_draw_box_wire_2d(shdr_pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
613 }
614#endif
615
617 }
618
619 /* When overlays are disabled, only show camera outline & passepartout. */
620 if (v3d->flag2 & V3D_HIDE_OVERLAYS || !(v3d->flag2 & V3D_SHOW_CAMERA_GUIDES)) {
621 return;
622 }
623
624 /* And now, the dashed lines! */
626
627 {
628 float viewport_size[4];
629 GPU_viewport_size_get_f(viewport_size);
630 immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
631
632 immUniform1i("colors_len", 0); /* "simple" mode */
633 immUniform1f("dash_width", 6.0f);
634 immUniform1f("udash_factor", 0.5f);
635
636 /* outer line not to confuse with object selection */
637 if (v3d->flag2 & V3D_LOCK_CAMERA) {
639 imm_draw_box_wire_2d(shdr_pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
640 }
641
643 imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
644 }
645
646 /* Render Border. */
647 if (scene->r.mode & R_BORDER) {
648 float x3, y3, x4, y4;
649
650 x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
651 y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
652 x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
653 y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
654
655 immUniformColor3f(1.0f, 0.25f, 0.25f);
656 imm_draw_box_wire_2d(shdr_pos, x3, y3, x4, y4);
657 }
658
659 /* safety border */
660 if (ca && (v3d->flag2 & V3D_SHOW_CAMERA_GUIDES)) {
663
664 if (ca->dtx & CAM_DTX_CENTER) {
665 float x3, y3;
666
667 x3 = x1 + 0.5f * (x2 - x1);
668 y3 = y1 + 0.5f * (y2 - y1);
669
671
672 immVertex2f(shdr_pos, x1, y3);
673 immVertex2f(shdr_pos, x2, y3);
674
675 immVertex2f(shdr_pos, x3, y1);
676 immVertex2f(shdr_pos, x3, y2);
677
678 immEnd();
679 }
680
681 if (ca->dtx & CAM_DTX_CENTER_DIAG) {
683
684 immVertex2f(shdr_pos, x1, y1);
685 immVertex2f(shdr_pos, x2, y2);
686
687 immVertex2f(shdr_pos, x1, y2);
688 immVertex2f(shdr_pos, x2, y1);
689
690 immEnd();
691 }
692
693 if (ca->dtx & CAM_DTX_THIRDS) {
694 drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f / 3.0f);
695 }
696
697 if (ca->dtx & CAM_DTX_GOLDEN) {
698 drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - M_GOLDEN_RATIO_CONJUGATE);
699 }
700
701 if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
702 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'A');
703 }
704
705 if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
706 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'B');
707 }
708
709 if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
710 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'A');
711 }
712
713 if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
714 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'B');
715 }
716
717 if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
718 rctf margins_rect{};
719 margins_rect.xmin = x1;
720 margins_rect.xmax = x2;
721 margins_rect.ymin = y1;
722 margins_rect.ymax = y2;
723
725 shdr_pos, &margins_rect, scene->safe_areas.title, scene->safe_areas.action);
726
727 if (ca->flag & CAM_SHOW_SAFE_CENTER) {
728 rctf center_rect{};
729 center_rect.xmin = x1;
730 center_rect.xmax = x2;
731 center_rect.ymin = y1;
732 center_rect.ymax = y2;
733 UI_draw_safe_areas(shdr_pos,
734 &center_rect,
735 scene->safe_areas.title_center,
736 scene->safe_areas.action_center);
737 }
738 }
739
740 if (ca->flag & CAM_SHOWSENSOR) {
741 /* determine sensor fit, and get sensor x/y, for auto fit we
742 * assume and square sensor and only use sensor_x */
743 float sizex = scene->r.xsch * scene->r.xasp;
744 float sizey = scene->r.ysch * scene->r.yasp;
745 int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
746 float sensor_x = ca->sensor_x;
747 float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
748
749 /* determine sensor plane */
750 rctf rect;
751
752 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
753 float sensor_scale = (x2i - x1i) / sensor_x;
754 float sensor_height = sensor_scale * sensor_y;
755
756 rect.xmin = x1i;
757 rect.xmax = x2i;
758 rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
759 rect.ymax = rect.ymin + sensor_height;
760 }
761 else {
762 float sensor_scale = (y2i - y1i) / sensor_y;
763 float sensor_width = sensor_scale * sensor_x;
764
765 rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
766 rect.xmax = rect.xmin + sensor_width;
767 rect.ymin = y1i;
768 rect.ymax = y2i;
769 }
770
771 /* draw */
773
774 /* TODO: Was using:
775 * `UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color);`
776 * We'll probably need a new imm_draw_line_roundbox_dashed or that - though in practice the
777 * 2.0f round corner effect was nearly not visible anyway. */
778 imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
779 }
780
782 }
783
785 /* end dashed lines */
786
787 /* camera name - draw in highlighted text color */
788 if (ca && ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) && (ca->flag & CAM_SHOWNAME)) {
791 y1i - (0.7f * U.widget_unit),
792 0.0f,
793 v3d->camera->id.name + 2,
794 sizeof(v3d->camera->id.name) - 2);
795 }
796}
797
798static void drawrenderborder(ARegion *region, View3D *v3d)
799{
800 /* use the same program for everything */
801 uint shdr_pos = GPU_vertformat_attr_add(
803
804 GPU_line_width(1.0f);
805
807
808 float viewport_size[4];
809 GPU_viewport_size_get_f(viewport_size);
810 immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
811
812 immUniform1i("colors_len", 0); /* "simple" mode */
813 immUniform4f("color", 1.0f, 0.25f, 0.25f, 1.0f);
814 immUniform1f("dash_width", 6.0f);
815 immUniform1f("udash_factor", 0.5f);
816
817 imm_draw_box_wire_2d(shdr_pos,
818 v3d->render_border.xmin * region->winx,
819 v3d->render_border.ymin * region->winy,
820 v3d->render_border.xmax * region->winx,
821 v3d->render_border.ymax * region->winy);
822
824}
825
828/* -------------------------------------------------------------------- */
832float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit)
833{
834 /* apply units */
835 if (scene->unit.system) {
836 const void *usys;
837 int len;
838
839 BKE_unit_system_get(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
840
841 if (usys) {
842 int i = BKE_unit_base_get(usys);
843 if (r_grid_unit) {
844 *r_grid_unit = IFACE_(BKE_unit_display_name_get(usys, i));
845 }
846 return float(BKE_unit_scalar_get(usys, i)) / scene->unit.scale_length;
847 }
848 }
849
850 return 1.0f;
851}
852
853float ED_view3d_grid_scale(const Scene *scene, const View3D *v3d, const char **r_grid_unit)
854{
855 return v3d->grid * ED_scene_grid_scale(scene, r_grid_unit);
856}
857
858#define STEPS_LEN 8
859static void view3d_grid_steps_ex(const Scene *scene,
860 const View3D *v3d,
861 const RegionView3D *rv3d,
862 float r_grid_steps[STEPS_LEN],
863 void const **r_usys_pt,
864 int *r_len)
865{
866 const void *usys;
867 int len;
868 BKE_unit_system_get(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
869 float grid_scale = v3d->grid;
871
872 if (usys) {
873 if (rv3d->view == RV3D_VIEW_USER) {
874 /* Skip steps */
875 len = BKE_unit_base_get(usys) + 1;
876 }
877
878 grid_scale /= scene->unit.scale_length;
879
880 int i;
881 for (i = 0; i < len; i++) {
882 r_grid_steps[i] = float(BKE_unit_scalar_get(usys, len - 1 - i)) * grid_scale;
883 }
884 for (; i < STEPS_LEN; i++) {
885 /* Fill last slots */
886 r_grid_steps[i] = r_grid_steps[len - 1];
887 }
888 }
889 else {
890 if (rv3d->view != RV3D_VIEW_USER) {
891 /* Allow 3 more subdivisions. */
892 grid_scale /= powf(v3d->gridsubdiv, 3);
893 }
894 int subdiv = 1;
895 for (int i = 0;; i++) {
896 r_grid_steps[i] = grid_scale * subdiv;
897
898 if (i == STEPS_LEN - 1) {
899 break;
900 }
901 subdiv *= v3d->gridsubdiv;
902 }
903 }
904 if (r_usys_pt) {
905 *r_usys_pt = usys;
906 }
907 if (r_len) {
908 *r_len = len;
909 }
910}
911
912void ED_view3d_grid_steps(const Scene *scene,
913 const View3D *v3d,
914 const RegionView3D *rv3d,
915 float r_grid_steps[STEPS_LEN])
916{
917 view3d_grid_steps_ex(scene, v3d, rv3d, r_grid_steps, nullptr, nullptr);
918}
919
921 const View3D *v3d,
922 const ARegion *region,
923 const char **r_grid_unit)
924{
925 float grid_scale;
926 const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
927 if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
928 /* Decrease the distance between grid snap points depending on zoom. */
929 float dist = 12.0f / (region->sizex * rv3d->winmat[0][0]);
930 float grid_steps[STEPS_LEN];
931 const void *usys;
932 int grid_steps_len;
933 view3d_grid_steps_ex(scene, v3d, rv3d, grid_steps, &usys, &grid_steps_len);
934 int i = 0;
935 while (true) {
936 grid_scale = grid_steps[i];
937 if (grid_scale > dist || i == (grid_steps_len - 1)) {
938 break;
939 }
940 i++;
941 }
942
943 if (r_grid_unit && usys) {
944 *r_grid_unit = IFACE_(BKE_unit_display_name_get(usys, grid_steps_len - i - 1));
945 }
946 }
947 else {
948 grid_scale = ED_view3d_grid_scale(scene, v3d, r_grid_unit);
949 }
950
951 return grid_scale;
952}
953
954#undef STEPS_LEN
955
956static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
957{
958 const float k = U.rvisize * U.pixelsize; /* axis size */
959 /* axis alpha offset (rvibright has range 0-10) */
960 const int bright = -20 * (10 - U.rvibright);
961
962 /* Axis center in screen coordinates.
963 *
964 * - Unit size offset so small text doesn't draw outside the screen
965 * - Extra X offset because of the panel expander.
966 */
967 const float startx = rect->xmax - (k + UI_UNIT_X * 1.5);
968 const float starty = rect->ymax - (k + UI_UNIT_Y);
969
970 float axis_pos[3][2];
971 uchar axis_col[3][4];
972
973 int axis_order[3] = {0, 1, 2};
974 axis_sort_v3(rv3d->viewinv[2], axis_order);
975
976 for (int axis_i = 0; axis_i < 3; axis_i++) {
977 int i = axis_order[axis_i];
978
979 /* get position of each axis tip on screen */
980 float vec[3] = {0.0f};
981 vec[i] = 1.0f;
982 mul_qt_v3(rv3d->viewquat, vec);
983 axis_pos[i][0] = startx + vec[0] * k;
984 axis_pos[i][1] = starty + vec[1] * k;
985
986 /* get color of each axis */
987 UI_GetThemeColorShade3ubv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
988 axis_col[i][3] = 255 * hypotf(vec[0], vec[1]); /* alpha */
989 }
990
991 /* draw axis lines */
992 GPU_line_width(2.0f);
993 GPU_line_smooth(true);
995
999
1002
1003 for (int axis_i = 0; axis_i < 3; axis_i++) {
1004 int i = axis_order[axis_i];
1005
1006 immAttr4ubv(col, axis_col[i]);
1007 immVertex2f(pos, startx, starty);
1008 immAttr4ubv(col, axis_col[i]);
1009 immVertex2fv(pos, axis_pos[i]);
1010 }
1011
1012 immEnd();
1014 GPU_line_smooth(false);
1015
1016 /* draw axis names */
1017 for (int axis_i = 0; axis_i < 3; axis_i++) {
1018 int i = axis_order[axis_i];
1019
1020 const char axis_text[2] = {char('x' + i), '\0'};
1021 BLF_color4ubv(BLF_default(), axis_col[i]);
1022 BLF_draw_default(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
1023 }
1024}
1025
1026#ifdef WITH_INPUT_NDOF
1027/* draw center and axis of rotation for ongoing 3D mouse navigation */
1028static void draw_rotation_guide(const RegionView3D *rv3d)
1029{
1030 float o[3]; /* center of rotation */
1031 float end[3]; /* endpoints for drawing */
1032
1033 uchar color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
1034
1035 negate_v3_v3(o, rv3d->ofs);
1036
1038 GPU_depth_mask(false); /* Don't overwrite the Z-buffer. */
1039
1043
1045
1046 if (rv3d->rot_angle != 0.0f) {
1047 /* -- draw rotation axis -- */
1048 float scaled_axis[3];
1049 const float scale = rv3d->dist;
1050 mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
1051
1053 color[3] = 0; /* more transparent toward the ends */
1054 immAttr4ubv(col, color);
1055 add_v3_v3v3(end, o, scaled_axis);
1056 immVertex3fv(pos, end);
1057
1058# if 0
1059 color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
1060 /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
1061# endif
1062
1063 color[3] = 127; /* more opaque toward the center */
1064 immAttr4ubv(col, color);
1065 immVertex3fv(pos, o);
1066
1067 color[3] = 0;
1068 immAttr4ubv(col, color);
1069 sub_v3_v3v3(end, o, scaled_axis);
1070 immVertex3fv(pos, end);
1071 immEnd();
1072
1073 /* -- draw ring around rotation center -- */
1074 {
1075# define ROT_AXIS_DETAIL 13
1076
1077 const float s = 0.05f * scale;
1078 const float step = 2.0f * float(M_PI / ROT_AXIS_DETAIL);
1079
1080 float q[4]; /* rotate ring so it's perpendicular to axis */
1081 const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
1082 if (!upright) {
1083 const float up[3] = {0.0f, 0.0f, 1.0f};
1084 float vis_angle, vis_axis[3];
1085
1086 cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
1087 vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
1088 axis_angle_to_quat(q, vis_axis, vis_angle);
1089 }
1090
1091 immBegin(GPU_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
1092 color[3] = 63; /* somewhat faint */
1093 immAttr4ubv(col, color);
1094 float angle = 0.0f;
1095 for (int i = 0; i < ROT_AXIS_DETAIL; i++, angle += step) {
1096 float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
1097
1098 if (!upright) {
1099 mul_qt_v3(q, p);
1100 }
1101
1102 add_v3_v3(p, o);
1103 immVertex3fv(pos, p);
1104 }
1105 immEnd();
1106
1107# undef ROT_AXIS_DETAIL
1108 }
1109
1110 color[3] = 255; /* solid dot */
1111 }
1112 else {
1113 color[3] = 127; /* see-through dot */
1114 }
1115
1117
1118 /* -- draw rotation center -- */
1120 immUniform1f("size", 7.0f);
1121 immUniform4fv("color", float4(color));
1123 immAttr4ubv(col, color);
1124 immVertex3fv(pos, o);
1125 immEnd();
1127
1129 GPU_depth_mask(true);
1130}
1131#endif /* WITH_INPUT_NDOF */
1132
1136static void view3d_draw_border(const bContext *C, ARegion *region)
1137{
1138 Scene *scene = CTX_data_scene(C);
1140 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1141 View3D *v3d = CTX_wm_view3d(C);
1142
1143 if (rv3d->persp == RV3D_CAMOB) {
1144 drawviewborder(scene, depsgraph, region, v3d);
1145 }
1146 else if (v3d->flag2 & V3D_RENDER_BORDER) {
1147 drawrenderborder(region, v3d);
1148 }
1149}
1150
1153/* -------------------------------------------------------------------- */
1160static void view3d_draw_grease_pencil(const bContext * /*C*/)
1161{
1162 /* TODO: viewport. */
1163}
1164
1168static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
1169{
1170 const char *name = nullptr;
1171
1172 switch (rv3d->view) {
1173 case RV3D_VIEW_FRONT:
1174 if (rv3d->persp == RV3D_ORTHO) {
1175 name = IFACE_("Front Orthographic");
1176 }
1177 else {
1178 name = IFACE_("Front Perspective");
1179 }
1180 break;
1181 case RV3D_VIEW_BACK:
1182 if (rv3d->persp == RV3D_ORTHO) {
1183 name = IFACE_("Back Orthographic");
1184 }
1185 else {
1186 name = IFACE_("Back Perspective");
1187 }
1188 break;
1189 case RV3D_VIEW_TOP:
1190 if (rv3d->persp == RV3D_ORTHO) {
1191 name = IFACE_("Top Orthographic");
1192 }
1193 else {
1194 name = IFACE_("Top Perspective");
1195 }
1196 break;
1197 case RV3D_VIEW_BOTTOM:
1198 if (rv3d->persp == RV3D_ORTHO) {
1199 name = IFACE_("Bottom Orthographic");
1200 }
1201 else {
1202 name = IFACE_("Bottom Perspective");
1203 }
1204 break;
1205 case RV3D_VIEW_RIGHT:
1206 if (rv3d->persp == RV3D_ORTHO) {
1207 name = IFACE_("Right Orthographic");
1208 }
1209 else {
1210 name = IFACE_("Right Perspective");
1211 }
1212 break;
1213 case RV3D_VIEW_LEFT:
1214 if (rv3d->persp == RV3D_ORTHO) {
1215 name = IFACE_("Left Orthographic");
1216 }
1217 else {
1218 name = IFACE_("Left Perspective");
1219 }
1220 break;
1221
1222 default:
1223 if (rv3d->persp == RV3D_CAMOB) {
1224 if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
1225 const Camera *cam = static_cast<const Camera *>(v3d->camera->data);
1226 if (cam->type == CAM_PERSP) {
1227 name = IFACE_("Camera Perspective");
1228 }
1229 else if (cam->type == CAM_ORTHO) {
1230 name = IFACE_("Camera Orthographic");
1231 }
1232 else {
1233 BLI_assert(cam->type == CAM_PANO);
1234 name = IFACE_("Camera Panoramic");
1235 }
1236 }
1237 else {
1238 name = IFACE_("Object as Camera");
1239 }
1240 }
1241 else {
1242 name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Orthographic") :
1243 IFACE_("User Perspective");
1244 }
1245 }
1246
1247 return name;
1248}
1249
1250static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *yoffset)
1251{
1252 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1253 const char *name = view3d_get_name(v3d, rv3d);
1254 const char *name_array[3] = {name, nullptr, nullptr};
1255 int name_array_len = 1;
1256
1257 /* 6 is the maximum size of the axis roll text. */
1258 /* increase size for unicode languages (Chinese in utf-8...) */
1259 char tmpstr[96 + 6];
1260
1262 const char *axis_roll;
1263 switch (rv3d->view_axis_roll) {
1265 axis_roll = " 90\xC2\xB0";
1266 break;
1268 axis_roll = " 180\xC2\xB0";
1269 break;
1270 default:
1271 axis_roll = " -90\xC2\xB0";
1272 break;
1273 }
1274 name_array[name_array_len++] = axis_roll;
1275 }
1276
1277 if (v3d->localvd) {
1278 name_array[name_array_len++] = IFACE_(" (Local)");
1279 }
1280
1281 /* Indicate that clipping region is enabled. */
1282 if (rv3d->rflag & RV3D_CLIPPING) {
1283 name_array[name_array_len++] = IFACE_(" (Clipped)");
1284 }
1285
1286 if (name_array_len > 1) {
1287 BLI_string_join_array(tmpstr, sizeof(tmpstr), name_array, name_array_len);
1288 name = tmpstr;
1289 }
1290 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
1291 BLF_draw_default(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
1292}
1293
1299 const View3D *v3d, Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
1300{
1301 const int cfra = scene->r.cfra;
1302 const char *msg_pin = " (Pinned)";
1303 const char *msg_sep = " : ";
1304 const char *msg_space = " ";
1305
1306 const int font_id = BLF_default();
1307
1308 const char *info_array[16];
1309 int i = 0;
1310
1311 struct {
1312 char frame[16];
1313 } info_buffers;
1314
1315 SNPRINTF(info_buffers.frame, "(%d)", cfra);
1316 info_array[i++] = info_buffers.frame;
1317
1318 if ((ob == nullptr) || (ob->mode == OB_MODE_OBJECT)) {
1319 BKE_view_layer_synced_ensure(scene, view_layer);
1320 LayerCollection *layer_collection = BKE_view_layer_active_collection_get(view_layer);
1321 info_array[i++] = msg_space;
1322 info_array[i++] = BKE_collection_ui_name_get(layer_collection->collection);
1323 if (ob != nullptr) {
1324 info_array[i++] = " |";
1325 }
1326 }
1327
1328 /* Info can contain:
1329 * - A frame `(7 + 2)`.
1330 * - A collection name `(MAX_NAME + 3)`.
1331 * - 3 object names `(MAX_NAME)`.
1332 * - 2 BREAD_CRUMB_SEPARATOR(s) `(6)`.
1333 * - A SHAPE_KEY_PINNED marker and a trailing '\0' `(9+1)` - translated, so give some room!
1334 * - A marker name `(MAX_NAME + 3)`.
1335 */
1336
1337 /* get name of marker on current frame (if available) */
1338 const char *markern = BKE_scene_find_marker_name(scene, cfra);
1339
1340 /* check if there is an object */
1341 if (ob) {
1342 info_array[i++] = msg_space;
1343 info_array[i++] = ob->id.name + 2;
1344
1345 /* name(s) to display depends on type of object */
1346 if (ob->type == OB_ARMATURE) {
1347 bArmature *arm = static_cast<bArmature *>(ob->data);
1348
1349 /* show name of active bone too (if possible) */
1350 if (arm->edbo) {
1351 if (arm->act_edbone) {
1352 info_array[i++] = msg_sep;
1353 info_array[i++] = arm->act_edbone->name;
1354 }
1355 }
1356 else if (ob->mode & OB_MODE_POSE) {
1357 if (arm->act_bone) {
1358
1360 info_array[i++] = msg_sep;
1361 info_array[i++] = arm->act_bone->name;
1362 }
1363 }
1364 }
1365 }
1366 else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVES_LEGACY)) {
1367 /* Try to display active bone and active shape-key too (if they exist). */
1368
1369 if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
1371 if (armobj && armobj->mode & OB_MODE_POSE) {
1372 bArmature *arm = static_cast<bArmature *>(armobj->data);
1373 if (arm->act_bone) {
1375 info_array[i++] = msg_sep;
1376 info_array[i++] = arm->act_bone->name;
1377 }
1378 }
1379 }
1380 }
1381
1382 Key *key = BKE_key_from_object(ob);
1383 if (key) {
1384 KeyBlock *kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
1385 if (kb) {
1386 info_array[i++] = msg_sep;
1387 info_array[i++] = kb->name;
1388 if (ob->shapeflag & OB_SHAPE_LOCK) {
1389 info_array[i++] = IFACE_(msg_pin);
1390 }
1391 }
1392 }
1393 }
1394
1395 /* color depends on whether there is a keyframe */
1396 if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_ctime_get(scene) */ float(cfra))) {
1398 }
1399 }
1400
1401 if (markern) {
1402 info_array[i++] = " <";
1403 info_array[i++] = markern;
1404 info_array[i++] = ">";
1405 }
1406
1407 if (v3d->flag2 & V3D_SHOW_VIEWER) {
1409 info_array[i++] = IFACE_(" (Viewer)");
1410 }
1411 }
1412
1413 BLI_assert(i < int(ARRAY_SIZE(info_array)));
1414 char info[300];
1415 /* It's expected there will be enough room for the buffer (if not, increase it). */
1416 BLI_assert(BLI_string_len_array(info_array, i) < sizeof(info));
1417 BLI_string_join_array(info, sizeof(info), info_array, i);
1418
1419 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
1420 BLF_draw_default(xoffset, *yoffset, 0.0f, info, sizeof(info));
1421}
1422
1424 Scene *scene, ARegion *region, View3D *v3d, int xoffset, int *yoffset)
1425{
1426 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1427 if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
1428 const char *grid_unit = nullptr;
1429 ED_view3d_grid_view_scale(scene, v3d, region, &grid_unit);
1430
1431 if (grid_unit) {
1432 char numstr[32] = "";
1433 if (v3d->grid != 1.0f) {
1434 SNPRINTF(numstr, "%s " BLI_STR_UTF8_MULTIPLICATION_SIGN " %.4g", grid_unit, v3d->grid);
1435 }
1436
1437 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
1438 BLF_draw_default(xoffset, *yoffset, 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr));
1439 }
1440 }
1441}
1442
1444{
1445 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1446 View3D *v3d = CTX_wm_view3d(C);
1447 Scene *scene = CTX_data_scene(C);
1449 Main *bmain = CTX_data_main(C);
1450 ViewLayer *view_layer = CTX_data_view_layer(C);
1451
1452#ifdef WITH_INPUT_NDOF
1453 if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) &&
1454 (rv3d->persp != RV3D_CAMOB))
1455 {
1456 /* TODO: draw something else (but not this) during fly mode */
1457 draw_rotation_guide(rv3d);
1458 }
1459#endif
1460
1461 /* correct projection matrix */
1462 ED_region_pixelspace(region);
1463
1464 /* local coordinate visible rect inside region, to accommodate overlapping ui */
1465 const rcti *rect = ED_region_visible_rect(region);
1466
1467 view3d_draw_border(C, region);
1469
1471
1473 /* pass */
1474 }
1475 else {
1476 switch ((eUserpref_MiniAxisType)U.mini_axis_type) {
1478 /* The gizmo handles its own drawing. */
1479 break;
1481 draw_view_axis(rv3d, rect);
1483 break;
1484 }
1485 }
1486
1487 if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) {
1488 int xoffset = rect->xmin + (0.5f * U.widget_unit);
1489 int yoffset = rect->ymax - (0.1f * U.widget_unit);
1490
1491 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
1492 UI_fontstyle_set(fstyle);
1493 BLF_default_size(fstyle->points);
1495
1496 const int font_id = BLF_default();
1497 float text_color[4], shadow_color[4];
1498 ED_view3d_text_colors_get(scene, v3d, text_color, shadow_color);
1499 BLF_color4fv(font_id, text_color);
1500 BLF_enable(font_id, BLF_SHADOW);
1501 BLF_shadow_offset(font_id, 0, 0);
1502 BLF_shadow(font_id, FontShadowType::Outline, shadow_color);
1503
1504 if ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
1505 if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
1506 ED_scene_draw_fps(scene, xoffset, &yoffset);
1507 BLF_color4fv(font_id, text_color);
1508 }
1509 else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
1510 draw_viewport_name(region, v3d, xoffset, &yoffset);
1511 }
1512
1513 if (U.uiflag & USER_DRAWVIEWINFO) {
1514 BKE_view_layer_synced_ensure(scene, view_layer);
1515 Object *ob = BKE_view_layer_active_object_get(view_layer);
1516 draw_selected_name(v3d, scene, view_layer, ob, xoffset, &yoffset);
1517 BLF_color4fv(font_id, text_color);
1518 }
1519
1521 /* draw below the viewport name */
1522 draw_grid_unit_name(scene, region, v3d, xoffset, &yoffset);
1523 }
1524
1526 }
1527
1528 if (v3d->overlay.flag & V3D_OVERLAY_STATS) {
1529 View3D *v3d_local = v3d->localvd ? v3d : nullptr;
1531 bmain, scene, view_layer, v3d_local, xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT);
1532 }
1533
1534 /* Set the size back to the default hard-coded size. Otherwise anyone drawing after this,
1535 * without setting explicit size, will draw with widget size. That is probably ideal,
1536 * but size should be set at the calling site not just carried over from here. */
1538 BLF_disable(font_id, BLF_SHADOW);
1539 }
1540
1542}
1543
1546/* -------------------------------------------------------------------- */
1550static void view3d_draw_view(const bContext *C, ARegion *region)
1551{
1553 CTX_wm_window(C),
1555 CTX_data_scene(C),
1556 region,
1557 CTX_wm_view3d(C),
1558 nullptr,
1559 nullptr,
1560 nullptr);
1561
1562 /* Only 100% compliant on new spec goes below */
1563 DRW_draw_view(C);
1564}
1565
1567{
1568 /*
1569 * Temporary viewport draw modes until we have a proper system.
1570 * all modes are done in the draw manager, except external render
1571 * engines like Cycles.
1572 */
1573 RenderEngineType *type = RE_engines_find(scene->r.engine);
1574 if (drawtype == OB_MATERIAL && (type->flag & RE_USE_EEVEE_VIEWPORT)) {
1576 }
1577 return type;
1578}
1579
1581{
1582 View3D *v3d = CTX_wm_view3d(C);
1583 WorkSpace *workspace = CTX_wm_workspace(C);
1584 /* Always use viewer path from workspace, pinning is not supported currently. */
1585 if (!BKE_viewer_path_equal(&v3d->viewer_path, &workspace->viewer_path)) {
1587 BKE_viewer_path_copy(&v3d->viewer_path, &workspace->viewer_path);
1588 }
1589}
1590
1592{
1593 using namespace blender::draw;
1594 Main *bmain = CTX_data_main(C);
1595 View3D *v3d = CTX_wm_view3d(C);
1596
1598 view3d_draw_view(C, region);
1599
1600 DRW_cache_free_old_subdiv();
1604
1605 /* No depth test for drawing action zones afterwards. */
1607
1608 v3d->runtime.flag &= ~V3D_RUNTIME_DEPTHBUF_OVERRIDDEN;
1609 /* TODO: Clear cache? */
1610}
1611
1614/* -------------------------------------------------------------------- */
1619 const Scene *scene,
1620 View3D *v3d,
1621 ARegion *region,
1622 const float winmat[4][4],
1623 const char *viewname)
1624{
1625 /* update the viewport matrices with the new camera */
1626 if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
1627 float viewmat[4][4];
1628 const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
1629
1630 BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
1631 view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
1632 }
1633 else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
1634 float viewmat[4][4];
1635 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
1636
1637 BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
1638 view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
1639 }
1640}
1641
1643 const Scene *scene,
1644 eDrawType drawtype,
1645 View3D *v3d,
1646 ARegion *region,
1647 int winx,
1648 int winy,
1649 const float viewmat[4][4],
1650 const float winmat[4][4],
1651 bool is_image_render,
1652 bool draw_background,
1653 const char *viewname,
1654 const bool do_color_management,
1655 const bool restore_rv3d_mats,
1656 GPUOffScreen *ofs,
1657 GPUViewport *viewport)
1658{
1659 using namespace blender::draw;
1660 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1661 RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype);
1662
1663 /* Store `orig` variables. */
1664 struct {
1665 bThemeState theme_state;
1666
1667 /* #View3D */
1668 eDrawType v3d_shading_type;
1669
1670 /* #Region */
1671 int region_winx, region_winy;
1672 rcti region_winrct;
1673
1674 /* #RegionView3D */
1679 RV3DMatrixStore *rv3d_mats;
1680 } orig{};
1681 orig.v3d_shading_type = eDrawType(v3d->shading.type);
1682 orig.region_winx = region->winx;
1683 orig.region_winy = region->winy;
1684 orig.region_winrct = region->winrct;
1685 orig.rv3d_mats = ED_view3d_mats_rv3d_backup(static_cast<RegionView3D *>(region->regiondata));
1686
1687 UI_Theme_Store(&orig.theme_state);
1689
1690 /* Set temporary new size. */
1691 region->winx = winx;
1692 region->winy = winy;
1693 region->winrct.xmin = 0;
1694 region->winrct.ymin = 0;
1695 region->winrct.xmax = winx;
1696 region->winrct.ymax = winy;
1697
1698 /* There are too many functions inside the draw manager that check the shading type,
1699 * so use a temporary override instead. */
1700 v3d->shading.type = drawtype;
1701
1702 /* Set flags. */
1704
1705 {
1706 /* Free images which can have changed on frame-change.
1707 * WARNING(@ideasman42): can be slow so only free animated images. */
1709 }
1710
1715
1716 if ((viewname != nullptr && viewname[0] != '\0') && (viewmat == nullptr) &&
1717 rv3d->persp == RV3D_CAMOB && v3d->camera)
1718 {
1719 view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, region, winmat, viewname);
1720 }
1721 else {
1722 view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
1723 }
1724
1725 if (viewport) {
1726 GPU_viewport_tag_update(viewport);
1727 }
1728
1729 /* main drawing call */
1731 engine_type,
1732 region,
1733 v3d,
1734 is_image_render,
1736 do_color_management,
1737 ofs,
1738 viewport);
1739 DRW_cache_free_old_subdiv();
1742
1743 /* Restore all `orig` members. */
1744 region->winx = orig.region_winx;
1745 region->winy = orig.region_winy;
1746 region->winrct = orig.region_winrct;
1747
1748 /* Optionally do _not_ restore rv3d matrices (e.g. they are used/stored in the ImBuff for
1749 * reprojection, see texture_paint_image_from_view_exec(). */
1750 if (restore_rv3d_mats) {
1751 ED_view3d_mats_rv3d_restore(static_cast<RegionView3D *>(region->regiondata), orig.rv3d_mats);
1752 }
1753 MEM_freeN(orig.rv3d_mats);
1754
1755 UI_Theme_Restore(&orig.theme_state);
1756
1757 v3d->shading.type = orig.v3d_shading_type;
1758
1759 G.f &= ~G_FLAG_RENDER_VIEWPORT;
1760}
1761
1763 Scene *scene,
1764 View3DShading *shading_override,
1765 eDrawType drawtype,
1766 int object_type_exclude_viewport_override,
1767 int object_type_exclude_select_override,
1768 int winx,
1769 int winy,
1770 uint draw_flags,
1771 const float viewmat[4][4],
1772 const float winmat[4][4],
1773 float clip_start,
1774 float clip_end,
1775 bool is_xr_surface,
1776 bool is_image_render,
1777 bool draw_background,
1778 const char *viewname,
1779 const bool do_color_management,
1780 GPUOffScreen *ofs,
1781 GPUViewport *viewport)
1782{
1783 View3D v3d = blender::dna::shallow_zero_initialize();
1784 ARegion ar = {nullptr};
1785 RegionView3D rv3d = {{{0}}};
1786
1787 v3d.regionbase.first = v3d.regionbase.last = &ar;
1788 ar.regiondata = &rv3d;
1790
1791 View3DShading *source_shading_settings = &scene->display.shading;
1792 if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != nullptr) {
1793 source_shading_settings = shading_override;
1794 }
1795 memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
1796 v3d.shading.type = drawtype;
1797
1798 if (shading_override) {
1799 /* Pass. */
1800 }
1801 else if (drawtype == OB_MATERIAL) {
1803 }
1804
1807 }
1808 else {
1809 if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) {
1811 }
1812 if (draw_flags & V3D_OFSDRAW_SHOW_GRIDFLOOR) {
1814 v3d.grid = 1.0f;
1815 v3d.gridlines = 16;
1816 v3d.gridsubdiv = 10;
1817 }
1818 if (draw_flags & V3D_OFSDRAW_SHOW_SELECTION) {
1819 v3d.flag |= V3D_SELECT_OUTLINE;
1820 }
1821 if (draw_flags & V3D_OFSDRAW_XR_SHOW_CONTROLLERS) {
1823 }
1824 if (draw_flags & V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS) {
1826 }
1827 if (draw_flags & V3D_OFSDRAW_XR_SHOW_PASSTHROUGH) {
1829 }
1830 /* Disable other overlays (set all available _HIDE_ flags). */
1833 if ((draw_flags & V3D_OFSDRAW_SHOW_OBJECT_EXTRAS) == 0) {
1835 }
1836 if ((object_type_exclude_viewport_override & (1 << OB_ARMATURE)) != 0) {
1838 }
1839 v3d.flag |= V3D_HIDE_HELPLINES;
1840 }
1841
1842 if (is_xr_surface) {
1844 }
1845
1846 v3d.object_type_exclude_viewport = object_type_exclude_viewport_override;
1847 v3d.object_type_exclude_select = object_type_exclude_select_override;
1848
1849 rv3d.persp = RV3D_PERSP;
1850 v3d.clip_start = clip_start;
1851 v3d.clip_end = clip_end;
1852 /* Actually not used since we pass in the projection matrix. */
1853 v3d.lens = 0;
1854
1855 /* WORKAROUND: Disable overscan because it is not supported for arbitrary input matrices.
1856 * The proper fix to this would be to support arbitrary matrices in `eevee::Camera::sync()`. */
1857 float overscan = scene->eevee.overscan;
1858 scene->eevee.overscan = 0.0f;
1859
1861 scene,
1862 drawtype,
1863 &v3d,
1864 &ar,
1865 winx,
1866 winy,
1867 viewmat,
1868 winmat,
1869 is_image_render,
1871 viewname,
1872 do_color_management,
1873 true,
1874 ofs,
1875 viewport);
1876
1877 /* Restore overscan. */
1878 scene->eevee.overscan = overscan;
1879}
1880
1882 Scene *scene,
1883 eDrawType drawtype,
1884 View3D *v3d,
1885 ARegion *region,
1886 int sizex,
1887 int sizey,
1888 eImBufFlags imbuf_flag,
1889 int alpha_mode,
1890 const char *viewname,
1891 const bool restore_rv3d_mats,
1892 GPUOffScreen *ofs,
1893 GPUViewport *viewport,
1894 /* output vars */
1895 char err_out[256])
1896{
1897 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1898 const bool draw_sky = (alpha_mode == R_ADDSKY);
1899
1900 /* view state */
1901 bool is_ortho = false;
1902 float winmat[4][4];
1903
1904 /* Guess format based on output buffer. */
1905 eGPUTextureFormat desired_format = (imbuf_flag & IB_rectfloat) ? GPU_RGBA16F : GPU_RGBA8;
1906
1907 if (ofs && ((GPU_offscreen_width(ofs) != sizex) || (GPU_offscreen_height(ofs) != sizey))) {
1908 /* If offscreen has already been created, recreate with the same format. */
1909 desired_format = GPU_offscreen_format(ofs);
1910 /* sizes differ, can't reuse */
1911 ofs = nullptr;
1912 }
1913
1914 GPUFrameBuffer *old_fb = GPU_framebuffer_active_get();
1915
1916 if (old_fb) {
1918 }
1919
1920 const bool own_ofs = (ofs == nullptr);
1922
1923 if (own_ofs) {
1924 /* bind */
1925 ofs = GPU_offscreen_create(sizex,
1926 sizey,
1927 true,
1928 desired_format,
1930 err_out);
1931 if (ofs == nullptr) {
1933 return nullptr;
1934 }
1935 }
1936
1937 GPU_offscreen_bind(ofs, true);
1938
1939 /* read in pixels & stamp */
1940 ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, imbuf_flag);
1941
1942 /* render 3d view */
1943 if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
1945 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
1946 const Object *camera_eval = DEG_get_evaluated_object(depsgraph, camera);
1947
1949 /* fallback for non camera objects */
1950 params.clip_start = v3d->clip_start;
1951 params.clip_end = v3d->clip_end;
1953 BKE_camera_multiview_params(&scene->r, &params, camera_eval, viewname);
1954 BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
1956
1957 is_ortho = params.is_ortho;
1958 copy_m4_m4(winmat, params.winmat);
1959 }
1960 else {
1961 rctf viewplane;
1962 float clip_start, clipend;
1963
1964 is_ortho = ED_view3d_viewplane_get(
1965 depsgraph, v3d, rv3d, sizex, sizey, &viewplane, &clip_start, &clipend, nullptr);
1966 if (is_ortho) {
1967 orthographic_m4(winmat,
1968 viewplane.xmin,
1969 viewplane.xmax,
1970 viewplane.ymin,
1971 viewplane.ymax,
1972 -clipend,
1973 clipend);
1974 }
1975 else {
1976 perspective_m4(winmat,
1977 viewplane.xmin,
1978 viewplane.xmax,
1979 viewplane.ymin,
1980 viewplane.ymax,
1981 clip_start,
1982 clipend);
1983 }
1984 }
1985
1986 /* XXX(jbakker): `do_color_management` should be controlled by the caller. Currently when doing a
1987 * viewport render animation and saving to an 8bit file format, color management would be applied
1988 * twice. Once here, and once when saving the saving to disk. In this case the Save As Render
1989 * option cannot be controlled either. But when doing an off-screen render you want to do the
1990 * color management here.
1991 *
1992 * This option was added here to increase the performance for quick view-port preview renders.
1993 * When using workbench the color differences haven't been reported as a bug. But users also use
1994 * the viewport rendering to render Eevee scenes. In the later situation the saved colors are
1995 * totally wrong. */
1996 const bool do_color_management = (ibuf->float_buffer.data == nullptr);
1998 scene,
1999 drawtype,
2000 v3d,
2001 region,
2002 sizex,
2003 sizey,
2004 nullptr,
2005 winmat,
2006 true,
2007 draw_sky,
2008 viewname,
2009 do_color_management,
2010 restore_rv3d_mats,
2011 ofs,
2012 viewport);
2013
2014 if (ibuf->float_buffer.data) {
2016 }
2017 else if (ibuf->byte_buffer.data) {
2019 }
2020
2021 /* unbind */
2022 GPU_offscreen_unbind(ofs, true);
2023
2024 if (own_ofs) {
2025 GPU_offscreen_free(ofs);
2026 }
2027
2029
2030 if (old_fb) {
2031 GPU_framebuffer_bind(old_fb);
2032 }
2033
2034 if (ibuf->float_buffer.data && ibuf->byte_buffer.data) {
2035 IMB_rect_from_float(ibuf);
2036 }
2037
2038 return ibuf;
2039}
2040
2042 Scene *scene,
2043 View3DShading *shading_override,
2044 eDrawType drawtype,
2045 Object *camera,
2046 int width,
2047 int height,
2048 eImBufFlags imbuf_flag,
2049 eV3DOffscreenDrawFlag draw_flags,
2050 int alpha_mode,
2051 const char *viewname,
2052 GPUOffScreen *ofs,
2053 GPUViewport *viewport,
2054 char err_out[256])
2055{
2056 View3D v3d = blender::dna::shallow_zero_initialize();
2057 ARegion region = {nullptr};
2058 RegionView3D rv3d = {{{0}}};
2059
2060 /* connect data */
2061 v3d.regionbase.first = v3d.regionbase.last = &region;
2062 region.regiondata = &rv3d;
2063 region.regiontype = RGN_TYPE_WINDOW;
2064
2065 v3d.camera = camera;
2066 View3DShading *source_shading_settings = &scene->display.shading;
2067 if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != nullptr) {
2068 source_shading_settings = shading_override;
2069 }
2070 memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
2071
2072 if (drawtype == OB_RENDER) {
2073 /* Don't use external engines for preview. Fall back to solid instead of Eevee as rendering
2074 * with Eevee is potentially slow due to compiling shaders and loading textures, and the
2075 * depsgraph may not have been updated to have all the right geometry attributes. */
2077 drawtype = OB_SOLID;
2078 }
2079 }
2080
2081 if (drawtype == OB_MATERIAL) {
2084 }
2085 else if (drawtype == OB_RENDER) {
2088 }
2089 else if (drawtype == OB_TEXTURE) {
2090 drawtype = OB_SOLID;
2093 }
2094 v3d.shading.type = drawtype;
2095
2097 /* HACK: When rendering gpencil objects this opacity is used to mix vertex colors in when not in
2098 * render mode (e.g. in the sequencer). */
2100
2101 /* Also initialize wire-frame properties to the default so it renders properly in sequencer.
2102 * Should find some way to use the viewport's current opacity and threshold,
2103 * but this is a start. */
2104 v3d.overlay.wireframe_opacity = 1.0f;
2105 v3d.overlay.wireframe_threshold = 0.5f;
2106
2107 if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) {
2109 }
2110 if (draw_flags & V3D_OFSDRAW_SHOW_GRIDFLOOR) {
2112 }
2113
2115
2116 rv3d.persp = RV3D_CAMOB;
2117
2118 copy_m4_m4(rv3d.viewinv, v3d.camera->object_to_world().ptr());
2119 normalize_m4(rv3d.viewinv);
2120 invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
2121
2122 {
2124 const Object *view_camera_eval = DEG_get_evaluated_object(
2125 depsgraph, BKE_camera_multiview_render(scene, v3d.camera, viewname));
2126
2128 BKE_camera_params_from_object(&params, view_camera_eval);
2129 BKE_camera_multiview_params(&scene->r, &params, view_camera_eval, viewname);
2130 BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
2132
2133 copy_m4_m4(rv3d.winmat, params.winmat);
2134 v3d.clip_start = params.clip_start;
2135 v3d.clip_end = params.clip_end;
2136 v3d.lens = params.lens;
2137 }
2138
2139 mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
2140 invert_m4_m4(rv3d.persinv, rv3d.viewinv);
2141
2143 scene,
2144 eDrawType(v3d.shading.type),
2145 &v3d,
2146 &region,
2147 width,
2148 height,
2149 imbuf_flag,
2150 alpha_mode,
2151 viewname,
2152 true,
2153 ofs,
2154 viewport,
2155 err_out);
2156}
2157
2162
2165/* -------------------------------------------------------------------- */
2169static bool view3d_clipping_test(const float co[3], const float clip[6][4])
2170{
2171 if (plane_point_side_v3(clip[0], co) > 0.0f && plane_point_side_v3(clip[1], co) > 0.0f &&
2172 plane_point_side_v3(clip[2], co) > 0.0f && plane_point_side_v3(clip[3], co) > 0.0f)
2173 {
2174 return false;
2175 }
2176 return true;
2177}
2178
2179bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
2180{
2181 return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
2182}
2183
2186/* -------------------------------------------------------------------- */
2194 const Scene *scene,
2195 ViewLayer *view_layer,
2196 ARegion *region,
2197 View3D *v3d,
2198 Object *obact)
2199{
2200 /* TODO: Use a flag in the selection engine itself. */
2202 return;
2203 }
2204 Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
2205
2206 BLI_assert(region->regiontype == RGN_TYPE_WINDOW);
2207 UNUSED_VARS_NDEBUG(region);
2208
2209 if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
2210 BKE_paint_select_face_test(obact_eval)))
2211 {
2212 /* do nothing */
2213 }
2214 /* texture paint mode sampling */
2215 else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) &&
2216 (v3d->shading.type > OB_WIRE))
2217 {
2218 /* do nothing */
2219 }
2220 else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) {
2221 /* do nothing */
2222 }
2223 else {
2225 return;
2226 }
2227
2228 if (obact_eval && ((obact_eval->base_flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0)) {
2229 BKE_view_layer_synced_ensure(scene, view_layer);
2230 Base *base = BKE_view_layer_base_find(view_layer, obact);
2232 }
2233
2235}
2236
2237/* Avoid calling this function multiple times in sequence to prevent frequent CPU-GPU
2238 * synchronization (which can be very slow). */
2239static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
2240{
2241 GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
2242
2243 GPUFrameBuffer *depth_read_fb = nullptr;
2244 GPU_framebuffer_ensure_config(&depth_read_fb,
2245 {
2246 GPU_ATTACHMENT_TEXTURE(depth_tx),
2248 });
2249
2250 GPU_framebuffer_bind(depth_read_fb);
2251 GPU_framebuffer_read_depth(depth_read_fb,
2252 rect->xmin,
2253 rect->ymin,
2254 BLI_rcti_size_x(rect),
2255 BLI_rcti_size_y(rect),
2257 data);
2258
2260 GPU_framebuffer_free(depth_read_fb);
2261}
2262
2264{
2266 vc->depsgraph, vc->scene, vc->view_layer, vc->region, vc->v3d, vc->obact);
2267}
2268
2269int ED_view3d_backbuf_sample_size_clamp(ARegion *region, const float dist)
2270{
2271 return int(min_ff(ceilf(dist), float(max_ii(region->winx, region->winx))));
2272}
2273
2276/* -------------------------------------------------------------------- */
2281{
2282 /* clamp rect by region */
2283 rcti r{};
2284 r.xmin = 0;
2285 r.xmax = region->winx - 1;
2286 r.ymin = 0;
2287 r.ymax = region->winy - 1;
2288
2289 /* Constrain rect to depth bounds */
2290 BLI_rcti_isect(&r, rect, rect);
2291
2292 /* assign values to compare with the ViewDepths */
2293 int x = rect->xmin;
2294 int y = rect->ymin;
2295
2296 int w = BLI_rcti_size_x(rect);
2297 int h = BLI_rcti_size_y(rect);
2298
2299 if (w <= 0 || h <= 0) {
2300 r_d->depths = nullptr;
2301 return;
2302 }
2303
2304 r_d->x = x;
2305 r_d->y = y;
2306 r_d->w = w;
2307 r_d->h = h;
2308
2309 r_d->depths = static_cast<float *>(MEM_mallocN(sizeof(float) * w * h, "View depths Subset"));
2310
2311 {
2312 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2313 view3d_opengl_read_Z_pixels(viewport, rect, r_d->depths);
2314 /* Range is assumed to be this as they are never changed. */
2315 r_d->depth_range[0] = 0.0;
2316 r_d->depth_range[1] = 1.0;
2317 }
2318}
2319
2320/* NOTE: with NOUVEAU drivers the #glReadPixels() is very slow. #24339. */
2322{
2323 ViewDepths *d = MEM_cnew<ViewDepths>("ViewDepths");
2324
2325 {
2326 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2327 GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
2328 uint32_t *int_depths = static_cast<uint32_t *>(
2329 GPU_texture_read(depth_tx, GPU_DATA_UINT_24_8, 0));
2330 d->w = GPU_texture_width(depth_tx);
2331 d->h = GPU_texture_height(depth_tx);
2332 d->depths = (float *)int_depths;
2333 /* Convert in-place. */
2334 int pixel_count = d->w * d->h;
2335 for (int i = 0; i < pixel_count; i++) {
2336 d->depths[i] = (int_depths[i] >> 8u) / float(0xFFFFFF);
2337 }
2338 /* Assumed to be this as they are never changed. */
2339 d->depth_range[0] = 0.0;
2340 d->depth_range[1] = 1.0;
2341 }
2342 return d;
2343}
2344
2346{
2347 /* Convert to float for comparisons. */
2348 const float near = float(d->depth_range[0]);
2349 const float far_real = float(d->depth_range[1]);
2350 float far = far_real;
2351
2352 const float *depths = d->depths;
2353 float depth = FLT_MAX;
2354 int i = int(d->w) * int(d->h); /* Cast to avoid short overflow. */
2355
2356 /* Far is both the starting 'far' value
2357 * and the closest value found. */
2358 while (i--) {
2359 depth = *depths++;
2360 if ((depth < far) && (depth > near)) {
2361 far = depth;
2362 }
2363 }
2364
2365 return far == far_real ? FLT_MAX : far;
2366}
2367
2369 ARegion *region,
2370 View3D *v3d,
2371 Object *obact,
2373 ViewDepths **r_depths)
2374{
2376 /* Force redraw if `r_depths` is required. */
2377 if (!r_depths || *r_depths != nullptr) {
2378 return;
2379 }
2380 }
2381 bThemeState theme_state;
2383 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2384
2385 short flag = v3d->flag;
2386 /* temp set drawtype to solid */
2387 /* Setting these temporarily is not nice */
2388 v3d->flag &= ~V3D_SELECT_OUTLINE;
2389
2390 /* Tools may request depth outside of regular drawing code. */
2391 UI_Theme_Store(&theme_state);
2393
2394 ED_view3d_draw_setup_view(static_cast<wmWindowManager *>(G_MAIN->wm.first),
2395 nullptr,
2396 depsgraph,
2397 scene,
2398 region,
2399 v3d,
2400 nullptr,
2401 nullptr,
2402 nullptr);
2403
2404 /* get surface depth without bias */
2406
2407 /* Needed in cases the 3D Viewport isn't already setup. */
2410
2411 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2412 /* When Blender is starting, a click event can trigger a depth test while the viewport is not
2413 * yet available. */
2414 if (viewport != nullptr) {
2415 switch (mode) {
2417 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, true, true, false, false);
2418 break;
2420 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, false, true, false, false);
2421 break;
2423 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, true, false, false, false);
2424 break;
2427 scene, region, v3d, viewport, DEG_get_evaluated_object(depsgraph, obact));
2428 break;
2430 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, false, true, false, true);
2431 break;
2432 }
2433
2434 if (r_depths) {
2435 if (*r_depths) {
2436 ED_view3d_depths_free(*r_depths);
2437 }
2438 *r_depths = view3d_depths_create(region);
2439 }
2440 }
2441
2443
2444 rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
2445
2446 v3d->flag = flag;
2448
2449 UI_Theme_Restore(&theme_state);
2450}
2451
2453{
2454 if (depths->depths) {
2455 MEM_freeN(depths->depths);
2456 }
2457 MEM_freeN(depths);
2458}
2459
2460bool ED_view3d_has_depth_buffer_updated(const Depsgraph *depsgraph, const View3D *v3d)
2461{
2462#ifdef REUSE_DEPTH_BUFFER
2463 /* Check if the depth buffer was drawn by any engine and thus can be reused.
2464 *
2465 * The idea is good, but it is too error prone.
2466 * Even when updated by an engine, the depth buffer can still be cleared by drawing callbacks and
2467 * by the GPU_select API used by gizmos.
2468 * Check #GPU_clear_depth to track when the depth buffer is cleared. */
2469 const char *engine_name = DEG_get_evaluated_scene(depsgraph)->r.engine;
2470 RenderEngineType *engine_type = RE_engines_find(engine_name);
2471
2472 bool is_viewport_wire_no_xray = v3d->shading.type < OB_SOLID && !XRAY_ENABLED(v3d);
2473 bool is_viewport_preview_solid = v3d->shading.type == OB_SOLID;
2474 bool is_viewport_preview_material = v3d->shading.type == OB_MATERIAL;
2475 bool is_viewport_render_eevee = v3d->shading.type == OB_RENDER &&
2476 (STREQ(engine_name, RE_engine_id_BLENDER_EEVEE_NEXT));
2477 bool is_viewport_render_workbench = v3d->shading.type == OB_RENDER &&
2479 bool is_viewport_render_external_with_overlay = v3d->shading.type == OB_RENDER &&
2480 !(engine_type->flag & RE_INTERNAL) &&
2481 !(v3d->flag2 & V3D_HIDE_OVERLAYS);
2482
2483 return is_viewport_preview_solid || is_viewport_preview_material || is_viewport_wire_no_xray ||
2484 is_viewport_render_eevee || is_viewport_render_workbench ||
2485 is_viewport_render_external_with_overlay;
2486#else
2487 UNUSED_VARS(depsgraph, v3d);
2488 return false;
2489#endif
2490}
2491
2494/* -------------------------------------------------------------------- */
2498void ED_view3d_datamask(const Scene *scene,
2499 ViewLayer *view_layer,
2500 const View3D *v3d,
2501 CustomData_MeshMasks *r_cddata_masks)
2502{
2503 /* NOTE(@ideasman42): as this function runs continuously while idle
2504 * (from #wm_event_do_depsgraph) take care to avoid expensive lookups.
2505 * While they won't hurt performance noticeably, they will increase CPU usage while idle. */
2508 r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
2509 }
2510 else if (v3d->shading.type == OB_SOLID) {
2512 r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2;
2513 }
2515 r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR;
2516 r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
2517 }
2518 }
2519
2520 BKE_view_layer_synced_ensure(scene, view_layer);
2521 Object *obact = BKE_view_layer_active_object_get(view_layer);
2522 if (obact) {
2523 switch (obact->type) {
2524 case OB_MESH: {
2525 switch (obact->mode) {
2526 case OB_MODE_EDIT: {
2528 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
2529 }
2530 break;
2531 }
2532 }
2533 break;
2534 }
2535 }
2536 }
2537}
2538
2540 ViewLayer *view_layer,
2541 const bScreen *screen,
2542 CustomData_MeshMasks *r_cddata_masks)
2543{
2545
2546 /* Check if we need UV or color data due to the view mode. */
2547 LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
2548 if (area->spacetype == SPACE_VIEW3D) {
2550 scene, view_layer, static_cast<View3D *>(area->spacedata.first), r_cddata_masks);
2551 }
2552 }
2553}
2554
2557/* -------------------------------------------------------------------- */
2569 float winmat[4][4];
2570 float viewmat[4][4];
2571 float viewinv[4][4];
2572 float persmat[4][4];
2573 float persinv[4][4];
2575 float pixsize;
2576};
2577
2579{
2580 RV3DMatrixStore *rv3dmat = static_cast<RV3DMatrixStore *>(
2581 MEM_mallocN(sizeof(*rv3dmat), __func__));
2582 copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
2583 copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
2584 copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
2585 copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
2586 copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
2588 rv3dmat->pixsize = rv3d->pixsize;
2589 return rv3dmat;
2590}
2591
2593{
2594 RV3DMatrixStore *rv3dmat = rv3dmat_pt;
2595 copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
2596 copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
2597 copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
2598 copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
2599 copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
2601 rv3d->pixsize = rv3dmat->pixsize;
2602}
2603
2606/* -------------------------------------------------------------------- */
2610void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
2611{
2613 if (!ED_scene_fps_average_calc(scene, &state)) {
2614 return;
2615 }
2616
2617 /* 8 4-bytes chars (complex writing systems like Devanagari in UTF8 encoding) */
2618 char printable[32];
2619 printable[0] = '\0';
2620
2621 bool show_fractional = state.fps_target_is_fractional;
2622
2623 const int font_id = BLF_default();
2624
2625 /* Is this more than half a frame behind? */
2626 if (state.fps_average + 0.5f < state.fps_target) {
2627 /* Always show fractional when under performing. */
2628 show_fractional = true;
2629 BLF_color4ub(font_id, 225, 36, 36, 255);
2630 }
2631
2632 if (show_fractional) {
2633 SNPRINTF(printable, IFACE_("fps: %.2f"), state.fps_average);
2634 }
2635 else {
2636 SNPRINTF(printable, IFACE_("fps: %i"), int(state.fps_average + 0.5f));
2637 }
2638
2639 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
2640
2641 BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable));
2642}
2643
2646/* -------------------------------------------------------------------- */
2651{
2652 RenderEngineType *type = RE_engines_find(scene->r.engine);
2653 return (type && type->view_update && type->view_draw);
2654}
2655
2657 const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *region, rcti *r_rect)
2658{
2659 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2660 bool use_border;
2661
2662 /* Test if there is a 3d view rendering. */
2664 return false;
2665 }
2666
2667 /* Test if there is a border render. */
2668 if (rv3d->persp == RV3D_CAMOB) {
2669 use_border = (scene->r.mode & R_BORDER) != 0;
2670 }
2671 else {
2672 use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
2673 }
2674
2675 if (!use_border) {
2676 return false;
2677 }
2678
2679 /* Compute border. */
2680 if (rv3d->persp == RV3D_CAMOB) {
2681 rctf viewborder;
2682 ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, false, &viewborder);
2683
2684 r_rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
2685 r_rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
2686 r_rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
2687 r_rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
2688 }
2689 else {
2690 r_rect->xmin = v3d->render_border.xmin * region->winx;
2691 r_rect->xmax = v3d->render_border.xmax * region->winx;
2692 r_rect->ymin = v3d->render_border.ymin * region->winy;
2693 r_rect->ymax = v3d->render_border.ymax * region->winy;
2694 }
2695
2696 BLI_rcti_translate(r_rect, region->winrct.xmin, region->winrct.ymin);
2697 BLI_rcti_isect(&region->winrct, r_rect, r_rect);
2698
2699 return true;
2700}
2701
2704/* -------------------------------------------------------------------- */
2709{
2710 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2711 if (viewport == nullptr) {
2712 return false;
2713 }
2714
2715 GPUTexture *color_tex = GPU_viewport_color_texture(viewport, 0);
2716 if (color_tex == nullptr) {
2717 return false;
2718 }
2719
2720 tex_w = GPU_texture_width(color_tex);
2721 tex_h = GPU_texture_height(color_tex);
2722 BLI_rcti_init(&valid_rect, 0, min_ii(region->winx, tex_w) - 1, 0, min_ii(region->winy, tex_h));
2723
2724 /* Copying pixels from textures only works when HOST_READ usage is enabled on them.
2725 * However, doing so can have performance impact, which we don't want for the viewport.
2726 * So, instead allocate a separate texture with HOST_READ here, copy to it, and then
2727 * copy that back to the host.
2728 * Since color picking is a fairly rare operation, the inefficiency here doesn't really
2729 * matter, and it means the viewport doesn't need HOST_READ. */
2731 "copy_tex", tex_w, tex_h, 1, GPU_RGBA16F, GPU_TEXTURE_USAGE_HOST_READ, nullptr);
2732 if (tex == nullptr) {
2733 return false;
2734 }
2735
2736 GPU_texture_copy(tex, color_tex);
2738 data = static_cast<blender::ushort4 *>(GPU_texture_read(tex, GPU_DATA_HALF_FLOAT, 0));
2739
2740 return true;
2741}
2742
2743bool ViewportColorSampleSession::sample(const int mval[2], float r_col[3])
2744{
2745 if (tex == nullptr || data == nullptr) {
2746 return false;
2747 }
2748
2749 if (!BLI_rcti_isect_pt_v(&valid_rect, mval)) {
2750 return false;
2751 }
2752
2753 blender::ushort4 pixel = data[mval[1] * tex_w + mval[0]];
2754
2755 if (blender::math::half_to_float(pixel.w) < 0.5f) {
2756 /* Background etc. are not rendered to the viewport texture, so fall back to basic color
2757 * picking for those. */
2758 return false;
2759 }
2760
2761 r_col[0] = blender::math::half_to_float(pixel.x);
2762 r_col[1] = blender::math::half_to_float(pixel.y);
2763 r_col[2] = blender::math::half_to_float(pixel.z);
2764
2765 return true;
2766}
2767
2769{
2770 if (data != nullptr) {
2771 MEM_freeN(data);
2772 }
2773 if (tex != nullptr) {
2774 GPU_texture_free(tex);
2775 }
2776}
2777
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bonecoll_is_visible_actbone(const bArmature *armature)
Camera data-block and utility functions.
void BKE_camera_multiview_params(const struct RenderData *rd, struct CameraParams *params, const struct Object *camera, const char *viewname)
float BKE_camera_multiview_shift_x(const struct RenderData *rd, const struct Object *camera, const char *viewname)
struct Object * BKE_camera_multiview_render(const struct Scene *scene, struct Object *camera, const char *viewname)
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
void BKE_camera_params_init(CameraParams *params)
void BKE_camera_multiview_view_matrix(const struct RenderData *rd, const struct Object *camera, bool is_left, float r_viewmat[4][4])
void BKE_camera_params_from_view3d(CameraParams *params, const struct Depsgraph *depsgraph, const struct View3D *v3d, const struct RegionView3D *rv3d)
void BKE_camera_params_from_object(CameraParams *params, const struct Object *cam_ob)
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float aspx, float aspy)
void BKE_camera_params_compute_matrix(CameraParams *params)
const char * BKE_collection_ui_name_get(Collection *collection)
Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
WorkSpace * CTX_wm_workspace(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)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src)
Definition customdata.cc:91
const CustomData_MeshMasks CD_MASK_BAREMESH
@ G_FLAG_RENDER_VIEWPORT
#define G_MAIN
void BKE_image_free_anim_gputextures(Main *bmain)
Definition image_gpu.cc:570
void BKE_image_free_old_gputextures(Main *bmain)
Definition image_gpu.cc:581
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1820
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
LayerCollection * BKE_view_layer_active_collection_get(ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
General operations, lookup, etc. for blender objects.
Object * BKE_object_pose_armature_get(Object *ob)
bool BKE_paint_select_face_test(const Object *ob)
Definition paint.cc:1607
bool BKE_scene_multiview_is_stereo3d(const RenderData *rd)
Definition scene.cc:2959
bool BKE_scene_uses_blender_workbench(const Scene *scene)
Definition scene.cc:2777
bool BKE_scene_uses_blender_eevee(const Scene *scene)
Definition scene.cc:2771
const char * BKE_scene_find_marker_name(const Scene *scene, int frame)
Definition scene.cc:2228
void BKE_unit_system_get(int system, int type, const void **r_usys_pt, int *r_len)
Definition unit.cc:2477
const char * BKE_unit_display_name_get(const void *usys_pt, int index)
Definition unit.cc:2506
@ B_UNIT_LENGTH
Definition BKE_unit.hh:107
int BKE_unit_base_get(const void *usys_pt)
Definition unit.cc:2490
double BKE_unit_scalar_get(const void *usys_pt, int index)
Definition unit.cc:2523
void BKE_viewer_path_copy(ViewerPath *dst, const ViewerPath *src)
void BKE_viewer_path_clear(ViewerPath *viewer_path)
bool BKE_viewer_path_equal(const ViewerPath *a, const ViewerPath *b, ViewerPathEqualFlag flag=ViewerPathEqualFlag(0))
int BLF_set_default()
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4]=nullptr)
Definition blf.cc:902
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:488
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:914
void BLF_batch_draw_begin()
Definition blf.cc:517
void BLF_disable(int fontid, int option)
Definition blf.cc:321
int BLF_default()
void BLF_batch_draw_end()
Definition blf.cc:530
void BLF_default_size(float size)
void BLF_enable(int fontid, int option)
Definition blf.cc:312
@ BLF_SHADOW
Definition BLF_api.hh:363
void BLF_color4ubv(int fontid, const unsigned char rgba[4])
Definition blf.cc:435
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
void BLF_color4ub(int fontid, unsigned char r, unsigned char g, unsigned char b, unsigned char alpha)
Definition blf.cc:464
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define M_PI
void orthographic_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
void perspective_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void normalize_m4(float R[4][4]) ATTR_NONNULL()
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void mul_qt_v3(const float q[4], float r[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
void BLI_rcti_translate(struct rcti *rect, int x, int y)
Definition rct.c:560
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.c:418
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:197
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:201
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
#define BLI_STR_UTF8_MULTIPLICATION_SIGN
size_t BLI_string_join_array(char *result, size_t result_maxncpy, const char *strings[], uint strings_num) ATTR_NONNULL()
void size_t BLI_string_len_array(const char *strings[], uint strings_num) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
unsigned char uchar
unsigned int uint
void BLI_thread_unlock(int type)
Definition threads.cc:333
void BLI_thread_lock(int type)
Definition threads.cc:328
@ LOCK_VIEW3D
Definition BLI_threads.h:75
#define ARRAY_SIZE(arr)
#define UNUSED_VARS(...)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define STREQ(a, b)
#define IFACE_(msgid)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
ID * DEG_get_evaluated_id(const Depsgraph *depsgraph, ID *id)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ CAMERA_SENSOR_FIT_HOR
@ CAMERA_SENSOR_FIT_AUTO
@ CAM_DTX_GOLDEN_TRI_A
@ CAM_DTX_CENTER
@ CAM_DTX_HARMONY_TRI_A
@ CAM_DTX_GOLDEN
@ CAM_DTX_GOLDEN_TRI_B
@ CAM_DTX_HARMONY_TRI_B
@ CAM_DTX_CENTER_DIAG
@ CAM_DTX_THIRDS
@ CAM_SHOWPASSEPARTOUT
@ CAM_SHOW_SAFE_MARGINS
@ CAM_SHOW_SAFE_CENTER
@ CAM_SHOWNAME
@ CAM_SHOWSENSOR
@ CAM_PERSP
@ CAM_PANO
@ CAM_ORTHO
#define CD_MASK_PROP_BYTE_COLOR
#define CD_MASK_PROP_COLOR
#define CD_MASK_ORCO
#define CD_MASK_MDEFORMVERT
#define CD_MASK_PROP_FLOAT2
@ BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT
eDrawType
@ OB_WIRE
@ OB_TEXTURE
@ OB_SOLID
@ OB_RENDER
@ OB_MATERIAL
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_POSE
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_OBJECT
@ OB_MODE_VERTEX_PAINT
Object is a sort of wrapper for general info.
@ OB_SHAPE_LOCK
@ OB_LATTICE
@ OB_CAMERA
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
#define STEREO_LEFT_NAME
@ R_MULTIVIEW
@ R_ADDSKY
@ R_BORDER
@ SCE_VIEWS_FORMAT_STEREO_3D
@ SCE_VIEWS_FORMAT_MULTIVIEW
#define STEREO_RIGHT_NAME
@ STEREO_MONO_ID
@ STEREO_LEFT_ID
@ STEREO_RIGHT_ID
@ STEREO_3D_ID
@ SCE_PASS_COMBINED
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ USER_SHOW_VIEWPORTNAME
@ USER_DRAWVIEWINFO
@ USER_SHOW_FPS
@ NDOF_SHOW_GUIDE
eUserpref_MiniAxisType
@ USER_MINI_AXIS_TYPE_GIZMO
@ USER_MINI_AXIS_TYPE_MINIMAL
@ USER_MINI_AXIS_TYPE_NONE
eV3DOffscreenDrawFlag
@ V3D_OFSDRAW_NONE
@ V3D_OFSDRAW_SHOW_OBJECT_EXTRAS
@ V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS
@ V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS
@ V3D_OFSDRAW_SHOW_GRIDFLOOR
@ V3D_OFSDRAW_XR_SHOW_PASSTHROUGH
@ V3D_OFSDRAW_SHOW_ANNOTATION
@ V3D_OFSDRAW_SHOW_SELECTION
@ V3D_OFSDRAW_XR_SHOW_CONTROLLERS
@ V3D_SHADING_BACKGROUND_WORLD
@ V3D_SHADING_TEXTURE_COLOR
@ V3D_SHADING_VERTEX_COLOR
@ V3D_LIGHTING_STUDIO
#define RV3D_VIEW_IS_AXIS(view)
@ V3D_OVERLAY_EDIT_WEIGHT
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_ZOFFSET_DISABLED
@ RV3D_CLIPPING
@ V3D_RUNTIME_DEPTHBUF_OVERRIDDEN
@ V3D_OVERLAY_HIDE_OBJECT_ORIGINS
@ V3D_OVERLAY_HIDE_BONES
@ V3D_OVERLAY_HIDE_MOTION_PATHS
@ V3D_OVERLAY_HIDE_OBJECT_XTRAS
@ V3D_OVERLAY_HIDE_CURSOR
@ V3D_OVERLAY_HIDE_TEXT
@ V3D_OVERLAY_STATS
@ V3D_SHADING_SCENE_WORLD_RENDER
@ V3D_SHADING_SCENE_WORLD
@ V3D_SHADING_SCENE_LIGHTS
@ V3D_SHADING_SCENE_LIGHTS_RENDER
@ V3D_GIZMO_HIDE
@ V3D_GIZMO_HIDE_NAVIGATE
@ V3D_SHOW_FLOOR
@ V3D_SHOW_Z
@ V3D_SHOW_X
@ V3D_SHOW_Y
@ RV3D_VIEW_AXIS_ROLL_180
@ RV3D_VIEW_AXIS_ROLL_90
@ RV3D_VIEW_AXIS_ROLL_0
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
@ RV3D_LOCK_ROTATION
@ V3D_SHOW_VIEWER
@ V3D_SHOW_CAMERA_PASSEPARTOUT
@ V3D_XR_SHOW_CUSTOM_OVERLAYS
@ V3D_HIDE_OVERLAYS
@ V3D_SHOW_ANNOTATION
@ V3D_RENDER_BORDER
@ V3D_LOCK_CAMERA
@ V3D_SHOW_CAMERA_GUIDES
@ V3D_XR_SHOW_PASSTHROUGH
@ V3D_XR_SHOW_CONTROLLERS
@ V3D_XR_SESSION_SURFACE
@ V3D_SELECT_OUTLINE
@ V3D_HIDE_HELPLINES
@ RV3D_VIEW_FRONT
@ RV3D_VIEW_BOTTOM
@ RV3D_VIEW_LEFT
@ RV3D_VIEW_RIGHT
@ RV3D_VIEW_TOP
@ RV3D_VIEW_BACK
@ RV3D_VIEW_USER
void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
bool DRW_draw_in_progress()
void DRW_draw_view(const bContext *C)
void DRW_gpu_context_disable()
void DRW_cache_free_old_batches(Main *bmain)
void DRW_draw_render_loop_offscreen(Depsgraph *depsgraph, RenderEngineType *engine_type, ARegion *region, View3D *v3d, bool is_image_render, bool draw_background, bool do_color_management, GPUOffScreen *ofs, GPUViewport *viewport)
void DRW_draw_depth_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, GPUViewport *viewport, const bool use_gpencil, const bool use_basic, const bool use_overlay, const bool use_only_selected)
void DRW_gpu_context_enable()
void DRW_draw_depth_object(Scene *scene, ARegion *region, View3D *v3d, GPUViewport *viewport, Object *object)
void DRW_select_buffer_context_create(Depsgraph *depsgraph, blender::Span< Base * > bases, short select_mode)
void ED_info_draw_stats(Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d_local, int x, int *y, int height)
bool ED_scene_fps_average_calc(const Scene *scene, SceneFPS_State *r_state) ATTR_NONNULL(1
const rcti * ED_region_visible_rect(ARegion *region)
Definition area.cc:4010
bScreen * ED_screen_animation_no_scrub(const wmWindowManager *wm)
void ED_region_pixelspace(const ARegion *region)
Definition area.cc:121
#define XRAY_ENABLED(v3d)
eV3DDepthOverrideMode
Definition ED_view3d.hh:184
@ V3D_DEPTH_SELECTED_ONLY
Definition ED_view3d.hh:194
@ V3D_DEPTH_NO_GPENCIL
Definition ED_view3d.hh:188
@ V3D_DEPTH_NO_OVERLAYS
Definition ED_view3d.hh:186
@ V3D_DEPTH_GPENCIL_ONLY
Definition ED_view3d.hh:190
@ V3D_DEPTH_OBJECT_ONLY
Definition ED_view3d.hh:192
bool ED_view3d_viewplane_get(const Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, int winx, int winy, rctf *r_viewplane, float *r_clip_start, float *r_clip_end, float *r_pixsize)
void ED_view3d_text_colors_get(const Scene *scene, const View3D *v3d, float r_text_color[4], float r_shadow_color[4])
GPUOffScreen * GPU_offscreen_create(int width, int height, bool with_depth_buffer, eGPUTextureFormat format, eGPUTextureUsage usage, char err_out[256])
#define GPU_ATTACHMENT_TEXTURE(_texture)
GPUFrameBuffer * GPU_framebuffer_active_get()
int GPU_offscreen_width(const GPUOffScreen *offscreen)
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
void GPU_framebuffer_restore()
void GPU_framebuffer_read_depth(GPUFrameBuffer *framebuffer, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
#define GPU_ATTACHMENT_NONE
int GPU_offscreen_height(const GPUOffScreen *offscreen)
void GPU_offscreen_free(GPUOffScreen *offscreen)
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
eGPUTextureFormat GPU_offscreen_format(const GPUOffScreen *offscreen)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_offscreen_read_color(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data)
void GPU_framebuffer_free(GPUFrameBuffer *framebuffer)
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore)
void immUniform4f(const char *name, float x, float y, float z, float w)
void immUniformThemeColorAlpha(int color_id, float a)
void immEnd()
void immUnbindProgram()
void immUniform2f(const char *name, float x, float y)
void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset)
void immAttr4ubv(uint attr_id, const unsigned char data[4])
void immVertex2f(uint attr_id, float x, float y)
void immUniformThemeColor(int color_id)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
void immUniformColor3ubv(const unsigned char rgb[3])
void immUniform1i(const char *name, int x)
void immUniformThemeColor3(int color_id)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat()
void immUniformColor3f(float r, float g, float b)
void immUniform4fv(const char *name, const float data[4])
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void GPU_pass_cache_garbage_collect()
void GPU_matrix_identity_set()
#define GPU_matrix_set(x)
void GPU_matrix_push()
void GPU_matrix_push_projection()
void GPU_matrix_pop_projection()
#define GPU_matrix_projection_set(x)
void GPU_matrix_pop()
@ GPU_PRIM_LINE_LOOP
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINE_STRIP
@ GPU_SHADER_3D_SMOOTH_COLOR
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
@ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_3D_FLAT_COLOR
void GPU_memory_barrier(eGPUBarrier barrier)
Definition gpu_state.cc:374
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_line_width(float width)
Definition gpu_state.cc:161
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
@ GPU_BARRIER_TEXTURE_UPDATE
Definition GPU_state.hh:39
@ GPU_DEPTH_NONE
Definition GPU_state.hh:108
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:262
int GPU_texture_height(const GPUTexture *texture)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
int GPU_texture_width(const GPUTexture *texture)
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
void * GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
@ GPU_DATA_HALF_FLOAT
@ GPU_DATA_UINT_24_8
@ GPU_DATA_UBYTE
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_HOST_READ
eGPUTextureFormat
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_U8
GPUTexture * GPU_viewport_color_texture(GPUViewport *viewport, int view)
GPUTexture * GPU_viewport_depth_texture(GPUViewport *viewport)
void GPU_viewport_tag_update(GPUViewport *viewport)
void IMB_rect_from_float(ImBuf *ibuf)
Definition divers.cc:694
Contains defines and structs used throughout the imbuf module.
eImBufFlags
@ IB_rectfloat
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
@ RE_INTERNAL
Definition RE_engine.h:47
@ RE_USE_EEVEE_VIEWPORT
Definition RE_engine.h:50
#define UI_UNIT_Y
void UI_draw_safe_areas(uint pos, const rctf *rect, const float title_aspect[2], const float action_aspect[2])
void UI_fontstyle_set(const uiFontStyle *fs)
#define UI_FSTYLE_WIDGET
#define UI_DEFAULT_TEXT_POINTS
#define UI_UNIT_X
void UI_Theme_Store(bThemeState *theme_state)
void UI_Theme_Restore(const bThemeState *theme_state)
@ TH_TIME_KEYFRAME
@ TH_BACK
@ TH_REDALERT
@ TH_CAMERA_PASSEPARTOUT
@ TH_AXIS_X
@ TH_VIEW_OVERLAY
@ TH_TEXT_HI
void UI_FontThemeColor(int fontid, int colorid)
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3])
void UI_SetTheme(int spacetype, int regionid)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
unsigned int U
Definition btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
bool init(ARegion *region)
bool sample(const int mval[2], float r_col[3])
static float is_left(const float p0[2], const float p1[2], const float p2[2])
const Depsgraph * depsgraph
#define sinf(x)
#define cosf(x)
#define powf(x, y)
#define ceilf(x)
#define hypotf(x, y)
#define floorf(x)
#define acosf(x)
#define fabsf(x)
#define sqrtf(x)
int len
uchar view3d_camera_border_hack_col[3]
Definition drawobject.cc:14
bool view3d_camera_border_hack_test
Definition drawobject.cc:15
bool id_frame_has_keyframe(ID *id, float frame)
Main Keyframe Checking API call.
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
uint col
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
RenderEngineType * RE_engines_find(const char *idname)
format
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
static ulong state[N]
#define G(x, y, z)
T step(const T &edge, const T &value)
float half_to_float(uint16_t v)
Definition math_half.cc:91
VecBase< float, 4 > float4
const char * RE_engine_id_BLENDER_EEVEE_NEXT
Definition scene.cc:1610
const char * RE_engine_id_BLENDER_WORKBENCH
Definition scene.cc:1611
static void draw_background()
#define FLT_MAX
Definition stdcycles.h:14
unsigned int uint32_t
Definition stdint.h:80
void * regiondata
char name[64]
char sensor_fit
float sensor_y
float passepartalpha
float sensor_x
char name[64]
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
char name[64]
ListBase block
struct Collection * collection
void * last
void * first
short base_flag
float viewinv[4][4]
float persinv[4][4]
float viewmat[4][4]
float persmat[4][4]
float viewcamtexcofac[4]
float winmat[4][4]
float viewcamtexcofac[4]
float persmat[4][4]
float clip[6][4]
float persinv[4][4]
float viewmat[4][4]
float clip_local[6][4]
float viewinv[4][4]
float winmat[4][4]
char engine[32]
bool fps_target_is_fractional
Definition ED_scene.hh:51
struct RenderData r
float gpencil_vertex_paint_opacity
char multiview_eye
View3DOverlay overlay
rctf render_border
View3D_Runtime runtime
struct Object * camera
short gridsubdiv
char stereo3d_camera
struct View3D * localvd
ViewerPath viewer_path
short gridlines
int object_type_exclude_select
int object_type_exclude_viewport
ListBase regionbase
View3DShading shading
float clip_start
ARegion * region
Definition ED_view3d.hh:73
Scene * scene
Definition ED_view3d.hh:69
ViewLayer * view_layer
Definition ED_view3d.hh:70
View3D * v3d
Definition ED_view3d.hh:74
Object * obact
Definition ED_view3d.hh:71
Depsgraph * depsgraph
Definition ED_view3d.hh:68
unsigned short w
Definition ED_view3d.hh:82
float * depths
Definition ED_view3d.hh:85
double depth_range[2]
Definition ED_view3d.hh:86
unsigned short h
Definition ED_view3d.hh:82
ViewerPath viewer_path
struct EditBone * act_edbone
ListBase * edbo
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
XrSessionSettings session_settings
static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *yoffset)
void ED_view3d_calc_camera_border_size(const Scene *scene, Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const RegionView3D *rv3d, float r_size[2])
static void draw_selected_name(const View3D *v3d, Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
void ED_view3d_datamask(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, CustomData_MeshMasks *r_cddata_masks)
RV3DMatrixStore * ED_view3d_mats_rv3d_backup(RegionView3D *rv3d)
float ED_view3d_grid_scale(const Scene *scene, const View3D *v3d, const char **r_grid_unit)
static void view3d_draw_border(const bContext *C, ARegion *region)
static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, View3D *v3d)
float ED_view3d_grid_view_scale(const Scene *scene, const View3D *v3d, const ARegion *region, const char **r_grid_unit)
static void view3d_main_region_setup_view(Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *region, const float viewmat[4][4], const float winmat[4][4], const rcti *rect)
ImBuf * ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph, Scene *scene, View3DShading *shading_override, eDrawType drawtype, Object *camera, int width, int height, eImBufFlags imbuf_flag, eV3DOffscreenDrawFlag draw_flags, int alpha_mode, const char *viewname, GPUOffScreen *ofs, GPUViewport *viewport, char err_out[256])
static bool view3d_stereo3d_active(wmWindow *win, const Scene *scene, View3D *v3d, RegionView3D *rv3d)
static void view3d_update_viewer_path(const bContext *C)
void view3d_draw_region_info(const bContext *C, ARegion *region)
void ED_view3d_screen_datamask(const Scene *scene, ViewLayer *view_layer, const bScreen *screen, CustomData_MeshMasks *r_cddata_masks)
static void validate_object_select_id(Depsgraph *depsgraph, const Scene *scene, ViewLayer *view_layer, ARegion *region, View3D *v3d, Object *obact)
bool ED_view3d_draw_offscreen_check_nested()
static void view3d_stereo3d_setup(Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *region, const rcti *rect)
void view3d_main_region_draw(const bContext *C, ARegion *region)
static void view3d_stereo3d_setup_offscreen(Depsgraph *depsgraph, const Scene *scene, View3D *v3d, ARegion *region, const float winmat[4][4], const char *viewname)
static void view3d_camera_border(const Scene *scene, const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const RegionView3D *rv3d, rctf *r_viewborder, const bool no_shift, const bool no_zoom)
void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
static ViewDepths * view3d_depths_create(ARegion *region)
bool ED_view3d_has_depth_buffer_updated(const Depsgraph *depsgraph, const View3D *v3d)
void ED_view3d_select_id_validate(const ViewContext *vc)
static void view3d_main_region_setup_offscreen(Depsgraph *depsgraph, const Scene *scene, View3D *v3d, ARegion *region, const float viewmat[4][4], const float winmat[4][4])
static void view3d_draw_grease_pencil(const bContext *)
float view3d_depth_near(ViewDepths *d)
#define VIEW3D_OVERLAY_LINEHEIGHT
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obact, eV3DDepthOverrideMode mode, ViewDepths **r_depths)
void ED_view3d_grid_steps(const Scene *scene, const View3D *v3d, const RegionView3D *rv3d, float r_grid_steps[STEPS_LEN])
static bool view3d_clipping_test(const float co[3], const float clip[6][4])
void ED_view3d_calc_camera_border(const Scene *scene, const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const RegionView3D *rv3d, const bool no_shift, rctf *r_viewborder)
static void view3d_draw_view(const bContext *C, ARegion *region)
void ED_view3d_mats_rv3d_restore(RegionView3D *rv3d, RV3DMatrixStore *rv3dmat_pt)
void ED_view3d_draw_setup_view(const wmWindowManager *wm, wmWindow *win, Depsgraph *depsgraph, Scene *scene, ARegion *region, View3D *v3d, const float viewmat[4][4], const float winmat[4][4], const rcti *rect)
static void draw_grid_unit_name(Scene *scene, ARegion *region, View3D *v3d, int xoffset, int *yoffset)
#define STEPS_LEN
int ED_view3d_backbuf_sample_size_clamp(ARegion *region, const float dist)
void ED_view3d_depths_free(ViewDepths *depths)
void ED_view3d_draw_offscreen(Depsgraph *depsgraph, const Scene *scene, eDrawType drawtype, View3D *v3d, ARegion *region, int winx, int winy, const float viewmat[4][4], const float winmat[4][4], bool is_image_render, bool draw_background, const char *viewname, const bool do_color_management, const bool restore_rv3d_mats, GPUOffScreen *ofs, GPUViewport *viewport)
static const char * view3d_get_name(View3D *v3d, RegionView3D *rv3d)
static bool view3d_main_region_do_render_draw(const Scene *scene)
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
ImBuf * ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, Scene *scene, eDrawType drawtype, View3D *v3d, ARegion *region, int sizex, int sizey, eImBufFlags imbuf_flag, int alpha_mode, const char *viewname, const bool restore_rv3d_mats, GPUOffScreen *ofs, GPUViewport *viewport, char err_out[256])
static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, float y2, float fac)
static void drawviewborder_triangle(uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
RenderEngineType * ED_view3d_engine_type(const Scene *scene, int drawtype)
bool ED_view3d_calc_render_border(const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *region, rcti *r_rect)
void ED_view3d_update_viewmat(const Depsgraph *depsgraph, const Scene *scene, View3D *v3d, ARegion *region, const float viewmat[4][4], const float winmat[4][4], const rcti *rect, bool offscreen)
#define M_GOLDEN_RATIO_CONJUGATE
void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph, Scene *scene, View3DShading *shading_override, eDrawType drawtype, int object_type_exclude_viewport_override, int object_type_exclude_select_override, int winx, int winy, uint draw_flags, const float viewmat[4][4], const float winmat[4][4], float clip_start, float clip_end, bool is_xr_surface, bool is_image_render, bool draw_background, const char *viewname, const bool do_color_management, GPUOffScreen *ofs, GPUViewport *viewport)
void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
static void drawrenderborder(ARegion *region, View3D *v3d)
float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit)
static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
static void view3d_grid_steps_ex(const Scene *scene, const View3D *v3d, const RegionView3D *rv3d, float r_grid_steps[STEPS_LEN], void const **r_usys_pt, int *r_len)
void view3d_viewmatrix_set(const Depsgraph *depsgraph, const Scene *scene, const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2])
void view3d_winmatrix_set(const Depsgraph *depsgraph, ARegion *region, const View3D *v3d, const rcti *rect)
void WM_draw_region_viewport_unbind(ARegion *region)
Definition wm_draw.cc:1657
void WM_draw_region_viewport_ensure(Scene *scene, ARegion *region, short space_type)
Definition wm_draw.cc:1646
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition wm_draw.cc:905
void WM_draw_region_viewport_bind(ARegion *region)
Definition wm_draw.cc:1652
bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check)
Definition wm_stereo.cc:141
uint8_t flag
Definition wm_window.cc:138
bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr, float r_viewmat[4][4], float *r_focal_len)