Blender V5.0
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
8
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#ifdef WITH_XR_OPENXR
21# include "BKE_idprop.hh"
22#endif
23#include "BKE_global.hh"
24#include "BKE_layer.hh"
25#include "BKE_lib_id.hh"
26#include "BKE_main.hh"
27#include "BKE_modifier.hh"
28#include "BKE_object.hh"
29#include "BKE_report.hh"
30#include "BKE_scene.hh"
31
33
34#include "UI_resources.hh"
35
36#include "GPU_matrix.hh"
37#include "GPU_select.hh"
38#include "GPU_state.hh"
39
40#include "WM_api.hh"
41
42#include "ED_info.hh"
43#include "ED_object.hh"
44#include "ED_screen.hh"
45
46#include "DRW_engine.hh"
47
48#include "RNA_access.hh"
49#include "RNA_define.hh"
50
51#include "view3d_intern.hh" /* own include */
52#include "view3d_navigate.hh"
53
54#include "DNA_camera_types.h"
55
56/* -------------------------------------------------------------------- */
59
61{
63 View3D *v3d;
64 ARegion *region;
65 RegionView3D *rv3d;
66
68
69 ED_view3d_context_user_region(C, &v3d, &region);
70 rv3d = static_cast<RegionView3D *>(region->regiondata);
71
73
75
77
78 ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
79
81
83 rv3d->persp = RV3D_CAMOB;
84
86
87 return OPERATOR_FINISHED;
88}
89
91{
92 View3D *v3d;
93 ARegion *region;
94
95 if (ED_view3d_context_user_region(C, &v3d, &region)) {
96 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
97 if (v3d && v3d->camera && BKE_id_is_editable(CTX_data_main(C), &v3d->camera->id)) {
98 if (rv3d && (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0) {
99 if (rv3d->persp != RV3D_CAMOB) {
100 return true;
101 }
102 }
103 }
104 }
105
106 return false;
107}
108
110{
111 /* identifiers */
112 ot->name = "Align Camera to View";
113 ot->description = "Set camera view to active view";
114 ot->idname = "VIEW3D_OT_camera_to_view";
115
116 /* API callbacks. */
119
120 /* flags */
122}
123
125
126/* -------------------------------------------------------------------- */
129
135{
136 Main *bmain = CTX_data_main(C);
138 Scene *scene = CTX_data_scene(C);
139 View3D *v3d = CTX_wm_view3d(C); /* can be nullptr */
140 Object *camera_ob = v3d ? v3d->camera : scene->camera;
141
142 if (camera_ob == nullptr) {
143 BKE_report(op->reports, RPT_ERROR, "No active camera");
144 return OPERATOR_CANCELLED;
145 }
146
147 if (ED_view3d_camera_to_view_selected(bmain, depsgraph, scene, camera_ob)) {
149 return OPERATOR_FINISHED;
150 }
151 return OPERATOR_CANCELLED;
152}
153
155{
156 /* identifiers */
157 ot->name = "Camera Fit Frame to Selected";
158 ot->description = "Move the camera so selected objects are framed";
159 ot->idname = "VIEW3D_OT_camera_to_view_selected";
160
161 /* API callbacks. */
164
165 /* flags */
167}
168
170
171/* -------------------------------------------------------------------- */
174
176 View3D *v3d,
177 Object *ob,
178 const int smooth_viewtx)
179{
180 Main *bmain = CTX_data_main(C);
181 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
182 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
183 LISTBASE_FOREACH (SpaceLink *, space_link, &area->spacedata) {
184 if (space_link->spacetype == SPACE_VIEW3D) {
185 View3D *other_v3d = reinterpret_cast<View3D *>(space_link);
186 if (other_v3d == v3d) {
187 continue;
188 }
189 if (other_v3d->camera == ob) {
190 continue;
191 }
192 /* Checking the other view is needed to prevent local cameras being modified. */
193 if (v3d->scenelock && other_v3d->scenelock) {
194 ListBase *lb = (space_link == area->spacedata.first) ? &area->regionbase :
195 &space_link->regionbase;
196 LISTBASE_FOREACH (ARegion *, other_region, lb) {
197 if (other_region->regiontype == RGN_TYPE_WINDOW) {
198 if (other_region->regiondata) {
199 RegionView3D *other_rv3d = static_cast<RegionView3D *>(other_region->regiondata);
200 if (other_rv3d->persp == RV3D_CAMOB) {
201 Object *other_camera_old = other_v3d->camera;
202 other_v3d->camera = ob;
203
204 V3D_SmoothParams sview_params = {};
205 sview_params.camera_old = other_camera_old;
206 sview_params.camera = other_v3d->camera;
207 sview_params.ofs = other_rv3d->ofs;
208 sview_params.quat = other_rv3d->viewquat;
209 sview_params.dist = &other_rv3d->dist;
210 sview_params.lens = &other_v3d->lens;
211 /* No undo because this switches cameras. */
212 sview_params.undo_str = nullptr;
213
214 ED_view3d_lastview_store(other_rv3d);
216 C, other_v3d, other_region, smooth_viewtx, &sview_params);
217 }
218 else {
219 other_v3d->camera = ob;
220 }
221 }
222 }
223 }
224 }
225 }
226 }
227 }
228 }
229}
230
232{
233 View3D *v3d;
234 ARegion *region;
235 RegionView3D *rv3d;
236
237 Scene *scene = CTX_data_scene(C);
239
240 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
241
242 /* no nullptr check is needed, poll checks */
243 ED_view3d_context_user_region(C, &v3d, &region);
244 rv3d = static_cast<RegionView3D *>(region->regiondata);
245
247
248 if (ob) {
249 Object *camera_old = (rv3d->persp == RV3D_CAMOB) ? V3D_CAMERA_SCENE(scene, v3d) : nullptr;
250 rv3d->persp = RV3D_CAMOB;
251 v3d->camera = ob;
252 if (v3d->scenelock && scene->camera != ob) {
253 scene->camera = ob;
256 }
257
258 /* unlikely but looks like a glitch when set to the same */
259 if (camera_old != ob) {
260 V3D_SmoothParams sview_params = {};
261 sview_params.camera_old = camera_old;
262 sview_params.camera = v3d->camera;
263 sview_params.ofs = rv3d->ofs;
264 sview_params.quat = rv3d->viewquat;
265 sview_params.dist = &rv3d->dist;
266 sview_params.lens = &v3d->lens;
267 /* No undo because this switches cameras. */
268 sview_params.undo_str = nullptr;
269
271 ED_view3d_smooth_view(C, v3d, region, smooth_viewtx, &sview_params);
272 }
273
274 if (v3d->scenelock) {
275 sync_viewport_camera_smoothview(C, v3d, ob, smooth_viewtx);
277 }
279 }
280
281 return OPERATOR_FINISHED;
282}
283
285{
286 View3D *v3d_dummy;
287 ARegion *region_dummy;
288
289 return ED_view3d_context_user_region(C, &v3d_dummy, &region_dummy);
290}
291
293{
294 /* identifiers */
295 ot->name = "Set Active Object as Camera";
296 ot->description = "Set the active object as the active camera for this view or scene";
297 ot->idname = "VIEW3D_OT_object_as_camera";
298
299 /* API callbacks. */
302
303 /* flags */
305}
306
308
309/* -------------------------------------------------------------------- */
312
313void view3d_winmatrix_set(const Depsgraph *depsgraph,
314 ARegion *region,
315 const View3D *v3d,
316 const rcti *rect)
317{
318 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
319 rctf full_viewplane;
320 float clipsta, clipend;
321 bool is_ortho;
322
324 v3d,
325 rv3d,
326 region->winx,
327 region->winy,
328 &full_viewplane,
329 &clipsta,
330 &clipend,
331 nullptr);
332 rv3d->is_persp = !is_ortho;
333
334#if 0
335 printf("%s: %d %d %f %f %f %f %f %f\n",
336 __func__,
337 winx,
338 winy,
339 full_viewplane.xmin,
340 full_viewplane.ymin,
341 full_viewplane.xmax,
342 full_viewplane.ymax,
343 clipsta,
344 clipend);
345#endif
346
347 /* Note the code here was tweaked to avoid an apparent compiler bug in clang 13 (see #91680). */
348 rctf viewplane;
349 if (rect) {
350 /* Smaller viewplane subset for selection picking. */
351 viewplane.xmin = full_viewplane.xmin +
352 (BLI_rctf_size_x(&full_viewplane) * (rect->xmin / float(region->winx)));
353 viewplane.ymin = full_viewplane.ymin +
354 (BLI_rctf_size_y(&full_viewplane) * (rect->ymin / float(region->winy)));
355 viewplane.xmax = full_viewplane.xmin +
356 (BLI_rctf_size_x(&full_viewplane) * (rect->xmax / float(region->winx)));
357 viewplane.ymax = full_viewplane.ymin +
358 (BLI_rctf_size_y(&full_viewplane) * (rect->ymax / float(region->winy)));
359 }
360 else {
361 viewplane = full_viewplane;
362 }
363
364 if (is_ortho) {
366 viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
367 }
368 else {
370 viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
371 }
372
373 /* update matrix in 3d view region */
375}
376
377static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
378{
379 float bmat[4][4];
380
381 rv3d->view = RV3D_VIEW_USER; /* don't show the grid */
382
383 normalize_m4_m4(bmat, ob->object_to_world().ptr());
384 invert_m4_m4(rv3d->viewmat, bmat);
385
386 /* view quat calculation, needed for add object */
388}
389
390void view3d_viewmatrix_set(const Depsgraph *depsgraph,
391 const Scene *scene,
392 const View3D *v3d,
393 RegionView3D *rv3d,
394 const float rect_scale[2])
395{
396 if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
397 if (v3d->camera) {
398 Object *ob_camera_eval = DEG_get_evaluated(depsgraph, v3d->camera);
399 obmat_to_viewmat(rv3d, ob_camera_eval);
400 }
401 else {
402 quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
403 rv3d->viewmat[3][2] -= rv3d->dist;
404 }
405 }
406 else {
407 bool use_lock_ofs = false;
408
409 /* should be moved to better initialize later on XXX */
411 ED_view3d_lock(rv3d);
412 }
413
414 quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
415 if (rv3d->persp == RV3D_PERSP) {
416 rv3d->viewmat[3][2] -= rv3d->dist;
417 }
418 if (v3d->ob_center) {
420 float vec[3];
421
422 copy_v3_v3(vec, ob_eval->object_to_world().location());
423 if (ob_eval->type == OB_ARMATURE && v3d->ob_center_bone[0]) {
425 if (pchan) {
426 copy_v3_v3(vec, pchan->pose_mat[3]);
427 mul_m4_v3(ob_eval->object_to_world().ptr(), vec);
428 }
429 }
430 translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
431 use_lock_ofs = true;
432 }
433 else if (v3d->ob_center_cursor) {
434 float vec[3];
435 copy_v3_v3(vec, scene->cursor.location);
436 translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
437 use_lock_ofs = true;
438 }
439 else {
440 translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
441 }
442
443 /* lock offset */
444 if (use_lock_ofs) {
445 float persmat[4][4], persinv[4][4];
446 float vec[3];
447
448 /* we could calculate the real persmat/persinv here
449 * but it would be unreliable so better to later */
450 mul_m4_m4m4(persmat, rv3d->winmat, rv3d->viewmat);
451 invert_m4_m4(persinv, persmat);
452
453 mul_v2_v2fl(vec, rv3d->ofs_lock, rv3d->is_persp ? rv3d->dist : 1.0f);
454 vec[2] = 0.0f;
455
456 if (rect_scale) {
457 /* Since `RegionView3D.winmat` has been calculated and this function doesn't take the
458 * #ARegion we don't know about the region size.
459 * Use `rect_scale` when drawing a sub-region to apply 2D offset,
460 * scaled by the difference between the sub-region and the region size.
461 */
462 vec[0] /= rect_scale[0];
463 vec[1] /= rect_scale[1];
464 }
465
466 mul_mat3_m4_v3(persinv, vec);
467 translate_m4(rv3d->viewmat, vec[0], vec[1], vec[2]);
468 }
469 /* end lock offset */
470 }
471}
472
474
475/* -------------------------------------------------------------------- */
478
483
488
496
497static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
498{
499 bool continue_pass = false;
500 DrawSelectLoopUserData *data = static_cast<DrawSelectLoopUserData *>(user_data);
501 if (stage == DRW_SELECT_PASS_PRE) {
502 GPU_select_begin_next(data->buffer, data->rect, data->gpu_select_mode, data->hits);
503 /* always run POST after PRE. */
504 continue_pass = true;
505 }
506 else if (stage == DRW_SELECT_PASS_POST) {
507 int hits = GPU_select_end();
508 if (data->pass == 0) {
509 /* quirk of GPU_select_end, only take hits value from first call. */
510 data->hits = hits;
511 }
512 data->pass += 1;
513 }
514 else {
515 BLI_assert(0);
516 }
517 return continue_pass;
518}
519
532
534static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
535{
536 const Object *obact = static_cast<const Object *>(user_data);
537 return BKE_object_is_mode_compat(ob, eObjectMode(obact->mode));
538}
539
545{
546 LinkNode *ob_pose_list = static_cast<LinkNode *>(user_data);
547 return ob_pose_list && (BLI_linklist_index(ob_pose_list, DEG_get_original(ob)) != -1);
548}
549
551 GPUSelectBuffer *buffer,
552 const rcti *input,
553 eV3DSelectMode select_mode,
554 eV3DSelectObjectFilter select_filter,
555 const bool do_material_slot_selection)
556{
557 bThemeState theme_state;
558 const wmWindowManager *wm = CTX_wm_manager(vc->C);
559 Depsgraph *depsgraph = vc->depsgraph;
560 Scene *scene = vc->scene;
561 View3D *v3d = vc->v3d;
562 ARegion *region = vc->region;
563 rcti rect;
564 int hits = 0;
566 const bool use_obedit_skip = (BKE_view_layer_edit_object_get(vc->view_layer) != nullptr) &&
567 (vc->obedit == nullptr);
568 const bool use_nearest = select_mode == VIEW3D_SELECT_PICK_NEAREST;
569 bool draw_surface = true;
570
571 GPUSelectMode gpu_select_mode = GPU_SELECT_INVALID;
572
573 /* case not a box select */
574 if (input->xmin == input->xmax) {
575 const int xy[2] = {input->xmin, input->ymin};
576 /* seems to be default value for bones only now */
577 BLI_rcti_init_pt_radius(&rect, xy, 12);
578 }
579 else {
580 rect = *input;
581 }
582
583 if (select_mode == VIEW3D_SELECT_PICK_NEAREST) {
584 gpu_select_mode = GPU_SELECT_PICK_NEAREST;
585 }
586 else if (select_mode == VIEW3D_SELECT_PICK_ALL) {
587 gpu_select_mode = GPU_SELECT_PICK_ALL;
588 }
589 else {
590 gpu_select_mode = GPU_SELECT_ALL;
591 }
592
593 /* Important to use `vc->obact`, not `BKE_view_layer_active_object_get(vc->view_layer)` below,
594 * so it will be nullptr when hidden. */
595 struct {
597 void *user_data;
598 } object_filter = {nullptr, nullptr};
599
600 /* Re-use cache (rect must be smaller than the cached)
601 * other context is assumed to be unchanged */
602 if (GPU_select_is_cached()) {
603 GPU_select_begin_next(buffer, &rect, gpu_select_mode, 0);
605 hits = GPU_select_end();
606 return hits;
607 }
608
609 switch (select_filter) {
611 Object *obact = vc->obact;
612 if (obact && obact->mode != OB_MODE_OBJECT) {
613 object_filter.fn = drw_select_filter_object_mode_lock;
614 object_filter.user_data = obact;
615 }
616 break;
617 }
619 Object *obact = vc->obact;
620 BLI_assert(obact && (obact->mode & OB_MODE_ALL_WEIGHT_PAINT));
621 /* While this uses `alloca` in a loop (which we typically avoid),
622 * the number of items is nearly always 1, maybe 2..3 in rare cases. */
623 LinkNode *ob_pose_list = nullptr;
624 VirtualModifierData virtual_modifier_data;
625 ModifierData *md = BKE_modifiers_get_virtual_modifierlist(obact, &virtual_modifier_data);
626 for (; md; md = md->next) {
627 if (md->type == eModifierType_Armature) {
628 ArmatureModifierData *amd = reinterpret_cast<ArmatureModifierData *>(md);
629 if (amd->object && (amd->object->mode & OB_MODE_POSE)) {
630 BLI_linklist_prepend_alloca(&ob_pose_list, amd->object);
631 }
632 }
635 reinterpret_cast<GreasePencilArmatureModifierData *>(md);
636 if (amd->object && (amd->object->mode & OB_MODE_POSE)) {
637 BLI_linklist_prepend_alloca(&ob_pose_list, amd->object);
638 }
639 }
640 }
642 object_filter.user_data = ob_pose_list;
643 break;
644 }
646 break;
647 }
648
649 /* Tools may request depth outside of regular drawing code. */
650 UI_Theme_Store(&theme_state);
652
653 /* All of the queries need to be perform on the drawing context. */
655
656 G.f |= G_FLAG_PICKSEL;
657
658 /* Important we use the 'viewmat' and don't re-calculate since
659 * the object & bone view locking takes 'rect' into account, see: #51629. */
661 wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, nullptr, &rect);
662
663 if (!XRAY_ACTIVE(v3d)) {
665 }
666
667 /* If in X-ray mode, we select the wires in priority. */
668 if (XRAY_ACTIVE(v3d) && use_nearest) {
669 /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
670 * because the GPU context created & destroyed inside this function. */
671 DrawSelectLoopUserData drw_select_loop_user_data = {};
672 drw_select_loop_user_data.pass = 0;
673 drw_select_loop_user_data.hits = 0;
674 drw_select_loop_user_data.buffer = buffer;
675 drw_select_loop_user_data.rect = &rect;
676 drw_select_loop_user_data.gpu_select_mode = gpu_select_mode;
677
678 draw_surface = false;
680 region,
681 v3d,
682 use_obedit_skip,
683 draw_surface,
684 use_nearest,
685 do_material_slot_selection,
686 &rect,
688 &drw_select_loop_user_data,
689 object_filter.fn,
690 object_filter.user_data);
691 hits = drw_select_loop_user_data.hits;
692 /* FIX: This cleanup the state before doing another selection pass.
693 * (see #56695) */
695 }
696
697 if (hits == 0) {
698 /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
699 * because the GPU context created & destroyed inside this function. */
700 DrawSelectLoopUserData drw_select_loop_user_data = {};
701 drw_select_loop_user_data.pass = 0;
702 drw_select_loop_user_data.hits = 0;
703 drw_select_loop_user_data.buffer = buffer;
704 drw_select_loop_user_data.rect = &rect;
705 drw_select_loop_user_data.gpu_select_mode = gpu_select_mode;
706
707 /* If are not in wireframe mode, we need to use the mesh surfaces to check for hits */
708 draw_surface = (v3d->shading.type > OB_WIRE) || !XRAY_ENABLED(v3d);
710 region,
711 v3d,
712 use_obedit_skip,
713 draw_surface,
714 use_nearest,
715 do_material_slot_selection,
716 &rect,
718 &drw_select_loop_user_data,
719 object_filter.fn,
720 object_filter.user_data);
721 hits = drw_select_loop_user_data.hits;
722 }
723
724 G.f &= ~G_FLAG_PICKSEL;
726 wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, nullptr, nullptr);
727
728 if (!XRAY_ACTIVE(v3d)) {
730 }
731
733
734 UI_Theme_Restore(&theme_state);
735
736 return hits;
737}
738
740 GPUSelectBuffer *buffer,
741 const rcti *input,
742 eV3DSelectMode select_mode,
743 eV3DSelectObjectFilter select_filter)
744{
745 return view3d_gpu_select_ex(vc, buffer, input, select_mode, select_filter, false);
746}
747
749 GPUSelectBuffer *buffer,
750 const rcti *input,
751 eV3DSelectMode select_mode,
752 eV3DSelectObjectFilter select_filter,
753 uint select_id)
754{
755 const int64_t start = buffer->storage.size();
756 int hits = view3d_gpu_select(vc, buffer, input, select_mode, select_filter);
757
758 /* Selection sometimes uses -1 for an invalid selection ID, remove these as they
759 * interfere with detection of actual number of hits in the selection. */
760 if (hits > 0) {
761 hits = GPU_select_buffer_remove_by_id(buffer->storage.as_mutable_span().slice(start, hits),
762 select_id);
763
764 /* Trim buffer to the exact size in case selections were removed. */
765 buffer->storage.resize(start + hits);
766 }
767 return hits;
768}
769
771
772/* -------------------------------------------------------------------- */
775
777{
778 ushort local_view_bits = 0;
779
780 /* Sometimes we lose a local-view: when an area is closed.
781 * Check all areas: which local-views are in use? */
782 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
783 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
784 SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
785 for (; sl; sl = sl->next) {
786 if (sl->spacetype == SPACE_VIEW3D) {
787 View3D *v3d = reinterpret_cast<View3D *>(sl);
788 if (v3d->localvd) {
789 local_view_bits |= v3d->local_view_uid;
790 }
791 }
792 }
793 }
794 }
795
796 for (int i = 0; i < 16; i++) {
797 if ((local_view_bits & (1 << i)) == 0) {
798 return (1 << i);
799 }
800 }
801
802 return 0;
803}
804
805static bool view3d_localview_init(const Depsgraph *depsgraph,
806 wmWindowManager *wm,
807 wmWindow *win,
808 Main *bmain,
809 const Scene *scene,
810 ViewLayer *view_layer,
811 ScrArea *area,
812 const bool frame_selected,
813 const int smooth_viewtx,
814 ReportList *reports)
815{
816 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
817 blender::float3 min, max, box;
818 float size = 0.0f;
819 uint local_view_bit;
820 bool changed = false;
821
822 if (v3d->localvd) {
823 return changed;
824 }
825
827
828 local_view_bit = free_localview_bit(bmain);
829
830 if (local_view_bit == 0) {
831 /* TODO(dfelinto): We can kick one of the other 3D views out of local view
832 * specially if it is not being used. */
833 BKE_report(reports, RPT_ERROR, "No more than 16 local views");
834 changed = false;
835 }
836 else {
837 BKE_view_layer_synced_ensure(scene, view_layer);
838 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
839 if (obedit) {
840 BKE_view_layer_synced_ensure(scene, view_layer);
842 base->local_view_bits &= ~local_view_bit;
843 }
844 FOREACH_BASE_IN_EDIT_MODE_BEGIN (scene, view_layer, v3d, base_iter) {
845 Object *ob_eval = DEG_get_evaluated(depsgraph, base_iter->object);
846 BKE_object_minmax(ob_eval ? ob_eval : base_iter->object, min, max);
847 base_iter->local_view_bits |= local_view_bit;
848 changed = true;
849 }
851 }
852 else {
853 BKE_view_layer_synced_ensure(scene, view_layer);
855 if (BASE_SELECTED(v3d, base)) {
856 Object *ob_eval = DEG_get_evaluated(depsgraph, base->object);
857 BKE_object_minmax(ob_eval ? ob_eval : base->object, min, max);
858 base->local_view_bits |= local_view_bit;
859 changed = true;
860 }
861 else {
862 base->local_view_bits &= ~local_view_bit;
863 }
864 }
865 }
866
867 sub_v3_v3v3(box, max, min);
868 size = max_fff(box[0], box[1], box[2]);
869 }
870
871 if (changed == false) {
872 return false;
873 }
874
875 /* Apply any running smooth-view values before reading from the viewport. */
876 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
877 if (region->regiontype == RGN_TYPE_WINDOW) {
878 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
879 if (rv3d->sms) {
881 }
882 }
883 }
884
885 v3d->localvd = MEM_mallocN<View3D>("localview");
886 *v3d->localvd = blender::dna::shallow_copy(*v3d);
887 v3d->local_view_uid = local_view_bit;
888
889 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
890 if (region->regiontype == RGN_TYPE_WINDOW) {
891 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
892 bool ok_dist = true;
893
894 /* New view values. */
895 Object *camera_old = nullptr;
896 float dist_new, ofs_new[3];
897
898 rv3d->localvd = MEM_mallocN<RegionView3D>("localview region");
899 memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
900
901 if (frame_selected) {
902 float mid[3];
903 mid_v3_v3v3(mid, min, max);
904 negate_v3_v3(ofs_new, mid);
905
906 if (rv3d->persp == RV3D_CAMOB) {
907 camera_old = v3d->camera;
908 const Camera &camera = *static_cast<Camera *>(camera_old->data);
909 rv3d->persp = (camera.type == CAM_ORTHO) ? RV3D_ORTHO : RV3D_PERSP;
910 }
911
912 if (rv3d->persp == RV3D_ORTHO) {
913 if (size < 0.0001f) {
914 ok_dist = false;
915 }
916 }
917
918 if (ok_dist) {
919 dist_new = ED_view3d_radius_to_dist(
920 v3d, region, depsgraph, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
921
922 if (rv3d->persp == RV3D_PERSP) {
923 /* Don't zoom closer than the near clipping plane. */
924 const float dist_min = ED_view3d_dist_soft_min_get(v3d, true);
925 CLAMP_MIN(dist_new, dist_min);
926 }
927 }
928
929 V3D_SmoothParams sview_params = {};
930 sview_params.camera_old = camera_old;
931 sview_params.ofs = ofs_new;
932 sview_params.quat = rv3d->viewquat;
933 sview_params.dist = ok_dist ? &dist_new : nullptr;
934 sview_params.lens = &v3d->lens;
935 /* No undo because this doesn't move the camera. */
936 sview_params.undo_str = nullptr;
937
939 depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_params);
940 }
941 }
942 }
943
944 return changed;
945}
946
947static bool view3d_localview_exit(const Depsgraph *depsgraph,
948 wmWindowManager *wm,
949 wmWindow *win,
950 const Scene *scene,
951 ViewLayer *view_layer,
952 ScrArea *area,
953 const bool frame_selected,
954 const int smooth_viewtx)
955{
956 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
957 bool changed = false;
958
959 if (v3d->localvd == nullptr) {
960 return changed;
961 }
962 BKE_view_layer_synced_ensure(scene, view_layer);
964 if (base->local_view_bits & v3d->local_view_uid) {
965 base->local_view_bits &= ~v3d->local_view_uid;
966 }
967 }
968
969 /* Apply any running smooth-view values before reading from the viewport. */
970 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
971 if (region->regiontype == RGN_TYPE_WINDOW) {
972 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
973 if (rv3d->localvd == nullptr) {
974 continue;
975 }
976 if (rv3d->sms) {
978 }
979 }
980 }
981
982 Object *camera_old = v3d->camera;
983 Object *camera_new = v3d->localvd->camera;
984
985 v3d->local_view_uid = 0;
986 v3d->camera = v3d->localvd->camera;
987
988 MEM_freeN(v3d->localvd);
989 v3d->localvd = nullptr;
991
992 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
993 if (region->regiontype == RGN_TYPE_WINDOW) {
994 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
995
996 if (rv3d->localvd == nullptr) {
997 continue;
998 }
999
1000 if (frame_selected && depsgraph) {
1001 Object *camera_old_rv3d, *camera_new_rv3d;
1002
1003 camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : nullptr;
1004 camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : nullptr;
1005
1006 rv3d->view = rv3d->localvd->view;
1007 rv3d->view_axis_roll = rv3d->localvd->view_axis_roll;
1008 rv3d->persp = rv3d->localvd->persp;
1009 rv3d->camzoom = rv3d->localvd->camzoom;
1010
1011 V3D_SmoothParams sview_params = {};
1012 sview_params.camera_old = camera_old_rv3d;
1013 sview_params.camera = camera_new_rv3d;
1014 sview_params.ofs = rv3d->localvd->ofs;
1015 sview_params.quat = rv3d->localvd->viewquat;
1016 sview_params.dist = &rv3d->localvd->dist;
1017 /* No undo because this doesn't move the camera. */
1018 sview_params.undo_str = nullptr;
1019
1021 depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_params);
1022 }
1023
1024 MEM_freeN(rv3d->localvd);
1025 rv3d->localvd = nullptr;
1026 changed = true;
1027 }
1028 }
1029 return changed;
1030}
1031
1033 Scene *scene,
1034 ViewLayer *view_layer,
1035 wmWindowManager *wm,
1036 wmWindow *win,
1037 View3D *v3d,
1038 ScrArea *area,
1039 const bool frame_selected,
1040 const int smooth_viewtx)
1041{
1042 if (v3d->localvd == nullptr) {
1043 return false;
1044 }
1045
1047
1048 BKE_view_layer_synced_ensure(scene, view_layer);
1050 if (base->local_view_bits & v3d->local_view_uid) {
1051 return false;
1052 }
1053 }
1054
1055 return view3d_localview_exit(
1056 depsgraph, wm, win, scene, view_layer, area, frame_selected, smooth_viewtx);
1057}
1058
1060{
1062 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1064 wmWindow *win = CTX_wm_window(C);
1065 Main *bmain = CTX_data_main(C);
1066 Scene *scene = CTX_data_scene(C);
1067 ViewLayer *view_layer = CTX_data_view_layer(C);
1068 ScrArea *area = CTX_wm_area(C);
1069 View3D *v3d = CTX_wm_view3d(C);
1070 bool frame_selected = RNA_boolean_get(op->ptr, "frame_selected");
1071 bool changed;
1072
1073 if (v3d->localvd) {
1074 changed = view3d_localview_exit(
1075 depsgraph, wm, win, scene, view_layer, area, frame_selected, smooth_viewtx);
1076 }
1077 else {
1079 wm,
1080 win,
1081 bmain,
1082 scene,
1083 view_layer,
1084 area,
1085 frame_selected,
1086 smooth_viewtx,
1087 op->reports);
1088 }
1089
1090 if (changed) {
1091 DEG_id_type_tag(bmain, ID_OB);
1092 ED_area_tag_redraw(area);
1093
1094 /* Unselected objects become selected when exiting. */
1095 if (v3d->localvd == nullptr) {
1098 }
1099 else {
1101 }
1102
1103 return OPERATOR_FINISHED;
1104 }
1105 return OPERATOR_CANCELLED;
1106}
1107
1109{
1110 /* identifiers */
1111 ot->name = "Local View";
1112 ot->description = "Toggle display of selected object(s) separately and centered in view";
1113 ot->idname = "VIEW3D_OT_localview";
1114
1115 /* API callbacks. */
1116 ot->exec = localview_exec;
1117 /* Use undo because local-view changes object layer bit-flags. */
1118 ot->flag = OPTYPE_UNDO;
1119
1121
1122 RNA_def_boolean(ot->srna,
1123 "frame_selected",
1124 true,
1125 "Frame Selected",
1126 "Move the view to frame the selected objects");
1127}
1128
1130{
1131 View3D *v3d = CTX_wm_view3d(C);
1132 Main *bmain = CTX_data_main(C);
1133 Scene *scene = CTX_data_scene(C);
1134 ViewLayer *view_layer = CTX_data_view_layer(C);
1135 bool changed = false;
1136 BKE_view_layer_synced_ensure(scene, view_layer);
1138 if (BASE_SELECTED(v3d, base)) {
1139 base->local_view_bits &= ~v3d->local_view_uid;
1141
1142 if (base == view_layer->basact) {
1143 view_layer->basact = nullptr;
1144 }
1145 changed = true;
1146 }
1147 }
1148
1149 /* If some object was removed from the local view, exit the local view if it is now empty. */
1150 if (changed) {
1152 scene,
1153 view_layer,
1156 v3d,
1157 CTX_wm_area(C),
1158 true,
1160 }
1161
1162 if (changed) {
1163 DEG_tag_on_visible_update(bmain, false);
1167 return OPERATOR_FINISHED;
1168 }
1169
1170 BKE_report(op->reports, RPT_ERROR, "No object selected");
1171 return OPERATOR_CANCELLED;
1172}
1173
1175{
1176 if (CTX_data_edit_object(C) != nullptr) {
1177 return false;
1178 }
1179
1180 View3D *v3d = CTX_wm_view3d(C);
1181 return v3d && v3d->localvd;
1182}
1183
1185{
1186 /* identifiers */
1187 ot->name = "Remove from Local View";
1188 ot->description = "Move selected objects out of local view";
1189 ot->idname = "VIEW3D_OT_localview_remove_from";
1190
1191 /* API callbacks. */
1194 ot->flag = OPTYPE_UNDO;
1195}
1196
1198
1199/* -------------------------------------------------------------------- */
1202
1204 ushort local_collections_uid,
1205 bool *r_reset)
1206{
1207 ushort local_view_bits = 0;
1208
1209 /* Check all areas: which local-views are in use? */
1210 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1211 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1212 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1213 if (sl->spacetype == SPACE_VIEW3D) {
1214 View3D *v3d = reinterpret_cast<View3D *>(sl);
1215 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1216 local_view_bits |= v3d->local_collections_uid;
1217 }
1218 }
1219 }
1220 }
1221 }
1222
1223 /* First try to keep the old uuid. */
1224 if (local_collections_uid && ((local_collections_uid & local_view_bits) == 0)) {
1225 return local_collections_uid;
1226 }
1227
1228 /* Otherwise get the first free available. */
1229 for (int i = 0; i < 16; i++) {
1230 if ((local_view_bits & (1 << i)) == 0) {
1231 *r_reset = true;
1232 return (1 << i);
1233 }
1234 }
1235
1236 return 0;
1237}
1238
1239static void local_collections_reset_uuid(LayerCollection *layer_collection,
1240 const ushort local_view_bit)
1241{
1242 if (layer_collection->flag & LAYER_COLLECTION_HIDE) {
1243 layer_collection->local_collections_bits &= ~local_view_bit;
1244 }
1245 else {
1246 layer_collection->local_collections_bits |= local_view_bit;
1247 }
1248
1249 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1250 local_collections_reset_uuid(child, local_view_bit);
1251 }
1252}
1253
1254static void view3d_local_collections_reset(const Main *bmain, const uint local_view_bit)
1255{
1256 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1257 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1258 LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
1259 local_collections_reset_uuid(layer_collection, local_view_bit);
1260 }
1261 }
1262 }
1263}
1264
1266{
1267 if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
1268 return true;
1269 }
1270
1271 bool reset = false;
1273 uint local_view_bit = free_localcollection_bit(bmain, v3d->local_collections_uid, &reset);
1274
1275 if (local_view_bit == 0) {
1276 return false;
1277 }
1278
1279 v3d->local_collections_uid = local_view_bit;
1281
1282 if (reset) {
1283 view3d_local_collections_reset(bmain, local_view_bit);
1284 }
1285
1286 return true;
1287}
1288
1289void ED_view3d_local_collections_reset(const bContext *C, const bool reset_all)
1290{
1291 Main *bmain = CTX_data_main(C);
1292 uint local_view_bit = ~0;
1293 bool do_reset = false;
1294
1295 /* Reset only the ones that are not in use. */
1296 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1297 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1298 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1299 if (sl->spacetype == SPACE_VIEW3D) {
1300 View3D *v3d = reinterpret_cast<View3D *>(sl);
1301 if (v3d->local_collections_uid) {
1302 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1303 local_view_bit &= ~v3d->local_collections_uid;
1304 }
1305 else {
1306 do_reset = true;
1307 }
1308 }
1309 }
1310 }
1311 }
1312 }
1313
1314 if (do_reset) {
1315 view3d_local_collections_reset(bmain, local_view_bit);
1316 }
1317 else if (reset_all && (do_reset || (local_view_bit != ~0))) {
1319 View3D v3d = {};
1320 v3d.local_collections_uid = ~0;
1323 }
1324}
1325
1327
1328/* -------------------------------------------------------------------- */
1331
1332#ifdef WITH_XR_OPENXR
1333
1334static void view3d_xr_mirror_begin(RegionView3D *rv3d)
1335{
1336 /* If there is no session yet, changes below should not be applied! */
1338
1340 /* Force perspective view. This isn't reset but that's not really an issue. */
1341 rv3d->persp = RV3D_PERSP;
1342}
1343
1344static void view3d_xr_mirror_end(RegionView3D *rv3d)
1345{
1347}
1348
1349void ED_view3d_xr_mirror_update(const ScrArea *area, const View3D *v3d, const bool enable)
1350{
1351 ARegion *region_rv3d;
1352
1354
1355 if (ED_view3d_area_user_region(area, v3d, &region_rv3d)) {
1356 if (enable) {
1357 view3d_xr_mirror_begin(static_cast<RegionView3D *>(region_rv3d->regiondata));
1358 }
1359 else {
1360 view3d_xr_mirror_end(static_cast<RegionView3D *>(region_rv3d->regiondata));
1361 }
1362 }
1363}
1364
1365void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const Scene *scene)
1366{
1368 View3DShading *xr_shading = &wm->xr.session_settings.shading;
1369 /* Flags that shouldn't be overridden by the 3D View shading. */
1370 int flag_copy = 0;
1371 if (v3d->shading.type != OB_SOLID) {
1372 /* Don't set V3D_SHADING_WORLD_ORIENTATION for solid shading since it results in distorted
1373 * lighting when the view matrix has a scale factor. */
1374 flag_copy |= V3D_SHADING_WORLD_ORIENTATION;
1375 }
1376
1378
1379 if (v3d->shading.type == OB_RENDER) {
1381 /* Keep old shading while using Cycles or another engine, they are typically not usable in
1382 * VR. */
1383 return;
1384 }
1385 }
1386
1387 if (xr_shading->prop) {
1388 IDP_FreeProperty(xr_shading->prop);
1389 xr_shading->prop = nullptr;
1390 }
1391
1392 /* Copy shading from View3D to VR view. */
1393 const int old_xr_shading_flag = xr_shading->flag;
1394 *xr_shading = v3d->shading;
1395 xr_shading->flag = (xr_shading->flag & ~flag_copy) | (old_xr_shading_flag & flag_copy);
1396 if (v3d->shading.prop) {
1397 xr_shading->prop = IDP_CopyProperty(xr_shading->prop);
1398 }
1399 }
1400}
1401
1402bool ED_view3d_is_region_xr_mirror_active(const wmWindowManager *wm,
1403 const View3D *v3d,
1404 const ARegion *region)
1405{
1406 return (v3d->flag & V3D_XR_SESSION_MIRROR) &&
1407 /* The free region (e.g. the camera region in quad-view) is always
1408 * the last in the list base. We don't want any other to be affected. */
1409 !region->next && //
1411}
1412
1413#endif
1414
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:1251
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:863
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:2523
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)
void BKE_object_minmax(Object *ob, blender::float3 &r_min, blender::float3 &r_max)
bool BKE_object_is_mode_compat(const Object *ob, eObjectMode object_mode)
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
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
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
MINLINE float max_fff(float a, float b, float c)
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.cc:466
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
unsigned int uint
unsigned short ushort
#define INIT_MINMAX(min, max)
#define CLAMP_MIN(a, b)
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)
T * DEG_get_original(T *id)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1054
@ ID_RECALC_SELECT
Definition DNA_ID.h:1101
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1104
@ ID_OB
@ CAM_ORTHO
@ LAYER_COLLECTION_HIDE
@ eModifierType_GreasePencilArmature
@ 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
@ V3D_SHADING_WORLD_ORIENTATION
@ RV3D_VIEW_USER
#define RV3D_LOCK_FLAGS(rv3d)
@ V3D_RUNTIME_LOCAL_MAYBE_EMPTY
@ V3D_RUNTIME_XR_SESSION_ROOT
@ V3D_LOCAL_COLLECTIONS
@ V3D_XR_SESSION_MIRROR
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
@ RV3D_LOCK_ANY_TRANSFORM
@ RV3D_LOCK_ROTATION
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void DRW_gpu_context_disable()
bool(*)(Object *ob, void *user_data) DRW_ObjectFilterFn
Definition DRW_engine.hh:51
void DRW_gpu_context_enable()
eDRWSelectStage
Definition DRW_engine.hh:46
@ DRW_SELECT_PASS_POST
Definition DRW_engine.hh:48
@ DRW_SELECT_PASS_PRE
Definition DRW_engine.hh:47
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_view3d_local_stats_free(View3D *v3d)
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:693
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:979
@ VIEW3D_SELECT_PICK_ALL
Definition ED_view3d.hh:983
@ VIEW3D_SELECT_PICK_NEAREST
Definition ED_view3d.hh:985
bool ED_view3d_camera_to_view_selected(Main *bmain, Depsgraph *depsgraph, const Scene *scene, Object *camera_ob)
eV3DSelectObjectFilter
Definition ED_view3d.hh:988
@ VIEW3D_SELECT_FILTER_NOP
Definition ED_view3d.hh:990
@ VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK
Definition ED_view3d.hh:992
@ VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK
Definition ED_view3d.hh:994
float ED_view3d_dist_soft_min_get(const View3D *v3d, bool use_persp_range)
bool ED_operator_rv3d_user_region_poll(bContext *C)
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)
void GPU_select_cache_end()
bool GPU_select_is_cached()
unsigned int GPU_select_end()
void GPU_select_begin_next(GPUSelectBuffer *buffer, const rcti *input, GPUSelectMode mode, int oldhits)
void GPU_select_cache_load_id()
uint GPU_select_buffer_remove_by_id(blender::MutableSpan< GPUSelectResult > hit_results, uint select_id)
void GPU_select_cache_begin()
GPUSelectMode
Definition GPU_select.hh:18
@ GPU_SELECT_INVALID
Definition GPU_select.hh:19
@ GPU_SELECT_PICK_ALL
Definition GPU_select.hh:25
@ GPU_SELECT_ALL
Definition GPU_select.hh:20
@ GPU_SELECT_PICK_NEAREST
Definition GPU_select.hh:26
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:114
@ GPU_DEPTH_NONE
Definition GPU_state.hh:111
void GPU_depth_test(GPUDepthTest test)
Definition gpu_state.cc:68
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
void UI_Theme_Store(bThemeState *theme_state)
void UI_Theme_Restore(const bThemeState *theme_state)
void UI_SetTheme(int spacetype, int regionid)
#define ND_DRAW
Definition WM_types.hh:461
#define ND_OB_ACTIVE
Definition WM_types.hh:440
#define ND_OB_SELECT
Definition WM_types.hh:442
#define NC_SCENE
Definition WM_types.hh:378
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define ND_TRANSFORM
Definition WM_types.hh:456
#define NC_OBJECT
Definition WM_types.hh:379
BMesh const char void * data
BPy_StructRNA * depsgraph
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
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()
nullptr float
#define input
#define printf(...)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void base_select(Base *base, eObjectSelect_Mode mode)
VecBase< float, 3 > float3
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.cc:36
void * regiondata
struct ARegion * next
GPUSelectMode gpu_select_mode
GPUSelectBuffer * buffer
GPUSelectStorage storage
Definition GPU_select.hh:47
ListBase layer_collections
unsigned short local_collections_bits
void * first
ListBase scenes
Definition BKE_main.hh:278
ListBase screens
Definition BKE_main.hh:292
struct ModifierData * next
struct bPose * pose
short protectflag
struct SmoothView3DStore * sms
struct RegionView3D * localvd
float viewmat[4][4]
float winmat[4][4]
struct ToolSettings * toolsettings
View3DCursor cursor
struct Object * camera
ListBase spacedata
ListBase regionbase
const char * undo_str
struct IDProperty * prop
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
RegionView3D * rv3d
Definition ED_view3d.hh:80
ARegion * region
Definition ED_view3d.hh:77
Scene * scene
Definition ED_view3d.hh:73
wmWindow * win
Definition ED_view3d.hh:79
ViewLayer * view_layer
Definition ED_view3d.hh:74
bContext * C
Definition ED_view3d.hh:66
View3D * v3d
Definition ED_view3d.hh:78
Object * obact
Definition ED_view3d.hh:75
Object * obedit
Definition ED_view3d.hh:76
Depsgraph * depsgraph
Definition ED_view3d.hh:72
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
struct ReportList * reports
struct PointerRNA * ptr
XrSessionSettings session_settings
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
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 ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
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])
void VIEW3D_OT_localview(wmOperatorType *ot)
int view3d_gpu_select(const ViewContext *vc, GPUSelectBuffer *buffer, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter)
static void view3d_local_collections_reset(const Main *bmain, const uint local_view_bit)
static wmOperatorStatus view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
static uint free_localview_bit(Main *bmain)
void view3d_gpu_select_cache_end()
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
void VIEW3D_OT_localview_remove_from(wmOperatorType *ot)
void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
static wmOperatorStatus view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
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)
static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void *user_data)
static wmOperatorStatus localview_remove_from_exec(bContext *C, wmOperator *op)
int view3d_gpu_select_ex(const ViewContext *vc, GPUSelectBuffer *buffer, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, const bool do_material_slot_selection)
static void sync_viewport_camera_smoothview(bContext *C, View3D *v3d, Object *ob, const int smooth_viewtx)
static wmOperatorStatus view3d_camera_to_view_exec(bContext *C, wmOperator *)
int view3d_gpu_select_with_id_filter(const ViewContext *vc, GPUSelectBuffer *buffer, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, uint select_id)
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 wmOperatorStatus localview_exec(bContext *C, wmOperator *op)
eV3DSelectObjectFilter ED_view3d_select_filter_from_mode(const Scene *scene, const Object *obact)
static bool localview_remove_from_poll(bContext *C)
void view3d_gpu_select_cache_begin()
void ED_view3d_local_collections_reset(const bContext *C, const bool reset_all)
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_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)
void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
int xy[2]
Definition wm_draw.cc:178
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4237
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)