Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_view.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c428
1 files changed, 25 insertions, 403 deletions
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 165f931394d..ddd5cc640bb 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -21,21 +21,14 @@
* \ingroup spview3d
*/
-#include "DNA_camera_types.h"
-#include "DNA_gpencil_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
-#include "BLI_utildefines.h"
#include "BKE_action.h"
-#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_gpencil_modifier.h"
@@ -47,7 +40,6 @@
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "UI_resources.h"
@@ -57,7 +49,6 @@
#include "GPU_state.h"
#include "WM_api.h"
-#include "WM_types.h"
#include "ED_object.h"
#include "ED_screen.h"
@@ -68,376 +59,7 @@
#include "RNA_define.h"
#include "view3d_intern.h" /* own include */
-
-/* -------------------------------------------------------------------- */
-/** \name Smooth View Operator & Utilities
- *
- * Use for view transitions to have smooth (animated) transitions.
- * \{ */
-
-/* This operator is one of the 'timer refresh' ones like animation playback */
-
-struct SmoothView3DState {
- float dist;
- float lens;
- float quat[4];
- float ofs[3];
-};
-
-struct SmoothView3DStore {
- /* Source. */
- struct SmoothView3DState src; /* source */
- struct SmoothView3DState dst; /* destination */
- struct SmoothView3DState org; /* original */
-
- bool to_camera;
-
- bool use_dyn_ofs;
- float dyn_ofs[3];
-
- /* When smooth-view is enabled, store the 'rv3d->view' here,
- * assign back when the view motion is completed. */
- char org_view;
-
- double time_allowed;
-};
-
-static void view3d_smooth_view_state_backup(struct SmoothView3DState *sms_state,
- const View3D *v3d,
- const RegionView3D *rv3d)
-{
- copy_v3_v3(sms_state->ofs, rv3d->ofs);
- copy_qt_qt(sms_state->quat, rv3d->viewquat);
- sms_state->dist = rv3d->dist;
- sms_state->lens = v3d->lens;
-}
-
-static void view3d_smooth_view_state_restore(const struct SmoothView3DState *sms_state,
- View3D *v3d,
- RegionView3D *rv3d)
-{
- copy_v3_v3(rv3d->ofs, sms_state->ofs);
- copy_qt_qt(rv3d->viewquat, sms_state->quat);
- rv3d->dist = sms_state->dist;
- v3d->lens = sms_state->lens;
-}
-
-/* will start timer if appropriate */
-void ED_view3d_smooth_view_ex(
- /* avoid passing in the context */
- const Depsgraph *depsgraph,
- wmWindowManager *wm,
- wmWindow *win,
- ScrArea *area,
- View3D *v3d,
- ARegion *region,
- const int smooth_viewtx,
- const V3D_SmoothParams *sview)
-{
- RegionView3D *rv3d = region->regiondata;
- struct SmoothView3DStore sms = {{0}};
-
- /* initialize sms */
- view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
- view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
- /* If smooth-view runs multiple times. */
- if (rv3d->sms == NULL) {
- view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
- }
- else {
- sms.org = rv3d->sms->org;
- }
- sms.org_view = rv3d->view;
-
- /* sms.to_camera = false; */ /* initialized to zero anyway */
-
- /* note on camera locking, this is a little confusing but works ok.
- * we may be changing the view 'as if' there is no active camera, but in fact
- * there is an active camera which is locked to the view.
- *
- * In the case where smooth view is moving _to_ a camera we don't want that
- * camera to be moved or changed, so only when the camera is not being set should
- * we allow camera option locking to initialize the view settings from the camera.
- */
- if (sview->camera == NULL && sview->camera_old == NULL) {
- ED_view3d_camera_lock_init(depsgraph, v3d, rv3d);
- }
-
- /* store the options we want to end with */
- if (sview->ofs) {
- copy_v3_v3(sms.dst.ofs, sview->ofs);
- }
- if (sview->quat) {
- copy_qt_qt(sms.dst.quat, sview->quat);
- }
- if (sview->dist) {
- sms.dst.dist = *sview->dist;
- }
- if (sview->lens) {
- sms.dst.lens = *sview->lens;
- }
-
- if (sview->dyn_ofs) {
- BLI_assert(sview->ofs == NULL);
- BLI_assert(sview->quat != NULL);
-
- copy_v3_v3(sms.dyn_ofs, sview->dyn_ofs);
- sms.use_dyn_ofs = true;
-
- /* calculate the final destination offset */
- view3d_orbit_apply_dyn_ofs(sms.dst.ofs, sms.src.ofs, sms.src.quat, sms.dst.quat, sms.dyn_ofs);
- }
-
- if (sview->camera) {
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
- if (sview->ofs != NULL) {
- sms.dst.dist = ED_view3d_offset_distance(
- ob_camera_eval->obmat, sview->ofs, VIEW3D_DIST_FALLBACK);
- }
- ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
- sms.to_camera = true; /* restore view3d values in end */
- }
-
- if ((sview->camera_old == sview->camera) && /* Camera. */
- (sms.dst.dist == rv3d->dist) && /* Distance. */
- (sms.dst.lens == v3d->lens) && /* Lens. */
- equals_v3v3(sms.dst.ofs, rv3d->ofs) && /* Offset. */
- equals_v4v4(sms.dst.quat, rv3d->viewquat) /* Rotation. */
- ) {
- /* Early return if nothing changed. */
- return;
- }
-
- /* Skip smooth viewing for external render engine draw. */
- if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) {
-
- /* original values */
- if (sview->camera_old) {
- Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old);
- if (sview->ofs != NULL) {
- sms.src.dist = ED_view3d_offset_distance(ob_camera_old_eval->obmat, sview->ofs, 0.0f);
- }
- ED_view3d_from_object(
- ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
- }
- /* grid draw as floor */
- if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
- /* use existing if exists, means multiple calls to smooth view
- * won't lose the original 'view' setting */
- rv3d->view = RV3D_VIEW_USER;
- }
-
- sms.time_allowed = (double)smooth_viewtx / 1000.0;
-
- /* If this is view rotation only we can decrease the time allowed by the angle between quats
- * this means small rotations won't lag. */
- if (sview->quat && !sview->ofs && !sview->dist) {
- /* scale the time allowed by the rotation */
- /* 180deg == 1.0 */
- sms.time_allowed *= (double)fabsf(angle_signed_normalized_qtqt(sms.dst.quat, sms.src.quat)) /
- M_PI;
- }
-
- /* ensure it shows correct */
- if (sms.to_camera) {
- /* use ortho if we move from an ortho view to an ortho camera */
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
- rv3d->persp = (((rv3d->is_persp == false) && (ob_camera_eval->type == OB_CAMERA) &&
- (((Camera *)ob_camera_eval->data)->type == CAM_ORTHO)) ?
- RV3D_ORTHO :
- RV3D_PERSP);
- }
-
- rv3d->rflag |= RV3D_NAVIGATING;
-
- /* not essential but in some cases the caller will tag the area for redraw, and in that
- * case we can get a flicker of the 'org' user view but we want to see 'src' */
- view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
-
- /* keep track of running timer! */
- if (rv3d->sms == NULL) {
- rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d");
- }
- *rv3d->sms = sms;
- if (rv3d->smooth_timer) {
- WM_event_remove_timer(wm, win, rv3d->smooth_timer);
- }
- /* #TIMER1 is hard-coded in key-map. */
- rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0);
- }
- else {
- /* Animation is disabled, apply immediately. */
- if (sms.to_camera == false) {
- copy_v3_v3(rv3d->ofs, sms.dst.ofs);
- copy_qt_qt(rv3d->viewquat, sms.dst.quat);
- rv3d->dist = sms.dst.dist;
- v3d->lens = sms.dst.lens;
-
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- }
-
- if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
- view3d_boxview_copy(area, region);
- }
-
- ED_region_tag_redraw(region);
-
- WM_event_add_mousemove(win);
- }
-}
-
-void ED_view3d_smooth_view(bContext *C,
- View3D *v3d,
- ARegion *region,
- const int smooth_viewtx,
- const struct V3D_SmoothParams *sview)
-{
- const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- ScrArea *area = CTX_wm_area(C);
-
- ED_view3d_smooth_view_ex(depsgraph, wm, win, area, v3d, region, smooth_viewtx, sview);
-}
-
-/* only meant for timer usage */
-static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, bool sync_boxview)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- RegionView3D *rv3d = region->regiondata;
- struct SmoothView3DStore *sms = rv3d->sms;
- float step, step_inv;
-
- if (sms->time_allowed != 0.0) {
- step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
- }
- else {
- step = 1.0f;
- }
-
- /* end timer */
- if (step >= 1.0f) {
- wmWindow *win = CTX_wm_window(C);
-
- /* if we went to camera, store the original */
- if (sms->to_camera) {
- rv3d->persp = RV3D_CAMOB;
- view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
- }
- else {
- const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-
- view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
-
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
- }
-
- if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
- rv3d->view = sms->org_view;
- }
-
- MEM_freeN(rv3d->sms);
- rv3d->sms = NULL;
-
- WM_event_remove_timer(wm, win, rv3d->smooth_timer);
- rv3d->smooth_timer = NULL;
- rv3d->rflag &= ~RV3D_NAVIGATING;
-
- /* Event handling won't know if a UI item has been moved under the pointer. */
- WM_event_add_mousemove(win);
- }
- else {
- /* ease in/out */
- step = (3.0f * step * step - 2.0f * step * step * step);
-
- step_inv = 1.0f - step;
-
- interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
-
- if (sms->use_dyn_ofs) {
- view3d_orbit_apply_dyn_ofs(
- rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
- }
- else {
- interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
- }
-
- rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
- v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
-
- const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- if (ED_screen_animation_playing(wm)) {
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
- }
- }
-
- if (sync_boxview && (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW)) {
- view3d_boxview_copy(CTX_wm_area(C), region);
- }
-
- /* NOTE: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
- * when switching camera in quad-view the other ortho views would zoom & reset.
- *
- * For now only redraw all regions when smooth-view finishes.
- */
- if (step >= 1.0f) {
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- }
- else {
- ED_region_tag_redraw(region);
- }
-}
-
-static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
-{
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *region = CTX_wm_region(C);
- RegionView3D *rv3d = region->regiondata;
-
- /* escape if not our timer */
- if (rv3d->smooth_timer == NULL || rv3d->smooth_timer != event->customdata) {
- return OPERATOR_PASS_THROUGH;
- }
-
- view3d_smoothview_apply(C, v3d, region, true);
-
- return OPERATOR_FINISHED;
-}
-
-void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
-{
- RegionView3D *rv3d = region->regiondata;
-
- if (rv3d && rv3d->sms) {
- rv3d->sms->time_allowed = 0.0; /* force finishing */
- view3d_smoothview_apply(C, v3d, region, false);
-
- /* force update of view matrix so tools that run immediately after
- * can use them without redrawing first */
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- ED_view3d_update_viewmat(depsgraph, scene, v3d, region, NULL, NULL, NULL, false);
- }
-}
-
-void VIEW3D_OT_smoothview(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Smooth View";
- ot->idname = "VIEW3D_OT_smoothview";
-
- /* api callbacks */
- ot->invoke = view3d_smoothview_invoke;
-
- /* flags */
- ot->flag = OPTYPE_INTERNAL;
-
- ot->poll = ED_operator_view3d_active;
-}
-
-/** \} */
+#include "view3d_navigate.h"
/* -------------------------------------------------------------------- */
/** \name Camera to View Operator
@@ -863,10 +485,10 @@ void view3d_opengl_select_cache_end(void)
struct DrawSelectLoopUserData {
uint pass;
uint hits;
- uint *buffer;
+ GPUSelectResult *buffer;
uint buffer_len;
const rcti *rect;
- char gpu_select_mode;
+ eGPUSelectMode gpu_select_mode;
};
static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
@@ -927,8 +549,8 @@ static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void
}
int view3d_opengl_select_ex(ViewContext *vc,
- uint *buffer,
- uint bufsize,
+ GPUSelectResult *buffer,
+ uint buffer_len,
const rcti *input,
eV3DSelectMode select_mode,
eV3DSelectObjectFilter select_filter,
@@ -950,7 +572,7 @@ int view3d_opengl_select_ex(ViewContext *vc,
const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST);
bool draw_surface = true;
- char gpu_select_mode;
+ eGPUSelectMode gpu_select_mode;
/* case not a box select */
if (input->xmin == input->xmax) {
@@ -981,6 +603,15 @@ int view3d_opengl_select_ex(ViewContext *vc,
}
}
+ /* Re-use cache (rect must be smaller than the cached)
+ * other context is assumed to be unchanged */
+ if (GPU_select_is_cached()) {
+ GPU_select_begin(buffer, buffer_len, &rect, gpu_select_mode, 0);
+ GPU_select_cache_load_id();
+ hits = GPU_select_end();
+ goto finally;
+ }
+
/* Important to use 'vc->obact', not 'OBACT(vc->view_layer)' below,
* so it will be NULL when hidden. */
struct {
@@ -1040,15 +671,6 @@ int view3d_opengl_select_ex(ViewContext *vc,
UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
- /* Re-use cache (rect must be smaller than the cached)
- * other context is assumed to be unchanged */
- if (GPU_select_is_cached()) {
- GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
- GPU_select_cache_load_id();
- hits = GPU_select_end();
- goto finally;
- }
-
/* All of the queries need to be perform on the drawing context. */
DRW_opengl_context_enable();
@@ -1071,7 +693,7 @@ int view3d_opengl_select_ex(ViewContext *vc,
.pass = 0,
.hits = 0,
.buffer = buffer,
- .buffer_len = bufsize,
+ .buffer_len = buffer_len,
.rect = &rect,
.gpu_select_mode = gpu_select_mode,
};
@@ -1101,7 +723,7 @@ int view3d_opengl_select_ex(ViewContext *vc,
.pass = 0,
.hits = 0,
.buffer = buffer,
- .buffer_len = bufsize,
+ .buffer_len = buffer_len,
.rect = &rect,
.gpu_select_mode = gpu_select_mode,
};
@@ -1132,36 +754,36 @@ int view3d_opengl_select_ex(ViewContext *vc,
DRW_opengl_context_disable();
+ UI_Theme_Restore(&theme_state);
+
finally:
if (hits < 0) {
printf("Too many objects in select buffer\n"); /* XXX make error message */
}
- UI_Theme_Restore(&theme_state);
-
return hits;
}
int view3d_opengl_select(ViewContext *vc,
- uint *buffer,
- uint bufsize,
+ GPUSelectResult *buffer,
+ uint buffer_len,
const rcti *input,
eV3DSelectMode select_mode,
eV3DSelectObjectFilter select_filter)
{
- return view3d_opengl_select_ex(vc, buffer, bufsize, input, select_mode, select_filter, false);
+ return view3d_opengl_select_ex(vc, buffer, buffer_len, input, select_mode, select_filter, false);
}
int view3d_opengl_select_with_id_filter(ViewContext *vc,
- uint *buffer,
- uint bufsize,
+ GPUSelectResult *buffer,
+ const uint buffer_len,
const rcti *input,
eV3DSelectMode select_mode,
eV3DSelectObjectFilter select_filter,
uint select_id)
{
- int hits = view3d_opengl_select(vc, buffer, bufsize, input, select_mode, select_filter);
+ int hits = view3d_opengl_select(vc, buffer, buffer_len, input, select_mode, select_filter);
/* Selection sometimes uses -1 for an invalid selection ID, remove these as they
* interfere with detection of actual number of hits in the selection. */