Blender V4.3
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_object(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_object(depsgraph, sview->camera_old);
305 if (sview->ofs != nullptr) {
307 ob_camera_old_eval->object_to_world().ptr(), sview->ofs, 0.0f);
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_object(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 = static_cast<SmoothView3DStore *>(
348 MEM_mallocN(sizeof(SmoothView3DStore), "smoothview v3d"));
349 }
350 *rv3d->sms = sms;
351 if (rv3d->smooth_timer) {
352 WM_event_timer_remove(wm, win, rv3d->smooth_timer);
353 }
354 /* #TIMER1 is hard-coded in key-map. */
355 rv3d->smooth_timer = WM_event_timer_add(wm, win, TIMER1, 1.0 / 100.0);
356 }
357 else {
358 /* Animation is disabled, apply immediately. */
359 if (sms.to_camera == false) {
360 copy_v3_v3(rv3d->ofs, sms.dst.ofs);
361 copy_qt_qt(rv3d->viewquat, sms.dst.quat);
362 rv3d->dist = sms.dst.dist;
363 v3d->lens = sms.dst.lens;
364
366 }
367
368 if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
369 view3d_boxview_copy(area, region);
370 }
371
372 ED_region_tag_redraw(region);
373
375 }
376
377 if (sms.to_camera == false) {
378 /* See comments in #ED_view3d_smooth_view_undo_begin for why this is needed. */
379 if (v3d->camera) {
380 v3d->camera->id.tag &= ~ID_TAG_DOIT;
381 }
382 }
383}
384
386 View3D *v3d,
387 ARegion *region,
388 const int smooth_viewtx,
389 const V3D_SmoothParams *sview)
390{
393 wmWindow *win = CTX_wm_window(C);
394 ScrArea *area = CTX_wm_area(C);
395
396 /* #ED_view3d_smooth_view_ex asserts this is not set as it doesn't support undo. */
397 V3D_SmoothParams sview_no_undo = *sview;
398 sview_no_undo.undo_str = nullptr;
399 sview_no_undo.undo_grouped = false;
400
401 const bool do_undo = (sview->undo_str != nullptr);
402 if (do_undo) {
404 }
405
406 ED_view3d_smooth_view_ex(depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_no_undo);
407
408 if (do_undo) {
410 }
411}
412
417 bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor)
418{
419 SmoothView3DStore *sms = rv3d->sms;
420
421 interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, factor);
422
423 if (sms->use_dyn_ofs) {
425 rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
426 }
427 else {
428 interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, factor);
429 }
430
431 rv3d->dist = interpf(sms->dst.dist, sms->src.dist, factor);
432 v3d->lens = interpf(sms->dst.lens, sms->src.lens, factor);
433
435 if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) {
436 if (use_autokey) {
437 ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
438 }
439 }
440}
441
446 wmWindow *win,
447 View3D *v3d,
448 RegionView3D *rv3d,
449 bContext *C_for_camera_lock)
450{
451 SmoothView3DStore *sms = rv3d->sms;
452
453 /* If we went to camera, store the original. */
454 if (sms->to_camera) {
455 rv3d->persp = RV3D_CAMOB;
456 view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
457 }
458 else {
459 view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
460
461 if (C_for_camera_lock) {
462 const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C_for_camera_lock);
463 if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) {
464 ED_view3d_camera_lock_autokey(v3d, rv3d, C_for_camera_lock, true, true);
465 }
466 }
467 }
468
469 if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
470 rv3d->view = sms->org_view;
472 }
473
474 MEM_freeN(rv3d->sms);
475 rv3d->sms = nullptr;
476
477 WM_event_timer_remove(wm, win, rv3d->smooth_timer);
478 rv3d->smooth_timer = nullptr;
479 rv3d->rflag &= ~RV3D_NAVIGATING;
480
481 /* Event handling won't know if a UI item has been moved under the pointer. */
483
484 /* NOTE: this doesn't work right because the `v3d->lens` is used in orthographic mode,
485 * when switching camera in quad-view the other orthographic views would zoom & reset.
486 *
487 * For now only redraw all regions when smooth-view finishes. */
489}
490
497
499{
501 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
502 SmoothView3DStore *sms = rv3d->sms;
503 float factor;
504
505 if (sms->time_allowed != 0.0) {
506 factor = float(rv3d->smooth_timer->time_duration / sms->time_allowed);
507 }
508 else {
509 factor = 1.0f;
510 }
511 if (factor >= 1.0f) {
513 }
514 else {
515 /* Ease in/out smoothing. */
516 factor = (3.0f * factor * factor - 2.0f * factor * factor * factor);
517 const bool use_autokey = ED_screen_animation_playing(wm);
518 view3d_smoothview_apply_with_interp(C, v3d, rv3d, use_autokey, factor);
519 }
520
521 if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
523 }
524
525 ED_region_tag_redraw(region);
526}
527
528static int view3d_smoothview_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
529{
530 View3D *v3d = CTX_wm_view3d(C);
531 ARegion *region = CTX_wm_region(C);
532 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
533
534 /* Escape if not our timer. */
535 if (rv3d->smooth_timer == nullptr || rv3d->smooth_timer != event->customdata) {
537 }
538
540
541 return OPERATOR_FINISHED;
542}
543
545 wmWindowManager *wm,
546 wmWindow *win,
547 const Scene *scene,
548 View3D *v3d,
549 ARegion *region,
550 bContext *C_for_camera_lock)
551{
552 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
553 BLI_assert(rv3d && rv3d->sms);
554
555 view3d_smoothview_apply_and_finish_ex(wm, win, v3d, rv3d, C_for_camera_lock);
556
557 if (depsgraph) {
558 /* Force update of view matrix so tools that run immediately after
559 * can use them without redrawing first. */
560 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, nullptr, nullptr, nullptr, false);
561 }
562}
563
565{
566 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
567 if (rv3d && rv3d->sms) {
568
570 Scene *scene = CTX_data_scene(C);
572 wmWindow *win = CTX_wm_window(C);
573
574 view3d_smooth_view_force_finish_ex(depsgraph, wm, win, scene, v3d, region, C);
575 }
576}
577
579 wmWindowManager *wm,
580 wmWindow *win,
581 const Scene *scene,
582 View3D *v3d,
583 ARegion *region)
584{
585
586 /* NOTE(@ideasman42): Ideally we would *always* apply the camera lock.
587 * Failing to do so results in incorrect behavior when a user performs
588 * a camera-locked view-port manipulation & immediately enters enters local-view
589 * before the operation is completed.
590 * In this case the camera isn't key-framed when it should be.
591 *
592 * A generic solution that supports forcing modal operators to finish their
593 * work may be best, but needs to be investigated.
594 *
595 * It's worth noting this *is* a corner case, while not ideal,
596 * rarely happens unless a motivated users is trying to cause it to fail.
597 * Even when it does occur, it simply misses completing & auto-keying the action. */
598
599 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
600 if (rv3d && rv3d->sms) {
601 view3d_smooth_view_force_finish_ex(depsgraph, wm, win, scene, v3d, region, nullptr);
602 }
603}
604
606{
607 /* Identifiers. */
608 ot->name = "Smooth View";
609 ot->idname = "VIEW3D_OT_smoothview";
610
611 /* API callbacks. */
614
615 /* Flags. */
616 ot->flag = OPTYPE_INTERNAL;
617}
618
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:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#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)
Definition math_vector.c:36
MINLINE bool equals_v4v4(const float v1[4], const float v2[4]) ATTR_WARN_UNUSED_RESULT
typedef double(DMatrix)[4][4]
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
@ CAM_ORTHO
@ OB_RENDER
@ OB_CAMERA
@ RGN_TYPE_WINDOW
@ USER_GLOBALUNDO
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_NAVIGATING
@ RV3D_VIEW_USER
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
@ RV3D_LOCK_ROTATION
@ RV3D_BOXVIEW
@ 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:634
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.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
#define C
Definition RandGen.cpp:29
@ OPTYPE_INTERNAL
Definition WM_types.hh:182
#define ND_SPACE_VIEW3D
Definition WM_types.hh:494
#define NC_SPACE
Definition WM_types.hh:359
#define U
BPy_StructRNA * depsgraph
#define fabsf(x)
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
void * regiondata
int tag
Definition DNA_ID.h:434
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:772
double time_duration
Definition WM_types.hh:925
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)
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
static int view3d_smoothview_invoke(bContext *C, wmOperator *, const wmEvent *event)
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 WM_main_add_notifier(uint type, void *reference)
void WM_event_add_mousemove(wmWindow *win)
@ TIMER1
wmOperatorType * ot
Definition wm_files.cc:4125
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)
wmTimer * WM_event_timer_add(wmWindowManager *wm, wmWindow *win, const int event_type, const double time_step)