Blender V4.5
view3d_navigate_smoothview.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "DNA_camera_types.h"
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_listbase.h"
14#include "BLI_math_rotation.h"
15#include "BLI_math_vector.h"
16
17#include "BKE_context.hh"
18
20
21#include "WM_api.hh"
22
23#include "ED_screen.hh"
24
25#include "view3d_intern.hh"
26#include "view3d_navigate.hh" /* Own include. */
27
29 bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor);
30
31/* -------------------------------------------------------------------- */
45
47{
48 const View3D *v3d = static_cast<const View3D *>(area->spacedata.first);
49 Object *camera = v3d->camera;
50 if (!camera) {
51 return;
52 }
53
54 /* Tag the camera object so it's known smooth-view is applied to the view-ports camera
55 * (needed to detect when a locked camera is being manipulated).
56 * NOTE: It doesn't matter if the actual object being manipulated is the camera or not. */
57 camera->id.tag &= ~ID_TAG_DOIT;
58
59 LISTBASE_FOREACH (const ARegion *, region, &area->regionbase) {
60 if (region->regiontype != RGN_TYPE_WINDOW) {
61 continue;
62 }
63 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
64 if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) {
65 camera->id.tag |= ID_TAG_DOIT;
66 break;
67 }
68 }
69}
70
72 const ScrArea *area,
73 const char *undo_str,
74 const bool undo_grouped)
75{
76 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
77 Object *camera = v3d->camera;
78 if (!camera) {
79 return;
80 }
81 if (camera->id.tag & ID_TAG_DOIT) {
82 /* Smooth view didn't touch the camera. */
83 camera->id.tag &= ~ID_TAG_DOIT;
84 return;
85 }
86
87 if ((U.uiflag & USER_GLOBALUNDO) == 0) {
88 return;
89 }
90
91 /* NOTE(@ideasman42): It is not possible that a single viewport references different cameras
92 * so even in the case there is a quad-view with multiple camera views set, these will all
93 * reference the same camera. In this case it doesn't matter which region is used.
94 * If in the future multiple cameras are supported, this logic can be extended. */
95 const ARegion *region_camera = nullptr;
96
97 /* An undo push should be performed. */
98 bool is_interactive = false;
99 LISTBASE_FOREACH (const ARegion *, region, &area->regionbase) {
100 if (region->regiontype != RGN_TYPE_WINDOW) {
101 continue;
102 }
103 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
104 if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) {
105 region_camera = region;
106 if (rv3d->sms) {
107 is_interactive = true;
108 }
109 }
110 }
111
112 if (region_camera == nullptr) {
113 return;
114 }
115
116 RegionView3D *rv3d = static_cast<RegionView3D *>(region_camera->regiondata);
117
118 /* Fast forward, undo push, then rewind. */
119 if (is_interactive) {
120 view3d_smoothview_apply_with_interp(C, v3d, rv3d, false, 1.0f);
121 }
122
123 if (undo_grouped) {
124 ED_view3d_camera_lock_undo_grouped_push(undo_str, v3d, rv3d, C);
125 }
126 else {
127 ED_view3d_camera_lock_undo_push(undo_str, v3d, rv3d, C);
128 }
129
130 if (is_interactive) {
131 view3d_smoothview_apply_with_interp(C, v3d, rv3d, false, 0.0f);
132 }
133}
134
136
137/* -------------------------------------------------------------------- */
146
148 float dist;
149 float lens;
150 float quat[4];
151 float ofs[3];
152};
153
184
186 const View3D *v3d,
187 const RegionView3D *rv3d)
188{
189 copy_v3_v3(sms_state->ofs, rv3d->ofs);
190 copy_qt_qt(sms_state->quat, rv3d->viewquat);
191 sms_state->dist = rv3d->dist;
192 sms_state->lens = v3d->lens;
193}
194
196 View3D *v3d,
197 RegionView3D *rv3d)
198{
199 copy_v3_v3(rv3d->ofs, sms_state->ofs);
200 copy_qt_qt(rv3d->viewquat, sms_state->quat);
201 rv3d->dist = sms_state->dist;
202 v3d->lens = sms_state->lens;
203}
204
206 /* Avoid passing in the context. */
207 const Depsgraph *depsgraph,
208 wmWindowManager *wm,
209 wmWindow *win,
210 ScrArea *area,
211 View3D *v3d,
212 ARegion *region,
213 const int smooth_viewtx,
214 const V3D_SmoothParams *sview)
215{
216 /* Will start a timer if appropriate. */
217
218 /* In this case use #ED_view3d_smooth_view_undo_begin & end functions
219 * instead of passing in undo. */
220 BLI_assert_msg(sview->undo_str == nullptr,
221 "Only the 'ED_view3d_smooth_view' version of this function handles undo!");
222
223 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
224 SmoothView3DStore sms = {{0}};
225
226 /* Initialize `sms`. */
227 view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
228 view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
229 /* If smooth-view runs multiple times. */
230 if (rv3d->sms == nullptr) {
231 view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
232 }
233 else {
234 sms.org = rv3d->sms->org;
235 }
236 sms.org_view = rv3d->view;
238
239 // sms.to_camera = false; /* Initialized to zero anyway. */
240
241 /* NOTE: Regarding camera locking: This is a little confusing but works OK.
242 * We may be changing the view 'as if' there is no active camera, but in fact
243 * there is an active camera which is locked to the view.
244 *
245 * In the case where smooth view is moving _to_ a camera we don't want that
246 * camera to be moved or changed, so only when the camera is not being set should
247 * we allow camera option locking to initialize the view settings from the camera. */
248 if (sview->camera == nullptr && sview->camera_old == nullptr) {
250 }
251
252 /* Store the options we want to end with. */
253 if (sview->ofs) {
254 copy_v3_v3(sms.dst.ofs, sview->ofs);
255 }
256 if (sview->quat) {
257 copy_qt_qt(sms.dst.quat, sview->quat);
258 }
259 if (sview->dist) {
260 sms.dst.dist = *sview->dist;
261 }
262 if (sview->lens) {
263 sms.dst.lens = *sview->lens;
264 }
265
266 if (sview->dyn_ofs) {
267 BLI_assert(sview->ofs == nullptr);
268 BLI_assert(sview->quat != nullptr);
269
270 copy_v3_v3(sms.dyn_ofs, sview->dyn_ofs);
271 sms.use_dyn_ofs = true;
272
273 /* Calculate the final destination offset. */
274 view3d_orbit_apply_dyn_ofs(sms.dst.ofs, sms.src.ofs, sms.src.quat, sms.dst.quat, sms.dyn_ofs);
275 }
276
277 if (sview->camera) {
278 Object *ob_camera_eval = DEG_get_evaluated(depsgraph, sview->camera);
279 if (sview->ofs != nullptr) {
281 ob_camera_eval->object_to_world().ptr(), sview->ofs, VIEW3D_DIST_FALLBACK);
282 }
283 ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
284 /* Restore view3d values in end. */
285 sms.to_camera = true;
286 }
287
288 if ((sview->camera_old == sview->camera) && /* Camera. */
289 (sms.dst.dist == rv3d->dist) && /* Distance. */
290 (sms.dst.lens == v3d->lens) && /* Lens. */
291 equals_v3v3(sms.dst.ofs, rv3d->ofs) && /* Offset. */
292 equals_v4v4(sms.dst.quat, rv3d->viewquat) /* Rotation. */
293 )
294 {
295 /* Early return if nothing changed. */
296 return;
297 }
298
299 /* Skip smooth viewing for external render engine draw. */
300 if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->view_render)) {
301
302 /* Original values. */
303 if (sview->camera_old) {
304 Object *ob_camera_old_eval = DEG_get_evaluated(depsgraph, sview->camera_old);
305 if (sview->ofs != nullptr) {
307 ob_camera_old_eval->object_to_world().ptr(), sview->ofs, 0);
308 }
310 ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
311 }
312 /* Grid draw as floor. */
313 if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
314 /* Use existing if exists, means multiple calls to smooth view
315 * won't lose the original 'view' setting. */
316 rv3d->view = RV3D_VIEW_USER;
317 }
318
319 sms.time_allowed = double(smooth_viewtx / 1000.0);
320
321 /* If this is view rotation only we can decrease the time allowed by the angle between
322 * quaternions this means small rotations won't lag. */
323 if (sview->quat && !sview->ofs && !sview->dist) {
324 /* Scale the time allowed by the rotation (180 degrees == 1.0). */
326 M_PI;
327 }
328
329 /* Ensure it shows correct. */
330 if (sms.to_camera) {
331 /* Use orthographic if we move from an orthographic view to an orthographic camera. */
332 Object *ob_camera_eval = DEG_get_evaluated(depsgraph, sview->camera);
333 rv3d->persp = ((rv3d->is_persp == false) && (ob_camera_eval->type == OB_CAMERA) &&
334 (static_cast<Camera *>(ob_camera_eval->data)->type == CAM_ORTHO)) ?
335 RV3D_ORTHO :
337 }
338
339 rv3d->rflag |= RV3D_NAVIGATING;
340
341 /* Not essential but in some cases the caller will tag the area for redraw, and in that
342 * case we can get a flicker of the 'org' user view but we want to see 'src'. */
343 view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
344
345 /* Keep track of running timer! */
346 if (rv3d->sms == nullptr) {
347 rv3d->sms = MEM_mallocN<SmoothView3DStore>("smoothview v3d");
348 }
349 *rv3d->sms = sms;
350 if (rv3d->smooth_timer) {
351 WM_event_timer_remove(wm, win, rv3d->smooth_timer);
352 }
353 /* #TIMER1 is hard-coded in key-map. */
354 rv3d->smooth_timer = WM_event_timer_add(wm, win, TIMER1, 1.0 / 100.0);
355 }
356 else {
357 /* Animation is disabled, apply immediately. */
358 if (sms.to_camera == false) {
359 copy_v3_v3(rv3d->ofs, sms.dst.ofs);
360 copy_qt_qt(rv3d->viewquat, sms.dst.quat);
361 rv3d->dist = sms.dst.dist;
362 v3d->lens = sms.dst.lens;
363
365 }
366
367 if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
368 view3d_boxview_copy(area, region);
369 }
370
371 ED_region_tag_redraw(region);
372
374 }
375
376 if (sms.to_camera == false) {
377 /* See comments in #ED_view3d_smooth_view_undo_begin for why this is needed. */
378 if (v3d->camera) {
379 v3d->camera->id.tag &= ~ID_TAG_DOIT;
380 }
381 }
382}
383
385 View3D *v3d,
386 ARegion *region,
387 const int smooth_viewtx,
388 const V3D_SmoothParams *sview)
389{
392 wmWindow *win = CTX_wm_window(C);
393 ScrArea *area = CTX_wm_area(C);
394
395 /* #ED_view3d_smooth_view_ex asserts this is not set as it doesn't support undo. */
396 V3D_SmoothParams sview_no_undo = *sview;
397 sview_no_undo.undo_str = nullptr;
398 sview_no_undo.undo_grouped = false;
399
400 const bool do_undo = (sview->undo_str != nullptr);
401 if (do_undo) {
403 }
404
405 ED_view3d_smooth_view_ex(depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_no_undo);
406
407 if (do_undo) {
409 }
410}
411
416 bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor)
417{
418 SmoothView3DStore *sms = rv3d->sms;
419
420 interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, factor);
421
422 if (sms->use_dyn_ofs) {
424 rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
425 }
426 else {
427 interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, factor);
428 }
429
430 rv3d->dist = interpf(sms->dst.dist, sms->src.dist, factor);
431 v3d->lens = interpf(sms->dst.lens, sms->src.lens, factor);
432
434 if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) {
435 if (use_autokey) {
436 ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
437 }
438 }
439}
440
445 wmWindow *win,
446 View3D *v3d,
447 RegionView3D *rv3d,
448 bContext *C_for_camera_lock)
449{
450 SmoothView3DStore *sms = rv3d->sms;
451
452 /* If we went to camera, store the original. */
453 if (sms->to_camera) {
454 rv3d->persp = RV3D_CAMOB;
455 view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
456 }
457 else {
458 view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
459
460 if (C_for_camera_lock) {
461 const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C_for_camera_lock);
462 if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) {
463 ED_view3d_camera_lock_autokey(v3d, rv3d, C_for_camera_lock, true, true);
464 }
465 }
466 }
467
468 if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
469 rv3d->view = sms->org_view;
471 }
472
473 MEM_freeN(rv3d->sms);
474 rv3d->sms = nullptr;
475
476 WM_event_timer_remove(wm, win, rv3d->smooth_timer);
477 rv3d->smooth_timer = nullptr;
478 rv3d->rflag &= ~RV3D_NAVIGATING;
479
480 /* Event handling won't know if a UI item has been moved under the pointer. */
482
483 /* NOTE: this doesn't work right because the `v3d->lens` is used in orthographic mode,
484 * when switching camera in quad-view the other orthographic views would zoom & reset.
485 *
486 * For now only redraw all regions when smooth-view finishes. */
488}
489
496
498{
500 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
501 SmoothView3DStore *sms = rv3d->sms;
502 float factor;
503
504 if (sms->time_allowed != 0.0) {
505 factor = float(rv3d->smooth_timer->time_duration / sms->time_allowed);
506 }
507 else {
508 factor = 1.0f;
509 }
510 if (factor >= 1.0f) {
512 }
513 else {
514 /* Ease in/out smoothing. */
515 factor = (3.0f * factor * factor - 2.0f * factor * factor * factor);
516 const bool use_autokey = ED_screen_animation_playing(wm);
517 view3d_smoothview_apply_with_interp(C, v3d, rv3d, use_autokey, factor);
518 }
519
520 if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
522 }
523
524 ED_region_tag_redraw(region);
525}
526
528 wmOperator * /*op*/,
529 const wmEvent *event)
530{
531 View3D *v3d = CTX_wm_view3d(C);
532 ARegion *region = CTX_wm_region(C);
533 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
534
535 /* Escape if not our timer. */
536 if (rv3d->smooth_timer == nullptr || rv3d->smooth_timer != event->customdata) {
538 }
539
541
542 return OPERATOR_FINISHED;
543}
544
546 wmWindowManager *wm,
547 wmWindow *win,
548 const Scene *scene,
549 View3D *v3d,
550 ARegion *region,
551 bContext *C_for_camera_lock)
552{
553 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
554 BLI_assert(rv3d && rv3d->sms);
555
556 view3d_smoothview_apply_and_finish_ex(wm, win, v3d, rv3d, C_for_camera_lock);
557
558 if (depsgraph) {
559 /* Force update of view matrix so tools that run immediately after
560 * can use them without redrawing first. */
561 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, nullptr, nullptr, nullptr, false);
562 }
563}
564
566{
567 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
568 if (rv3d && rv3d->sms) {
569
571 Scene *scene = CTX_data_scene(C);
573 wmWindow *win = CTX_wm_window(C);
574
575 view3d_smooth_view_force_finish_ex(depsgraph, wm, win, scene, v3d, region, C);
576 }
577}
578
580 wmWindowManager *wm,
581 wmWindow *win,
582 const Scene *scene,
583 View3D *v3d,
584 ARegion *region)
585{
586
587 /* NOTE(@ideasman42): Ideally we would *always* apply the camera lock.
588 * Failing to do so results in incorrect behavior when a user performs
589 * a camera-locked view-port manipulation & immediately enters local-view
590 * before the operation is completed.
591 * In this case the camera isn't key-framed when it should be.
592 *
593 * A generic solution that supports forcing modal operators to finish their
594 * work may be best, but needs to be investigated.
595 *
596 * It's worth noting this *is* a corner case, while not ideal,
597 * rarely happens unless a motivated users is trying to cause it to fail.
598 * Even when it does occur, it simply misses completing & auto-keying the action. */
599
600 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
601 if (rv3d && rv3d->sms) {
602 view3d_smooth_view_force_finish_ex(depsgraph, wm, win, scene, v3d, region, nullptr);
603 }
604}
605
607{
608 /* Identifiers. */
609 ot->name = "Smooth View";
610 ot->idname = "VIEW3D_OT_smoothview";
611
612 /* API callbacks. */
615
616 /* Flags. */
617 ot->flag = OPTYPE_INTERNAL;
618}
619
621{
622 MEM_SAFE_FREE(rv3d->sms);
623}
624
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define LISTBASE_FOREACH(type, var, list)
MINLINE float interpf(float target, float origin, float t)
#define M_PI
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void copy_qt_qt(float q[4], const float a[4])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE bool equals_v4v4(const float v1[4], const float v2[4]) ATTR_WARN_UNUSED_RESULT
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_TAG_DOIT
Definition DNA_ID.h:944
@ CAM_ORTHO
@ OB_RENDER
@ OB_CAMERA
@ RGN_TYPE_WINDOW
@ USER_GLOBALUNDO
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_LOCK_ROTATION
@ RV3D_BOXVIEW
@ RV3D_VIEW_USER
@ RV3D_NAVIGATING
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
bool ED_operator_view3d_active(bContext *C)
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:639
bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], const float *dist, float *lens)
#define VIEW3D_DIST_FALLBACK
float ED_view3d_offset_distance(const float mat[4][4], const float ofs[3], float fallback_dist)
bool ED_view3d_camera_lock_undo_push(const char *str, const View3D *v3d, const RegionView3D *rv3d, bContext *C)
void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
bool ED_view3d_camera_lock_autokey(View3D *v3d, RegionView3D *rv3d, bContext *C, bool do_rotate, bool do_translate)
void ED_view3d_update_viewmat(const Depsgraph *depsgraph, const Scene *scene, View3D *v3d, ARegion *region, const float viewmat[4][4], const float winmat[4][4], const rcti *rect, bool offscreen)
bool ED_view3d_camera_lock_undo_test(const View3D *v3d, const RegionView3D *rv3d, bContext *C)
bool ED_view3d_camera_lock_undo_grouped_push(const char *str, const View3D *v3d, const RegionView3D *rv3d, bContext *C)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
#define ND_SPACE_VIEW3D
Definition WM_types.hh:525
#define NC_SPACE
Definition WM_types.hh:389
#define U
BPy_StructRNA * depsgraph
#define fabsf(x)
#define MEM_SAFE_FREE(v)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void * regiondata
int tag
Definition DNA_ID.h:424
void * first
struct SmoothView3DStore * sms
struct ViewRender * view_render
struct wmTimer * smooth_timer
ListBase spacedata
ListBase regionbase
const char * undo_str
const float * dyn_ofs
struct Object * camera
View3DShading shading
void * customdata
Definition WM_types.hh:804
double time_duration
Definition WM_types.hh:965
void view3d_boxview_copy(ScrArea *area, ARegion *region)
void view3d_orbit_apply_dyn_ofs(float r_ofs[3], const float ofs_old[3], const float viewquat_old[4], const float viewquat_new[4], const float dyn_ofs[3])
void ED_view3d_smooth_view_undo_begin(bContext *C, const ScrArea *area)
void ED_view3d_smooth_view_undo_end(bContext *C, const ScrArea *area, const char *undo_str, const bool undo_grouped)
void ED_view3d_smooth_view_force_finish_no_camera_lock(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, const Scene *scene, View3D *v3d, ARegion *region)
static void view3d_smoothview_apply_and_finish_ex(wmWindowManager *wm, wmWindow *win, View3D *v3d, RegionView3D *rv3d, bContext *C_for_camera_lock)
static void view3d_smoothview_apply_from_timer(bContext *C, View3D *v3d, ARegion *region)
static void view3d_smoothview_apply_with_interp(bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor)
static void view3d_smooth_view_state_backup(SmoothView3DState *sms_state, const View3D *v3d, const RegionView3D *rv3d)
static void view3d_smooth_view_state_restore(const SmoothView3DState *sms_state, View3D *v3d, RegionView3D *rv3d)
static void view3d_smoothview_apply_and_finish(bContext *C, View3D *v3d, RegionView3D *rv3d)
void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *region, const int smooth_viewtx, const V3D_SmoothParams *sview)
void ED_view3d_smooth_view_ex(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, ScrArea *area, View3D *v3d, ARegion *region, const int smooth_viewtx, const V3D_SmoothParams *sview)
static wmOperatorStatus view3d_smoothview_invoke(bContext *C, wmOperator *, const wmEvent *event)
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
static void view3d_smooth_view_force_finish_ex(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, const Scene *scene, View3D *v3d, ARegion *region, bContext *C_for_camera_lock)
void VIEW3D_OT_smoothview(wmOperatorType *ot)
void view3d_smooth_free(RegionView3D *rv3d)
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_mousemove(wmWindow *win)
@ TIMER1
wmOperatorType * ot
Definition wm_files.cc:4225
wmTimer * WM_event_timer_add(wmWindowManager *wm, wmWindow *win, const wmEventType event_type, const double time_step)
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)