Blender  V3.3
view3d_navigate.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "DNA_curve_types.h"
8 #include "DNA_gpencil_types.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_math.h"
13 #include "BLI_rect.h"
14 
15 #include "BLT_translation.h"
16 
17 #include "BKE_armature.h"
18 #include "BKE_context.h"
19 #include "BKE_gpencil_geom.h"
20 #include "BKE_layer.h"
21 #include "BKE_object.h"
22 #include "BKE_paint.h"
23 #include "BKE_scene.h"
24 #include "BKE_screen.h"
25 #include "BKE_vfont.h"
26 
27 #include "DEG_depsgraph_query.h"
28 
29 #include "ED_mesh.h"
30 #include "ED_particle.h"
31 #include "ED_screen.h"
32 #include "ED_transform.h"
33 
34 #include "WM_api.h"
35 #include "WM_message.h"
36 
37 #include "RNA_access.h"
38 #include "RNA_define.h"
39 
40 #include "UI_resources.h"
41 
42 #include "view3d_intern.h"
43 
44 #include "view3d_navigate.h" /* own include */
45 
46 /* -------------------------------------------------------------------- */
50 static bool view3d_navigation_poll_impl(bContext *C, const char viewlock)
51 {
53  return false;
54  }
55 
56  const RegionView3D *rv3d = CTX_wm_region_view3d(C);
57  return !(RV3D_LOCK_FLAGS(rv3d) & viewlock);
58 }
59 
61 {
63 }
64 
66 {
68 }
69 
71 {
73 }
74 
77 /* -------------------------------------------------------------------- */
82 {
83  if (flag & V3D_OP_PROP_MOUSE_CO) {
84  PropertyRNA *prop;
85  prop = RNA_def_int(ot->srna, "mx", 0, 0, INT_MAX, "Region Position X", "", 0, INT_MAX);
87  prop = RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Region Position Y", "", 0, INT_MAX);
89  }
90  if (flag & V3D_OP_PROP_DELTA) {
91  RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
92  }
93  if (flag & V3D_OP_PROP_USE_ALL_REGIONS) {
94  PropertyRNA *prop;
95  prop = RNA_def_boolean(
96  ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
98  }
99  if (flag & V3D_OP_PROP_USE_MOUSE_INIT) {
101  }
102 }
103 
106 /* -------------------------------------------------------------------- */
110 void calctrackballvec(const rcti *rect, const int event_xy[2], float r_dir[3])
111 {
112  const float radius = V3D_OP_TRACKBALLSIZE;
113  const float t = radius / (float)M_SQRT2;
114  const float size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
115  /* Aspect correct so dragging in a non-square view doesn't squash the direction.
116  * So diagonal motion rotates the same direction the cursor is moving. */
117  const float size_min = min_ff(size[0], size[1]);
118  const float aspect[2] = {size_min / size[0], size_min / size[1]};
119 
120  /* Normalize x and y. */
121  r_dir[0] = (event_xy[0] - BLI_rcti_cent_x(rect)) / ((size[0] * aspect[0]) / 2.0);
122  r_dir[1] = (event_xy[1] - BLI_rcti_cent_y(rect)) / ((size[1] * aspect[1]) / 2.0);
123  const float d = len_v2(r_dir);
124  if (d < t) {
125  /* Inside sphere. */
126  r_dir[2] = sqrtf(square_f(radius) - square_f(d));
127  }
128  else {
129  /* On hyperbola. */
130  r_dir[2] = square_f(t) / d;
131  }
132 }
133 
134 void view3d_orbit_apply_dyn_ofs(float r_ofs[3],
135  const float ofs_old[3],
136  const float viewquat_old[4],
137  const float viewquat_new[4],
138  const float dyn_ofs[3])
139 {
140  float q[4];
141  invert_qt_qt_normalized(q, viewquat_old);
142  mul_qt_qtqt(q, q, viewquat_new);
143 
145 
146  sub_v3_v3v3(r_ofs, ofs_old, dyn_ofs);
147  mul_qt_v3(q, r_ofs);
148  add_v3_v3(r_ofs, dyn_ofs);
149 }
150 
151 void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat_new[4])
152 {
153  if (vod->use_dyn_ofs) {
154  RegionView3D *rv3d = vod->rv3d;
156  rv3d->ofs, vod->init.ofs, vod->init.quat, viewquat_new, vod->dyn_ofs);
157  }
158 }
159 
160 bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
161 {
162  static float lastofs[3] = {0, 0, 0};
163  bool is_set = false;
164 
168  View3D *v3d = CTX_wm_view3d(C);
169  Object *ob_act_eval = OBACT(view_layer_eval);
170  Object *ob_act = DEG_get_original_object(ob_act_eval);
171 
172  if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
173  /* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
174  ((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0) {
175  /* in case of sculpting use last average stroke position as a rotation
176  * center, in other cases it's not clear what rotation center shall be
177  * so just rotate around object origin
178  */
179  if (ob_act->mode &
181  float stroke[3];
182  BKE_paint_stroke_get_average(scene, ob_act_eval, stroke);
183  copy_v3_v3(lastofs, stroke);
184  }
185  else {
186  copy_v3_v3(lastofs, ob_act_eval->obmat[3]);
187  }
188  is_set = true;
189  }
190  else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
191  Curve *cu = ob_act_eval->data;
192  EditFont *ef = cu->editfont;
193 
194  zero_v3(lastofs);
195  for (int i = 0; i < 4; i++) {
196  add_v2_v2(lastofs, ef->textcurs[i]);
197  }
198  mul_v2_fl(lastofs, 1.0f / 4.0f);
199 
200  mul_m4_v3(ob_act_eval->obmat, lastofs);
201 
202  is_set = true;
203  }
204  else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
205  /* object mode use boundbox centers */
206  Base *base_eval;
207  uint tot = 0;
208  float select_center[3];
209 
210  zero_v3(select_center);
211  for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
212  if (BASE_SELECTED(v3d, base_eval)) {
213  /* use the boundbox if we can */
214  Object *ob_eval = base_eval->object;
215 
216  if (ob_eval->runtime.bb && !(ob_eval->runtime.bb->flag & BOUNDBOX_DIRTY)) {
217  float cent[3];
218 
219  BKE_boundbox_calc_center_aabb(ob_eval->runtime.bb, cent);
220 
221  mul_m4_v3(ob_eval->obmat, cent);
222  add_v3_v3(select_center, cent);
223  }
224  else {
225  add_v3_v3(select_center, ob_eval->obmat[3]);
226  }
227  tot++;
228  }
229  }
230  if (tot) {
231  mul_v3_fl(select_center, 1.0f / (float)tot);
232  copy_v3_v3(lastofs, select_center);
233  is_set = true;
234  }
235  }
236  else {
237  /* If there's no selection, `lastofs` is unmodified and last value since static. */
239  }
240 
241  copy_v3_v3(r_dyn_ofs, lastofs);
242 
243  return is_set;
244 }
245 
246 static enum eViewOpsFlag viewops_flag_from_args(bool use_select, bool use_depth)
247 {
248  enum eViewOpsFlag flag = 0;
249  if (use_select) {
251  }
252  if (use_depth) {
254  }
255 
256  return flag;
257 }
258 
260 {
261  return viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0,
262  (U.uiflag & USER_DEPTH_NAVIGATE) != 0);
263 }
264 
265 ViewOpsData *viewops_data_create(bContext *C, const wmEvent *event, enum eViewOpsFlag viewops_flag)
266 {
267  ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), __func__);
268 
269  /* Store data. */
270  vod->bmain = CTX_data_main(C);
272  vod->scene = CTX_data_scene(C);
273  vod->area = CTX_wm_area(C);
274  vod->region = CTX_wm_region(C);
275  vod->v3d = vod->area->spacedata.first;
276  vod->rv3d = vod->region->regiondata;
277 
278  Depsgraph *depsgraph = vod->depsgraph;
279  RegionView3D *rv3d = vod->rv3d;
280 
281  /* Could do this more nicely. */
282  if ((viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) == 0) {
283  viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
284  }
285 
286  /* we need the depth info before changing any viewport options */
287  if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
288  float fallback_depth_pt[3];
289 
290  view3d_operator_needs_opengl(C); /* Needed for Z-buffer drawing. */
291 
292  negate_v3_v3(fallback_depth_pt, rv3d->ofs);
293 
295  depsgraph, vod->region, vod->v3d, event->mval, vod->dyn_ofs, true, fallback_depth_pt);
296  }
297  else {
298  vod->use_dyn_ofs = false;
299  }
300 
301  if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) {
302  if (ED_view3d_persp_ensure(depsgraph, vod->v3d, vod->region)) {
303  /* If we're switching from camera view to the perspective one,
304  * need to tag viewport update, so camera view and borders are properly updated. */
306  }
307  }
308 
309  /* set the view from the camera, if view locking is enabled.
310  * we may want to make this optional but for now its needed always */
312 
313  vod->init.persp = rv3d->persp;
314  vod->init.dist = rv3d->dist;
315  vod->init.camzoom = rv3d->camzoom;
316  copy_qt_qt(vod->init.quat, rv3d->viewquat);
317  copy_v2_v2_int(vod->init.event_xy, event->xy);
318  copy_v2_v2_int(vod->prev.event_xy, event->xy);
319 
320  if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) {
322  }
323  else {
324  /* Simulate the event starting in the middle of the region. */
325  vod->init.event_xy_offset[0] = BLI_rcti_cent_x(&vod->region->winrct) - event->xy[0];
326  vod->init.event_xy_offset[1] = BLI_rcti_cent_y(&vod->region->winrct) - event->xy[1];
327  }
328 
329  vod->init.event_type = event->type;
330  copy_v3_v3(vod->init.ofs, rv3d->ofs);
331 
332  copy_qt_qt(vod->curr.viewquat, rv3d->viewquat);
333 
334  if (viewops_flag & VIEWOPS_FLAG_ORBIT_SELECT) {
335  float ofs[3];
336  if (view3d_orbit_calc_center(C, ofs) || (vod->use_dyn_ofs == false)) {
337  vod->use_dyn_ofs = true;
338  negate_v3_v3(vod->dyn_ofs, ofs);
339  viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
340  }
341  }
342 
343  if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
344  if (vod->use_dyn_ofs) {
345  if (rv3d->is_persp) {
346  float my_origin[3]; /* Original #RegionView3D.ofs. */
347  float my_pivot[3]; /* View pivot. */
348  float dvec[3];
349 
350  /* locals for dist correction */
351  float mat[3][3];
352  float upvec[3];
353 
354  negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
355 
356  /* Set the dist value to be the distance from this 3d point this means you'll
357  * always be able to zoom into it and panning won't go bad when dist was zero. */
358 
359  /* remove dist value */
360  upvec[0] = upvec[1] = 0;
361  upvec[2] = rv3d->dist;
362  copy_m3_m4(mat, rv3d->viewinv);
363 
364  mul_m3_v3(mat, upvec);
365  sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
366  negate_v3(my_pivot); /* ofs is flipped */
367 
368  /* find a new ofs value that is along the view axis
369  * (rather than the mouse location) */
370  closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
371  vod->init.dist = rv3d->dist = len_v3v3(my_pivot, dvec);
372 
373  negate_v3_v3(rv3d->ofs, dvec);
374  }
375  else {
376  const float mval_region_mid[2] = {(float)vod->region->winx / 2.0f,
377  (float)vod->region->winy / 2.0f};
378 
379  ED_view3d_win_to_3d(vod->v3d, vod->region, vod->dyn_ofs, mval_region_mid, rv3d->ofs);
380  negate_v3(rv3d->ofs);
381  }
382  negate_v3(vod->dyn_ofs);
383  copy_v3_v3(vod->init.ofs, rv3d->ofs);
384  }
385  }
386 
387  /* For dolly */
388  ED_view3d_win_to_vector(vod->region, (const float[2]){UNPACK2(event->mval)}, vod->init.mousevec);
389 
390  {
391  int event_xy_offset[2];
392  add_v2_v2v2_int(event_xy_offset, event->xy, vod->init.event_xy_offset);
393 
394  /* For rotation with trackball rotation. */
395  calctrackballvec(&vod->region->winrct, event_xy_offset, vod->init.trackvec);
396  }
397 
398  {
399  float tvec[3];
400  negate_v3_v3(tvec, rv3d->ofs);
401  vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec);
402  }
403 
404  vod->reverse = 1.0f;
405  if (rv3d->persmat[2][1] < 0.0f) {
406  vod->reverse = -1.0f;
407  }
408 
409  rv3d->rflag |= RV3D_NAVIGATING;
410 
411  return vod;
412 }
413 
415 {
416  ARegion *region;
417  if (vod) {
418  region = vod->region;
419  vod->rv3d->rflag &= ~RV3D_NAVIGATING;
420 
421  if (vod->timer) {
423  }
424 
425  if (vod->init.dial) {
426  MEM_freeN(vod->init.dial);
427  }
428 
429  MEM_freeN(vod);
430  }
431  else {
432  region = CTX_wm_region(C);
433  }
434 
435  /* Need to redraw because drawing code uses RV3D_NAVIGATING to draw
436  * faster while navigation operator runs. */
437  ED_region_tag_redraw(region);
438 }
439 
442 /* -------------------------------------------------------------------- */
449 static void axis_set_view(bContext *C,
450  View3D *v3d,
451  ARegion *region,
452  const float quat_[4],
453  char view,
454  char view_axis_roll,
455  int perspo,
456  const float *align_to_quat,
457  const int smooth_viewtx)
458 {
459  RegionView3D *rv3d = region->regiondata; /* no NULL check is needed, poll checks */
460  float quat[4];
461  const short orig_persp = rv3d->persp;
462 
463  normalize_qt_qt(quat, quat_);
464 
465  if (align_to_quat) {
466  mul_qt_qtqt(quat, quat, align_to_quat);
467  rv3d->view = view = RV3D_VIEW_USER;
469  }
470 
471  if (align_to_quat == NULL) {
472  rv3d->view = view;
473  rv3d->view_axis_roll = view_axis_roll;
474  }
475 
476  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) {
477  ED_region_tag_redraw(region);
478  return;
479  }
480 
481  if (U.uiflag & USER_AUTOPERSP) {
482  rv3d->persp = RV3D_VIEW_IS_AXIS(view) ? RV3D_ORTHO : perspo;
483  }
484  else if (rv3d->persp == RV3D_CAMOB) {
485  rv3d->persp = perspo;
486  }
487 
488  if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
489  /* to camera */
491  v3d,
492  region,
493  smooth_viewtx,
494  &(const V3D_SmoothParams){
495  .camera_old = v3d->camera,
496  .ofs = rv3d->ofs,
497  .quat = quat,
498  /* No undo because this switches to/from camera. */
499  .undo_str = NULL,
500  });
501  }
502  else if (orig_persp == RV3D_CAMOB && v3d->camera) {
503  /* from camera */
504  float ofs[3], dist;
505 
506  copy_v3_v3(ofs, rv3d->ofs);
507  dist = rv3d->dist;
508 
509  /* so we animate _from_ the camera location */
511  v3d->camera);
512  ED_view3d_from_object(camera_eval, rv3d->ofs, NULL, &rv3d->dist, NULL);
513 
515  v3d,
516  region,
517  smooth_viewtx,
518  &(const V3D_SmoothParams){
519  .camera_old = camera_eval,
520  .ofs = ofs,
521  .quat = quat,
522  .dist = &dist,
523  /* No undo because this switches to/from camera. */
524  .undo_str = NULL,
525  });
526  }
527  else {
528  /* rotate around selection */
529  const float *dyn_ofs_pt = NULL;
530  float dyn_ofs[3];
531 
532  if (U.uiflag & USER_ORBIT_SELECTION) {
533  if (view3d_orbit_calc_center(C, dyn_ofs)) {
534  negate_v3(dyn_ofs);
535  dyn_ofs_pt = dyn_ofs;
536  }
537  }
538 
539  /* no camera involved */
541  v3d,
542  region,
543  smooth_viewtx,
544  &(const V3D_SmoothParams){
545  .quat = quat,
546  .dyn_ofs = dyn_ofs_pt,
547  /* No undo because this isn't a camera view. */
548  .undo_str = NULL,
549  });
550  }
551 }
552 
553 void viewmove_apply(ViewOpsData *vod, int x, int y)
554 {
555  const float event_ofs[2] = {
556  vod->prev.event_xy[0] - x,
557  vod->prev.event_xy[1] - y,
558  };
559 
560  if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
561  ED_view3d_camera_view_pan(vod->region, event_ofs);
562  }
563  else if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
564  vod->rv3d->ofs_lock[0] -= (event_ofs[0] * 2.0f) / (float)vod->region->winx;
565  vod->rv3d->ofs_lock[1] -= (event_ofs[1] * 2.0f) / (float)vod->region->winy;
566  }
567  else {
568  float dvec[3];
569 
570  ED_view3d_win_to_delta(vod->region, event_ofs, vod->init.zfac, dvec);
571 
572  sub_v3_v3(vod->rv3d->ofs, dvec);
573 
574  if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) {
575  view3d_boxview_sync(vod->area, vod->region);
576  }
577  }
578 
579  vod->prev.event_xy[0] = x;
580  vod->prev.event_xy[1] = y;
581 
582  ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
583 
585 }
586 
589 /* -------------------------------------------------------------------- */
595 static bool view3d_object_skip_minmax(const View3D *v3d,
596  const RegionView3D *rv3d,
597  const Object *ob,
598  const bool skip_camera,
599  bool *r_only_center)
600 {
601  BLI_assert(ob->id.orig_id == NULL);
602  *r_only_center = false;
603 
604  if (skip_camera && (ob == v3d->camera)) {
605  return true;
606  }
607 
608  if ((ob->type == OB_EMPTY) && (ob->empty_drawtype == OB_EMPTY_IMAGE) &&
610  *r_only_center = true;
611  return false;
612  }
613 
614  return false;
615 }
616 
618  Scene *scene,
619  Object *ob_eval,
620  const bool only_center,
621  float min[3],
622  float max[3])
623 {
624  /* Account for duplis. */
625  if (BKE_object_minmax_dupli(depsgraph, scene, ob_eval, min, max, false) == 0) {
626  /* Use if duplis aren't found. */
627  if (only_center) {
628  minmax_v3v3_v3(min, max, ob_eval->obmat[3]);
629  }
630  else {
631  BKE_object_minmax(ob_eval, min, max, false);
632  }
633  }
634 }
635 
637  View3D *v3d,
638  ARegion *region,
639  const float min[3],
640  const float max[3],
641  bool ok_dist,
642  const int smooth_viewtx)
643 {
644  RegionView3D *rv3d = region->regiondata;
645  float afm[3];
646  float size;
647 
649 
650  /* SMOOTHVIEW */
651  float new_ofs[3];
652  float new_dist;
653 
654  sub_v3_v3v3(afm, max, min);
655  size = max_fff(afm[0], afm[1], afm[2]);
656 
657  if (ok_dist) {
658  char persp;
659 
660  if (rv3d->is_persp) {
661  if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
662  persp = RV3D_CAMOB;
663  }
664  else {
665  persp = RV3D_PERSP;
666  }
667  }
668  else { /* ortho */
669  if (size < 0.0001f) {
670  /* bounding box was a single point so do not zoom */
671  ok_dist = false;
672  }
673  else {
674  /* adjust zoom so it looks nicer */
675  persp = RV3D_ORTHO;
676  }
677  }
678 
679  if (ok_dist) {
681  new_dist = ED_view3d_radius_to_dist(
682  v3d, region, depsgraph, persp, true, (size / 2) * VIEW3D_MARGIN);
683  if (rv3d->is_persp) {
684  /* don't zoom closer than the near clipping plane */
685  new_dist = max_ff(new_dist, v3d->clip_start * 1.5f);
686  }
687  }
688  }
689 
690  mid_v3_v3v3(new_ofs, min, max);
691  negate_v3(new_ofs);
692 
693  if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
694  rv3d->persp = RV3D_PERSP;
696  v3d,
697  region,
698  smooth_viewtx,
699  &(const V3D_SmoothParams){
700  .camera_old = v3d->camera,
701  .ofs = new_ofs,
702  .dist = ok_dist ? &new_dist : NULL,
703  /* The caller needs to use undo begin/end calls. */
704  .undo_str = NULL,
705  });
706  }
707  else {
709  v3d,
710  region,
711  smooth_viewtx,
712  &(const V3D_SmoothParams){
713  .ofs = new_ofs,
714  .dist = ok_dist ? &new_dist : NULL,
715  /* The caller needs to use undo begin/end calls. */
716  .undo_str = NULL,
717  });
718  }
719 
720  /* Smooth-view does view-lock #RV3D_BOXVIEW copy. */
721 }
722 
727  View3D *v3d,
728  const float min[3],
729  const float max[3],
730  const bool ok_dist,
731  const int smooth_viewtx)
732 {
734  ARegion *region;
735  for (region = area->regionbase.first; region; region = region->next) {
736  if (region->regiontype == RGN_TYPE_WINDOW) {
737  RegionView3D *rv3d = region->regiondata;
738  /* when using all regions, don't jump out of camera view,
739  * but _do_ allow locked cameras to be moved */
740  if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
741  view3d_from_minmax(C, v3d, region, min, max, ok_dist, smooth_viewtx);
742  }
743  }
744  }
745 }
746 
748 {
750  ARegion *region = CTX_wm_region(C);
751  View3D *v3d = CTX_wm_view3d(C);
756  Base *base_eval;
757  const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
758  const bool skip_camera = (ED_view3d_camera_lock_check(v3d, region->regiondata) ||
759  /* any one of the regions may be locked */
760  (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
761  const bool center = RNA_boolean_get(op->ptr, "center");
762  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
763 
764  float min[3], max[3];
765  bool changed = false;
766 
767  if (center) {
768  /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */
769  View3DCursor *cursor = &scene->cursor;
770  zero_v3(min);
771  zero_v3(max);
772  zero_v3(cursor->location);
773  float mat3[3][3];
774  unit_m3(mat3);
775  BKE_scene_cursor_mat3_to_rot(cursor, mat3, false);
776  }
777  else {
778  INIT_MINMAX(min, max);
779  }
780 
781  for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
782  if (BASE_VISIBLE(v3d, base_eval)) {
783  bool only_center = false;
784  Object *ob = DEG_get_original_object(base_eval->object);
785  if (view3d_object_skip_minmax(v3d, rv3d, ob, skip_camera, &only_center)) {
786  continue;
787  }
788  view3d_object_calc_minmax(depsgraph, scene, base_eval->object, only_center, min, max);
789  changed = true;
790  }
791  }
792 
793  if (center) {
794  struct wmMsgBus *mbus = CTX_wm_message_bus(C);
795  WM_msg_publish_rna_prop(mbus, &scene->id, &scene->cursor, View3DCursor, location);
796 
798  }
799 
800  if (!changed) {
801  ED_region_tag_redraw(region);
802  /* TODO: should this be cancel?
803  * I think no, because we always move the cursor, with or without
804  * object, but in this case there is no change in the scene,
805  * only the cursor so I choice a ED_region_tag like
806  * view3d_smooth_view do for the center_cursor.
807  * See bug T22640.
808  */
809  return OPERATOR_FINISHED;
810  }
811 
812  if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
813  /* This is an approximation, see function documentation for details. */
815  }
817 
818  if (use_all_regions) {
819  view3d_from_minmax_multi(C, v3d, min, max, true, smooth_viewtx);
820  }
821  else {
822  view3d_from_minmax(C, v3d, region, min, max, true, smooth_viewtx);
823  }
824 
826 
827  return OPERATOR_FINISHED;
828 }
829 
831 {
832  /* identifiers */
833  ot->name = "Frame All";
834  ot->description = "View all objects in scene";
835  ot->idname = "VIEW3D_OT_view_all";
836 
837  /* api callbacks */
840 
841  /* flags */
842  ot->flag = 0;
843 
844  /* properties */
846  RNA_def_boolean(ot->srna, "center", 0, "Center", "");
847 }
848 
851 /* -------------------------------------------------------------------- */
858 {
860  ARegion *region = CTX_wm_region(C);
861  View3D *v3d = CTX_wm_view3d(C);
866  Object *ob_eval = OBACT(view_layer_eval);
867  Object *obedit = CTX_data_edit_object(C);
868  const bGPdata *gpd_eval = ob_eval && (ob_eval->type == OB_GPENCIL) ? ob_eval->data : NULL;
869  const bool is_gp_edit = gpd_eval ? GPENCIL_ANY_MODE(gpd_eval) : false;
870  const bool is_face_map = ((is_gp_edit == false) && region->gizmo_map &&
872  float min[3], max[3];
873  bool ok = false, ok_dist = true;
874  const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
875  const bool skip_camera = (ED_view3d_camera_lock_check(v3d, region->regiondata) ||
876  /* any one of the regions may be locked */
877  (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
878  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
879 
880  INIT_MINMAX(min, max);
881  if (is_face_map) {
882  ob_eval = NULL;
883  }
884 
885  if (ob_eval && (ob_eval->mode & OB_MODE_WEIGHT_PAINT)) {
886  /* hard-coded exception, we look for the one selected armature */
887  /* this is weak code this way, we should make a generic
888  * active/selection callback interface once... */
889  Base *base_eval;
890  for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
891  if (BASE_SELECTED_EDITABLE(v3d, base_eval)) {
892  if (base_eval->object->type == OB_ARMATURE) {
893  if (base_eval->object->mode & OB_MODE_POSE) {
894  break;
895  }
896  }
897  }
898  }
899  if (base_eval) {
900  ob_eval = base_eval->object;
901  }
902  }
903 
904  if (is_gp_edit) {
905  CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
906  /* we're only interested in selected points here... */
907  if ((gps->flag & GP_STROKE_SELECT) && (gps->flag & GP_STROKE_3DSPACE)) {
908  ok |= BKE_gpencil_stroke_minmax(gps, true, min, max);
909  }
910  if (gps->editcurve != NULL) {
911  for (int i = 0; i < gps->editcurve->tot_curve_points; i++) {
912  BezTriple *bezt = &gps->editcurve->curve_points[i].bezt;
913  if ((bezt->f1 & SELECT)) {
914  minmax_v3v3_v3(min, max, bezt->vec[0]);
915  ok = true;
916  }
917  if ((bezt->f2 & SELECT)) {
918  minmax_v3v3_v3(min, max, bezt->vec[1]);
919  ok = true;
920  }
921  if ((bezt->f3 & SELECT)) {
922  minmax_v3v3_v3(min, max, bezt->vec[2]);
923  ok = true;
924  }
925  }
926  }
927  }
928  CTX_DATA_END;
929 
930  if ((ob_eval) && (ok)) {
931  mul_m4_v3(ob_eval->obmat, min);
932  mul_m4_v3(ob_eval->obmat, max);
933  }
934  }
935  else if (is_face_map) {
936  ok = WM_gizmomap_minmax(region->gizmo_map, true, true, min, max);
937  }
938  else if (obedit) {
939  /* only selected */
940  FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, obedit->type, obedit->mode, ob_eval_iter) {
941  ok |= ED_view3d_minmax_verts(ob_eval_iter, min, max);
942  }
944  }
945  else if (ob_eval && (ob_eval->mode & OB_MODE_POSE)) {
947  view_layer_eval, v3d, ob_eval->type, ob_eval->mode, ob_eval_iter) {
948  ok |= BKE_pose_minmax(ob_eval_iter, min, max, true, true);
949  }
951  }
952  else if (BKE_paint_select_face_test(ob_eval)) {
953  ok = paintface_minmax(ob_eval, min, max);
954  }
955  else if (ob_eval && (ob_eval->mode & OB_MODE_PARTICLE_EDIT)) {
957  }
958  else if (ob_eval && (ob_eval->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT |
961  copy_v3_v3(max, min);
962  ok = true;
963  ok_dist = 0; /* don't zoom */
964  }
965  else {
966  Base *base_eval;
967  for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
968  if (BASE_SELECTED(v3d, base_eval)) {
969  bool only_center = false;
970  Object *ob = DEG_get_original_object(base_eval->object);
971  if (view3d_object_skip_minmax(v3d, rv3d, ob, skip_camera, &only_center)) {
972  continue;
973  }
974  view3d_object_calc_minmax(depsgraph, scene, base_eval->object, only_center, min, max);
975  ok = 1;
976  }
977  }
978  }
979 
980  if (ok == 0) {
981  return OPERATOR_FINISHED;
982  }
983 
984  if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
985  /* This is an approximation, see function documentation for details. */
987  }
988 
990 
991  if (use_all_regions) {
992  view3d_from_minmax_multi(C, v3d, min, max, ok_dist, smooth_viewtx);
993  }
994  else {
995  view3d_from_minmax(C, v3d, region, min, max, ok_dist, smooth_viewtx);
996  }
997 
999 
1000  return OPERATOR_FINISHED;
1001 }
1002 
1004 {
1005  /* identifiers */
1006  ot->name = "Frame Selected";
1007  ot->description = "Move the view to the selection center";
1008  ot->idname = "VIEW3D_OT_view_selected";
1009 
1010  /* api callbacks */
1013 
1014  /* flags */
1015  ot->flag = 0;
1016 
1017  /* properties */
1019 }
1020 
1023 /* -------------------------------------------------------------------- */
1028 {
1029  View3D *v3d = CTX_wm_view3d(C);
1032 
1033  if (rv3d) {
1034  ARegion *region = CTX_wm_region(C);
1035  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1036 
1037  ED_view3d_smooth_view_force_finish(C, v3d, region);
1038 
1039  /* non camera center */
1040  float new_ofs[3];
1041  negate_v3_v3(new_ofs, scene->cursor.location);
1043  v3d,
1044  region,
1045  smooth_viewtx,
1046  &(const V3D_SmoothParams){
1047  .ofs = new_ofs,
1048  .undo_str = op->type->name,
1049  });
1050 
1051  /* Smooth view does view-lock #RV3D_BOXVIEW copy. */
1052  }
1053 
1054  return OPERATOR_FINISHED;
1055 }
1056 
1058 {
1059  /* identifiers */
1060  ot->name = "Center View to Cursor";
1061  ot->description = "Center the view so that the cursor is in the middle of the view";
1062  ot->idname = "VIEW3D_OT_view_center_cursor";
1063 
1064  /* api callbacks */
1067 
1068  /* flags */
1069  ot->flag = 0;
1070 }
1071 
1074 /* -------------------------------------------------------------------- */
1078 static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1079 {
1080  View3D *v3d = CTX_wm_view3d(C);
1082  ARegion *region = CTX_wm_region(C);
1083 
1084  if (rv3d) {
1086  float new_ofs[3];
1087  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1088 
1089  ED_view3d_smooth_view_force_finish(C, v3d, region);
1090 
1092 
1093  if (ED_view3d_autodist(depsgraph, region, v3d, event->mval, new_ofs, false, NULL)) {
1094  /* pass */
1095  }
1096  else {
1097  /* fallback to simple pan */
1098  negate_v3_v3(new_ofs, rv3d->ofs);
1099  ED_view3d_win_to_3d_int(v3d, region, new_ofs, event->mval, new_ofs);
1100  }
1101  negate_v3(new_ofs);
1103  v3d,
1104  region,
1105  smooth_viewtx,
1106  &(const V3D_SmoothParams){
1107  .ofs = new_ofs,
1108  .undo_str = op->type->name,
1109  });
1110  }
1111 
1112  return OPERATOR_FINISHED;
1113 }
1114 
1116 {
1117  /* identifiers */
1118  ot->name = "Center View to Mouse";
1119  ot->description = "Center the view to the Z-depth position under the mouse cursor";
1120  ot->idname = "VIEW3D_OT_view_center_pick";
1121 
1122  /* api callbacks */
1125 
1126  /* flags */
1127  ot->flag = 0;
1128 }
1129 
1132 /* -------------------------------------------------------------------- */
1137  {RV3D_VIEW_LEFT, "LEFT", ICON_TRIA_LEFT, "Left", "View from the left"},
1138  {RV3D_VIEW_RIGHT, "RIGHT", ICON_TRIA_RIGHT, "Right", "View from the right"},
1139  {RV3D_VIEW_BOTTOM, "BOTTOM", ICON_TRIA_DOWN, "Bottom", "View from the bottom"},
1140  {RV3D_VIEW_TOP, "TOP", ICON_TRIA_UP, "Top", "View from the top"},
1141  {RV3D_VIEW_FRONT, "FRONT", 0, "Front", "View from the front"},
1142  {RV3D_VIEW_BACK, "BACK", 0, "Back", "View from the back"},
1143  {0, NULL, 0, NULL, NULL},
1144 };
1145 
1147 {
1148  View3D *v3d;
1149  ARegion *region;
1150  RegionView3D *rv3d;
1151  static int perspo = RV3D_PERSP;
1152  int viewnum;
1153  int view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
1154  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1155 
1156  /* no NULL check is needed, poll checks */
1157  ED_view3d_context_user_region(C, &v3d, &region);
1158  rv3d = region->regiondata;
1159 
1160  ED_view3d_smooth_view_force_finish(C, v3d, region);
1161 
1162  viewnum = RNA_enum_get(op->ptr, "type");
1163 
1164  float align_quat_buf[4];
1165  float *align_quat = NULL;
1166 
1167  if (RNA_boolean_get(op->ptr, "align_active")) {
1168  /* align to active object */
1169  Object *obact = CTX_data_active_object(C);
1170  if (obact != NULL) {
1171  float twmat[3][3];
1172  struct ViewLayer *view_layer = CTX_data_view_layer(C);
1173  Object *obedit = CTX_data_edit_object(C);
1174  /* same as transform gizmo when normal is set */
1175  ED_getTransformOrientationMatrix(view_layer, v3d, obact, obedit, V3D_AROUND_ACTIVE, twmat);
1176  align_quat = align_quat_buf;
1177  mat3_to_quat(align_quat, twmat);
1178  invert_qt_normalized(align_quat);
1179  }
1180  }
1181 
1182  if (RNA_boolean_get(op->ptr, "relative")) {
1183  float quat_rotate[4];
1184  float quat_test[4];
1185 
1186  if (viewnum == RV3D_VIEW_LEFT) {
1187  axis_angle_to_quat(quat_rotate, rv3d->viewinv[1], -M_PI_2);
1188  }
1189  else if (viewnum == RV3D_VIEW_RIGHT) {
1190  axis_angle_to_quat(quat_rotate, rv3d->viewinv[1], M_PI_2);
1191  }
1192  else if (viewnum == RV3D_VIEW_TOP) {
1193  axis_angle_to_quat(quat_rotate, rv3d->viewinv[0], -M_PI_2);
1194  }
1195  else if (viewnum == RV3D_VIEW_BOTTOM) {
1196  axis_angle_to_quat(quat_rotate, rv3d->viewinv[0], M_PI_2);
1197  }
1198  else if (viewnum == RV3D_VIEW_FRONT) {
1199  unit_qt(quat_rotate);
1200  }
1201  else if (viewnum == RV3D_VIEW_BACK) {
1202  axis_angle_to_quat(quat_rotate, rv3d->viewinv[0], M_PI);
1203  }
1204  else {
1205  BLI_assert(0);
1206  }
1207 
1208  mul_qt_qtqt(quat_test, rv3d->viewquat, quat_rotate);
1209 
1210  float angle_best = FLT_MAX;
1211  int view_best = -1;
1212  int view_axis_roll_best = -1;
1213  for (int i = RV3D_VIEW_FRONT; i <= RV3D_VIEW_BOTTOM; i++) {
1214  for (int j = RV3D_VIEW_AXIS_ROLL_0; j <= RV3D_VIEW_AXIS_ROLL_270; j++) {
1215  float quat_axis[4];
1216  ED_view3d_quat_from_axis_view(i, j, quat_axis);
1217  if (align_quat) {
1218  mul_qt_qtqt(quat_axis, quat_axis, align_quat);
1219  }
1220  const float angle_test = fabsf(angle_signed_qtqt(quat_axis, quat_test));
1221  if (angle_best > angle_test) {
1222  angle_best = angle_test;
1223  view_best = i;
1224  view_axis_roll_best = j;
1225  }
1226  }
1227  }
1228  if (view_best == -1) {
1229  view_best = RV3D_VIEW_FRONT;
1230  view_axis_roll_best = RV3D_VIEW_AXIS_ROLL_0;
1231  }
1232 
1233  /* Disallow non-upright views in turn-table modes,
1234  * it's too difficult to navigate out of them. */
1235  if ((U.flag & USER_TRACKBALL) == 0) {
1236  if (!ELEM(view_best, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
1237  view_axis_roll_best = RV3D_VIEW_AXIS_ROLL_0;
1238  }
1239  }
1240 
1241  viewnum = view_best;
1242  view_axis_roll = view_axis_roll_best;
1243  }
1244 
1245  /* Use this to test if we started out with a camera */
1246  const int nextperspo = (rv3d->persp == RV3D_CAMOB) ? rv3d->lpersp : perspo;
1247  float quat[4];
1248  ED_view3d_quat_from_axis_view(viewnum, view_axis_roll, quat);
1249  axis_set_view(
1250  C, v3d, region, quat, viewnum, view_axis_roll, nextperspo, align_quat, smooth_viewtx);
1251 
1252  perspo = rv3d->persp;
1253 
1254  return OPERATOR_FINISHED;
1255 }
1256 
1258 {
1259  PropertyRNA *prop;
1260 
1261  /* identifiers */
1262  ot->name = "View Axis";
1263  ot->description = "Use a preset viewpoint";
1264  ot->idname = "VIEW3D_OT_view_axis";
1265 
1266  /* api callbacks */
1267  ot->exec = view_axis_exec;
1269 
1270  /* flags */
1271  ot->flag = 0;
1272 
1273  ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use");
1276 
1277  prop = RNA_def_boolean(
1278  ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis");
1280  prop = RNA_def_boolean(
1281  ot->srna, "relative", 0, "Relative", "Rotate relative to the current orientation");
1283 }
1284 
1287 /* -------------------------------------------------------------------- */
1292 {
1293  View3D *v3d;
1294  ARegion *region;
1295  RegionView3D *rv3d;
1296  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1297 
1298  /* no NULL check is needed, poll checks */
1299  ED_view3d_context_user_region(C, &v3d, &region);
1300  rv3d = region->regiondata;
1301 
1302  ED_view3d_smooth_view_force_finish(C, v3d, region);
1303 
1304  if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ANY_TRANSFORM) == 0) {
1305  ViewLayer *view_layer = CTX_data_view_layer(C);
1307 
1308  if (rv3d->persp != RV3D_CAMOB) {
1309  Object *ob = OBACT(view_layer);
1310 
1311  if (!rv3d->smooth_timer) {
1312  /* store settings of current view before allowing overwriting with camera view
1313  * only if we're not currently in a view transition */
1314 
1316  }
1317 
1318  /* first get the default camera for the view lock type */
1319  if (v3d->scenelock) {
1320  /* sets the camera view if available */
1321  v3d->camera = scene->camera;
1322  }
1323  else {
1324  /* use scene camera if one is not set (even though we're unlocked) */
1325  if (v3d->camera == NULL) {
1326  v3d->camera = scene->camera;
1327  }
1328  }
1329 
1330  /* if the camera isn't found, check a number of options */
1331  if (v3d->camera == NULL && ob && ob->type == OB_CAMERA) {
1332  v3d->camera = ob;
1333  }
1334 
1335  if (v3d->camera == NULL) {
1336  v3d->camera = BKE_view_layer_camera_find(view_layer);
1337  }
1338 
1339  /* couldn't find any useful camera, bail out */
1340  if (v3d->camera == NULL) {
1341  return OPERATOR_CANCELLED;
1342  }
1343 
1344  /* important these don't get out of sync for locked scenes */
1345  if (v3d->scenelock && scene->camera != v3d->camera) {
1346  scene->camera = v3d->camera;
1348  }
1349 
1350  /* finally do snazzy view zooming */
1351  rv3d->persp = RV3D_CAMOB;
1353  C,
1354  v3d,
1355  region,
1356  smooth_viewtx,
1357  &(const V3D_SmoothParams){
1358  .camera = v3d->camera,
1359  .ofs = rv3d->ofs,
1360  .quat = rv3d->viewquat,
1361  .dist = &rv3d->dist,
1362  .lens = &v3d->lens,
1363  /* No undo because this changes cameras (and wont move the camera). */
1364  .undo_str = NULL,
1365  });
1366  }
1367  else {
1368  /* return to settings of last view */
1369  /* does view3d_smooth_view too */
1370  axis_set_view(C,
1371  v3d,
1372  region,
1373  rv3d->lviewquat,
1374  rv3d->lview,
1375  rv3d->lview_axis_roll,
1376  rv3d->lpersp,
1377  NULL,
1378  smooth_viewtx);
1379  }
1380  }
1381 
1382  return OPERATOR_FINISHED;
1383 }
1384 
1386 {
1387  /* identifiers */
1388  ot->name = "View Camera";
1389  ot->description = "Toggle the camera view";
1390  ot->idname = "VIEW3D_OT_view_camera";
1391 
1392  /* api callbacks */
1395 
1396  /* flags */
1397  ot->flag = 0;
1398 }
1399 
1402 /* -------------------------------------------------------------------- */
1408 enum {
1413 };
1414 
1416  {V3D_VIEW_STEPLEFT, "ORBITLEFT", 0, "Orbit Left", "Orbit the view around to the left"},
1417  {V3D_VIEW_STEPRIGHT, "ORBITRIGHT", 0, "Orbit Right", "Orbit the view around to the right"},
1418  {V3D_VIEW_STEPUP, "ORBITUP", 0, "Orbit Up", "Orbit the view up"},
1419  {V3D_VIEW_STEPDOWN, "ORBITDOWN", 0, "Orbit Down", "Orbit the view down"},
1420  {0, NULL, 0, NULL, NULL},
1421 };
1422 
1424 {
1425  View3D *v3d;
1426  ARegion *region;
1427  RegionView3D *rv3d;
1428  int orbitdir;
1429  char view_opposite;
1430  PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
1431  float angle = RNA_property_is_set(op->ptr, prop_angle) ?
1432  RNA_property_float_get(op->ptr, prop_angle) :
1433  DEG2RADF(U.pad_rot_angle);
1434 
1435  /* no NULL check is needed, poll checks */
1436  v3d = CTX_wm_view3d(C);
1437  region = CTX_wm_region(C);
1438  rv3d = region->regiondata;
1439 
1440  /* support for switching to the opposite view (even when in locked views) */
1441  view_opposite = (fabsf(angle) == (float)M_PI) ? ED_view3d_axis_view_opposite(rv3d->view) :
1443  orbitdir = RNA_enum_get(op->ptr, "type");
1444 
1445  if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) {
1446  /* no NULL check is needed, poll checks */
1447  ED_view3d_context_user_region(C, &v3d, &region);
1448  rv3d = region->regiondata;
1449  }
1450 
1451  ED_view3d_smooth_view_force_finish(C, v3d, region);
1452 
1453  if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0 || (view_opposite != RV3D_VIEW_USER)) {
1454  const bool is_camera_lock = ED_view3d_camera_lock_check(v3d, rv3d);
1455  if ((rv3d->persp != RV3D_CAMOB) || is_camera_lock) {
1456  if (is_camera_lock) {
1459  }
1460  int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1461  float quat_mul[4];
1462  float quat_new[4];
1463 
1464  if (view_opposite == RV3D_VIEW_USER) {
1466  ED_view3d_persp_ensure(depsgraph, v3d, region);
1467  }
1468 
1469  if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
1470  if (orbitdir == V3D_VIEW_STEPRIGHT) {
1471  angle = -angle;
1472  }
1473 
1474  /* z-axis */
1475  axis_angle_to_quat_single(quat_mul, 'Z', angle);
1476  }
1477  else {
1478 
1479  if (orbitdir == V3D_VIEW_STEPDOWN) {
1480  angle = -angle;
1481  }
1482 
1483  /* horizontal axis */
1484  axis_angle_to_quat(quat_mul, rv3d->viewinv[0], angle);
1485  }
1486 
1487  mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
1488 
1489  /* avoid precision loss over time */
1490  normalize_qt(quat_new);
1491 
1492  if (view_opposite != RV3D_VIEW_USER) {
1493  rv3d->view = view_opposite;
1494  /* avoid float in-precision, just get a new orientation */
1495  ED_view3d_quat_from_axis_view(view_opposite, rv3d->view_axis_roll, quat_new);
1496  }
1497  else {
1498  rv3d->view = RV3D_VIEW_USER;
1499  }
1500 
1501  float dyn_ofs[3], *dyn_ofs_pt = NULL;
1502 
1503  if (U.uiflag & USER_ORBIT_SELECTION) {
1504  if (view3d_orbit_calc_center(C, dyn_ofs)) {
1505  negate_v3(dyn_ofs);
1506  dyn_ofs_pt = dyn_ofs;
1507  }
1508  }
1509 
1511  v3d,
1512  region,
1513  smooth_viewtx,
1514  &(const V3D_SmoothParams){
1515  .quat = quat_new,
1516  .dyn_ofs = dyn_ofs_pt,
1517  /* Group as successive orbit may run by holding a key. */
1518  .undo_str = op->type->name,
1519  .undo_grouped = true,
1520  });
1521 
1522  return OPERATOR_FINISHED;
1523  }
1524  }
1525 
1526  return OPERATOR_CANCELLED;
1527 }
1528 
1530 {
1531  PropertyRNA *prop;
1532 
1533  /* identifiers */
1534  ot->name = "View Orbit";
1535  ot->description = "Orbit the view";
1536  ot->idname = "VIEW3D_OT_view_orbit";
1537 
1538  /* api callbacks */
1539  ot->exec = vieworbit_exec;
1541 
1542  /* flags */
1543  ot->flag = 0;
1544 
1545  /* properties */
1546  prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
1548 
1549  ot->prop = RNA_def_enum(
1550  ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
1551 }
1552 
1555 /* -------------------------------------------------------------------- */
1561 enum {
1566 };
1567 
1569  {V3D_VIEW_PANLEFT, "PANLEFT", 0, "Pan Left", "Pan the view to the left"},
1570  {V3D_VIEW_PANRIGHT, "PANRIGHT", 0, "Pan Right", "Pan the view to the right"},
1571  {V3D_VIEW_PANUP, "PANUP", 0, "Pan Up", "Pan the view up"},
1572  {V3D_VIEW_PANDOWN, "PANDOWN", 0, "Pan Down", "Pan the view down"},
1573  {0, NULL, 0, NULL, NULL},
1574 };
1575 
1576 static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1577 {
1578  int x = 0, y = 0;
1579  int pandir = RNA_enum_get(op->ptr, "type");
1580 
1581  if (pandir == V3D_VIEW_PANRIGHT) {
1582  x = -32;
1583  }
1584  else if (pandir == V3D_VIEW_PANLEFT) {
1585  x = 32;
1586  }
1587  else if (pandir == V3D_VIEW_PANUP) {
1588  y = -25;
1589  }
1590  else if (pandir == V3D_VIEW_PANDOWN) {
1591  y = 25;
1592  }
1593 
1596 
1597  viewmove_apply(vod, vod->prev.event_xy[0] + x, vod->prev.event_xy[1] + y);
1598 
1599  ED_view3d_camera_lock_undo_push(op->type->name, vod->v3d, vod->rv3d, C);
1600  viewops_data_free(C, vod);
1601 
1602  return OPERATOR_FINISHED;
1603 }
1604 
1606 {
1607  /* identifiers */
1608  ot->name = "Pan View Direction";
1609  ot->description = "Pan the view in a given direction";
1610  ot->idname = "VIEW3D_OT_view_pan";
1611 
1612  /* api callbacks */
1615 
1616  /* flags */
1617  ot->flag = 0;
1618 
1619  /* Properties */
1620  ot->prop = RNA_def_enum(
1621  ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
1622 }
1623 
typedef float(TangentPoint)[2]
bool BKE_pose_minmax(struct Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select)
Definition: armature.c:2711
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1370
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
#define CTX_DATA_BEGIN(C, Type, instance, member)
Definition: BKE_context.h:269
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct wmMsgBus * CTX_wm_message_bus(const bContext *C)
Definition: context.c:770
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
#define CTX_DATA_END
Definition: BKE_context.h:278
bool BKE_gpencil_stroke_minmax(const struct bGPDstroke *gps, bool use_select, float r_min[3], float r_max[3])
struct Object * BKE_view_layer_camera_find(struct ViewLayer *view_layer)
Definition: layer.c:311
#define FOREACH_OBJECT_IN_MODE_END
Definition: BKE_layer.h:384
#define FOREACH_OBJECT_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _instance)
Definition: BKE_layer.h:380
General operations, lookup, etc. for blender objects.
bool BKE_object_minmax_dupli(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, float r_min[3], float r_max[3], bool use_hidden)
Definition: object.cc:4075
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.cc:2511
void BKE_boundbox_calc_center_aabb(const struct BoundBox *bb, float r_cent[3])
void BKE_object_minmax(struct Object *ob, float r_min[3], float r_max[3], bool use_hidden)
Definition: object.cc:3839
bool BKE_object_empty_image_frame_is_visible_in_view3d(const struct Object *ob, const struct RegionView3D *rv3d)
bool BKE_paint_select_face_test(struct Object *ob)
Definition: paint.c:980
void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3])
Definition: paint.c:1184
void BKE_scene_cursor_mat3_to_rot(struct View3DCursor *cursor, const float mat[3][3], bool use_compat)
Definition: scene.cc:3612
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
#define M_SQRT2
Definition: BLI_math_base.h:29
MINLINE float min_ff(float a, float b)
#define M_PI_2
Definition: BLI_math_base.h:23
MINLINE float square_f(float a)
#define M_PI
Definition: BLI_math_base.h:20
float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
Definition: math_geom.c:3176
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void invert_qt_normalized(float q[4])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void axis_angle_to_quat_single(float q[4], char axis, float angle)
void mat3_to_quat(float q[4], const float mat[3][3])
float normalize_qt(float q[4])
#define DEG2RADF(_deg)
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:59
void unit_qt(float q[4])
Definition: math_rotation.c:27
float normalize_qt_qt(float r[4], const float q[4])
void invert_qt_qt_normalized(float q1[4], const float q2[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:33
float angle_signed_qtqt(const float q1[4], const float q2[4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:867
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void negate_v3(float r[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE int BLI_rcti_cent_y(const struct rcti *rct)
Definition: BLI_rect.h:173
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct)
Definition: BLI_rect.h:169
unsigned int uint
Definition: BLI_sys_types.h:67
#define INIT_MINMAX(min, max)
#define ELEM(...)
#define BLT_I18NCONTEXT_EDITOR_VIEW3D
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
struct Object * DEG_get_original_object(struct Object *object)
struct ViewLayer * DEG_get_evaluated_view_layer(const struct Depsgraph *graph)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ GP_STROKE_SELECT
@ GP_STROKE_3DSPACE
#define GPENCIL_ANY_MODE(gpd)
@ BASE_SELECTED
#define OB_MODE_ALL_PAINT
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_OBJECT
@ OB_MODE_VERTEX_PAINT
@ OB_EMPTY_IMAGE
@ OB_EMPTY
@ OB_CAMERA
@ OB_FONT
@ OB_ARMATURE
@ OB_GPENCIL
@ BOUNDBOX_DIRTY
#define BASE_SELECTED_EDITABLE(v3d, base)
#define FIRSTBASE(_view_layer)
#define OBACT(_view_layer)
#define BASE_VISIBLE(v3d, base)
@ RGN_TYPE_WINDOW
@ USER_ORBIT_SELECTION
@ USER_AUTOPERSP
@ USER_DEPTH_NAVIGATE
@ USER_TRACKBALL
@ V3D_AROUND_ACTIVE
@ V3D_AROUND_CENTER_MEDIAN
#define RV3D_VIEW_IS_AXIS(view)
#define V3D_LOCK_CAMERA
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_VIEW_AXIS_ROLL_270
@ RV3D_VIEW_AXIS_ROLL_0
#define RV3D_CAMOB
#define RV3D_VIEW_BACK
@ RV3D_LOCK_ANY_TRANSFORM
@ RV3D_LOCK_ROTATION
@ RV3D_LOCK_LOCATION
@ RV3D_LOCK_ZOOM_AND_DOLLY
@ RV3D_BOXVIEW
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
#define RV3D_VIEW_BOTTOM
#define RV3D_VIEW_LEFT
#define RV3D_VIEW_RIGHT
#define RV3D_PERSP
#define RV3D_VIEW_TOP
#define RV3D_VIEW_USER
#define RV3D_VIEW_FRONT
#define RV3D_NAVIGATING
#define RV3D_ORTHO
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3])
Definition: editface.cc:308
int PE_minmax(struct Depsgraph *depsgraph, struct Scene *scene, struct ViewLayer *view_layer, float min[3], float max[3])
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
bool ED_operator_region_view3d_active(struct bContext *C)
Definition: screen_ops.c:230
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2])
Definition: transform.c:1341
void ED_getTransformOrientationMatrix(struct ViewLayer *view_layer, const struct View3D *v3d, struct Object *ob, struct Object *obedit, short around, float r_orientation_mat[3][3])
bool ED_view3d_camera_view_pan(struct ARegion *region, const float event_ofs[2])
Definition: view3d_utils.c:525
bool ED_view3d_camera_lock_sync(const struct Depsgraph *depsgraph, struct View3D *v3d, struct RegionView3D *rv3d)
bool ED_view3d_clipping_clamp_minmax(const struct RegionView3D *rv3d, float min[3], float max[3])
char ED_view3d_axis_view_opposite(char view)
void ED_view3d_win_to_3d_int(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
bool ED_view3d_camera_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d)
void ED_view3d_win_to_delta(const struct ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
bool ED_operator_rv3d_user_region_poll(struct bContext *C)
Definition: view3d_view.c:277
bool ED_view3d_quat_from_axis_view(char view, char view_axis_roll, float r_quat[4])
bool ED_view3d_offset_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d)
#define VIEW3D_MARGIN
Definition: ED_view3d.h:1229
bool ED_view3d_persp_ensure(const struct Depsgraph *depsgraph, struct View3D *v3d, struct ARegion *region)
void ED_view3d_from_object(const struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
void ED_view3d_win_to_vector(const struct ARegion *region, const float mval[2], float r_out[3])
float ED_view3d_radius_to_dist(const struct View3D *v3d, const struct ARegion *region, const struct Depsgraph *depsgraph, char persp, bool use_aspect, float radius)
float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3])
bool ED_view3d_camera_lock_undo_push(const char *str, View3D *v3d, struct RegionView3D *rv3d, struct bContext *C)
Definition: view3d_utils.c:726
void ED_view3d_lastview_store(struct RegionView3D *rv3d)
Definition: view3d_utils.c:440
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
void ED_view3d_camera_lock_init(const struct Depsgraph *depsgraph, struct View3D *v3d, struct RegionView3D *rv3d)
void view3d_operator_needs_opengl(const struct bContext *C)
bool ED_view3d_context_user_region(struct bContext *C, struct View3D **r_v3d, struct ARegion **r_region)
Definition: space_view3d.c:98
bool ED_view3d_autodist(struct Depsgraph *depsgraph, struct ARegion *region, struct View3D *v3d, const int mval[2], float mouse_worldloc[3], bool alphaoverride, const float fallback_depth_pt[3])
static AppView * view
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
@ PROP_HIDDEN
Definition: RNA_types.h:216
#define C
Definition: RandGen.cpp:25
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
#define SELECT
Scene scene
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
MINLINE void zero_v2_int(int r[2])
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
static void area(int d1, int d2, int e1, int e2, float weights[2])
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
Definition: rna_define.c:2848
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
#define min(a, b)
Definition: sort.c:35
void * regiondata
struct ARegion * next
short regiontype
struct wmGizmoMap * gizmo_map
struct Base * next
struct Object * object
uint8_t f3
float vec[3][3]
uint8_t f1
uint8_t f2
struct EditFont * editfont
float textcurs[4][2]
Definition: BKE_vfont.h:36
struct ID * orig_id
Definition: DNA_ID.h:419
void * first
Definition: DNA_listBase.h:31
struct BoundBox * bb
char empty_drawtype
Object_Runtime runtime
float obmat[4][4]
float quat[4]
void * data
float viewquat[4]
float persmat[4][4]
float lviewquat[4]
struct wmTimer * smooth_timer
float viewinv[4][4]
View3DCursor cursor
struct Object * camera
ListBase spacedata
struct Object * camera
short scenelock
float clip_start
ListBase object_bases
struct Dial * dial
struct ViewOpsData::@578 curr
float viewquat[4]
struct RegionView3D * rv3d
struct wmTimer * timer
float dyn_ofs[3]
struct ViewOpsData::@577 prev
struct Depsgraph * depsgraph
struct ARegion * region
struct ViewOpsData::@576 init
float quat[4]
float trackvec[3]
int event_xy_offset[2]
struct ScrArea * area
struct Scene * scene
float mousevec[3]
struct Main * bmain
struct View3D * v3d
float ofs[3]
int xy[2]
Definition: WM_types.h:682
int mval[2]
Definition: WM_types.h:684
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
PropertyRNA * prop
Definition: WM_types.h:981
struct wmOperatorType * type
struct PointerRNA * ptr
struct wmWindow * win
Definition: WM_types.h:860
float max
bool ED_view3d_minmax_verts(struct Object *obedit, float min[3], float max[3])
Definition: view3d_snap.c:1000
void view3d_boxview_sync(struct ScrArea *area, struct ARegion *region)
Definition: view3d_utils.c:890
static void view3d_from_minmax_multi(bContext *C, View3D *v3d, const float min[3], const float max[3], const bool ok_dist, const int smooth_viewtx)
void VIEW3D_OT_view_axis(wmOperatorType *ot)
static int view_camera_exec(bContext *C, wmOperator *op)
static int view_axis_exec(bContext *C, wmOperator *op)
void view3d_operator_properties_common(wmOperatorType *ot, const enum eV3D_OpPropFlag flag)
void viewops_data_free(bContext *C, ViewOpsData *vod)
ViewOpsData * viewops_data_create(bContext *C, const wmEvent *event, enum eViewOpsFlag viewops_flag)
static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *region, const float min[3], const float max[3], bool ok_dist, const int smooth_viewtx)
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
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])
static int viewselected_exec(bContext *C, wmOperator *op)
static void axis_set_view(bContext *C, View3D *v3d, ARegion *region, const float quat_[4], char view, char view_axis_roll, int perspo, const float *align_to_quat, const int smooth_viewtx)
bool view3d_rotation_poll(bContext *C)
bool view3d_location_poll(bContext *C)
static int vieworbit_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_view_orbit_items[]
static bool view3d_object_skip_minmax(const View3D *v3d, const RegionView3D *rv3d, const Object *ob, const bool skip_camera, bool *r_only_center)
enum eViewOpsFlag viewops_flag_from_prefs(void)
bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void viewmove_apply(ViewOpsData *vod, int x, int y)
void calctrackballvec(const rcti *rect, const int event_xy[2], float r_dir[3])
void VIEW3D_OT_view_pan(wmOperatorType *ot)
static int view3d_all_exec(bContext *C, wmOperator *op)
static void view3d_object_calc_minmax(Depsgraph *depsgraph, Scene *scene, Object *ob_eval, const bool only_center, float min[3], float max[3])
void VIEW3D_OT_view_all(wmOperatorType *ot)
static bool view3d_navigation_poll_impl(bContext *C, const char viewlock)
static enum eViewOpsFlag viewops_flag_from_args(bool use_select, bool use_depth)
void VIEW3D_OT_view_selected(wmOperatorType *ot)
@ V3D_VIEW_STEPRIGHT
@ V3D_VIEW_STEPUP
@ V3D_VIEW_STEPLEFT
@ V3D_VIEW_STEPDOWN
static const EnumPropertyItem prop_view_items[]
void VIEW3D_OT_view_camera(wmOperatorType *ot)
void VIEW3D_OT_view_center_pick(wmOperatorType *ot)
void VIEW3D_OT_view_center_cursor(wmOperatorType *ot)
void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat_new[4])
static const EnumPropertyItem prop_view_pan_items[]
static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool view3d_zoom_or_dolly_poll(bContext *C)
@ V3D_VIEW_PANLEFT
@ V3D_VIEW_PANDOWN
@ V3D_VIEW_PANUP
@ V3D_VIEW_PANRIGHT
void ED_view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *region, int smooth_viewtx, const V3D_SmoothParams *sview)
eViewOpsFlag
@ VIEWOPS_FLAG_USE_MOUSE_INIT
@ VIEWOPS_FLAG_ORBIT_SELECT
@ VIEWOPS_FLAG_DEPTH_NAVIGATE
@ VIEWOPS_FLAG_PERSP_ENSURE
void ED_view3d_smooth_view_force_finish(struct bContext *C, struct View3D *v3d, struct ARegion *region)
eV3D_OpPropFlag
@ V3D_OP_PROP_USE_MOUSE_INIT
@ V3D_OP_PROP_DELTA
@ V3D_OP_PROP_USE_ALL_REGIONS
@ V3D_OP_PROP_MOUSE_CO
void ED_view3d_smooth_view_undo_end(struct bContext *C, struct ScrArea *area, const char *undo_str, bool undo_grouped)
void ED_view3d_smooth_view_undo_begin(struct bContext *C, struct ScrArea *area)
#define V3D_OP_TRACKBALLSIZE
wmOperatorType * ot
Definition: wm_files.c:3479
bool WM_gizmomap_is_any_selected(const wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:227
bool WM_gizmomap_minmax(const wmGizmoMap *gzmap, bool UNUSED(use_hidden), bool use_select, float r_min[3], float r_max[3])
Definition: wm_gizmo_map.c:237
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
void WM_operator_properties_use_cursor_init(wmOperatorType *ot)
int WM_operator_smooth_viewtx_get(const wmOperator *op)
void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer)
Definition: wm_window.c:1682