Blender V5.0
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
8
9#include <cmath>
10
11#include "BLI_listbase.h"
12#include "BLI_math_color.h"
13#include "BLI_math_geom.h"
14#include "BLI_math_half.hh"
15#include "BLI_math_matrix.h"
16#include "BLI_math_rotation.h"
17#include "BLI_rect.h"
18#include "BLI_string_utf8.h"
19#include "BLI_string_utils.hh"
20#include "BLI_threads.h"
21
22#include "BKE_armature.hh"
23#include "BKE_camera.h"
24#include "BKE_collection.hh"
25#include "BKE_context.hh"
26#include "BKE_customdata.hh"
27#include "BKE_global.hh"
28#include "BKE_grease_pencil.hh"
29#include "BKE_image.hh"
30#include "BKE_key.hh"
31#include "BKE_layer.hh"
32#include "BKE_main.hh"
33#include "BKE_object.hh"
34#include "BKE_paint.hh"
35#include "BKE_scene.hh"
36#include "BKE_screen.hh"
37#include "BKE_unit.hh"
38#include "BKE_viewer_path.hh"
39
40#include "BLF_api.hh"
41
42#include "BLT_translation.hh"
43
44#include "DNA_armature_types.h"
45#include "DNA_camera_types.h"
46#include "DNA_key_types.h"
47#include "DNA_object_types.h"
48#include "DNA_view3d_types.h"
50
51#include "DRW_engine.hh"
52#include "DRW_select_buffer.hh"
53
54#include "ED_gpencil_legacy.hh"
55#include "ED_info.hh"
56#include "ED_scene.hh"
57#include "ED_screen.hh"
59#include "ED_viewer_path.hh"
60
62
64
65#include "GPU_framebuffer.hh"
66#include "GPU_immediate.hh"
67#include "GPU_immediate_util.hh"
68#include "GPU_matrix.hh"
69#include "GPU_state.hh"
70#include "GPU_viewport.hh"
71
72#include "MEM_guardedalloc.h"
73
74#include "UI_interface.hh"
75#include "UI_resources.hh"
76
77#include "RE_engine.h"
78
79#include "WM_api.hh"
80#include "WM_types.hh"
81
82#include "IMB_imbuf.hh"
83#include "IMB_imbuf_types.hh"
84
85#include "ANIM_keyframing.hh"
86
87#include "view3d_intern.hh" /* own include */
88
89using blender::float4;
90
91#define M_GOLDEN_RATIO_CONJUGATE 0.618033988749895f
92
93#define VIEW3D_OVERLAY_LINEHEIGHT (UI_style_get()->widget.points * UI_SCALE_FAC * 1.6f)
94
95/* -------------------------------------------------------------------- */
98
99void ED_view3d_update_viewmat(const Depsgraph *depsgraph,
100 const Scene *scene,
101 View3D *v3d,
102 ARegion *region,
103 const float viewmat[4][4],
104 const float winmat[4][4],
105 const rcti *rect,
106 bool offscreen)
107{
108 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
109
110 /* setup window matrices */
111 if (winmat) {
112 copy_m4_m4(rv3d->winmat, winmat);
113 }
114 else {
115 view3d_winmatrix_set(depsgraph, region, v3d, rect);
116 }
117
118 /* setup view matrix */
119 if (viewmat) {
120 copy_m4_m4(rv3d->viewmat, viewmat);
121 }
122 else {
123 float rect_scale[2];
124 if (rect) {
125 rect_scale[0] = float(BLI_rcti_size_x(rect)) / float(region->winx);
126 rect_scale[1] = float(BLI_rcti_size_y(rect)) / float(region->winy);
127 }
128 /* NOTE: calls BKE_object_where_is_calc for camera... */
129 view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : nullptr);
130 }
131 /* update utility matrices */
132 mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
133 invert_m4_m4(rv3d->persinv, rv3d->persmat);
134 invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
135
136 /* calculate GLSL view dependent values */
137
138 /* store window coordinates scaling/offset */
139 if (!offscreen && rv3d->persp == RV3D_CAMOB && v3d->camera) {
140 rctf cameraborder;
141 ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, false, &cameraborder);
142 rv3d->viewcamtexcofac[0] = float(region->winx) / BLI_rctf_size_x(&cameraborder);
143 rv3d->viewcamtexcofac[1] = float(region->winy) / BLI_rctf_size_y(&cameraborder);
144
145 rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / float(region->winx);
146 rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / float(region->winy);
147 }
148 else {
149 rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
150 rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
151 }
152
153 /* Calculate pixel-size factor once, this is used for lights and object-centers. */
154 {
155 /* NOTE: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
156 * because of float point precision problems at large values #23908. */
157 float v1[3], v2[3];
158 float len_px, len_sc;
159
160 v1[0] = rv3d->persmat[0][0];
161 v1[1] = rv3d->persmat[1][0];
162 v1[2] = rv3d->persmat[2][0];
163
164 v2[0] = rv3d->persmat[0][1];
165 v2[1] = rv3d->persmat[1][1];
166 v2[2] = rv3d->persmat[2][1];
167
168 len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
169
170 if (rect) {
171 len_sc = float(max_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)));
172 }
173 else {
174 len_sc = float(std::max(region->winx, region->winy));
175 }
176
177 rv3d->pixsize = len_px / len_sc;
178 }
179}
180
182 Scene *scene,
183 View3D *v3d,
184 ARegion *region,
185 const float viewmat[4][4],
186 const float winmat[4][4],
187 const rcti *rect)
188{
189 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
190
191 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, rect, false);
192
193 /* Set for GPU drawing. */
195 GPU_matrix_set(rv3d->viewmat);
196}
197
199 const Scene *scene,
200 View3D *v3d,
201 ARegion *region,
202 const float viewmat[4][4],
203 const float winmat[4][4])
204{
205 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
206 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, nullptr, true);
207
208 /* Set for GPU drawing. */
210 GPU_matrix_set(rv3d->viewmat);
211}
212
214 const Scene *scene,
215 View3D *v3d,
216 RegionView3D *rv3d)
217{
218 if ((scene->r.scemode & R_MULTIVIEW) == 0) {
219 return false;
220 }
221
222 if ((v3d->camera == nullptr) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
223 return false;
224 }
225
226 switch (v3d->stereo3d_camera) {
227 case STEREO_MONO_ID:
228 return false;
229 break;
230 case STEREO_3D_ID:
231 /* win will be nullptr when calling this from the selection or draw loop. */
232 if ((win == nullptr) || (WM_stereo3d_enabled(win, true) == false)) {
233 return false;
234 }
235 if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
237 {
238 return false;
239 }
240 break;
241 /* We always need the stereo calculation for left and right cameras. */
242 case STEREO_LEFT_ID:
243 case STEREO_RIGHT_ID:
244 default:
245 break;
246 }
247 return true;
248}
249
250/* setup the view and win matrices for the multiview cameras
251 *
252 * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
253 * we have no winmatrix (i.e., projection matrix) defined at that time.
254 * Since the camera and the camera shift are needed for the winmat calculation
255 * we do a small hack to replace it temporarily so we don't need to change the
256 * view3d)main_region_setup_view() code to account for that.
257 */
259 Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *region, const rcti *rect)
260{
261 bool is_left;
262 const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
263 const char *viewname;
264
265 /* show only left or right camera */
266 if (v3d->stereo3d_camera != STEREO_3D_ID) {
267 v3d->multiview_eye = v3d->stereo3d_camera;
268 }
269
271 viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
272
273 /* update the viewport matrices with the new camera */
275 Camera *data, *data_eval;
276 float viewmat[4][4];
277 float shiftx;
278
279 data = (Camera *)v3d->camera->data;
280 data_eval = DEG_get_evaluated(depsgraph, data);
281
282 shiftx = data_eval->shiftx;
283
285 data_eval->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
286
287 BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
288 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
289
290 data_eval->shiftx = shiftx;
292 }
293 else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
294 float viewmat[4][4];
295 Object *view_ob = v3d->camera;
296 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
297
299 v3d->camera = camera;
300
301 BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
302 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
303
304 v3d->camera = view_ob;
306 }
307}
308
309#ifdef WITH_XR_OPENXR
310static void view3d_xr_mirror_setup(const wmWindowManager *wm,
311 Depsgraph *depsgraph,
312 Scene *scene,
313 View3D *v3d,
314 ARegion *region,
315 const rcti *rect)
316{
317 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
318 float viewmat[4][4];
319 const float lens_old = v3d->lens;
320
321 if (!WM_xr_session_state_viewer_pose_matrix_info_get(&wm->xr, viewmat, &v3d->lens)) {
322 /* Can't get info from XR session, use fallback values. */
323 copy_m4_m4(viewmat, rv3d->viewmat);
324 v3d->lens = lens_old;
325 }
326 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, nullptr, rect);
327
328 /* Set draw flags. */
334 0,
336 /* Hide navigation gizmo since it gets distorted if the view matrix has a scale factor. */
338
339 /* Reset overridden View3D data. */
340 v3d->lens = lens_old;
341}
342#endif /* WITH_XR_OPENXR */
343
345 wmWindow *win,
346 Depsgraph *depsgraph,
347 Scene *scene,
348 ARegion *region,
349 View3D *v3d,
350 const float viewmat[4][4],
351 const float winmat[4][4],
352 const rcti *rect)
353{
354 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
355
356#ifdef WITH_XR_OPENXR
357 /* Setup the view matrix. */
358 if (ED_view3d_is_region_xr_mirror_active(wm, v3d, region)) {
359 view3d_xr_mirror_setup(wm, depsgraph, scene, v3d, region, rect);
360 }
361 else
362#endif
363 if (view3d_stereo3d_active(win, scene, v3d, rv3d))
364 {
365 view3d_stereo3d_setup(depsgraph, scene, v3d, region, rect);
366 }
367 else {
368 view3d_main_region_setup_view(depsgraph, scene, v3d, region, viewmat, winmat, rect);
369 }
370
371#ifndef WITH_XR_OPENXR
372 UNUSED_VARS(wm);
373#endif
374}
375
377
378/* -------------------------------------------------------------------- */
381
382static void view3d_camera_border(const Scene *scene,
383 const Depsgraph *depsgraph,
384 const ARegion *region,
385 const View3D *v3d,
386 const RegionView3D *rv3d,
387 rctf *r_viewborder,
388 const bool no_shift,
389 const bool no_zoom)
390{
392 rctf rect_view, rect_camera;
393 Object *camera_eval = DEG_get_evaluated(depsgraph, v3d->camera);
394
395 /* get viewport viewplane */
398 if (no_zoom) {
399 params.zoom = 1.0f;
400 }
401 BKE_camera_params_compute_viewplane(&params, region->winx, region->winy, 1.0f, 1.0f);
402 rect_view = params.viewplane;
403
404 /* get camera viewplane */
406 /* fallback for non camera objects */
407 params.clip_start = v3d->clip_start;
408 params.clip_end = v3d->clip_end;
410 if (no_shift) {
411 params.shiftx = 0.0f;
412 params.shifty = 0.0f;
413 }
415 &params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
416 rect_camera = params.viewplane;
417
418 /* get camera border within viewport */
419 r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) *
420 region->winx;
421 r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) *
422 region->winx;
423 r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) *
424 region->winy;
425 r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) *
426 region->winy;
427}
428
430 Depsgraph *depsgraph,
431 const ARegion *region,
432 const View3D *v3d,
433 const RegionView3D *rv3d,
434 float r_size[2])
435{
436 rctf viewborder;
437
438 view3d_camera_border(scene, depsgraph, region, v3d, rv3d, &viewborder, true, true);
439 r_size[0] = BLI_rctf_size_x(&viewborder);
440 r_size[1] = BLI_rctf_size_y(&viewborder);
441}
442
444 const Depsgraph *depsgraph,
445 const ARegion *region,
446 const View3D *v3d,
447 const RegionView3D *rv3d,
448 const bool no_shift,
449 rctf *r_viewborder)
450{
451 view3d_camera_border(scene, depsgraph, region, v3d, rv3d, r_viewborder, no_shift, false);
452}
453
454static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, float y2, float fac)
455{
456 float x3, y3, x4, y4;
457
458 x3 = x1 + fac * (x2 - x1);
459 y3 = y1 + fac * (y2 - y1);
460 x4 = x1 + (1.0f - fac) * (x2 - x1);
461 y4 = y1 + (1.0f - fac) * (y2 - y1);
462
464
465 immVertex2f(shdr_pos, x1, y3);
466 immVertex2f(shdr_pos, x2, y3);
467
468 immVertex2f(shdr_pos, x1, y4);
469 immVertex2f(shdr_pos, x2, y4);
470
471 immVertex2f(shdr_pos, x3, y1);
472 immVertex2f(shdr_pos, x3, y2);
473
474 immVertex2f(shdr_pos, x4, y1);
475 immVertex2f(shdr_pos, x4, y2);
476
477 immEnd();
478}
479
480/* harmonious triangle */
482 uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
483{
484 float ofs;
485 float w = x2 - x1;
486 float h = y2 - y1;
487
489
490 if (w > h) {
491 if (golden) {
492 ofs = w * (1.0f - M_GOLDEN_RATIO_CONJUGATE);
493 }
494 else {
495 ofs = h * (h / w);
496 }
497 if (dir == 'B') {
498 std::swap(y1, y2);
499 }
500
501 immVertex2f(shdr_pos, x1, y1);
502 immVertex2f(shdr_pos, x2, y2);
503
504 immVertex2f(shdr_pos, x2, y1);
505 immVertex2f(shdr_pos, x1 + (w - ofs), y2);
506
507 immVertex2f(shdr_pos, x1, y2);
508 immVertex2f(shdr_pos, x1 + ofs, y1);
509 }
510 else {
511 if (golden) {
512 ofs = h * (1.0f - M_GOLDEN_RATIO_CONJUGATE);
513 }
514 else {
515 ofs = w * (w / h);
516 }
517 if (dir == 'B') {
518 std::swap(x1, x2);
519 }
520
521 immVertex2f(shdr_pos, x1, y1);
522 immVertex2f(shdr_pos, x2, y2);
523
524 immVertex2f(shdr_pos, x2, y1);
525 immVertex2f(shdr_pos, x1, y1 + ofs);
526
527 immVertex2f(shdr_pos, x1, y2);
528 immVertex2f(shdr_pos, x2, y1 + (h - ofs));
529 }
530
531 immEnd();
532}
533
534static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, View3D *v3d)
535{
536 float x1, x2, y1, y2;
537 float x1i, x2i, y1i, y2i;
538
539 rctf viewborder;
540 Camera *ca = nullptr;
541 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
542
543 if (v3d->camera == nullptr) {
544 return;
545 }
546 if (v3d->camera->type == OB_CAMERA) {
547 ca = static_cast<Camera *>(v3d->camera->data);
548 }
549
550 ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, false, &viewborder);
551 /* the offsets */
552 x1 = viewborder.xmin;
553 y1 = viewborder.ymin;
554 x2 = viewborder.xmax;
555 y2 = viewborder.ymax;
556
557 GPU_line_width(1.0f);
558
559 /* apply offsets so the real 3D camera shows through */
560
561 /* NOTE: quite un-scientific but without this bit extra
562 * 0.0001 on the lower left the 2D border sometimes
563 * obscures the 3D camera border */
564 /* NOTE: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
565 * but keep it here in case we need to remove the workaround */
566 x1i = int(x1 - 1.0001f);
567 y1i = int(y1 - 1.0001f);
568 x2i = int(x2 + (1.0f - 0.0001f));
569 y2i = int(y2 + (1.0f - 0.0001f));
570
571 uint shdr_pos = GPU_vertformat_attr_add(
572 immVertexFormat(), "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
573
574 /* First, solid lines. */
575 {
577
578 /* passepartout, specified in camera edit buttons */
579 if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f &&
581 {
582 const float winx = (region->winx + 1);
583 const float winy = (region->winy + 1);
584
585 float alpha = 1.0f;
586
587 if (ca->passepartalpha != 1.0f) {
589 alpha = ca->passepartalpha;
590 }
591
593
594 if (x1i > 0.0f) {
595 immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f);
596 }
597 if (x2i < winx) {
598 immRectf(shdr_pos, x2i, winy, winx, 0.0f);
599 }
600 if (y2i < winy) {
601 immRectf(shdr_pos, x1i, winy, x2i, y2i);
602 }
603 if (y2i > 0.0f) {
604 immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
605 }
606
609 imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
610 }
611
612#ifdef VIEW3D_CAMERA_BORDER_HACK
613 if (view3d_camera_border_hack_test == true) {
615 imm_draw_box_wire_2d(shdr_pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
617 }
618#endif
619
621 }
622
623 /* When overlays are disabled, only show camera outline & passepartout. */
624 if (v3d->flag2 & V3D_HIDE_OVERLAYS || !(v3d->flag2 & V3D_SHOW_CAMERA_GUIDES)) {
625 return;
626 }
627
628 /* And now, the dashed lines! */
630
631 {
632 float viewport_size[4];
633 GPU_viewport_size_get_f(viewport_size);
634 immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
635
636 immUniform1i("colors_len", 0); /* "simple" mode */
637 immUniform1f("dash_width", 6.0f);
638 immUniform1f("udash_factor", 0.5f);
639
640 /* outer line not to confuse with object selection */
641 if (v3d->flag2 & V3D_LOCK_CAMERA) {
643 imm_draw_box_wire_2d(shdr_pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
644 }
645
647 imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
648 }
649
650 /* Render Border. */
651 if (scene->r.mode & R_BORDER) {
652 float x3, y3, x4, y4;
653
654 x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
655 y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
656 x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
657 y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
658
659 immUniformColor3f(1.0f, 0.25f, 0.25f);
660 imm_draw_box_wire_2d(shdr_pos, x3, y3, x4, y4);
661 }
662
663 /* safety border */
664 if (ca && (v3d->flag2 & V3D_SHOW_CAMERA_GUIDES)) {
667
668 if (ca->dtx & CAM_DTX_CENTER) {
669 float x3, y3;
670
671 x3 = x1 + 0.5f * (x2 - x1);
672 y3 = y1 + 0.5f * (y2 - y1);
673
675
676 immVertex2f(shdr_pos, x1, y3);
677 immVertex2f(shdr_pos, x2, y3);
678
679 immVertex2f(shdr_pos, x3, y1);
680 immVertex2f(shdr_pos, x3, y2);
681
682 immEnd();
683 }
684
685 if (ca->dtx & CAM_DTX_CENTER_DIAG) {
687
688 immVertex2f(shdr_pos, x1, y1);
689 immVertex2f(shdr_pos, x2, y2);
690
691 immVertex2f(shdr_pos, x1, y2);
692 immVertex2f(shdr_pos, x2, y1);
693
694 immEnd();
695 }
696
697 if (ca->dtx & CAM_DTX_THIRDS) {
698 drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f / 3.0f);
699 }
700
701 if (ca->dtx & CAM_DTX_GOLDEN) {
702 drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - M_GOLDEN_RATIO_CONJUGATE);
703 }
704
705 if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
706 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'A');
707 }
708
709 if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
710 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'B');
711 }
712
713 if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
714 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'A');
715 }
716
717 if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
718 drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'B');
719 }
720
721 if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
722 rctf margins_rect{};
723 margins_rect.xmin = x1;
724 margins_rect.xmax = x2;
725 margins_rect.ymin = y1;
726 margins_rect.ymax = y2;
727
728 /* draw */
730
732 shdr_pos, &margins_rect, scene->safe_areas.title, scene->safe_areas.action);
733
734 if (ca->flag & CAM_SHOW_SAFE_CENTER) {
735 rctf center_rect{};
736 center_rect.xmin = x1;
737 center_rect.xmax = x2;
738 center_rect.ymin = y1;
739 center_rect.ymax = y2;
740 UI_draw_safe_areas(shdr_pos,
741 &center_rect,
744 }
745 }
746
747 if (ca->flag & CAM_SHOWSENSOR) {
748 /* determine sensor fit, and get sensor x/y, for auto fit we
749 * assume and square sensor and only use sensor_x */
750 float sizex = scene->r.xsch * scene->r.xasp;
751 float sizey = scene->r.ysch * scene->r.yasp;
752 int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
753 float sensor_x = ca->sensor_x;
754 float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
755
756 /* determine sensor plane */
757 rctf rect;
758
759 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
760 float sensor_scale = (x2i - x1i) / sensor_x;
761 float sensor_height = sensor_scale * sensor_y;
762
763 rect.xmin = x1i;
764 rect.xmax = x2i;
765 rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
766 rect.ymax = rect.ymin + sensor_height;
767 }
768 else {
769 float sensor_scale = (y2i - y1i) / sensor_y;
770 float sensor_width = sensor_scale * sensor_x;
771
772 rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
773 rect.xmax = rect.xmin + sensor_width;
774 rect.ymin = y1i;
775 rect.ymax = y2i;
776 }
777
778 /* draw */
780
781 /* TODO: Was using:
782 * `UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color);`
783 * We'll probably need a new imm_draw_line_roundbox_dashed or that - though in practice the
784 * 2.0f round corner effect was nearly not visible anyway. */
785 imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
786 }
787
789 }
790
792 /* end dashed lines */
793
794 /* camera name - draw in highlighted text color */
795 if (ca && ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) && (ca->flag & CAM_SHOWNAME)) {
798 y1i - (0.7f * U.widget_unit),
799 0.0f,
800 v3d->camera->id.name + 2,
801 sizeof(v3d->camera->id.name) - 2);
802 }
803}
804
805static void drawrenderborder(ARegion *region, View3D *v3d)
806{
807 /* use the same program for everything */
808 uint shdr_pos = GPU_vertformat_attr_add(
809 immVertexFormat(), "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
810
811 GPU_line_width(1.0f);
812
814
815 float viewport_size[4];
816 GPU_viewport_size_get_f(viewport_size);
817 immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
818
819 immUniform1i("colors_len", 0); /* "simple" mode */
820 immUniform4f("color", 1.0f, 0.25f, 0.25f, 1.0f);
821 immUniform1f("dash_width", 6.0f);
822 immUniform1f("udash_factor", 0.5f);
823
824 imm_draw_box_wire_2d(shdr_pos,
825 v3d->render_border.xmin * region->winx,
826 v3d->render_border.ymin * region->winy,
827 v3d->render_border.xmax * region->winx,
828 v3d->render_border.ymax * region->winy);
829
831}
832
834
835/* -------------------------------------------------------------------- */
838
839float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit)
840{
841 /* apply units */
842 if (scene->unit.system) {
843 const void *usys;
844 int len;
845
847
848 if (usys) {
849 int i = BKE_unit_base_get(usys);
850 if (r_grid_unit) {
851 *r_grid_unit = IFACE_(BKE_unit_display_name_get(usys, i));
852 }
853 return float(BKE_unit_scalar_get(usys, i)) / scene->unit.scale_length;
854 }
855 }
856
857 return 1.0f;
858}
859
860float ED_view3d_grid_scale(const Scene *scene, const View3D *v3d, const char **r_grid_unit)
861{
862 return v3d->grid * ED_scene_grid_scale(scene, r_grid_unit);
863}
864
865#define STEPS_LEN 8
866static void view3d_grid_steps_ex(const Scene *scene,
867 const View3D *v3d,
868 const RegionView3D *rv3d,
869 float r_grid_steps[STEPS_LEN],
870 void const **r_usys_pt,
871 int *r_len)
872{
873 const void *usys;
874 int len;
876 float grid_scale = v3d->grid;
878
879 if (usys) {
880 if (rv3d->view == RV3D_VIEW_USER) {
881 /* Skip steps */
882 len = BKE_unit_base_get(usys) + 1;
883 }
884
885 grid_scale /= scene->unit.scale_length;
886
887 int i;
888 for (i = 0; i < len; i++) {
889 r_grid_steps[i] = float(BKE_unit_scalar_get(usys, len - 1 - i)) * grid_scale;
890 }
891 for (; i < STEPS_LEN; i++) {
892 /* Fill last slots */
893 r_grid_steps[i] = r_grid_steps[len - 1];
894 }
895 }
896 else {
897 if (rv3d->view != RV3D_VIEW_USER) {
898 /* Allow 3 more subdivisions. */
899 grid_scale /= powf(v3d->gridsubdiv, 3);
900 }
901 int subdiv = 1;
902 for (int i = 0;; i++) {
903 r_grid_steps[i] = grid_scale * subdiv;
904
905 if (i == STEPS_LEN - 1) {
906 break;
907 }
908 subdiv *= v3d->gridsubdiv;
909 }
910 }
911 if (r_usys_pt) {
912 *r_usys_pt = usys;
913 }
914 if (r_len) {
915 *r_len = len;
916 }
917}
918
919void ED_view3d_grid_steps(const Scene *scene,
920 const View3D *v3d,
921 const RegionView3D *rv3d,
922 float r_grid_steps[STEPS_LEN])
923{
924 view3d_grid_steps_ex(scene, v3d, rv3d, r_grid_steps, nullptr, nullptr);
925}
926
928 const View3D *v3d,
929 const ARegion *region,
930 const char **r_grid_unit)
931{
932 float grid_scale;
933 const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
934 if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
935 /* Decrease the distance between grid snap points depending on zoom. */
936 float dist = 12.0f / (region->sizex * rv3d->winmat[0][0]);
937 float grid_steps[STEPS_LEN];
938 const void *usys;
939 int grid_steps_len;
940 view3d_grid_steps_ex(scene, v3d, rv3d, grid_steps, &usys, &grid_steps_len);
941 int i = 0;
942 while (true) {
943 grid_scale = grid_steps[i];
944 if (grid_scale > dist || i == (grid_steps_len - 1)) {
945 break;
946 }
947 i++;
948 }
949
950 if (r_grid_unit && usys) {
951 *r_grid_unit = IFACE_(BKE_unit_display_name_get(usys, grid_steps_len - i - 1));
952 }
953 }
954 else {
955 grid_scale = ED_view3d_grid_scale(scene, v3d, r_grid_unit);
956 }
957
958 return grid_scale;
959}
960
961#undef STEPS_LEN
962
963static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
964{
965 const float k = U.rvisize * UI_SCALE_FAC; /* axis size */
966 /* axis alpha offset (rvibright has range 0-10) */
967 const int bright = -20 * (10 - U.rvibright);
968
969 /* Axis center in screen coordinates.
970 *
971 * - Unit size offset so small text doesn't draw outside the screen
972 * - Extra X offset because of the panel expander.
973 */
974 const float startx = rect->xmax - (k + UI_UNIT_X * 1.5);
975 const float starty = rect->ymax - (k + UI_UNIT_Y);
976
977 float axis_pos[3][2];
978 float axis_col[3][4];
979
980 int axis_order[3] = {0, 1, 2};
981 axis_sort_v3(rv3d->viewinv[2], axis_order);
982
983 for (int axis_i = 0; axis_i < 3; axis_i++) {
984 int i = axis_order[axis_i];
985
986 /* get position of each axis tip on screen */
987 float vec[3] = {0.0f};
988 vec[i] = 1.0f;
989 mul_qt_v3(rv3d->viewquat, vec);
990 axis_pos[i][0] = startx + vec[0] * k;
991 axis_pos[i][1] = starty + vec[1] * k;
992
993 /* get color of each axis */
994 UI_GetThemeColorShade3fv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
995 axis_col[i][3] = hypotf(vec[0], vec[1]); /* alpha */
996 }
997
998 /* draw axis lines */
999 GPU_line_width(2.0f);
1000 GPU_line_smooth(true);
1002
1004 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1006 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
1007
1010
1011 for (int axis_i = 0; axis_i < 3; axis_i++) {
1012 int i = axis_order[axis_i];
1013
1014 immAttr4fv(col, axis_col[i]);
1015 immVertex2f(pos, startx, starty);
1016 immAttr4fv(col, axis_col[i]);
1017 immVertex2fv(pos, axis_pos[i]);
1018 }
1019
1020 immEnd();
1022 GPU_line_smooth(false);
1023
1024 /* draw axis names */
1025 for (int axis_i = 0; axis_i < 3; axis_i++) {
1026 int i = axis_order[axis_i];
1027
1028 const char axis_text[2] = {char('x' + i), '\0'};
1029 BLF_color4fv(BLF_default(), axis_col[i]);
1030 BLF_draw_default(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
1031 }
1032}
1033
1034#ifdef WITH_INPUT_NDOF
1038static void draw_ndof_guide_orbit_axis(const RegionView3D *rv3d)
1039{
1040 float o[3]; /* center of rotation */
1041 float end[3]; /* endpoints for drawing */
1042
1043 float color[4] = {0.0f, 0.42f, 1.0f, 1.0f}; /* bright blue so it matches device LEDs */
1044
1045 negate_v3_v3(o, rv3d->ofs);
1046
1048 GPU_depth_mask(false); /* Don't overwrite the Z-buffer. */
1049
1051 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
1053 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
1054
1056
1057 if (rv3d->ndof_rot_angle != 0.0f) {
1058 /* -- draw rotation axis -- */
1059 float scaled_axis[3];
1060 const float scale = rv3d->dist;
1061 mul_v3_v3fl(scaled_axis, rv3d->ndof_rot_axis, scale);
1062
1064 color[3] = 0; /* more transparent toward the ends */
1065 immAttr4fv(col, color);
1066 add_v3_v3v3(end, o, scaled_axis);
1067 immVertex3fv(pos, end);
1068
1069# if 0
1070 color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
1071 /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
1072# endif
1073
1074 color[3] = 0.5f; /* more opaque toward the center */
1075 immAttr4fv(col, color);
1076 immVertex3fv(pos, o);
1077
1078 color[3] = 0;
1079 immAttr4fv(col, color);
1080 sub_v3_v3v3(end, o, scaled_axis);
1081 immVertex3fv(pos, end);
1082 immEnd();
1083
1084 /* -- draw ring around rotation center -- */
1085 {
1086# define ROT_AXIS_DETAIL 13
1087
1088 const float s = 0.05f * scale;
1089 const float step = 2.0f * float(M_PI / ROT_AXIS_DETAIL);
1090
1091 float q[4]; /* rotate ring so it's perpendicular to axis */
1092 const int upright = fabsf(rv3d->ndof_rot_axis[2]) >= 0.95f;
1093 if (!upright) {
1094 const float up[3] = {0.0f, 0.0f, 1.0f};
1095 float vis_angle, vis_axis[3];
1096
1097 cross_v3_v3v3(vis_axis, up, rv3d->ndof_rot_axis);
1098 vis_angle = acosf(dot_v3v3(up, rv3d->ndof_rot_axis));
1099 axis_angle_to_quat(q, vis_axis, vis_angle);
1100 }
1101
1102 immBegin(GPU_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
1103 color[3] = 0.25f; /* somewhat faint */
1104 immAttr4fv(col, color);
1105 float angle = 0.0f;
1106 for (int i = 0; i < ROT_AXIS_DETAIL; i++, angle += step) {
1107 float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
1108
1109 if (!upright) {
1110 mul_qt_v3(q, p);
1111 }
1112
1113 add_v3_v3(p, o);
1114 immVertex3fv(pos, p);
1115 }
1116 immEnd();
1117
1118# undef ROT_AXIS_DETAIL
1119 }
1120
1121 color[3] = 1.0f; /* solid dot */
1122 }
1123 else {
1124 color[3] = 0.5f; /* see-through dot */
1125 }
1126
1128
1129 /* -- draw rotation center -- */
1131 immUniform1f("size", 7.0f);
1132 immUniform4fv("color", float4(color));
1134 immAttr4fv(col, color);
1135 immVertex3fv(pos, o);
1136 immEnd();
1138
1140 GPU_depth_mask(true);
1141}
1142
1143static void draw_ndof_guide_orbit_center(const RegionView3D *rv3d)
1144{
1145 uchar color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
1147 GPU_depth_mask(false); /* Don't overwrite the Z-buffer. */
1148
1150 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
1151 uint col = GPU_vertformat_attr_add(format, "color", blender::gpu::VertAttrType::UNORM_8_8_8_8);
1152
1154 immUniform1f("size", 7.0f);
1155 immUniform4fv("color", float4(color));
1157 immAttr4ubv(col, color);
1158 float center[3];
1159 negate_v3_v3(center, rv3d->ndof_ofs);
1160 immVertex3fv(pos, center);
1161 immEnd();
1163
1165 GPU_depth_mask(true);
1166}
1167
1168#endif /* WITH_INPUT_NDOF */
1169
1173static void view3d_draw_border(const bContext *C, ARegion *region)
1174{
1175 Scene *scene = CTX_data_scene(C);
1177 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1178 View3D *v3d = CTX_wm_view3d(C);
1179
1180 if (rv3d->persp == RV3D_CAMOB) {
1181 drawviewborder(scene, depsgraph, region, v3d);
1182 }
1183 else if (v3d->flag2 & V3D_RENDER_BORDER) {
1184 drawrenderborder(region, v3d);
1185 }
1186}
1187
1189
1190/* -------------------------------------------------------------------- */
1193
1197static void view3d_draw_grease_pencil(const bContext * /*C*/)
1198{
1199 /* TODO: viewport. */
1200}
1201
1205static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
1206{
1207 const char *name = nullptr;
1208
1209 switch (rv3d->view) {
1210 case RV3D_VIEW_FRONT:
1211 if (rv3d->persp == RV3D_ORTHO) {
1212 name = IFACE_("Front Orthographic");
1213 }
1214 else {
1215 name = IFACE_("Front Perspective");
1216 }
1217 break;
1218 case RV3D_VIEW_BACK:
1219 if (rv3d->persp == RV3D_ORTHO) {
1220 name = IFACE_("Back Orthographic");
1221 }
1222 else {
1223 name = IFACE_("Back Perspective");
1224 }
1225 break;
1226 case RV3D_VIEW_TOP:
1227 if (rv3d->persp == RV3D_ORTHO) {
1228 name = IFACE_("Top Orthographic");
1229 }
1230 else {
1231 name = IFACE_("Top Perspective");
1232 }
1233 break;
1234 case RV3D_VIEW_BOTTOM:
1235 if (rv3d->persp == RV3D_ORTHO) {
1236 name = IFACE_("Bottom Orthographic");
1237 }
1238 else {
1239 name = IFACE_("Bottom Perspective");
1240 }
1241 break;
1242 case RV3D_VIEW_RIGHT:
1243 if (rv3d->persp == RV3D_ORTHO) {
1244 name = IFACE_("Right Orthographic");
1245 }
1246 else {
1247 name = IFACE_("Right Perspective");
1248 }
1249 break;
1250 case RV3D_VIEW_LEFT:
1251 if (rv3d->persp == RV3D_ORTHO) {
1252 name = IFACE_("Left Orthographic");
1253 }
1254 else {
1255 name = IFACE_("Left Perspective");
1256 }
1257 break;
1258
1259 default:
1260 if (rv3d->persp == RV3D_CAMOB) {
1261 if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
1262 const Camera *cam = static_cast<const Camera *>(v3d->camera->data);
1263 if (cam->type == CAM_PERSP) {
1264 name = IFACE_("Camera Perspective");
1265 }
1266 else if (cam->type == CAM_ORTHO) {
1267 name = IFACE_("Camera Orthographic");
1268 }
1269 else if (cam->type == CAM_PANO) {
1270 name = IFACE_("Camera Panoramic");
1271 }
1272 else {
1273 BLI_assert(cam->type == CAM_CUSTOM);
1274 name = IFACE_("Camera Custom");
1275 }
1276 }
1277 else {
1278 name = IFACE_("Object as Camera");
1279 }
1280 }
1281 else {
1282 name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Orthographic") :
1283 IFACE_("User Perspective");
1284 }
1285 }
1286
1287 return name;
1288}
1289
1290static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *yoffset)
1291{
1292 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1293 const char *name = view3d_get_name(v3d, rv3d);
1294 const char *name_array[3] = {name, nullptr, nullptr};
1295 int name_array_len = 1;
1296
1297 /* 6 is the maximum size of the axis roll text. */
1298 /* increase size for unicode languages (Chinese in UTF8...). */
1299 char tmpstr[96 + 6];
1300
1302 const char *axis_roll;
1303 switch (rv3d->view_axis_roll) {
1305 axis_roll = " 90\xC2\xB0";
1306 break;
1308 axis_roll = " 180\xC2\xB0";
1309 break;
1310 default:
1311 axis_roll = " -90\xC2\xB0";
1312 break;
1313 }
1314 name_array[name_array_len++] = axis_roll;
1315 }
1316
1317 if (v3d->localvd) {
1318 name_array[name_array_len++] = IFACE_(" (Local)");
1319 }
1320
1321 /* Indicate that clipping region is enabled. */
1322 if (rv3d->rflag & RV3D_CLIPPING) {
1323 name_array[name_array_len++] = IFACE_(" (Clipped)");
1324 }
1325
1326 if (name_array_len > 1) {
1327 BLI_string_join_array(tmpstr, sizeof(tmpstr), name_array, name_array_len);
1328 name = tmpstr;
1329 }
1330 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
1331 BLF_draw_default(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
1332}
1333
1335{
1336 if (ob.type != OB_GREASE_PENCIL) {
1337 return false;
1338 }
1339
1340 using namespace blender::bke::greasepencil;
1341 const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob.data);
1342 for (const Layer *layer : grease_pencil.layers()) {
1343 if (!layer->frames().is_empty()) {
1344 return true;
1345 }
1346 }
1347 return false;
1348}
1349
1355 const View3D *v3d, Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
1356{
1357 const int cfra = scene->r.cfra;
1358 const char *msg_pin = " (Soloed)";
1359 const char *msg_sep = " : ";
1360 const char *msg_space = " ";
1361
1362 const int font_id = BLF_default();
1363
1364 const char *info_array[16];
1365 int i = 0;
1366
1367 struct {
1368 char frame[16];
1369 } info_buffers;
1370
1371 /* Info can contain:
1372 * - 1 frame number `(7 + 2)`.
1373 * - 1 collection name `(MAX_ID_NAME - 2 + 3)`.
1374 * - 1 object name `(MAX_ID_NAME - 2)`.
1375 * - 1 object data name `(MAX_ID_NAME - 2)`.
1376 * - 2 non-ID data names (bones, shape-keys...) `(MAX_NAME * 2)`.
1377 * - 2 BREAD_CRUMB_SEPARATOR(s) `(6)`.
1378 * - 1 SHAPE_KEY_PINNED marker and a trailing '\0' `(9+1)` - translated, so give some room!
1379 * - 1 marker name `(MAX_NAME + 3)`.
1380 */
1381
1382 SNPRINTF_UTF8(info_buffers.frame, "(%d)", cfra);
1383 info_array[i++] = info_buffers.frame;
1384
1385 if ((ob == nullptr) || (ob->mode == OB_MODE_OBJECT)) {
1386 BKE_view_layer_synced_ensure(scene, view_layer);
1387 LayerCollection *layer_collection = BKE_view_layer_active_collection_get(view_layer);
1388 info_array[i++] = msg_space;
1389 info_array[i++] = BKE_collection_ui_name_get(layer_collection->collection);
1390 if (ob != nullptr) {
1391 info_array[i++] = " |";
1392 }
1393 }
1394
1395 /* get name of marker on current frame (if available) */
1396 const char *markern = BKE_scene_find_marker_name(scene, cfra);
1397
1398 /* check if there is an object */
1399 if (ob) {
1400 info_array[i++] = msg_space;
1401 info_array[i++] = ob->id.name + 2;
1402
1403 /* Show object data name when not in object mode. */
1404 if (ob->mode != OB_MODE_OBJECT) {
1405 if (const ID *data_id = static_cast<const ID *>(ob->data)) {
1406 info_array[i++] = " | ";
1407 info_array[i++] = data_id->name + 2;
1408 }
1409 }
1410
1411 /* name(s) to display depends on type of object */
1412 if (ob->type == OB_ARMATURE) {
1413 bArmature *arm = static_cast<bArmature *>(ob->data);
1414
1415 /* show name of active bone too (if possible) */
1416 if (arm->edbo) {
1417 if (arm->act_edbone) {
1418 info_array[i++] = msg_sep;
1419 info_array[i++] = arm->act_edbone->name;
1420 }
1421 }
1422 else if (ob->mode & OB_MODE_POSE) {
1423 if (arm->act_bone) {
1424
1426 info_array[i++] = msg_sep;
1427 info_array[i++] = arm->act_bone->name;
1428 }
1429 }
1430 }
1431 }
1432 else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVES_LEGACY)) {
1433 /* Try to display active bone and active shape-key too (if they exist). */
1434
1435 if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
1437 if (armobj && armobj->mode & OB_MODE_POSE) {
1438 bArmature *arm = static_cast<bArmature *>(armobj->data);
1439 if (arm->act_bone) {
1441 info_array[i++] = msg_sep;
1442 info_array[i++] = arm->act_bone->name;
1443 }
1444 }
1445 }
1446 }
1447
1448 Key *key = BKE_key_from_object(ob);
1449 if (key) {
1450 KeyBlock *kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
1451 if (kb) {
1452 info_array[i++] = msg_sep;
1453 info_array[i++] = kb->name;
1454 if (ob->shapeflag & OB_SHAPE_LOCK) {
1455 info_array[i++] = IFACE_(msg_pin);
1456 }
1457 }
1458 }
1459 }
1460
1461 /* color depends on whether there is a keyframe */
1464 }
1465
1467 /* BKE_scene_ctime_get(scene) */ float(cfra)))
1468 {
1470 }
1471 }
1472
1473 if (markern) {
1474 info_array[i++] = " <";
1475 info_array[i++] = markern;
1476 info_array[i++] = ">";
1477 }
1478
1479 if (v3d->flag2 & V3D_SHOW_VIEWER) {
1481 info_array[i++] = IFACE_(" (Viewer)");
1482 }
1483 }
1484
1485 BLI_assert(i < int(ARRAY_SIZE(info_array)));
1486
1487 char info[MAX_ID_NAME * 4];
1488 /* It's expected there will be enough room for the whole string in the buffer.
1489 * If not, increase it. */
1490 BLI_assert(BLI_string_len_array(info_array, i) < sizeof(info));
1491
1492 BLI_string_join_array(info, sizeof(info), info_array, i);
1493
1494 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
1495 BLF_draw_default(xoffset, *yoffset, 0.0f, info, sizeof(info));
1496}
1497
1499 Scene *scene, ARegion *region, View3D *v3d, int xoffset, int *yoffset)
1500{
1501 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1502 if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
1503 const char *grid_unit = nullptr;
1504 ED_view3d_grid_view_scale(scene, v3d, region, &grid_unit);
1505
1506 if (grid_unit) {
1507 char numstr[32] = "";
1508 if (v3d->grid != 1.0f) {
1510 numstr, "%s " BLI_STR_UTF8_MULTIPLICATION_SIGN " %.4g", grid_unit, v3d->grid);
1511 }
1512
1513 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
1514 BLF_draw_default(xoffset, *yoffset, 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr));
1515 }
1516 }
1517}
1518
1520{
1521 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1522 View3D *v3d = CTX_wm_view3d(C);
1523 Scene *scene = CTX_data_scene(C);
1525 Main *bmain = CTX_data_main(C);
1526 ViewLayer *view_layer = CTX_data_view_layer(C);
1527
1528#ifdef WITH_INPUT_NDOF
1529 if (U.ndof_flag & NDOF_SHOW_GUIDE_ORBIT_AXIS) {
1530 if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
1531 /* It only makes sense to show when orbiting. */
1532 if (rv3d->ndof_rot_angle != 0.0f) {
1533 /* TODO: draw something else (but not this) during fly mode. */
1534 draw_ndof_guide_orbit_axis(rv3d);
1535 }
1536 }
1537 }
1538
1539 if (U.ndof_flag & NDOF_SHOW_GUIDE_ORBIT_CENTER) {
1540 /* Draw this only when orbiting and auto orbit-center is enabled */
1542 if (rv3d->ndof_flag & RV3D_NDOF_OFS_IS_VALID) {
1543 /* When the center is locked, the auto-center is not used. */
1544 if (!(v3d->ob_center_cursor || v3d->ob_center)) {
1545 /* It only makes sense to show when orbiting. */
1546 if (rv3d->ndof_rot_angle != 0.0f) {
1547 draw_ndof_guide_orbit_center(rv3d);
1548 }
1549 }
1550 }
1551 }
1552 }
1553#endif
1554
1555 /* correct projection matrix */
1556 ED_region_pixelspace(region);
1557
1558 /* local coordinate visible rect inside region, to accommodate overlapping ui */
1559 const rcti *rect = ED_region_visible_rect(region);
1560
1561 view3d_draw_border(C, region);
1563
1565
1567 /* pass */
1568 }
1569 else {
1570 switch ((eUserpref_MiniAxisType)U.mini_axis_type) {
1572 /* The gizmo handles its own drawing. */
1573 break;
1575 draw_view_axis(rv3d, rect);
1577 break;
1578 }
1579 }
1580
1581 if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) {
1582 int xoffset = rect->xmin + (0.5f * U.widget_unit);
1583 int yoffset = rect->ymax - (0.1f * U.widget_unit);
1584
1585 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
1586 UI_fontstyle_set(fstyle);
1587 BLF_default_size(fstyle->points);
1589
1590 const int font_id = BLF_default();
1591 float text_color[4], shadow_color[4];
1592 ED_view3d_text_colors_get(scene, v3d, text_color, shadow_color);
1593 BLF_color4fv(font_id, text_color);
1594 BLF_enable(font_id, BLF_SHADOW);
1595 BLF_shadow_offset(font_id, 0, 0);
1596 BLF_shadow(font_id, FontShadowType::Outline, shadow_color);
1597
1598 if ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
1599 if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
1600 ED_scene_draw_fps(scene, xoffset, &yoffset);
1601 BLF_color4fv(font_id, text_color);
1602 }
1603 else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
1604 draw_viewport_name(region, v3d, xoffset, &yoffset);
1605 }
1606
1607 if (U.uiflag & USER_DRAWVIEWINFO) {
1608 BKE_view_layer_synced_ensure(scene, view_layer);
1609 Object *ob = BKE_view_layer_active_object_get(view_layer);
1610 draw_selected_name(v3d, scene, view_layer, ob, xoffset, &yoffset);
1611 BLF_color4fv(font_id, text_color);
1612 }
1613
1615 /* draw below the viewport name */
1616 draw_grid_unit_name(scene, region, v3d, xoffset, &yoffset);
1617 }
1618
1620 }
1621
1622 if (v3d->overlay.flag & V3D_OVERLAY_STATS) {
1623 View3D *v3d_local = v3d->localvd ? v3d : nullptr;
1625 bmain, scene, view_layer, v3d_local, xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT);
1626 }
1627
1628 /* Set the size back to the default hard-coded size. Otherwise anyone drawing after this,
1629 * without setting explicit size, will draw with widget size. That is probably ideal,
1630 * but size should be set at the calling site not just carried over from here. */
1632 BLF_disable(font_id, BLF_SHADOW);
1633 }
1634
1636}
1637
1639
1640/* -------------------------------------------------------------------- */
1643
1644static void view3d_draw_view(const bContext *C, ARegion *region)
1645{
1650 region,
1652 nullptr,
1653 nullptr,
1654 nullptr);
1655
1656 /* Only 100% compliant on new spec goes below */
1658}
1659
1661{
1662 /*
1663 * Temporary viewport draw modes until we have a proper system.
1664 * all modes are done in the draw manager, except external render
1665 * engines like Cycles.
1666 */
1667 RenderEngineType *type = RE_engines_find(scene->r.engine);
1668 if (drawtype == OB_MATERIAL && (type->flag & RE_USE_EEVEE_VIEWPORT)) {
1670 }
1671 return type;
1672}
1673
1675{
1676 View3D *v3d = CTX_wm_view3d(C);
1677 WorkSpace *workspace = CTX_wm_workspace(C);
1678 /* Always use viewer path from workspace, pinning is not supported currently. */
1679 if (!BKE_viewer_path_equal(&v3d->viewer_path, &workspace->viewer_path)) {
1681 BKE_viewer_path_copy(&v3d->viewer_path, &workspace->viewer_path);
1682 }
1683}
1684
1686{
1687 using namespace blender::draw;
1688 Main *bmain = CTX_data_main(C);
1689 View3D *v3d = CTX_wm_view3d(C);
1690
1692 view3d_draw_view(C, region);
1693
1697
1698 /* No depth test for drawing action zones afterwards. */
1700
1702 /* TODO: Clear cache? */
1703}
1704
1706
1707/* -------------------------------------------------------------------- */
1710
1712 const Scene *scene,
1713 View3D *v3d,
1714 ARegion *region,
1715 const float winmat[4][4],
1716 const char *viewname)
1717{
1718 /* update the viewport matrices with the new camera */
1720 float viewmat[4][4];
1721 const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
1722
1723 BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
1724 view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
1725 }
1726 else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
1727 float viewmat[4][4];
1728 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
1729
1730 BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
1731 view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
1732 }
1733}
1734
1736 const Scene *scene,
1737 eDrawType drawtype,
1738 View3D *v3d,
1739 ARegion *region,
1740 int winx,
1741 int winy,
1742 const float viewmat[4][4],
1743 const float winmat[4][4],
1744 bool is_image_render,
1745 bool draw_background,
1746 const char *viewname,
1747 const bool do_color_management,
1748 const bool restore_rv3d_mats,
1749 GPUOffScreen *ofs,
1750 GPUViewport *viewport)
1751{
1752 using namespace blender::draw;
1753 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1754 RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype);
1755
1756 /* Store `orig` variables. */
1757 struct {
1758 bThemeState theme_state;
1759
1760 /* #View3D */
1761 eDrawType v3d_shading_type;
1762 Object *v3d_camera;
1763 float v3d_lens;
1764
1765 /* #Region */
1766 int region_winx, region_winy;
1767 rcti region_winrct;
1768
1769 /* #RegionView3D */
1774 RV3DMatrixStore *rv3d_mats;
1775 char rv3d_persp;
1776 } orig{};
1777 orig.v3d_shading_type = eDrawType(v3d->shading.type);
1778 orig.v3d_camera = v3d->camera;
1779 orig.v3d_lens = v3d->lens;
1780 orig.region_winx = region->winx;
1781 orig.region_winy = region->winy;
1782 orig.region_winrct = region->winrct;
1783 orig.rv3d_persp = rv3d->persp;
1784 orig.rv3d_mats = ED_view3d_mats_rv3d_backup(static_cast<RegionView3D *>(region->regiondata));
1785
1786 UI_Theme_Store(&orig.theme_state);
1788
1789 /* Set temporary new size. */
1790 region->winx = winx;
1791 region->winy = winy;
1792 region->winrct.xmin = 0;
1793 region->winrct.ymin = 0;
1794 region->winrct.xmax = winx;
1795 region->winrct.ymax = winy;
1796
1797 /* There are too many functions inside the draw manager that check the shading type,
1798 * so use a temporary override instead. */
1799 v3d->shading.type = drawtype;
1800
1801 /* Set flags. */
1803
1804 {
1805 /* Free images which can have changed on frame-change.
1806 * WARNING(@ideasman42): can be slow so only free animated images. */
1808 }
1809
1810 if (viewmat) {
1811 /* WORKAROUND: Disable camera view to avoid EEVEE being confused and try to
1812 * get the projection matrix from the camera.
1813 * Set the `lens` parameter to 0 to make EEVEE prefer the `winmat` from the rv3d instead of
1814 * trying to rederive it. Note that this produces incorrect result with over-scan. */
1815 rv3d->persp = (winmat[3][3] == 0.0f) ? RV3D_PERSP : RV3D_ORTHO;
1816 v3d->camera = nullptr;
1817 v3d->lens = 0.0f;
1818 }
1819
1824
1825 if ((viewname != nullptr && viewname[0] != '\0') && (viewmat == nullptr) &&
1826 rv3d->persp == RV3D_CAMOB && v3d->camera)
1827 {
1828 view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, region, winmat, viewname);
1829 }
1830 else {
1831 view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
1832 }
1833
1834 if (viewport) {
1835 GPU_viewport_tag_update(viewport);
1836 }
1837
1838 /* main drawing call */
1840 engine_type,
1841 region,
1842 v3d,
1843 is_image_render,
1845 do_color_management,
1846 ofs,
1847 viewport);
1851
1852 /* Restore all `orig` members. */
1853 region->winx = orig.region_winx;
1854 region->winy = orig.region_winy;
1855 region->winrct = orig.region_winrct;
1856
1857 /* Optionally do _not_ restore rv3d matrices (e.g. they are used/stored in the ImBuff for
1858 * reprojection, see texture_paint_image_from_view_exec(). */
1859 if (restore_rv3d_mats) {
1860 ED_view3d_mats_rv3d_restore(static_cast<RegionView3D *>(region->regiondata), orig.rv3d_mats);
1861 }
1862 MEM_freeN(orig.rv3d_mats);
1863 rv3d->persp = orig.rv3d_persp;
1864
1865 UI_Theme_Restore(&orig.theme_state);
1866
1867 v3d->shading.type = orig.v3d_shading_type;
1868 v3d->camera = orig.v3d_camera;
1869 v3d->lens = orig.v3d_lens;
1870
1872}
1873
1875 Scene *scene,
1876 View3DShading *shading_override,
1877 eDrawType drawtype,
1878 int object_type_exclude_viewport_override,
1879 int object_type_exclude_select_override,
1880 int winx,
1881 int winy,
1882 uint draw_flags,
1883 const float viewmat[4][4],
1884 const float winmat[4][4],
1885 float clip_start,
1886 float clip_end,
1887 float vignette_aperture,
1888 bool is_xr_surface,
1889 bool is_image_render,
1890 bool draw_background,
1891 const char *viewname,
1892 const bool do_color_management,
1893 GPUOffScreen *ofs,
1894 GPUViewport *viewport)
1895{
1896 View3D v3d = blender::dna::shallow_zero_initialize();
1897 ARegion ar = {nullptr};
1898 blender::bke::ARegionRuntime region_runtime{};
1899 ar.runtime = &region_runtime;
1900 RegionView3D rv3d = {{{0}}};
1901
1902 v3d.regionbase.first = v3d.regionbase.last = &ar;
1903 ar.regiondata = &rv3d;
1905
1906 View3DShading *source_shading_settings = &scene->display.shading;
1907 if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != nullptr) {
1908 source_shading_settings = shading_override;
1909 }
1910 memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
1911 v3d.shading.type = drawtype;
1912
1913 if (shading_override) {
1914 /* Pass. */
1915 }
1916 else if (drawtype == OB_MATERIAL) {
1918 }
1919
1922 }
1923 else {
1924 if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) {
1926 }
1927 if (draw_flags & V3D_OFSDRAW_SHOW_GRIDFLOOR) {
1929 v3d.grid = 1.0f;
1930 v3d.gridlines = 16;
1931 v3d.gridsubdiv = 10;
1932 }
1933 if (draw_flags & V3D_OFSDRAW_SHOW_SELECTION) {
1934 v3d.flag |= V3D_SELECT_OUTLINE;
1935 }
1936 if (draw_flags & V3D_OFSDRAW_XR_SHOW_CONTROLLERS) {
1938 }
1939 if (draw_flags & V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS) {
1941 }
1942 if (draw_flags & V3D_OFSDRAW_XR_SHOW_PASSTHROUGH) {
1944 }
1945 /* Disable other overlays (set all available _HIDE_ flags). */
1948 if ((draw_flags & V3D_OFSDRAW_SHOW_OBJECT_EXTRAS) == 0) {
1950 }
1951 if ((object_type_exclude_viewport_override & (1 << OB_ARMATURE)) != 0) {
1953 }
1954 v3d.flag |= V3D_HIDE_HELPLINES;
1955 }
1956
1957 if (is_xr_surface) {
1959 }
1960
1961 v3d.object_type_exclude_viewport = object_type_exclude_viewport_override;
1962 v3d.object_type_exclude_select = object_type_exclude_select_override;
1963
1964 rv3d.persp = RV3D_PERSP;
1965 v3d.clip_start = clip_start;
1966 v3d.clip_end = clip_end;
1967 /* Actually not used since we pass in the projection matrix. */
1968 v3d.lens = 0;
1969 v3d.vignette_aperture = vignette_aperture;
1970
1971 /* WORKAROUND: Disable overscan because it is not supported for arbitrary input matrices.
1972 * The proper fix to this would be to support arbitrary matrices in `eevee::Camera::sync()`. */
1973 float overscan = scene->eevee.overscan;
1974 scene->eevee.overscan = 0.0f;
1975
1977 scene,
1978 drawtype,
1979 &v3d,
1980 &ar,
1981 winx,
1982 winy,
1983 viewmat,
1984 winmat,
1985 is_image_render,
1987 viewname,
1988 do_color_management,
1989 true,
1990 ofs,
1991 viewport);
1992
1993 /* Restore overscan. */
1994 scene->eevee.overscan = overscan;
1995}
1996
1998 Scene *scene,
1999 eDrawType drawtype,
2000 View3D *v3d,
2001 ARegion *region,
2002 int sizex,
2003 int sizey,
2004 eImBufFlags imbuf_flag,
2005 int alpha_mode,
2006 const char *viewname,
2007 const bool restore_rv3d_mats,
2008 GPUOffScreen *ofs,
2009 GPUViewport *viewport,
2010 /* output vars */
2011 char err_out[256])
2012{
2013 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2014 const bool draw_sky = (alpha_mode == R_ADDSKY);
2015
2016 /* view state */
2017 bool is_ortho = false;
2018 float winmat[4][4];
2019
2020 /* Guess format based on output buffer. */
2021 blender::gpu::TextureFormat desired_format =
2022 (imbuf_flag & IB_float_data) ? blender::gpu::TextureFormat::SFLOAT_16_16_16_16 :
2023 blender::gpu::TextureFormat::UNORM_8_8_8_8;
2024
2025 if (ofs && ((GPU_offscreen_width(ofs) != sizex) || (GPU_offscreen_height(ofs) != sizey))) {
2026 /* If offscreen has already been created, recreate with the same format. */
2027 desired_format = GPU_offscreen_format(ofs);
2028 /* sizes differ, can't reuse */
2029 ofs = nullptr;
2030 }
2031
2033
2034 if (old_fb) {
2036 }
2037
2038 const bool own_ofs = (ofs == nullptr);
2040
2041 if (own_ofs) {
2042 /* bind */
2043 ofs = GPU_offscreen_create(sizex,
2044 sizey,
2045 true,
2046 desired_format,
2048 false,
2049 err_out);
2050 if (ofs == nullptr) {
2052 return nullptr;
2053 }
2054 }
2055
2056 GPU_offscreen_bind(ofs, true);
2057
2058 /* read in pixels & stamp */
2059 ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, imbuf_flag);
2060
2061 /* render 3d view */
2062 if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
2064 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
2065 const Object *camera_eval = DEG_get_evaluated(depsgraph, camera);
2066
2068 /* fallback for non camera objects */
2069 params.clip_start = v3d->clip_start;
2070 params.clip_end = v3d->clip_end;
2072 BKE_camera_multiview_params(&scene->r, &params, camera_eval, viewname);
2073 BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
2075
2076 is_ortho = params.is_ortho;
2077 copy_m4_m4(winmat, params.winmat);
2078 }
2079 else {
2080 rctf viewplane;
2081 float clip_start, clipend;
2082
2083 is_ortho = ED_view3d_viewplane_get(
2084 depsgraph, v3d, rv3d, sizex, sizey, &viewplane, &clip_start, &clipend, nullptr);
2085 if (is_ortho) {
2086 orthographic_m4(winmat,
2087 viewplane.xmin,
2088 viewplane.xmax,
2089 viewplane.ymin,
2090 viewplane.ymax,
2091 -clipend,
2092 clipend);
2093 }
2094 else {
2095 perspective_m4(winmat,
2096 viewplane.xmin,
2097 viewplane.xmax,
2098 viewplane.ymin,
2099 viewplane.ymax,
2100 clip_start,
2101 clipend);
2102 }
2103 }
2104
2105 /* XXX(jbakker): `do_color_management` should be controlled by the caller. Currently when doing a
2106 * viewport render animation and saving to an 8bit file format, color management would be applied
2107 * twice. Once here, and once when saving the saving to disk. In this case the Save As Render
2108 * option cannot be controlled either. But when doing an off-screen render you want to do the
2109 * color management here.
2110 *
2111 * This option was added here to increase the performance for quick view-port preview renders.
2112 * When using workbench the color differences haven't been reported as a bug. But users also use
2113 * the viewport rendering to render Eevee scenes. In the later situation the saved colors are
2114 * totally wrong. */
2115 const bool do_color_management = (ibuf->float_buffer.data == nullptr);
2117 scene,
2118 drawtype,
2119 v3d,
2120 region,
2121 sizex,
2122 sizey,
2123 nullptr,
2124 winmat,
2125 true,
2126 draw_sky,
2127 viewname,
2128 do_color_management,
2129 restore_rv3d_mats,
2130 ofs,
2131 viewport);
2132
2133 if (ibuf->float_buffer.data) {
2135 }
2136 else if (ibuf->byte_buffer.data) {
2138 }
2139
2140 /* unbind */
2141 GPU_offscreen_unbind(ofs, true);
2142
2143 if (own_ofs) {
2144 GPU_offscreen_free(ofs);
2145 }
2146
2148
2149 if (old_fb) {
2150 GPU_framebuffer_bind(old_fb);
2151 }
2152
2153 if (ibuf->float_buffer.data && ibuf->byte_buffer.data) {
2154 IMB_byte_from_float(ibuf);
2155 }
2156
2157 return ibuf;
2158}
2159
2161 Scene *scene,
2162 View3DShading *shading_override,
2163 eDrawType drawtype,
2164 Object *camera,
2165 int width,
2166 int height,
2167 eImBufFlags imbuf_flag,
2168 eV3DOffscreenDrawFlag draw_flags,
2169 int alpha_mode,
2170 const char *viewname,
2171 GPUOffScreen *ofs,
2172 GPUViewport *viewport,
2173 char err_out[256])
2174{
2175 View3D v3d = blender::dna::shallow_zero_initialize();
2176 ARegion region = {nullptr};
2177 blender::bke::ARegionRuntime region_runtime{};
2178 region.runtime = &region_runtime;
2179 RegionView3D rv3d = {{{0}}};
2180
2181 /* connect data */
2182 v3d.regionbase.first = v3d.regionbase.last = &region;
2183 region.regiondata = &rv3d;
2184 region.regiontype = RGN_TYPE_WINDOW;
2185
2186 v3d.camera = camera;
2187 View3DShading *source_shading_settings = &scene->display.shading;
2188 if (draw_flags & V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS && shading_override != nullptr) {
2189 source_shading_settings = shading_override;
2190 }
2191 memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
2192
2193 if (drawtype == OB_RENDER) {
2194 /* Don't use external engines for preview. Fall back to solid instead of Eevee as rendering
2195 * with Eevee is potentially slow due to compiling shaders and loading textures, and the
2196 * depsgraph may not have been updated to have all the right geometry attributes. */
2198 drawtype = OB_SOLID;
2199 }
2200 }
2201
2202 if (drawtype == OB_MATERIAL) {
2205 }
2206 else if (drawtype == OB_RENDER) {
2209 }
2210 else if (drawtype == OB_TEXTURE) {
2211 drawtype = OB_SOLID;
2214 }
2215 v3d.shading.type = drawtype;
2216
2218 /* HACK: When rendering gpencil objects this opacity is used to mix vertex colors in when not in
2219 * render mode (e.g. in the sequencer). */
2221
2222 /* Also initialize wire-frame properties to the default so it renders properly in sequencer.
2223 * Should find some way to use the viewport's current opacity and threshold,
2224 * but this is a start. */
2225 v3d.overlay.wireframe_opacity = 1.0f;
2226 v3d.overlay.wireframe_threshold = 0.5f;
2227
2228 if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) {
2230 }
2231 if (draw_flags & V3D_OFSDRAW_SHOW_GRIDFLOOR) {
2233 }
2234
2236
2237 rv3d.persp = RV3D_CAMOB;
2238
2239 copy_m4_m4(rv3d.viewinv, v3d.camera->object_to_world().ptr());
2240 normalize_m4(rv3d.viewinv);
2241 invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
2242
2243 {
2245 const Object *view_camera_eval = DEG_get_evaluated(
2246 depsgraph, BKE_camera_multiview_render(scene, v3d.camera, viewname));
2247
2249 BKE_camera_params_from_object(&params, view_camera_eval);
2250 BKE_camera_multiview_params(&scene->r, &params, view_camera_eval, viewname);
2251 BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
2253
2254 copy_m4_m4(rv3d.winmat, params.winmat);
2255 v3d.clip_start = params.clip_start;
2256 v3d.clip_end = params.clip_end;
2257 v3d.lens = params.lens;
2258 }
2259
2260 mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
2261 invert_m4_m4(rv3d.persinv, rv3d.viewinv);
2262
2264 scene,
2265 eDrawType(v3d.shading.type),
2266 &v3d,
2267 &region,
2268 width,
2269 height,
2270 imbuf_flag,
2271 alpha_mode,
2272 viewname,
2273 true,
2274 ofs,
2275 viewport,
2276 err_out);
2277}
2278
2283
2285
2286/* -------------------------------------------------------------------- */
2289
2290static bool view3d_clipping_test(const float co[3], const float clip[6][4])
2291{
2292 if (plane_point_side_v3(clip[0], co) > 0.0f && plane_point_side_v3(clip[1], co) > 0.0f &&
2293 plane_point_side_v3(clip[2], co) > 0.0f && plane_point_side_v3(clip[3], co) > 0.0f)
2294 {
2295 return false;
2296 }
2297 return true;
2298}
2299
2300bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
2301{
2302 return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
2303}
2304
2306
2307/* -------------------------------------------------------------------- */
2310
2315 const Scene *scene,
2316 ViewLayer *view_layer,
2317 ARegion *region,
2318 View3D *v3d,
2319 Object *obact)
2320{
2321 /* TODO: Use a flag in the selection engine itself. */
2323 return;
2324 }
2325 Object *obact_eval = DEG_get_evaluated(depsgraph, obact);
2326
2328 UNUSED_VARS_NDEBUG(region);
2329
2330 if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
2331 BKE_paint_select_face_test(obact_eval)))
2332 {
2333 /* do nothing */
2334 }
2335 /* texture paint mode sampling */
2336 else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) &&
2337 (v3d->shading.type > OB_WIRE))
2338 {
2339 /* do nothing */
2340 }
2341 else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) {
2342 /* do nothing */
2343 }
2344 else {
2346 return;
2347 }
2348
2349 if (obact_eval && ((obact_eval->base_flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0)) {
2350 BKE_view_layer_synced_ensure(scene, view_layer);
2351 Base *base = BKE_view_layer_base_find(view_layer, obact);
2353 }
2354
2356}
2357
2358/* Avoid calling this function multiple times in sequence to prevent frequent CPU-GPU
2359 * synchronization (which can be very slow). */
2360static void view3d_gpu_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
2361{
2363
2364 blender::gpu::FrameBuffer *depth_read_fb = nullptr;
2365 GPU_framebuffer_ensure_config(&depth_read_fb,
2366 {
2367 GPU_ATTACHMENT_TEXTURE(depth_tx),
2369 });
2370
2371 GPU_framebuffer_bind(depth_read_fb);
2372 GPU_framebuffer_read_depth(depth_read_fb,
2373 rect->xmin,
2374 rect->ymin,
2375 BLI_rcti_size_x(rect),
2376 BLI_rcti_size_y(rect),
2378 data);
2379
2381 GPU_framebuffer_free(depth_read_fb);
2382}
2383
2385{
2387 vc->depsgraph, vc->scene, vc->view_layer, vc->region, vc->v3d, vc->obact);
2388}
2389
2390int ED_view3d_backbuf_sample_size_clamp(ARegion *region, const float dist)
2391{
2392 return int(min_ff(ceilf(dist), float(max_ii(region->winx, region->winy))));
2393}
2394
2396
2397/* -------------------------------------------------------------------- */
2400
2402{
2403 /* clamp rect by region */
2404 rcti r{};
2405 r.xmin = 0;
2406 r.xmax = region->winx - 1;
2407 r.ymin = 0;
2408 r.ymax = region->winy - 1;
2409
2410 /* Constrain rect to depth bounds */
2411 BLI_rcti_isect(&r, rect, rect);
2412
2413 /* assign values to compare with the ViewDepths */
2414 int x = rect->xmin;
2415 int y = rect->ymin;
2416
2417 int w = BLI_rcti_size_x(rect);
2418 int h = BLI_rcti_size_y(rect);
2419
2420 if (w <= 0 || h <= 0) {
2421 r_d->depths = nullptr;
2422 return;
2423 }
2424
2425 r_d->x = x;
2426 r_d->y = y;
2427 r_d->w = w;
2428 r_d->h = h;
2429
2430 r_d->depths = MEM_malloc_arrayN<float>(w * h, "View depths Subset");
2431
2432 {
2433 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2434 view3d_gpu_read_Z_pixels(viewport, rect, r_d->depths);
2435 /* Range is assumed to be this as they are never changed. */
2436 r_d->depth_range[0] = 0.0;
2437 r_d->depth_range[1] = 1.0;
2438 }
2439}
2440
2441/* NOTE: with NOUVEAU drivers the #glReadPixels() is very slow. #24339. */
2443{
2444 ViewDepths *d = MEM_callocN<ViewDepths>("ViewDepths");
2445
2446 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2448 d->w = GPU_texture_width(depth_tx);
2449 d->h = GPU_texture_height(depth_tx);
2450 d->depths = static_cast<float *>(GPU_texture_read(depth_tx, GPU_DATA_FLOAT, 0));
2451 /* Assumed to be this as they are never changed. */
2452 d->depth_range[0] = 0.0;
2453 d->depth_range[1] = 1.0;
2454
2455 return d;
2456}
2457
2458float view3d_depth_near_ex(ViewDepths *d, int r_xy[2])
2459{
2460 /* Convert to float for comparisons. */
2461 const float near = float(d->depth_range[0]);
2462 const float far_real = float(d->depth_range[1]);
2463 float far = far_real;
2464
2465 const float *depths = d->depths;
2466 const int depth_num = int(d->w) * int(d->h); /* Cast to avoid short overflow. */
2467
2468 /* Far is both the starting 'far' value
2469 * and the closest value found. */
2470 if (r_xy != nullptr) {
2471 int index_found = -1;
2472 for (int i = 0; i < depth_num; i++) {
2473 const float depth = *depths++;
2474 if ((depth < far) && (depth > near)) {
2475 far = depth;
2476 index_found = i;
2477 }
2478 }
2479 if (index_found != -1) {
2480 r_xy[0] = d->x + (index_found % int(d->w));
2481 r_xy[1] = d->y + (index_found / int(d->w));
2482 }
2483 }
2484 else {
2485 for (int i = 0; i < depth_num; i++) {
2486 const float depth = depths[i];
2487 if ((depth < far) && (depth > near)) {
2488 far = depth;
2489 }
2490 }
2491 }
2492
2493 return far == far_real ? FLT_MAX : far;
2494}
2495
2497{
2498 return view3d_depth_near_ex(d, nullptr);
2499}
2500
2502 ARegion *region,
2503 View3D *v3d,
2504 Object * /* obact */,
2506 bool use_overlay,
2507 ViewDepths **r_depths)
2508{
2510 /* Force redraw if `r_depths` is required. */
2511 if (!r_depths || *r_depths != nullptr) {
2512 return;
2513 }
2514 }
2515 bThemeState theme_state;
2517 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2518
2519 short flag = v3d->flag;
2520 int flag2 = v3d->flag2;
2521 /* Setting these temporarily is not nice */
2522 v3d->flag &= ~V3D_SELECT_OUTLINE;
2523
2524 if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
2525 use_overlay = false;
2526 }
2527
2528 if (!use_overlay) {
2529 v3d->flag2 |= V3D_HIDE_OVERLAYS;
2530 }
2531
2532 /* Tools may request depth outside of regular drawing code. */
2533 UI_Theme_Store(&theme_state);
2535
2536 ED_view3d_draw_setup_view(static_cast<wmWindowManager *>(G_MAIN->wm.first),
2537 nullptr,
2538 depsgraph,
2539 scene,
2540 region,
2541 v3d,
2542 nullptr,
2543 nullptr,
2544 nullptr);
2545
2546 /* get surface depth without bias */
2548
2549 /* Needed in cases the 3D Viewport isn't already setup. */
2552
2553 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2554 /* When Blender is starting, a click event can trigger a depth test while the viewport is not
2555 * yet available. */
2556 if (viewport != nullptr) {
2557 switch (mode) {
2558 case V3D_DEPTH_ALL:
2559 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, true, false, false);
2560 break;
2562 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, false, false, false);
2563 break;
2565 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, true, false, false);
2566 break;
2568 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, false, false, true);
2569 break;
2571 DRW_draw_depth_loop(depsgraph, region, v3d, viewport, false, true, false);
2572 break;
2573 }
2574
2575 if (r_depths) {
2576 if (*r_depths) {
2577 ED_view3d_depths_free(*r_depths);
2578 }
2579 *r_depths = view3d_depths_create(region);
2580 }
2581 }
2582
2584
2586
2587 /* Restore. */
2588 v3d->flag = flag;
2589 v3d->flag2 = flag2;
2591
2592 UI_Theme_Restore(&theme_state);
2593}
2594
2596{
2597 if (depths->depths) {
2598 MEM_freeN(depths->depths);
2599 }
2600 MEM_freeN(depths);
2601}
2602
2603bool ED_view3d_has_depth_buffer_updated(const Depsgraph *depsgraph, const View3D *v3d)
2604{
2605#ifdef REUSE_DEPTH_BUFFER
2606 /* Check if the depth buffer was drawn by any engine and thus can be reused.
2607 *
2608 * The idea is good, but it is too error prone.
2609 * Even when updated by an engine, the depth buffer can still be cleared by drawing callbacks and
2610 * by the GPU_select API used by gizmos.
2611 * Check #GPU_clear_depth to track when the depth buffer is cleared. */
2612 const char *engine_name = DEG_get_evaluated_scene(depsgraph)->r.engine;
2613 RenderEngineType *engine_type = RE_engines_find(engine_name);
2614
2615 bool is_viewport_wire_no_xray = v3d->shading.type < OB_SOLID && !XRAY_ENABLED(v3d);
2616 bool is_viewport_preview_solid = v3d->shading.type == OB_SOLID;
2617 bool is_viewport_preview_material = v3d->shading.type == OB_MATERIAL;
2618 bool is_viewport_render_eevee = v3d->shading.type == OB_RENDER &&
2619 (STREQ(engine_name, RE_engine_id_BLENDER_EEVEE));
2620 bool is_viewport_render_workbench = v3d->shading.type == OB_RENDER &&
2622 bool is_viewport_render_external_with_overlay = v3d->shading.type == OB_RENDER &&
2623 !(engine_type->flag & RE_INTERNAL) &&
2624 !(v3d->flag2 & V3D_HIDE_OVERLAYS);
2625
2626 return is_viewport_preview_solid || is_viewport_preview_material || is_viewport_wire_no_xray ||
2627 is_viewport_render_eevee || is_viewport_render_workbench ||
2628 is_viewport_render_external_with_overlay;
2629#else
2630 UNUSED_VARS(depsgraph, v3d);
2631 return false;
2632#endif
2633}
2634
2636
2637/* -------------------------------------------------------------------- */
2640
2641void ED_view3d_datamask(const Scene *scene,
2642 ViewLayer *view_layer,
2643 const View3D *v3d,
2644 CustomData_MeshMasks *r_cddata_masks)
2645{
2646 /* NOTE(@ideasman42): as this function runs continuously while idle
2647 * (from #wm_event_do_depsgraph) take care to avoid expensive lookups.
2648 * While they won't hurt performance noticeably, they will increase CPU usage while idle. */
2651 r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
2652 }
2653 else if (v3d->shading.type == OB_SOLID) {
2655 r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2;
2656 }
2658 r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR;
2659 r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
2660 }
2661 }
2662
2663 BKE_view_layer_synced_ensure(scene, view_layer);
2664 Object *obact = BKE_view_layer_active_object_get(view_layer);
2665 if (obact) {
2666 switch (obact->type) {
2667 case OB_MESH: {
2668 switch (obact->mode) {
2669 case OB_MODE_EDIT: {
2671 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
2672 }
2673 break;
2674 }
2675 }
2676 break;
2677 }
2678 }
2679 }
2680}
2681
2683 ViewLayer *view_layer,
2684 const bScreen *screen,
2685 CustomData_MeshMasks *r_cddata_masks)
2686{
2688
2689 /* Check if we need UV or color data due to the view mode. */
2690 LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
2691 if (area->spacetype == SPACE_VIEW3D) {
2693 scene, view_layer, static_cast<View3D *>(area->spacedata.first), r_cddata_masks);
2694 }
2695 }
2696}
2697
2699
2700/* -------------------------------------------------------------------- */
2703
2712 float winmat[4][4];
2713 float viewmat[4][4];
2714 float viewinv[4][4];
2715 float persmat[4][4];
2716 float persinv[4][4];
2718 float pixsize;
2719};
2720
2722{
2723 RV3DMatrixStore *rv3dmat = static_cast<RV3DMatrixStore *>(
2724 MEM_mallocN(sizeof(*rv3dmat), __func__));
2725 copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
2726 copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
2727 copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
2728 copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
2729 copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
2731 rv3dmat->pixsize = rv3d->pixsize;
2732 return rv3dmat;
2733}
2734
2736{
2737 RV3DMatrixStore *rv3dmat = rv3dmat_pt;
2738 copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
2739 copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
2740 copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
2741 copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
2742 copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
2744 rv3d->pixsize = rv3dmat->pixsize;
2745}
2746
2748{
2749 MEM_freeN(rv3d_mat);
2750}
2751
2753
2754/* -------------------------------------------------------------------- */
2757
2758void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
2759{
2760 *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT;
2761
2763 if (!ED_scene_fps_average_calc(scene, &state)) {
2764 return;
2765 }
2766
2767 /* 8 4-bytes chars (complex writing systems like Devanagari in UTF8 encoding) */
2768 char printable[32];
2769 printable[0] = '\0';
2770
2771 bool show_fractional = state.fps_target_is_fractional;
2772
2773 const int font_id = BLF_default();
2774
2775 /* Is this more than half a frame behind? */
2776 if (state.fps_average + 0.5f < state.fps_target) {
2777 /* Always show fractional when under performing. */
2778 show_fractional = true;
2779 float alert_rgb[4];
2780 float alert_hsv[4];
2781 UI_GetThemeColor4fv(TH_REDALERT, alert_rgb);
2782 /* Brighten since we favor dark shadows to increase contrast.
2783 * This gives similar results to the old hardcoded 225, 36, 36. */
2784 rgb_to_hsv_v(alert_rgb, alert_hsv);
2785 alert_hsv[2] = 1.0;
2786 hsv_to_rgb_v(alert_hsv, alert_rgb);
2787 BLF_color4fv(font_id, alert_rgb);
2788 }
2789
2790 if (show_fractional) {
2791 SNPRINTF_UTF8(printable, IFACE_("fps: %.2f"), state.fps_average);
2792 }
2793 else {
2794 SNPRINTF_UTF8(printable, IFACE_("fps: %i"), int(state.fps_average + 0.5f));
2795 }
2796
2797 BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable));
2798}
2799
2801
2802/* -------------------------------------------------------------------- */
2805
2807{
2808 RenderEngineType *type = RE_engines_find(scene->r.engine);
2809 return (type && type->view_update && type->view_draw);
2810}
2811
2813 const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *region, rcti *r_rect)
2814{
2815 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2816 bool use_border;
2817
2818 /* Test if there is a 3d view rendering. */
2820 return false;
2821 }
2822
2823 /* Test if there is a border render. */
2824 if (rv3d->persp == RV3D_CAMOB) {
2825 use_border = (scene->r.mode & R_BORDER) != 0;
2826 }
2827 else {
2828 use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
2829 }
2830
2831 if (!use_border) {
2832 return false;
2833 }
2834
2835 /* Compute border. */
2836 if (rv3d->persp == RV3D_CAMOB) {
2837 rctf viewborder;
2838 ED_view3d_calc_camera_border(scene, depsgraph, region, v3d, rv3d, false, &viewborder);
2839
2840 r_rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
2841 r_rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
2842 r_rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
2843 r_rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
2844 }
2845 else {
2846 r_rect->xmin = v3d->render_border.xmin * region->winx;
2847 r_rect->xmax = v3d->render_border.xmax * region->winx;
2848 r_rect->ymin = v3d->render_border.ymin * region->winy;
2849 r_rect->ymax = v3d->render_border.ymax * region->winy;
2850 }
2851
2852 BLI_rcti_translate(r_rect, region->winrct.xmin, region->winrct.ymin);
2853 BLI_rcti_isect(&region->winrct, r_rect, r_rect);
2854
2855 return true;
2856}
2857
2859
2860/* -------------------------------------------------------------------- */
2863
2865{
2866 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2867 if (viewport == nullptr) {
2868 return false;
2869 }
2870
2871 blender::gpu::Texture *color_tex = GPU_viewport_color_texture(viewport, 0);
2872 if (color_tex == nullptr) {
2873 return false;
2874 }
2875
2876 tex_w = GPU_texture_width(color_tex);
2877 tex_h = GPU_texture_height(color_tex);
2878 BLI_rcti_init(&valid_rect, 0, min_ii(region->winx, tex_w) - 1, 0, min_ii(region->winy, tex_h));
2879
2880 /* Copying pixels from textures only works when HOST_READ usage is enabled on them.
2881 * However, doing so can have performance impact, which we don't want for the viewport.
2882 * So, instead allocate a separate texture with HOST_READ here, copy to it, and then
2883 * copy that back to the host.
2884 * Since color picking is a fairly rare operation, the inefficiency here doesn't really
2885 * matter, and it means the viewport doesn't need HOST_READ. */
2886 tex = GPU_texture_create_2d("copy_tex",
2887 tex_w,
2888 tex_h,
2889 1,
2890 blender::gpu::TextureFormat::SFLOAT_16_16_16_16,
2892 nullptr);
2893 if (tex == nullptr) {
2894 return false;
2895 }
2896
2897 GPU_texture_copy(tex, color_tex);
2899 data = static_cast<blender::ushort4 *>(GPU_texture_read(tex, GPU_DATA_HALF_FLOAT, 0));
2900
2901 return true;
2902}
2903
2904bool ViewportColorSampleSession::sample(const int mval[2], float r_col[3])
2905{
2906 if (tex == nullptr || data == nullptr) {
2907 return false;
2908 }
2909
2910 if (!BLI_rcti_isect_pt_v(&valid_rect, mval)) {
2911 return false;
2912 }
2913
2914 blender::ushort4 pixel = data[mval[1] * tex_w + mval[0]];
2915
2916 if (blender::math::half_to_float(pixel.w) < 0.5f) {
2917 /* Background etc. are not rendered to the viewport texture, so fall back to basic color
2918 * picking for those. */
2919 return false;
2920 }
2921
2922 r_col[0] = blender::math::half_to_float(pixel.x);
2923 r_col[1] = blender::math::half_to_float(pixel.y);
2924 r_col[2] = blender::math::half_to_float(pixel.z);
2925
2926 return true;
2927}
2928
2930{
2931 if (data != nullptr) {
2932 MEM_freeN(data);
2933 }
2934 if (tex != nullptr) {
2935 GPU_texture_free(tex);
2936 }
2937}
2938
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bonecoll_is_visible_actbone(const bArmature *armature)
Functions to insert, delete or modify keyframes.
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:96
const CustomData_MeshMasks CD_MASK_BAREMESH
@ G_FLAG_RENDER_VIEWPORT
#define G_MAIN
Low-level operations for grease pencil.
void BKE_image_free_anim_gputextures(Main *bmain)
Definition image_gpu.cc:595
void BKE_image_free_old_gputextures(Main *bmain)
Definition image_gpu.cc:606
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1791
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:1640
bool BKE_scene_multiview_is_stereo3d(const RenderData *rd)
Definition scene.cc:2971
bool BKE_scene_uses_blender_workbench(const Scene *scene)
Definition scene.cc:2829
bool BKE_scene_uses_blender_eevee(const Scene *scene)
Definition scene.cc:2824
const char * BKE_scene_find_marker_name(const Scene *scene, int frame)
Definition scene.cc:2276
@ B_UNIT_LENGTH
Definition BKE_unit.hh:137
void BKE_unit_system_get(int system, int type, const void **r_usys_pt, int *r_len)
Definition unit.cc:2519
const char * BKE_unit_display_name_get(const void *usys_pt, int index)
Definition unit.cc:2548
int BKE_unit_base_get(const void *usys_pt)
Definition unit.cc:2532
double BKE_unit_scalar_get(const void *usys_pt, int index)
Definition unit.cc:2565
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_enable(int fontid, FontFlags flag)
Definition blf.cc:320
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4]=nullptr)
Definition blf.cc:934
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:505
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:946
void BLF_batch_draw_begin()
Definition blf.cc:534
int BLF_default()
void BLF_batch_draw_end()
Definition blf.cc:547
void BLF_default_size(float size)
void BLF_disable(int fontid, FontFlags flag)
Definition blf.cc:329
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
@ BLF_SHADOW
Definition BLF_enums.hh:35
#define BLI_assert(a)
Definition BLI_assert.h:46
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition math_color.cc:57
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
#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:198
void BLI_rcti_translate(struct rcti *rect, int x, int y)
Definition rct.cc:566
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.cc:414
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:194
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:202
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:206
#define SNPRINTF_UTF8(dst, format,...)
#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:71
#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)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
#define MAX_ID_NAME
Definition DNA_ID.h:373
@ CAM_PERSP
@ CAM_PANO
@ CAM_CUSTOM
@ CAM_ORTHO
@ CAM_SHOWPASSEPARTOUT
@ CAM_SHOW_SAFE_MARGINS
@ CAM_SHOW_SAFE_CENTER
@ CAM_SHOWNAME
@ CAM_SHOWSENSOR
@ 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
@ CAMERA_SENSOR_FIT_HOR
@ CAMERA_SENSOR_FIT_AUTO
#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_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
#define STEREO_LEFT_NAME
@ R_BORDER
#define STEREO_RIGHT_NAME
@ R_ADDSKY
@ STEREO_MONO_ID
@ STEREO_LEFT_ID
@ STEREO_RIGHT_ID
@ STEREO_3D_ID
@ SCE_VIEWS_FORMAT_STEREO_3D
@ SCE_VIEWS_FORMAT_MULTIVIEW
@ SCE_PASS_COMBINED
@ R_MULTIVIEW
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
#define UI_SCALE_FAC
#define NDOF_IS_ORBIT_AROUND_CENTER_MODE(userdef)
@ USER_SHOW_VIEWPORTNAME
@ USER_DRAWVIEWINFO
@ USER_SHOW_FPS
@ NDOF_SHOW_GUIDE_ORBIT_AXIS
@ NDOF_ORBIT_CENTER_AUTO
@ NDOF_SHOW_GUIDE_ORBIT_CENTER
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
@ 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
#define RV3D_VIEW_IS_AXIS(view)
@ 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
@ RV3D_VIEW_AXIS_ROLL_180
@ RV3D_VIEW_AXIS_ROLL_90
@ RV3D_VIEW_AXIS_ROLL_0
@ RV3D_VIEW_FRONT
@ RV3D_VIEW_BOTTOM
@ RV3D_VIEW_LEFT
@ RV3D_VIEW_RIGHT
@ RV3D_VIEW_TOP
@ RV3D_VIEW_BACK
@ RV3D_VIEW_USER
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_ZOFFSET_DISABLED
@ RV3D_CLIPPING
@ V3D_RUNTIME_DEPTHBUF_OVERRIDDEN
@ V3D_XR_SESSION_SURFACE
@ V3D_SELECT_OUTLINE
@ V3D_HIDE_HELPLINES
@ V3D_OVERLAY_EDIT_WEIGHT
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
@ RV3D_NDOF_OFS_IS_VALID
@ V3D_SHOW_FLOOR
@ V3D_SHOW_Z
@ V3D_SHOW_X
@ V3D_SHOW_Y
@ RV3D_LOCK_ROTATION
@ 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
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_draw_depth_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, GPUViewport *viewport, const bool use_gpencil, const bool use_only_selected, const bool use_only_active_object)
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_gpu_context_enable()
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:4301
bScreen * ED_screen_animation_no_scrub(const wmWindowManager *wm)
void ED_region_pixelspace(const ARegion *region)
Definition area.cc:87
#define XRAY_ENABLED(v3d)
eV3DDepthOverrideMode
Definition ED_view3d.hh:188
@ V3D_DEPTH_ALL
Definition ED_view3d.hh:190
@ V3D_DEPTH_SELECTED_ONLY
Definition ED_view3d.hh:198
@ V3D_DEPTH_NO_GPENCIL
Definition ED_view3d.hh:192
@ V3D_DEPTH_GPENCIL_ONLY
Definition ED_view3d.hh:194
@ V3D_DEPTH_OBJECT_ONLY
Definition ED_view3d.hh:196
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])
#define GPU_ATTACHMENT_TEXTURE(_texture)
int GPU_offscreen_width(const GPUOffScreen *offscreen)
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
void GPU_framebuffer_restore()
blender::gpu::TextureFormat GPU_offscreen_format(const GPUOffScreen *offscreen)
#define GPU_ATTACHMENT_NONE
void GPU_framebuffer_free(blender::gpu::FrameBuffer *fb)
int GPU_offscreen_height(const GPUOffScreen *offscreen)
GPUOffScreen * GPU_offscreen_create(int width, int height, bool with_depth_buffer, blender::gpu::TextureFormat format, eGPUTextureUsage usage, bool clear, char err_out[256])
void GPU_offscreen_free(GPUOffScreen *offscreen)
void GPU_framebuffer_read_depth(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_offscreen_read_color(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data)
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore)
blender::gpu::FrameBuffer * GPU_framebuffer_active_get()
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 immAttr4fv(uint attr_id, const float data[4])
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
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 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 immUniformColor4fv(const float rgba[4])
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_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
@ GPU_BARRIER_TEXTURE_UPDATE
Definition GPU_state.hh:39
@ GPU_DEPTH_NONE
Definition GPU_state.hh:111
void GPU_line_width(float width)
Definition gpu_state.cc:166
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
void GPU_blend(GPUBlend blend)
Definition gpu_state.cc:42
void GPU_depth_test(GPUDepthTest test)
Definition gpu_state.cc:68
void GPU_memory_barrier(GPUBarrier barrier)
Definition gpu_state.cc:326
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:273
void GPU_texture_copy(blender::gpu::Texture *dst, blender::gpu::Texture *src)
int GPU_texture_height(const blender::gpu::Texture *texture)
int GPU_texture_width(const blender::gpu::Texture *texture)
@ GPU_DATA_HALF_FLOAT
@ GPU_DATA_UBYTE
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_HOST_READ
void * GPU_texture_read(blender::gpu::Texture *texture, eGPUDataFormat data_format, int mip_level)
blender::gpu::Texture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(blender::gpu::Texture *texture)
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
void GPU_viewport_tag_update(GPUViewport *viewport)
blender::gpu::Texture * GPU_viewport_color_texture(GPUViewport *viewport, int view)
blender::gpu::Texture * GPU_viewport_depth_texture(GPUViewport *viewport)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void IMB_byte_from_float(ImBuf *ibuf)
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
eImBufFlags
@ IB_float_data
Read Guarded memory(de)allocation.
@ RE_INTERNAL
Definition RE_engine.h:43
@ RE_USE_EEVEE_VIEWPORT
Definition RE_engine.h:46
#define C
Definition RandGen.cpp:29
#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_BACK
@ TH_TIME_GP_KEYFRAME
@ TH_KEYTYPE_KEYFRAME_SELECT
@ TH_REDALERT
@ TH_CAMERA_PASSEPARTOUT
@ TH_AXIS_X
@ TH_VIEW_OVERLAY
@ TH_TEXT_HI
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3])
void UI_GetThemeColor4fv(int colorid, float col[4])
void UI_FontThemeColor(int fontid, int colorid)
void UI_SetTheme(int spacetype, int regionid)
#define U
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
BPy_StructRNA * depsgraph
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])
nullptr float
static float is_left(const float2 &p0, const float2 &p1, const float2 &p2)
#define powf(x, y)
#define hypotf(x, y)
#define acosf(x)
uchar view3d_camera_border_hack_col[3]
Definition drawobject.cc:12
bool view3d_camera_border_hack_test
Definition drawobject.cc:13
uint pos
uint col
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
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:128
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static ulong state[N]
#define G(x, y, z)
bool id_frame_has_keyframe(ID *id, float frame)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
float half_to_float(uint16_t v)
Definition math_half.cc:108
VecBase< float, 4 > float4
blender::VecBase< uint16_t, 4 > ushort4
const char * name
#define floorf
#define fabsf
#define sqrtf
#define sinf
#define cosf
#define ceilf
const char * RE_engine_id_BLENDER_WORKBENCH
Definition scene.cc:1582
const char * RE_engine_id_BLENDER_EEVEE
Definition scene.cc:1580
#define FLT_MAX
Definition stdcycles.h:14
void * regiondata
ARegionRuntimeHandle * runtime
char name[64]
char sensor_fit
float sensor_y
float composition_guide_color[4]
float passepartalpha
float sensor_x
char name[64]
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
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 ndof_rot_axis[3]
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]
void(* view_draw)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition RE_engine.h:103
void(* view_update)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition RE_engine.h:100
View3DShading shading
struct SceneDisplay display
struct RenderData r
struct UnitSettings unit
struct DisplaySafeAreas safe_areas
struct SceneEEVEE eevee
float gpencil_vertex_paint_opacity
char multiview_eye
View3DOverlay overlay
rctf render_border
float vignette_aperture
View3D_Runtime runtime
struct Object * camera
short gridsubdiv
char stereo3d_camera
struct View3D * localvd
ViewerPath viewer_path
short gridlines
int object_type_exclude_select
short ob_center_cursor
struct Object * ob_center
int object_type_exclude_viewport
ListBase regionbase
View3DShading shading
float clip_start
ARegion * region
Definition ED_view3d.hh:77
Scene * scene
Definition ED_view3d.hh:73
ViewLayer * view_layer
Definition ED_view3d.hh:74
View3D * v3d
Definition ED_view3d.hh:78
Object * obact
Definition ED_view3d.hh:75
Depsgraph * depsgraph
Definition ED_view3d.hh:72
unsigned short w
Definition ED_view3d.hh:86
float * depths
Definition ED_view3d.hh:89
double depth_range[2]
Definition ED_view3d.hh:90
unsigned short h
Definition ED_view3d.hh:86
ViewerPath viewer_path
struct EditBone * act_edbone
ListBase * edbo
ListBase areabase
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
XrSessionSettings session_settings
i
Definition text_draw.cc:230
static void draw_background(const rcti *rect)
uint len
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)
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *, eV3DDepthOverrideMode mode, bool use_overlay, ViewDepths **r_depths)
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 view3d_gpu_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
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_grid_steps(const Scene *scene, const View3D *v3d, const RegionView3D *rv3d, float r_grid_steps[STEPS_LEN])
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, float vignette_aperture, 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_view3D_mats_rv3d_free(RV3DMatrixStore *rv3d_mat)
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_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
static void drawrenderborder(ARegion *region, View3D *v3d)
static bool is_grease_pencil_with_layer_keyframe(const Object &ob)
float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit)
float view3d_depth_near_ex(ViewDepths *d, int r_xy[2])
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:1731
void WM_draw_region_viewport_ensure(Scene *scene, ARegion *region, short space_type)
Definition wm_draw.cc:1720
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition wm_draw.cc:940
void WM_draw_region_viewport_bind(ARegion *region)
Definition wm_draw.cc:1726
bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check)
Definition wm_stereo.cc:140
uint8_t flag
Definition wm_window.cc:145
bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr, float r_viewmat[4][4], float *r_focal_len)