Blender V4.3
view3d_view.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "BLI_linklist.h"
12#include "BLI_listbase.h"
13#include "BLI_math_matrix.h"
14#include "BLI_math_rotation.h"
15#include "BLI_math_vector.h"
16#include "BLI_rect.h"
17
18#include "BKE_action.hh"
19#include "BKE_context.hh"
20#include "BKE_global.hh"
21#include "BKE_idprop.hh"
22#include "BKE_layer.hh"
23#include "BKE_lib_id.hh"
24#include "BKE_main.hh"
25#include "BKE_modifier.hh"
26#include "BKE_object.hh"
27#include "BKE_report.hh"
28#include "BKE_scene.hh"
29
31
32#include "UI_resources.hh"
33
34#include "GPU_matrix.hh"
35#include "GPU_platform.hh"
36#include "GPU_select.hh"
37#include "GPU_state.hh"
38
39#include "WM_api.hh"
40
41#include "ED_object.hh"
42#include "ED_screen.hh"
43
44#include "DRW_engine.hh"
45
46#include "RNA_access.hh"
47#include "RNA_define.hh"
48
49#include "view3d_intern.hh" /* own include */
50#include "view3d_navigate.hh"
51
52/* -------------------------------------------------------------------- */
57{
59 View3D *v3d;
60 ARegion *region;
61 RegionView3D *rv3d;
62
64
65 ED_view3d_context_user_region(C, &v3d, &region);
66 rv3d = static_cast<RegionView3D *>(region->regiondata);
67
69
71
72 ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
73
75
77 rv3d->persp = RV3D_CAMOB;
78
80
81 return OPERATOR_FINISHED;
82}
83
85{
86 View3D *v3d;
87 ARegion *region;
88
89 if (ED_view3d_context_user_region(C, &v3d, &region)) {
90 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
91 if (v3d && v3d->camera && BKE_id_is_editable(CTX_data_main(C), &v3d->camera->id)) {
92 if (rv3d && (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0) {
93 if (rv3d->persp != RV3D_CAMOB) {
94 return true;
95 }
96 }
97 }
98 }
99
100 return false;
101}
102
104{
105 /* identifiers */
106 ot->name = "Align Camera to View";
107 ot->description = "Set camera view to active view";
108 ot->idname = "VIEW3D_OT_camera_to_view";
109
110 /* api callbacks */
113
114 /* flags */
116}
117
120/* -------------------------------------------------------------------- */
124/* unlike VIEW3D_OT_view_selected this is for framing a render and not
125 * meant to take into account vertex/bone selection for eg. */
127{
128 Main *bmain = CTX_data_main(C);
130 Scene *scene = CTX_data_scene(C);
131 View3D *v3d = CTX_wm_view3d(C); /* can be nullptr */
132 Object *camera_ob = v3d ? v3d->camera : scene->camera;
133
134 if (camera_ob == nullptr) {
135 BKE_report(op->reports, RPT_ERROR, "No active camera");
136 return OPERATOR_CANCELLED;
137 }
138
139 if (ED_view3d_camera_to_view_selected(bmain, depsgraph, scene, camera_ob)) {
141 return OPERATOR_FINISHED;
142 }
143 return OPERATOR_CANCELLED;
144}
145
147{
148 /* identifiers */
149 ot->name = "Camera Fit Frame to Selected";
150 ot->description = "Move the camera so selected objects are framed";
151 ot->idname = "VIEW3D_OT_camera_to_view_selected";
152
153 /* api callbacks */
156
157 /* flags */
159}
160
163/* -------------------------------------------------------------------- */
168 View3D *v3d,
169 Object *ob,
170 const int smooth_viewtx)
171{
172 Main *bmain = CTX_data_main(C);
173 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
174 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
175 LISTBASE_FOREACH (SpaceLink *, space_link, &area->spacedata) {
176 if (space_link->spacetype == SPACE_VIEW3D) {
177 View3D *other_v3d = reinterpret_cast<View3D *>(space_link);
178 if (other_v3d == v3d) {
179 continue;
180 }
181 if (other_v3d->camera == ob) {
182 continue;
183 }
184 /* Checking the other view is needed to prevent local cameras being modified. */
185 if (v3d->scenelock && other_v3d->scenelock) {
186 ListBase *lb = (space_link == area->spacedata.first) ? &area->regionbase :
187 &space_link->regionbase;
188 LISTBASE_FOREACH (ARegion *, other_region, lb) {
189 if (other_region->regiontype == RGN_TYPE_WINDOW) {
190 if (other_region->regiondata) {
191 RegionView3D *other_rv3d = static_cast<RegionView3D *>(other_region->regiondata);
192 if (other_rv3d->persp == RV3D_CAMOB) {
193 Object *other_camera_old = other_v3d->camera;
194 other_v3d->camera = ob;
195
196 V3D_SmoothParams sview_params = {};
197 sview_params.camera_old = other_camera_old;
198 sview_params.camera = other_v3d->camera;
199 sview_params.ofs = other_rv3d->ofs;
200 sview_params.quat = other_rv3d->viewquat;
201 sview_params.dist = &other_rv3d->dist;
202 sview_params.lens = &other_v3d->lens;
203 /* No undo because this switches cameras. */
204 sview_params.undo_str = nullptr;
205
206 ED_view3d_lastview_store(other_rv3d);
208 C, other_v3d, other_region, smooth_viewtx, &sview_params);
209 }
210 else {
211 other_v3d->camera = ob;
212 }
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220 }
221}
222
224{
225 View3D *v3d;
226 ARegion *region;
227 RegionView3D *rv3d;
228
229 Scene *scene = CTX_data_scene(C);
231
232 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
233
234 /* no nullptr check is needed, poll checks */
235 ED_view3d_context_user_region(C, &v3d, &region);
236 rv3d = static_cast<RegionView3D *>(region->regiondata);
237
238 if (ob) {
239 Object *camera_old = (rv3d->persp == RV3D_CAMOB) ? V3D_CAMERA_SCENE(scene, v3d) : nullptr;
240 rv3d->persp = RV3D_CAMOB;
241 v3d->camera = ob;
242 if (v3d->scenelock && scene->camera != ob) {
243 scene->camera = ob;
246 }
247
248 /* unlikely but looks like a glitch when set to the same */
249 if (camera_old != ob) {
250 V3D_SmoothParams sview_params = {};
251 sview_params.camera_old = camera_old;
252 sview_params.camera = v3d->camera;
253 sview_params.ofs = rv3d->ofs;
254 sview_params.quat = rv3d->viewquat;
255 sview_params.dist = &rv3d->dist;
256 sview_params.lens = &v3d->lens;
257 /* No undo because this switches cameras. */
258 sview_params.undo_str = nullptr;
259
261 ED_view3d_smooth_view(C, v3d, region, smooth_viewtx, &sview_params);
262 }
263
264 if (v3d->scenelock) {
265 sync_viewport_camera_smoothview(C, v3d, ob, smooth_viewtx);
267 }
269 }
270
271 return OPERATOR_FINISHED;
272}
273
275{
276 View3D *v3d_dummy;
277 ARegion *region_dummy;
278
279 return ED_view3d_context_user_region(C, &v3d_dummy, &region_dummy);
280}
281
283{
284 /* identifiers */
285 ot->name = "Set Active Object as Camera";
286 ot->description = "Set the active object as the active camera for this view or scene";
287 ot->idname = "VIEW3D_OT_object_as_camera";
288
289 /* api callbacks */
292
293 /* flags */
295}
296
299/* -------------------------------------------------------------------- */
303void view3d_winmatrix_set(const Depsgraph *depsgraph,
304 ARegion *region,
305 const View3D *v3d,
306 const rcti *rect)
307{
308 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
309 rctf full_viewplane;
310 float clipsta, clipend;
311 bool is_ortho;
312
314 v3d,
315 rv3d,
316 region->winx,
317 region->winy,
318 &full_viewplane,
319 &clipsta,
320 &clipend,
321 nullptr);
322 rv3d->is_persp = !is_ortho;
323
324#if 0
325 printf("%s: %d %d %f %f %f %f %f %f\n",
326 __func__,
327 winx,
328 winy,
329 full_viewplane.xmin,
330 full_viewplane.ymin,
331 full_viewplane.xmax,
332 full_viewplane.ymax,
333 clipsta,
334 clipend);
335#endif
336
337 /* Note the code here was tweaked to avoid an apparent compiler bug in clang 13 (see #91680). */
338 rctf viewplane;
339 if (rect) {
340 /* Smaller viewplane subset for selection picking. */
341 viewplane.xmin = full_viewplane.xmin +
342 (BLI_rctf_size_x(&full_viewplane) * (rect->xmin / float(region->winx)));
343 viewplane.ymin = full_viewplane.ymin +
344 (BLI_rctf_size_y(&full_viewplane) * (rect->ymin / float(region->winy)));
345 viewplane.xmax = full_viewplane.xmin +
346 (BLI_rctf_size_x(&full_viewplane) * (rect->xmax / float(region->winx)));
347 viewplane.ymax = full_viewplane.ymin +
348 (BLI_rctf_size_y(&full_viewplane) * (rect->ymax / float(region->winy)));
349 }
350 else {
351 viewplane = full_viewplane;
352 }
353
354 if (is_ortho) {
356 viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
357 }
358 else {
360 viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
361 }
362
363 /* update matrix in 3d view region */
365}
366
367static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
368{
369 float bmat[4][4];
370
371 rv3d->view = RV3D_VIEW_USER; /* don't show the grid */
372
373 normalize_m4_m4(bmat, ob->object_to_world().ptr());
374 invert_m4_m4(rv3d->viewmat, bmat);
375
376 /* view quat calculation, needed for add object */
378}
379
380void view3d_viewmatrix_set(const Depsgraph *depsgraph,
381 const Scene *scene,
382 const View3D *v3d,
383 RegionView3D *rv3d,
384 const float rect_scale[2])
385{
386 if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
387 if (v3d->camera) {
388 Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
389 obmat_to_viewmat(rv3d, ob_camera_eval);
390 }
391 else {
392 quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
393 rv3d->viewmat[3][2] -= rv3d->dist;
394 }
395 }
396 else {
397 bool use_lock_ofs = false;
398
399 /* should be moved to better initialize later on XXX */
401 ED_view3d_lock(rv3d);
402 }
403
404 quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
405 if (rv3d->persp == RV3D_PERSP) {
406 rv3d->viewmat[3][2] -= rv3d->dist;
407 }
408 if (v3d->ob_center) {
410 float vec[3];
411
412 copy_v3_v3(vec, ob_eval->object_to_world().location());
413 if (ob_eval->type == OB_ARMATURE && v3d->ob_center_bone[0]) {
415 if (pchan) {
416 copy_v3_v3(vec, pchan->pose_mat[3]);
417 mul_m4_v3(ob_eval->object_to_world().ptr(), vec);
418 }
419 }
420 translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
421 use_lock_ofs = true;
422 }
423 else if (v3d->ob_center_cursor) {
424 float vec[3];
425 copy_v3_v3(vec, scene->cursor.location);
426 translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
427 use_lock_ofs = true;
428 }
429 else {
430 translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
431 }
432
433 /* lock offset */
434 if (use_lock_ofs) {
435 float persmat[4][4], persinv[4][4];
436 float vec[3];
437
438 /* we could calculate the real persmat/persinv here
439 * but it would be unreliable so better to later */
440 mul_m4_m4m4(persmat, rv3d->winmat, rv3d->viewmat);
441 invert_m4_m4(persinv, persmat);
442
443 mul_v2_v2fl(vec, rv3d->ofs_lock, rv3d->is_persp ? rv3d->dist : 1.0f);
444 vec[2] = 0.0f;
445
446 if (rect_scale) {
447 /* Since 'RegionView3D.winmat' has been calculated and this function doesn't take the
448 * 'ARegion' we don't know about the region size.
449 * Use 'rect_scale' when drawing a sub-region to apply 2D offset,
450 * scaled by the difference between the sub-region and the region size.
451 */
452 vec[0] /= rect_scale[0];
453 vec[1] /= rect_scale[1];
454 }
455
456 mul_mat3_m4_v3(persinv, vec);
457 translate_m4(rv3d->viewmat, vec[0], vec[1], vec[2]);
458 }
459 /* end lock offset */
460 }
461}
462
465/* -------------------------------------------------------------------- */
473
478
486
487static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
488{
489 bool continue_pass = false;
490 DrawSelectLoopUserData *data = static_cast<DrawSelectLoopUserData *>(user_data);
491 if (stage == DRW_SELECT_PASS_PRE) {
492 GPU_select_begin_next(data->buffer, data->rect, data->gpu_select_mode, data->hits);
493 /* always run POST after PRE. */
494 continue_pass = true;
495 }
496 else if (stage == DRW_SELECT_PASS_POST) {
497 int hits = GPU_select_end();
498 if (data->pass == 0) {
499 /* quirk of GPU_select_end, only take hits value from first call. */
500 data->hits = hits;
501 }
502 if (data->gpu_select_mode == GPU_SELECT_NEAREST_FIRST_PASS) {
503 data->gpu_select_mode = GPU_SELECT_NEAREST_SECOND_PASS;
504 continue_pass = (hits > 0);
505 }
506 data->pass += 1;
507 }
508 else {
509 BLI_assert(0);
510 }
511 return continue_pass;
512}
513
515{
516 if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
517 if (obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT) &&
519 {
521 }
523 }
525}
526
528static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
529{
530 const Object *obact = static_cast<const Object *>(user_data);
531 return BKE_object_is_mode_compat(ob, eObjectMode(obact->mode));
532}
533
539{
540 LinkNode *ob_pose_list = static_cast<LinkNode *>(user_data);
541 return ob_pose_list && (BLI_linklist_index(ob_pose_list, DEG_get_original_object(ob)) != -1);
542}
543
545 GPUSelectBuffer *buffer,
546 const rcti *input,
547 eV3DSelectMode select_mode,
548 eV3DSelectObjectFilter select_filter,
549 const bool do_material_slot_selection)
550{
551 bThemeState theme_state;
552 const wmWindowManager *wm = CTX_wm_manager(vc->C);
553 Depsgraph *depsgraph = vc->depsgraph;
554 Scene *scene = vc->scene;
555 View3D *v3d = vc->v3d;
556 ARegion *region = vc->region;
557 rcti rect;
558 int hits = 0;
560 const bool use_obedit_skip = (BKE_view_layer_edit_object_get(vc->view_layer) != nullptr) &&
561 (vc->obedit == nullptr);
562 /* WORKAROUND: GPU depth picking is not working on AMD/NVIDIA official Vulkan drivers. */
563 const bool is_pick_select = (!GPU_type_matches_ex(GPU_DEVICE_ATI | GPU_DEVICE_NVIDIA,
567 (U.gpu_flag & USER_GPU_FLAG_NO_DEPT_PICK) == 0;
568 const bool do_passes = ((is_pick_select == false) &&
569 (select_mode == VIEW3D_SELECT_PICK_NEAREST));
570 const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST);
571 bool draw_surface = true;
572
573 eGPUSelectMode gpu_select_mode;
574
575 /* case not a box select */
576 if (input->xmin == input->xmax) {
577 const int xy[2] = {input->xmin, input->ymin};
578 /* seems to be default value for bones only now */
579 BLI_rcti_init_pt_radius(&rect, xy, 12);
580 }
581 else {
582 rect = *input;
583 }
584
585 if (is_pick_select) {
586 if (select_mode == VIEW3D_SELECT_PICK_NEAREST) {
587 gpu_select_mode = GPU_SELECT_PICK_NEAREST;
588 }
589 else if (select_mode == VIEW3D_SELECT_PICK_ALL) {
590 gpu_select_mode = GPU_SELECT_PICK_ALL;
591 }
592 else {
593 gpu_select_mode = GPU_SELECT_ALL;
594 }
595 }
596 else {
597 if (do_passes) {
598 gpu_select_mode = GPU_SELECT_NEAREST_FIRST_PASS;
599 }
600 else {
601 gpu_select_mode = GPU_SELECT_ALL;
602 }
603 }
604
605 /* Important to use 'vc->obact', not 'BKE_view_layer_active_object_get(vc->view_layer)' below,
606 * so it will be nullptr when hidden. */
607 struct {
609 void *user_data;
610 } object_filter = {nullptr, nullptr};
611
612 /* Re-use cache (rect must be smaller than the cached)
613 * other context is assumed to be unchanged */
614 if (GPU_select_is_cached()) {
615 GPU_select_begin_next(buffer, &rect, gpu_select_mode, 0);
617 hits = GPU_select_end();
618 goto finally;
619 }
620
621 switch (select_filter) {
623 Object *obact = vc->obact;
624 if (obact && obact->mode != OB_MODE_OBJECT) {
625 object_filter.fn = drw_select_filter_object_mode_lock;
626 object_filter.user_data = obact;
627 }
628 break;
629 }
631 Object *obact = vc->obact;
632 BLI_assert(obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT));
633 /* While this uses 'alloca' in a loop (which we typically avoid),
634 * the number of items is nearly always 1, maybe 2..3 in rare cases. */
635 LinkNode *ob_pose_list = nullptr;
636 VirtualModifierData virtual_modifier_data;
638 &virtual_modifier_data);
639 for (; md; md = md->next) {
640 if (md->type == eModifierType_Armature) {
642 if (amd->object && (amd->object->mode & OB_MODE_POSE)) {
643 BLI_linklist_prepend_alloca(&ob_pose_list, amd->object);
644 }
645 }
646 }
648 object_filter.user_data = ob_pose_list;
649 break;
650 }
652 break;
653 }
654
655 /* Tools may request depth outside of regular drawing code. */
656 UI_Theme_Store(&theme_state);
658
659 /* All of the queries need to be perform on the drawing context. */
661
662 G.f |= G_FLAG_PICKSEL;
663
664 /* Important we use the 'viewmat' and don't re-calculate since
665 * the object & bone view locking takes 'rect' into account, see: #51629. */
667 wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, nullptr, &rect);
668
669 if (!XRAY_ACTIVE(v3d)) {
671 }
672
673 /* If in X-ray mode, we select the wires in priority. */
674 if (XRAY_ACTIVE(v3d) && use_nearest) {
675 /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
676 * because the OpenGL context created & destroyed inside this function. */
677 DrawSelectLoopUserData drw_select_loop_user_data = {};
678 drw_select_loop_user_data.pass = 0;
679 drw_select_loop_user_data.hits = 0;
680 drw_select_loop_user_data.buffer = buffer;
681 drw_select_loop_user_data.rect = &rect;
682 drw_select_loop_user_data.gpu_select_mode = gpu_select_mode;
683
684 draw_surface = false;
686 region,
687 v3d,
688 use_obedit_skip,
689 draw_surface,
690 use_nearest,
691 do_material_slot_selection,
692 &rect,
694 &drw_select_loop_user_data,
695 object_filter.fn,
696 object_filter.user_data);
697 hits = drw_select_loop_user_data.hits;
698 /* FIX: This cleanup the state before doing another selection pass.
699 * (see #56695) */
701 }
702
703 if (hits == 0) {
704 /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
705 * because the OpenGL context created & destroyed inside this function. */
706 DrawSelectLoopUserData drw_select_loop_user_data = {};
707 drw_select_loop_user_data.pass = 0;
708 drw_select_loop_user_data.hits = 0;
709 drw_select_loop_user_data.buffer = buffer;
710 drw_select_loop_user_data.rect = &rect;
711 drw_select_loop_user_data.gpu_select_mode = gpu_select_mode;
712
713 /* If are not in wireframe mode, we need to use the mesh surfaces to check for hits */
714 draw_surface = (v3d->shading.type > OB_WIRE) || !XRAY_ENABLED(v3d);
716 region,
717 v3d,
718 use_obedit_skip,
719 draw_surface,
720 use_nearest,
721 do_material_slot_selection,
722 &rect,
724 &drw_select_loop_user_data,
725 object_filter.fn,
726 object_filter.user_data);
727 hits = drw_select_loop_user_data.hits;
728 }
729
730 G.f &= ~G_FLAG_PICKSEL;
732 wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, nullptr, nullptr);
733
734 if (!XRAY_ACTIVE(v3d)) {
736 }
737
739
740 UI_Theme_Restore(&theme_state);
741
742finally:
743 return hits;
744}
745
747 GPUSelectBuffer *buffer,
748 const rcti *input,
749 eV3DSelectMode select_mode,
750 eV3DSelectObjectFilter select_filter)
751{
752 return view3d_opengl_select_ex(vc, buffer, input, select_mode, select_filter, false);
753}
754
756 GPUSelectBuffer *buffer,
757 const rcti *input,
758 eV3DSelectMode select_mode,
759 eV3DSelectObjectFilter select_filter,
760 uint select_id)
761{
762 const int64_t start = buffer->storage.size();
763 int hits = view3d_opengl_select(vc, buffer, input, select_mode, select_filter);
764
765 /* Selection sometimes uses -1 for an invalid selection ID, remove these as they
766 * interfere with detection of actual number of hits in the selection. */
767 if (hits > 0) {
768 hits = GPU_select_buffer_remove_by_id(buffer->storage.as_mutable_span().slice(start, hits),
769 select_id);
770
771 /* Trim buffer to the exact size in case selections were removed. */
772 buffer->storage.resize(start + hits);
773 }
774 return hits;
775}
776
779/* -------------------------------------------------------------------- */
784{
785 ushort local_view_bits = 0;
786
787 /* Sometimes we lose a local-view: when an area is closed.
788 * Check all areas: which local-views are in use? */
789 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
790 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
791 SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
792 for (; sl; sl = sl->next) {
793 if (sl->spacetype == SPACE_VIEW3D) {
794 View3D *v3d = reinterpret_cast<View3D *>(sl);
795 if (v3d->localvd) {
796 local_view_bits |= v3d->local_view_uid;
797 }
798 }
799 }
800 }
801 }
802
803 for (int i = 0; i < 16; i++) {
804 if ((local_view_bits & (1 << i)) == 0) {
805 return (1 << i);
806 }
807 }
808
809 return 0;
810}
811
812static bool view3d_localview_init(const Depsgraph *depsgraph,
813 wmWindowManager *wm,
814 wmWindow *win,
815 Main *bmain,
816 const Scene *scene,
817 ViewLayer *view_layer,
818 ScrArea *area,
819 const bool frame_selected,
820 const int smooth_viewtx,
821 ReportList *reports)
822{
823 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
824 float min[3], max[3], box[3];
825 float size = 0.0f;
826 uint local_view_bit;
827 bool changed = false;
828
829 if (v3d->localvd) {
830 return changed;
831 }
832
833 INIT_MINMAX(min, max);
834
835 local_view_bit = free_localview_bit(bmain);
836
837 if (local_view_bit == 0) {
838 /* TODO(dfelinto): We can kick one of the other 3D views out of local view
839 * specially if it is not being used. */
840 BKE_report(reports, RPT_ERROR, "No more than 16 local views");
841 changed = false;
842 }
843 else {
844 BKE_view_layer_synced_ensure(scene, view_layer);
845 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
846 if (obedit) {
847 BKE_view_layer_synced_ensure(scene, view_layer);
849 base->local_view_bits &= ~local_view_bit;
850 }
851 FOREACH_BASE_IN_EDIT_MODE_BEGIN (scene, view_layer, v3d, base_iter) {
852 Object *ob_eval = DEG_get_evaluated_object(depsgraph, base_iter->object);
853 BKE_object_minmax(ob_eval ? ob_eval : base_iter->object, min, max);
854 base_iter->local_view_bits |= local_view_bit;
855 changed = true;
856 }
858 }
859 else {
860 BKE_view_layer_synced_ensure(scene, view_layer);
862 if (BASE_SELECTED(v3d, base)) {
863 Object *ob_eval = DEG_get_evaluated_object(depsgraph, base->object);
864 BKE_object_minmax(ob_eval ? ob_eval : base->object, min, max);
865 base->local_view_bits |= local_view_bit;
866 changed = true;
867 }
868 else {
869 base->local_view_bits &= ~local_view_bit;
870 }
871 }
872 }
873
874 sub_v3_v3v3(box, max, min);
875 size = max_fff(box[0], box[1], box[2]);
876 }
877
878 if (changed == false) {
879 return false;
880 }
881
882 /* Apply any running smooth-view values before reading from the viewport. */
883 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
884 if (region->regiontype == RGN_TYPE_WINDOW) {
885 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
886 if (rv3d->sms) {
888 }
889 }
890 }
891
892 v3d->localvd = static_cast<View3D *>(MEM_mallocN(sizeof(View3D), "localview"));
893 *v3d->localvd = blender::dna::shallow_copy(*v3d);
894 v3d->local_view_uid = local_view_bit;
895
896 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
897 if (region->regiontype == RGN_TYPE_WINDOW) {
898 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
899 bool ok_dist = true;
900
901 /* New view values. */
902 Object *camera_old = nullptr;
903 float dist_new, ofs_new[3];
904
905 rv3d->localvd = static_cast<RegionView3D *>(
906 MEM_mallocN(sizeof(RegionView3D), "localview region"));
907 memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
908
909 if (frame_selected) {
910 float mid[3];
911 mid_v3_v3v3(mid, min, max);
912 negate_v3_v3(ofs_new, mid);
913
914 if (rv3d->persp == RV3D_CAMOB) {
915 rv3d->persp = RV3D_PERSP;
916 camera_old = v3d->camera;
917 }
918
919 if (rv3d->persp == RV3D_ORTHO) {
920 if (size < 0.0001f) {
921 ok_dist = false;
922 }
923 }
924
925 if (ok_dist) {
926 dist_new = ED_view3d_radius_to_dist(
927 v3d, region, depsgraph, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
928
929 if (rv3d->persp == RV3D_PERSP) {
930 /* Don't zoom closer than the near clipping plane. */
931 dist_new = max_ff(dist_new, v3d->clip_start * 1.5f);
932 }
933 }
934
935 V3D_SmoothParams sview_params = {};
936 sview_params.camera_old = camera_old;
937 sview_params.ofs = ofs_new;
938 sview_params.quat = rv3d->viewquat;
939 sview_params.dist = ok_dist ? &dist_new : nullptr;
940 sview_params.lens = &v3d->lens;
941 /* No undo because this doesn't move the camera. */
942 sview_params.undo_str = nullptr;
943
945 depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_params);
946 }
947 }
948 }
949
950 return changed;
951}
952
953static bool view3d_localview_exit(const Depsgraph *depsgraph,
954 wmWindowManager *wm,
955 wmWindow *win,
956 const Scene *scene,
957 ViewLayer *view_layer,
958 ScrArea *area,
959 const bool frame_selected,
960 const int smooth_viewtx)
961{
962 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
963 bool changed = false;
964
965 if (v3d->localvd == nullptr) {
966 return changed;
967 }
968 BKE_view_layer_synced_ensure(scene, view_layer);
970 if (base->local_view_bits & v3d->local_view_uid) {
971 base->local_view_bits &= ~v3d->local_view_uid;
972 }
973 }
974
975 /* Apply any running smooth-view values before reading from the viewport. */
976 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
977 if (region->regiontype == RGN_TYPE_WINDOW) {
978 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
979 if (rv3d->localvd == nullptr) {
980 continue;
981 }
982 if (rv3d->sms) {
984 }
985 }
986 }
987
988 Object *camera_old = v3d->camera;
989 Object *camera_new = v3d->localvd->camera;
990
991 v3d->local_view_uid = 0;
992 v3d->camera = v3d->localvd->camera;
993
994 MEM_freeN(v3d->localvd);
995 v3d->localvd = nullptr;
997
998 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
999 if (region->regiontype == RGN_TYPE_WINDOW) {
1000 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1001
1002 if (rv3d->localvd == nullptr) {
1003 continue;
1004 }
1005
1006 if (frame_selected && depsgraph) {
1007 Object *camera_old_rv3d, *camera_new_rv3d;
1008
1009 camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : nullptr;
1010 camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : nullptr;
1011
1012 rv3d->view = rv3d->localvd->view;
1013 rv3d->view_axis_roll = rv3d->localvd->view_axis_roll;
1014 rv3d->persp = rv3d->localvd->persp;
1015 rv3d->camzoom = rv3d->localvd->camzoom;
1016
1017 V3D_SmoothParams sview_params = {};
1018 sview_params.camera_old = camera_old_rv3d;
1019 sview_params.camera = camera_new_rv3d;
1020 sview_params.ofs = rv3d->localvd->ofs;
1021 sview_params.quat = rv3d->localvd->viewquat;
1022 sview_params.dist = &rv3d->localvd->dist;
1023 /* No undo because this doesn't move the camera. */
1024 sview_params.undo_str = nullptr;
1025
1027 depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_params);
1028 }
1029
1030 MEM_freeN(rv3d->localvd);
1031 rv3d->localvd = nullptr;
1032 changed = true;
1033 }
1034 }
1035 return changed;
1036}
1037
1039 Scene *scene,
1040 ViewLayer *view_layer,
1041 wmWindowManager *wm,
1042 wmWindow *win,
1043 View3D *v3d,
1044 ScrArea *area,
1045 const bool frame_selected,
1046 const int smooth_viewtx)
1047{
1048 if (v3d->localvd == nullptr) {
1049 return false;
1050 }
1051
1052 v3d->localvd->runtime.flag &= ~V3D_RUNTIME_LOCAL_MAYBE_EMPTY;
1053
1054 BKE_view_layer_synced_ensure(scene, view_layer);
1056 if (base->local_view_bits & v3d->local_view_uid) {
1057 return false;
1058 }
1059 }
1060
1061 return view3d_localview_exit(
1062 depsgraph, wm, win, scene, view_layer, area, frame_selected, smooth_viewtx);
1063}
1064
1066{
1067 const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
1068 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1070 wmWindow *win = CTX_wm_window(C);
1071 Main *bmain = CTX_data_main(C);
1072 Scene *scene = CTX_data_scene(C);
1073 ViewLayer *view_layer = CTX_data_view_layer(C);
1074 ScrArea *area = CTX_wm_area(C);
1075 View3D *v3d = CTX_wm_view3d(C);
1076 bool frame_selected = RNA_boolean_get(op->ptr, "frame_selected");
1077 bool changed;
1078
1079 if (v3d->localvd) {
1080 changed = view3d_localview_exit(
1081 depsgraph, wm, win, scene, view_layer, area, frame_selected, smooth_viewtx);
1082 }
1083 else {
1085 wm,
1086 win,
1087 bmain,
1088 scene,
1089 view_layer,
1090 area,
1091 frame_selected,
1092 smooth_viewtx,
1093 op->reports);
1094 }
1095
1096 if (changed) {
1097 DEG_id_type_tag(bmain, ID_OB);
1098 ED_area_tag_redraw(area);
1099
1100 /* Unselected objects become selected when exiting. */
1101 if (v3d->localvd == nullptr) {
1104 }
1105 else {
1107 }
1108
1109 return OPERATOR_FINISHED;
1110 }
1111 return OPERATOR_CANCELLED;
1112}
1113
1115{
1116 /* identifiers */
1117 ot->name = "Local View";
1118 ot->description = "Toggle display of selected object(s) separately and centered in view";
1119 ot->idname = "VIEW3D_OT_localview";
1120
1121 /* api callbacks */
1123 ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
1124
1126
1128 "frame_selected",
1129 true,
1130 "Frame Selected",
1131 "Move the view to frame the selected objects");
1132}
1133
1135{
1136 View3D *v3d = CTX_wm_view3d(C);
1137 Main *bmain = CTX_data_main(C);
1138 Scene *scene = CTX_data_scene(C);
1139 ViewLayer *view_layer = CTX_data_view_layer(C);
1140 bool changed = false;
1141 BKE_view_layer_synced_ensure(scene, view_layer);
1143 if (BASE_SELECTED(v3d, base)) {
1144 base->local_view_bits &= ~v3d->local_view_uid;
1146
1147 if (base == view_layer->basact) {
1148 view_layer->basact = nullptr;
1149 }
1150 changed = true;
1151 }
1152 }
1153
1154 /* If some object was removed from the local view, exit the local view if it is now empty. */
1155 if (changed) {
1157 scene,
1158 view_layer,
1159 CTX_wm_manager(C),
1160 CTX_wm_window(C),
1161 v3d,
1162 CTX_wm_area(C),
1163 true,
1165 }
1166
1167 if (changed) {
1168 DEG_tag_on_visible_update(bmain, false);
1172 return OPERATOR_FINISHED;
1173 }
1174
1175 BKE_report(op->reports, RPT_ERROR, "No object selected");
1176 return OPERATOR_CANCELLED;
1177}
1178
1180{
1181 if (CTX_data_edit_object(C) != nullptr) {
1182 return false;
1183 }
1184
1185 View3D *v3d = CTX_wm_view3d(C);
1186 return v3d && v3d->localvd;
1187}
1188
1190{
1191 /* identifiers */
1192 ot->name = "Remove from Local View";
1193 ot->description = "Move selected objects out of local view";
1194 ot->idname = "VIEW3D_OT_localview_remove_from";
1195
1196 /* api callbacks */
1199 ot->flag = OPTYPE_UNDO;
1200}
1201
1204/* -------------------------------------------------------------------- */
1209 ushort local_collections_uid,
1210 bool *r_reset)
1211{
1212 ushort local_view_bits = 0;
1213
1214 /* Check all areas: which local-views are in use? */
1215 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1216 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1217 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1218 if (sl->spacetype == SPACE_VIEW3D) {
1219 View3D *v3d = reinterpret_cast<View3D *>(sl);
1220 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1221 local_view_bits |= v3d->local_collections_uid;
1222 }
1223 }
1224 }
1225 }
1226 }
1227
1228 /* First try to keep the old uuid. */
1229 if (local_collections_uid && ((local_collections_uid & local_view_bits) == 0)) {
1230 return local_collections_uid;
1231 }
1232
1233 /* Otherwise get the first free available. */
1234 for (int i = 0; i < 16; i++) {
1235 if ((local_view_bits & (1 << i)) == 0) {
1236 *r_reset = true;
1237 return (1 << i);
1238 }
1239 }
1240
1241 return 0;
1242}
1243
1244static void local_collections_reset_uuid(LayerCollection *layer_collection,
1245 const ushort local_view_bit)
1246{
1247 if (layer_collection->flag & LAYER_COLLECTION_HIDE) {
1248 layer_collection->local_collections_bits &= ~local_view_bit;
1249 }
1250 else {
1251 layer_collection->local_collections_bits |= local_view_bit;
1252 }
1253
1254 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1255 local_collections_reset_uuid(child, local_view_bit);
1256 }
1257}
1258
1259static void view3d_local_collections_reset(const Main *bmain, const uint local_view_bit)
1260{
1261 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1262 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1263 LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
1264 local_collections_reset_uuid(layer_collection, local_view_bit);
1265 }
1266 }
1267 }
1268}
1269
1271{
1272 if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
1273 return true;
1274 }
1275
1276 bool reset = false;
1277 v3d->flag &= ~V3D_LOCAL_COLLECTIONS;
1278 uint local_view_bit = free_localcollection_bit(bmain, v3d->local_collections_uid, &reset);
1279
1280 if (local_view_bit == 0) {
1281 return false;
1282 }
1283
1284 v3d->local_collections_uid = local_view_bit;
1286
1287 if (reset) {
1288 view3d_local_collections_reset(bmain, local_view_bit);
1289 }
1290
1291 return true;
1292}
1293
1294void ED_view3d_local_collections_reset(const bContext *C, const bool reset_all)
1295{
1296 Main *bmain = CTX_data_main(C);
1297 uint local_view_bit = ~(0);
1298 bool do_reset = false;
1299
1300 /* Reset only the ones that are not in use. */
1301 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1302 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1303 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1304 if (sl->spacetype == SPACE_VIEW3D) {
1305 View3D *v3d = reinterpret_cast<View3D *>(sl);
1306 if (v3d->local_collections_uid) {
1307 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1308 local_view_bit &= ~v3d->local_collections_uid;
1309 }
1310 else {
1311 do_reset = true;
1312 }
1313 }
1314 }
1315 }
1316 }
1317 }
1318
1319 if (do_reset) {
1320 view3d_local_collections_reset(bmain, local_view_bit);
1321 }
1322 else if (reset_all && (do_reset || (local_view_bit != ~(0)))) {
1323 view3d_local_collections_reset(bmain, ~(0));
1324 View3D v3d = {};
1325 v3d.local_collections_uid = ~(0);
1328 }
1329}
1330
1333/* -------------------------------------------------------------------- */
1337#ifdef WITH_XR_OPENXR
1338
1339static void view3d_xr_mirror_begin(RegionView3D *rv3d)
1340{
1341 /* If there is no session yet, changes below should not be applied! */
1343
1345 /* Force perspective view. This isn't reset but that's not really an issue. */
1346 rv3d->persp = RV3D_PERSP;
1347}
1348
1349static void view3d_xr_mirror_end(RegionView3D *rv3d)
1350{
1351 rv3d->runtime_viewlock &= ~RV3D_LOCK_ANY_TRANSFORM;
1352}
1353
1354void ED_view3d_xr_mirror_update(const ScrArea *area, const View3D *v3d, const bool enable)
1355{
1356 ARegion *region_rv3d;
1357
1359
1360 if (ED_view3d_area_user_region(area, v3d, &region_rv3d)) {
1361 if (enable) {
1362 view3d_xr_mirror_begin(static_cast<RegionView3D *>(region_rv3d->regiondata));
1363 }
1364 else {
1365 view3d_xr_mirror_end(static_cast<RegionView3D *>(region_rv3d->regiondata));
1366 }
1367 }
1368}
1369
1370void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const Scene *scene)
1371{
1373 View3DShading *xr_shading = &wm->xr.session_settings.shading;
1374 /* Flags that shouldn't be overridden by the 3D View shading. */
1375 int flag_copy = 0;
1376 if (v3d->shading.type != OB_SOLID) {
1377 /* Don't set V3D_SHADING_WORLD_ORIENTATION for solid shading since it results in distorted
1378 * lighting when the view matrix has a scale factor. */
1379 flag_copy |= V3D_SHADING_WORLD_ORIENTATION;
1380 }
1381
1383
1384 if (v3d->shading.type == OB_RENDER) {
1386 /* Keep old shading while using Cycles or another engine, they are typically not usable in
1387 * VR. */
1388 return;
1389 }
1390 }
1391
1392 if (xr_shading->prop) {
1393 IDP_FreeProperty(xr_shading->prop);
1394 xr_shading->prop = nullptr;
1395 }
1396
1397 /* Copy shading from View3D to VR view. */
1398 const int old_xr_shading_flag = xr_shading->flag;
1399 *xr_shading = v3d->shading;
1400 xr_shading->flag = (xr_shading->flag & ~flag_copy) | (old_xr_shading_flag & flag_copy);
1401 if (v3d->shading.prop) {
1402 xr_shading->prop = IDP_CopyProperty(xr_shading->prop);
1403 }
1404 }
1405}
1406
1407bool ED_view3d_is_region_xr_mirror_active(const wmWindowManager *wm,
1408 const View3D *v3d,
1409 const ARegion *region)
1410{
1411 return (v3d->flag & V3D_XR_SESSION_MIRROR) &&
1412 /* The free region (e.g. the camera region in quad-view) is always
1413 * the last in the list base. We don't want any other to be affected. */
1414 !region->next && //
1416}
1417
1418#endif
1419
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(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)
@ G_FLAG_PICKSEL
#define G_MAIN
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1227
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:861
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
#define FOREACH_BASE_IN_EDIT_MODE_BEGIN(_scene, _view_layer, _v3d, _instance)
Definition BKE_layer.hh:372
#define FOREACH_BASE_IN_EDIT_MODE_END
Definition BKE_layer.hh:375
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
Object * BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2456
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
void BKE_object_tfm_protected_backup(const Object *ob, ObjectTfmProtectedChannels *obtfm)
Object * BKE_object_pose_armature_get(Object *ob)
void BKE_object_tfm_protected_restore(Object *ob, const ObjectTfmProtectedChannels *obtfm, short protectflag)
bool BKE_object_is_mode_compat(const Object *ob, eObjectMode object_mode)
void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3])
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
bool BKE_scene_uses_blender_workbench(const Scene *scene)
Definition scene.cc:2777
bool BKE_scene_uses_blender_eevee(const Scene *scene)
Definition scene.cc:2771
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void normalize_m4_m4(float rmat[4][4], const float mat[4][4]) ATTR_NONNULL()
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
void quat_to_mat4(float m[4][4], const float q[4])
void mat4_normalized_to_quat(float q[4], const float mat[4][4])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_v2fl(float r[2], const float a[2], float f)
void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size)
Definition rct.c:470
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:197
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:201
unsigned short ushort
unsigned int uint
#define INIT_MINMAX(min, max)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_id_type_tag(Main *bmain, short id_type)
void DEG_tag_on_visible_update(Main *bmain, bool do_time)
void DEG_relations_tag_update(Main *bmain)
Object * DEG_get_original_object(Object *object)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_SELECT
Definition DNA_ID.h:1068
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1071
@ ID_OB
@ LAYER_COLLECTION_HIDE
@ eModifierType_Armature
@ OB_WIRE
@ OB_SOLID
@ OB_RENDER
#define OB_MODE_ALL_WEIGHT_PAINT
eObjectMode
@ OB_MODE_POSE
@ OB_MODE_OBJECT
@ OB_ARMATURE
#define BASE_SELECTED(v3d, base)
#define V3D_CAMERA_SCENE(scene, v3d)
@ SCE_OBJECT_MODE_LOCK
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ USER_GPU_FLAG_NO_DEPT_PICK
#define RV3D_LOCK_FLAGS(rv3d)
@ V3D_RUNTIME_XR_SESSION_ROOT
@ V3D_SHADING_WORLD_ORIENTATION
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
@ RV3D_LOCK_ANY_TRANSFORM
@ RV3D_LOCK_ROTATION
@ V3D_LOCAL_COLLECTIONS
@ V3D_XR_SESSION_MIRROR
@ RV3D_VIEW_USER
void DRW_gpu_context_disable()
bool(*)(Object *ob, void *user_data) DRW_ObjectFilterFn
Definition DRW_engine.hh:63
void DRW_gpu_context_enable()
eDRWSelectStage
Definition DRW_engine.hh:58
@ DRW_SELECT_PASS_POST
Definition DRW_engine.hh:60
@ DRW_SELECT_PASS_PRE
Definition DRW_engine.hh:59
void DRW_draw_select_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bool use_obedit_skip, bool draw_surface, bool use_nearest, bool do_material_sub_selection, const rcti *rect, DRW_SelectPassFn select_pass_fn, void *select_pass_user_data, DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data)
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:708
bool ED_operator_scene_editable(bContext *C)
bool ED_operator_view3d_active(bContext *C)
#define XRAY_ENABLED(v3d)
void ED_view3d_to_object(const Depsgraph *depsgraph, Object *ob, const float ofs[3], const float quat[4], float dist)
bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_region)
bool ED_view3d_lock(RegionView3D *rv3d)
void ED_view3d_lastview_store(RegionView3D *rv3d)
#define VIEW3D_MARGIN
#define XRAY_ACTIVE(v3d)
float ED_view3d_radius_to_dist(const View3D *v3d, const ARegion *region, const Depsgraph *depsgraph, char persp, bool use_aspect, float radius)
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)
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)
eV3DSelectMode
Definition ED_view3d.hh:914
@ VIEW3D_SELECT_PICK_ALL
Definition ED_view3d.hh:918
@ VIEW3D_SELECT_PICK_NEAREST
Definition ED_view3d.hh:920
bool ED_view3d_camera_to_view_selected(Main *bmain, Depsgraph *depsgraph, const Scene *scene, Object *camera_ob)
eV3DSelectObjectFilter
Definition ED_view3d.hh:923
@ VIEW3D_SELECT_FILTER_NOP
Definition ED_view3d.hh:925
@ VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK
Definition ED_view3d.hh:927
@ VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK
Definition ED_view3d.hh:929
bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion **r_region)
void GPU_matrix_ortho_set(float left, float right, float bottom, float top, float near, float far)
void GPU_matrix_frustum_set(float left, float right, float bottom, float top, float near, float far)
#define GPU_matrix_projection_get(x)
@ GPU_DRIVER_OFFICIAL
bool GPU_type_matches_ex(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver, eGPUBackendType backend)
@ GPU_OS_ANY
@ GPU_DEVICE_ATI
@ GPU_DEVICE_NVIDIA
void GPU_select_cache_end()
eGPUSelectMode
Definition GPU_select.hh:18
@ GPU_SELECT_NEAREST_SECOND_PASS
Definition GPU_select.hh:22
@ GPU_SELECT_NEAREST_FIRST_PASS
Definition GPU_select.hh:21
@ GPU_SELECT_PICK_ALL
Definition GPU_select.hh:24
@ GPU_SELECT_ALL
Definition GPU_select.hh:19
@ GPU_SELECT_PICK_NEAREST
Definition GPU_select.hh:25
bool GPU_select_is_cached()
unsigned int GPU_select_end()
void GPU_select_cache_load_id()
void GPU_select_begin_next(GPUSelectBuffer *buffer, const rcti *input, eGPUSelectMode mode, int oldhits)
uint GPU_select_buffer_remove_by_id(blender::MutableSpan< GPUSelectResult > hit_results, uint select_id)
void GPU_select_cache_begin()
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:111
@ GPU_DEPTH_NONE
Definition GPU_state.hh:108
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void UI_Theme_Store(bThemeState *theme_state)
void UI_Theme_Restore(const bThemeState *theme_state)
void UI_SetTheme(int spacetype, int regionid)
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define ND_DRAW
Definition WM_types.hh:428
#define ND_OB_ACTIVE
Definition WM_types.hh:407
#define ND_OB_SELECT
Definition WM_types.hh:409
#define NC_SCENE
Definition WM_types.hh:345
#define ND_TRANSFORM
Definition WM_types.hh:423
#define NC_OBJECT
Definition WM_types.hh:346
unsigned int U
Definition btGjkEpa3.h:78
void reset()
clear internal cached data and reset random seed
int64_t size() const
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
#define printf
EvaluationStage stage
Definition deg_eval.cc:83
const Depsgraph * depsgraph
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define G(x, y, z)
void base_select(Base *base, eObjectSelect_Mode mode)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
#define min(a, b)
Definition sort.c:32
__int64 int64_t
Definition stdint.h:89
void * regiondata
GPUSelectBuffer * buffer
eGPUSelectMode gpu_select_mode
GPUSelectStorage storage
Definition GPU_select.hh:46
ListBase layer_collections
unsigned short local_collections_bits
ListBase scenes
Definition BKE_main.hh:210
ListBase screens
Definition BKE_main.hh:225
struct ModifierData * next
struct bPose * pose
short protectflag
struct SmoothView3DStore * sms
struct RegionView3D * localvd
float viewmat[4][4]
float winmat[4][4]
const char * undo_str
struct IDProperty * prop
struct SceneStats * local_stats
unsigned short local_collections_uid
View3D_Runtime runtime
struct Object * camera
struct View3D * localvd
char ob_center_bone[64]
short scenelock
short ob_center_cursor
struct Object * ob_center
View3DShading shading
unsigned short local_view_uid
float clip_start
RegionView3D * rv3d
Definition ED_view3d.hh:76
ARegion * region
Definition ED_view3d.hh:73
Scene * scene
Definition ED_view3d.hh:69
wmWindow * win
Definition ED_view3d.hh:75
ViewLayer * view_layer
Definition ED_view3d.hh:70
bContext * C
Definition ED_view3d.hh:62
View3D * v3d
Definition ED_view3d.hh:74
Object * obact
Definition ED_view3d.hh:71
Object * obedit
Definition ED_view3d.hh:72
Depsgraph * depsgraph
Definition ED_view3d.hh:68
struct Base * basact
struct View3DShading shading
float pose_mat[4][4]
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct PointerRNA * ptr
XrSessionSettings session_settings
float max
void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *region, int smooth_viewtx, const V3D_SmoothParams *sview)
void ED_view3d_smooth_view_force_finish_no_camera_lock(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, const Scene *scene, View3D *v3d, ARegion *region)
void ED_view3d_smooth_view_ex(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, ScrArea *area, View3D *v3d, ARegion *region, int smooth_viewtx, const V3D_SmoothParams *sview)
void view3d_opengl_select_cache_begin()
static void local_collections_reset_uuid(LayerCollection *layer_collection, const ushort local_view_bit)
void view3d_viewmatrix_set(const Depsgraph *depsgraph, const Scene *scene, const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2])
static int localview_remove_from_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_localview(wmOperatorType *ot)
static void view3d_local_collections_reset(const Main *bmain, const uint local_view_bit)
static uint free_localview_bit(Main *bmain)
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
static int localview_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_localview_remove_from(wmOperatorType *ot)
void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
int view3d_opengl_select_ex(const ViewContext *vc, GPUSelectBuffer *buffer, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, const bool do_material_slot_selection)
static bool view3d_localview_exit(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, const Scene *scene, ViewLayer *view_layer, ScrArea *area, const bool frame_selected, const int smooth_viewtx)
int view3d_opengl_select(const ViewContext *vc, GPUSelectBuffer *buffer, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter)
static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void *user_data)
static void sync_viewport_camera_smoothview(bContext *C, View3D *v3d, Object *ob, const int smooth_viewtx)
bool ED_localview_exit_if_empty(const Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, wmWindowManager *wm, wmWindow *win, View3D *v3d, ScrArea *area, const bool frame_selected, const int smooth_viewtx)
static int view3d_camera_to_view_exec(bContext *C, wmOperator *)
eV3DSelectObjectFilter ED_view3d_select_filter_from_mode(const Scene *scene, const Object *obact)
static bool localview_remove_from_poll(bContext *C)
void ED_view3d_local_collections_reset(const bContext *C, const bool reset_all)
int view3d_opengl_select_with_id_filter(const ViewContext *vc, GPUSelectBuffer *buffer, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, uint select_id)
bool ED_view3d_local_collections_set(const Main *bmain, View3D *v3d)
static uint free_localcollection_bit(const Main *bmain, ushort local_collections_uid, bool *r_reset)
static bool view3d_localview_init(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, Main *bmain, const Scene *scene, ViewLayer *view_layer, ScrArea *area, const bool frame_selected, const int smooth_viewtx, ReportList *reports)
void view3d_opengl_select_cache_end()
void view3d_winmatrix_set(const Depsgraph *depsgraph, ARegion *region, const View3D *v3d, const rcti *rect)
void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
static bool view3d_camera_to_view_poll(bContext *C)
bool ED_operator_rv3d_user_region_poll(bContext *C)
static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
int xy[2]
Definition wm_draw.cc:170
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4125
int WM_operator_smooth_viewtx_get(const wmOperator *op)
bool WM_xr_session_is_ready(const wmXrData *xr)
bool WM_xr_session_exists(const wmXrData *xr)