Blender  V2.93
view3d_utils.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include <float.h>
27 #include <math.h>
28 #include <stdio.h>
29 #include <string.h>
30 
31 #include "DNA_camera_types.h"
32 #include "DNA_curve_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_scene_types.h"
35 #include "DNA_world_types.h"
36 
37 #include "MEM_guardedalloc.h"
38 
39 #include "BLI_array_utils.h"
40 #include "BLI_bitmap_draw_2d.h"
41 #include "BLI_blenlib.h"
42 #include "BLI_math.h"
43 #include "BLI_utildefines.h"
44 
45 #include "BKE_camera.h"
46 #include "BKE_context.h"
47 #include "BKE_object.h"
48 #include "BKE_scene.h"
49 #include "BKE_screen.h"
50 
51 #include "DEG_depsgraph.h"
52 #include "DEG_depsgraph_query.h"
53 
54 #include "BIF_glutil.h"
55 
56 #include "GPU_matrix.h"
57 
58 #include "WM_api.h"
59 #include "WM_types.h"
60 
61 #include "ED_keyframing.h"
62 #include "ED_screen.h"
63 #include "ED_view3d.h"
64 
65 #include "UI_resources.h"
66 
67 #include "view3d_intern.h" /* own include */
68 
69 /* -------------------------------------------------------------------- */
73 void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float r_color[3])
74 {
76  if (scene->world) {
77  copy_v3_v3(r_color, &scene->world->horr);
78  return;
79  }
80  }
82  copy_v3_v3(r_color, v3d->shading.background_color);
83  return;
84  }
85 
86  UI_GetThemeColor3fv(TH_BACK, r_color);
87 }
88 
90  const Object *ob,
91  const View3D *v3d)
92 {
93  if (v3d->shading.type == OB_SOLID) {
95  return true;
96  }
97  if (ob && ob->mode == OB_MODE_TEXTURE_PAINT) {
98  return true;
99  }
100  }
101  else if (v3d->shading.type == OB_RENDER) {
104  }
105  }
106  return false;
107 }
108 
110 {
111  /* establish the camera object,
112  * so we can default to view mapping if anything is wrong with it */
113  if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
114  return v3d->camera->data;
115  }
116  return NULL;
117 }
118 
119 void ED_view3d_dist_range_get(const View3D *v3d, float r_dist_range[2])
120 {
121  r_dist_range[0] = v3d->grid * 0.001f;
122  r_dist_range[1] = v3d->clip_end * 10.0f;
123 }
124 
129  const View3D *v3d,
130  const RegionView3D *rv3d,
131  float *r_clipsta,
132  float *r_clipend,
133  const bool use_ortho_factor)
134 {
136 
139 
140  if (use_ortho_factor && params.is_ortho) {
141  const float fac = 2.0f / (params.clip_end - params.clip_start);
142  params.clip_start *= fac;
143  params.clip_end *= fac;
144  }
145 
146  if (r_clipsta) {
147  *r_clipsta = params.clip_start;
148  }
149  if (r_clipend) {
150  *r_clipend = params.clip_end;
151  }
152 
153  return params.is_ortho;
154 }
155 
157  const View3D *v3d,
158  const RegionView3D *rv3d,
159  int winx,
160  int winy,
161  rctf *r_viewplane,
162  float *r_clip_start,
163  float *r_clip_end,
164  float *r_pixsize)
165 {
167 
170  BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
171 
172  if (r_viewplane) {
173  *r_viewplane = params.viewplane;
174  }
175  if (r_clip_start) {
176  *r_clip_start = params.clip_start;
177  }
178  if (r_clip_end) {
179  *r_clip_end = params.clip_end;
180  }
181  if (r_pixsize) {
182  *r_pixsize = params.viewdx;
183  }
184 
185  return params.is_ortho;
186 }
187 
190 /* -------------------------------------------------------------------- */
199 {
200  wmWindow *win = CTX_wm_window(C);
201  ARegion *region = CTX_wm_region(C);
202 
204 }
205 
207 {
208  /* for debugging purpose, context should always be OK */
209  if ((region == NULL) || (region->regiontype != RGN_TYPE_WINDOW)) {
210  printf("view3d_region_operator_needs_opengl error, wrong region\n");
211  }
212  else {
213  RegionView3D *rv3d = region->regiondata;
214 
215  wmViewport(&region->winrct); /* TODO: bad */
217  GPU_matrix_set(rv3d->viewmat);
218  }
219 }
220 
224 void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
225 {
226  if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
227  return;
228  }
229 
230  float viewdist = rv3d->dist;
231 
232  /* Special exception for orthographic camera (`viewdist` isn't used for perspective cameras). */
233  if (dist != 0.0f) {
234  if (rv3d->persp == RV3D_CAMOB) {
235  if (rv3d->is_persp == false) {
236  viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
237  }
238  }
239  }
240 
241  GPU_polygon_offset(viewdist, dist);
242 }
243 
245 {
246  bScreen *screen = CTX_wm_screen(C);
248 
249  /* area can be NULL when called from python */
250  if (area == NULL || area->spacetype != SPACE_VIEW3D) {
252  }
253 
254  if (area == NULL) {
255  return false;
256  }
257 
259  if (region == NULL) {
260  return false;
261  }
262 
263  /* bad context switch .. */
265  CTX_wm_region_set(C, region);
266 
267  return true;
268 }
269 
272 /* -------------------------------------------------------------------- */
277  const BoundBox *bb,
278  const bool is_flip)
279 {
280  for (int val = 0; val < 4; val++) {
281  normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
282  if (UNLIKELY(is_flip)) {
283  negate_v3(clip[val]);
284  }
285 
286  clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
287  }
288 }
289 
291  BoundBox *bb, float planes[4][4], const ARegion *region, const Object *ob, const rcti *rect)
292 {
293  /* init in case unproject fails */
294  memset(bb->vec, 0, sizeof(bb->vec));
295 
296  /* four clipping planes and bounding volume */
297  /* first do the bounding volume */
298  for (int val = 0; val < 4; val++) {
299  float xs = (ELEM(val, 0, 3)) ? rect->xmin : rect->xmax;
300  float ys = (ELEM(val, 0, 1)) ? rect->ymin : rect->ymax;
301 
302  ED_view3d_unproject(region, xs, ys, 0.0, bb->vec[val]);
303  ED_view3d_unproject(region, xs, ys, 1.0, bb->vec[4 + val]);
304  }
305 
306  /* optionally transform to object space */
307  if (ob) {
308  float imat[4][4];
309  invert_m4_m4(imat, ob->obmat);
310 
311  for (int val = 0; val < 8; val++) {
312  mul_m4_v3(imat, bb->vec[val]);
313  }
314  }
315 
316  /* verify if we have negative scale. doing the transform before cross
317  * product flips the sign of the vector compared to doing cross product
318  * before transform then, so we correct for that. */
319  int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
320 
321  ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
322 }
323 
326 /* -------------------------------------------------------------------- */
331  float min[3];
332  float max[3];
333 };
334 
336  const float co[3], int UNUSED(i), int UNUSED(j), int UNUSED(k), void *user_data_p)
337 {
338  struct PointsInPlanesMinMax_UserData *user_data = user_data_p;
339  minmax_v3v3_v3(user_data->min, user_data->max, co);
340 }
341 
354 bool ED_view3d_clipping_clamp_minmax(const RegionView3D *rv3d, float min[3], float max[3])
355 {
356  /* 6 planes for the cube, 4..6 for the current view clipping planes. */
357  float planes[6 + 6][4];
358 
359  /* Convert the min/max to 6 planes. */
360  for (int i = 0; i < 3; i++) {
361  float *plane_min = planes[(i * 2) + 0];
362  float *plane_max = planes[(i * 2) + 1];
363  zero_v3(plane_min);
364  zero_v3(plane_max);
365  plane_min[i] = -1.0f;
366  plane_min[3] = +min[i];
367  plane_max[i] = +1.0f;
368  plane_max[3] = -max[i];
369  }
370 
371  /* Copy planes from the viewport & flip. */
372  int planes_len = 6;
373  int clip_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6;
374  for (int i = 0; i < clip_len; i++) {
375  negate_v4_v4(planes[planes_len], rv3d->clip[i]);
376  planes_len += 1;
377  }
378 
379  /* Calculate points intersecting all planes (effectively intersecting two bounding boxes). */
381  INIT_MINMAX(user_data.min, user_data.max);
382 
383  const float eps_coplanar = 1e-4f;
384  const float eps_isect = 1e-6f;
385  if (isect_planes_v3_fn(
386  planes, planes_len, eps_coplanar, eps_isect, points_in_planes_minmax_fn, &user_data)) {
387  copy_v3_v3(min, user_data.min);
388  copy_v3_v3(max, user_data.max);
389  return true;
390  }
391  return false;
392 }
393 
396 /* -------------------------------------------------------------------- */
400 static bool view3d_boundbox_clip_m4(const BoundBox *bb, const float persmatob[4][4])
401 {
402  int a, flag = -1, fl;
403 
404  for (a = 0; a < 8; a++) {
405  float vec[4], min, max;
406  copy_v3_v3(vec, bb->vec[a]);
407  vec[3] = 1.0;
408  mul_m4_v4(persmatob, vec);
409  max = vec[3];
410  min = -vec[3];
411 
412  fl = 0;
413  if (vec[0] < min) {
414  fl += 1;
415  }
416  if (vec[0] > max) {
417  fl += 2;
418  }
419  if (vec[1] < min) {
420  fl += 4;
421  }
422  if (vec[1] > max) {
423  fl += 8;
424  }
425  if (vec[2] < min) {
426  fl += 16;
427  }
428  if (vec[2] > max) {
429  fl += 32;
430  }
431 
432  flag &= fl;
433  if (flag == 0) {
434  return true;
435  }
436  }
437 
438  return false;
439 }
440 
441 bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
442 {
443  /* return 1: draw */
444 
445  float persmatob[4][4];
446 
447  if (bb == NULL) {
448  return true;
449  }
450  if (bb->flag & BOUNDBOX_DISABLED) {
451  return true;
452  }
453 
454  mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
455 
456  return view3d_boundbox_clip_m4(bb, persmatob);
457 }
458 
460 {
461  if (bb == NULL) {
462  return true;
463  }
464  if (bb->flag & BOUNDBOX_DISABLED) {
465  return true;
466  }
467 
468  return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
469 }
470 
473 /* -------------------------------------------------------------------- */
479 bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
480 {
481  return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_center_cursor || v3d->ob_center);
482 }
483 
488 {
489  copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
490  rv3d->lview = rv3d->view;
491  rv3d->lview_axis_roll = rv3d->view_axis_roll;
492  if (rv3d->persp != RV3D_CAMOB) {
493  rv3d->lpersp = rv3d->persp;
494  }
495 }
496 
498 {
499  v3d->ob_center = NULL;
500  v3d->ob_center_bone[0] = '\0';
501  v3d->ob_center_cursor = false;
502 
503  v3d->flag2 &= ~V3D_LOCK_CAMERA;
504 }
505 
514  View3D *v3d,
515  RegionView3D *rv3d,
516  const char persp)
517 {
518  BLI_assert(rv3d->persp == RV3D_CAMOB);
519  BLI_assert(persp != RV3D_CAMOB);
520 
521  if (v3d->camera) {
522  Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
523  rv3d->dist = ED_view3d_offset_distance(ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
524  ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
525  }
526 
527  if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
528  rv3d->persp = persp;
529  }
530 }
538 {
539  RegionView3D *rv3d = region->regiondata;
540  const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
541 
543 
544  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
545  return false;
546  }
547 
548  if (rv3d->persp != RV3D_PERSP) {
549  if (rv3d->persp == RV3D_CAMOB) {
550  /* If autopersp and previous view was an axis one,
551  * switch back to PERSP mode, else reuse previous mode. */
552  char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
554  }
555  else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
556  rv3d->persp = RV3D_PERSP;
557  }
558  return true;
559  }
560 
561  return false;
562 }
563 
566 /* -------------------------------------------------------------------- */
575 bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
576 {
577  return ((v3d->camera) && (!ID_IS_LINKED(v3d->camera)) && (v3d->flag2 & V3D_LOCK_CAMERA) &&
578  (rv3d->persp == RV3D_CAMOB));
579 }
580 
586  View3D *v3d,
587  RegionView3D *rv3d,
588  const bool calc_dist)
589 {
590  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
591  Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
592  if (calc_dist) {
593  /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
595  ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
596  }
597  ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
598  }
599 }
600 
602 {
603  ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, true);
604 }
605 
612 {
613  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
615  Object *root_parent;
616 
618  (root_parent = v3d->camera->parent)) {
619  Object *ob_update;
620  float tmat[4][4];
621  float imat[4][4];
622  float view_mat[4][4];
623  float diff_mat[4][4];
624  float parent_mat[4][4];
625 
626  while (root_parent->parent) {
627  root_parent = root_parent->parent;
628  }
629  Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
630  Object *root_parent_eval = DEG_get_evaluated_object(depsgraph, root_parent);
631 
632  ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
633 
634  normalize_m4_m4(tmat, ob_camera_eval->obmat);
635 
636  invert_m4_m4(imat, tmat);
637  mul_m4_m4m4(diff_mat, view_mat, imat);
638 
639  mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->obmat);
640 
641  BKE_object_tfm_protected_backup(root_parent, &obtfm);
642  BKE_object_apply_mat4(root_parent, parent_mat, true, false);
643  BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
644 
645  ob_update = v3d->camera;
646  while (ob_update) {
649  ob_update = ob_update->parent;
650  }
651  }
652  else {
653  /* always maintain the same scale */
654  const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
656  ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
658  v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
659 
662  }
663 
664  return true;
665  }
666  return false;
667 }
668 
670  ID *id_key,
671  struct bContext *C,
672  const bool do_rotate,
673  const bool do_translate)
674 {
675  if (autokeyframe_cfra_can_key(scene, id_key)) {
676  const float cfra = (float)CFRA;
677  ListBase dsources = {NULL, NULL};
678 
679  /* add data-source override for the camera object */
680  ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
681 
682  /* insert keyframes
683  * 1) on the first frame
684  * 2) on each subsequent frame
685  * TODO: need to check in future that frame changed before doing this
686  */
687  if (do_rotate) {
689  ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
690  }
691  if (do_translate) {
693  ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
694  }
695 
696  /* free temp data */
697  BLI_freelistN(&dsources);
698 
699  return true;
700  }
701  return false;
702 }
703 
711  RegionView3D *rv3d,
712  struct bContext *C,
713  const bool do_rotate,
714  const bool do_translate)
715 {
716  /* similar to ED_view3d_cameracontrol_update */
717  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
719  ID *id_key;
720  Object *root_parent;
722  (root_parent = v3d->camera->parent)) {
723  while (root_parent->parent) {
724  root_parent = root_parent->parent;
725  }
726  id_key = &root_parent->id;
727  }
728  else {
729  id_key = &v3d->camera->id;
730  }
731 
732  return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
733  }
734  return false;
735 }
736 
739 /* -------------------------------------------------------------------- */
746 {
747  BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
748  float clip[6][4];
749  float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
750 
751  /* create bounding box */
752  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
753  if (region->regiontype == RGN_TYPE_WINDOW) {
754  RegionView3D *rv3d = region->regiondata;
755 
756  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) {
757  if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
758  if (region->winx > region->winy) {
759  x1 = rv3d->dist;
760  }
761  else {
762  x1 = region->winx * rv3d->dist / region->winy;
763  }
764 
765  if (region->winx > region->winy) {
766  y1 = region->winy * rv3d->dist / region->winx;
767  }
768  else {
769  y1 = rv3d->dist;
770  }
771  copy_v2_v2(ofs, rv3d->ofs);
772  }
773  else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
774  ofs[2] = rv3d->ofs[2];
775 
776  if (region->winx > region->winy) {
777  z1 = region->winy * rv3d->dist / region->winx;
778  }
779  else {
780  z1 = rv3d->dist;
781  }
782  }
783  }
784  }
785  }
786 
787  for (int val = 0; val < 8; val++) {
788  if (ELEM(val, 0, 3, 4, 7)) {
789  bb->vec[val][0] = -x1 - ofs[0];
790  }
791  else {
792  bb->vec[val][0] = x1 - ofs[0];
793  }
794 
795  if (ELEM(val, 0, 1, 4, 5)) {
796  bb->vec[val][1] = -y1 - ofs[1];
797  }
798  else {
799  bb->vec[val][1] = y1 - ofs[1];
800  }
801 
802  if (val > 3) {
803  bb->vec[val][2] = -z1 - ofs[2];
804  }
805  else {
806  bb->vec[val][2] = z1 - ofs[2];
807  }
808  }
809 
810  /* normals for plane equations */
811  normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
812  normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
813  normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
814  normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
815  normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
816  normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
817 
818  /* then plane equations */
819  for (int val = 0; val < 6; val++) {
820  clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
821  }
822 
823  /* create bounding box */
824  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
825  if (region->regiontype == RGN_TYPE_WINDOW) {
826  RegionView3D *rv3d = region->regiondata;
827 
828  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) {
829  rv3d->rflag |= RV3D_CLIPPING;
830  memcpy(rv3d->clip, clip, sizeof(clip));
831  if (rv3d->clipbb) {
832  MEM_freeN(rv3d->clipbb);
833  }
834  rv3d->clipbb = MEM_dupallocN(bb);
835  }
836  }
837  }
838  MEM_freeN(bb);
839 }
840 
845 static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
846 {
847  /* absolute axis values above this are considered to be set (will be ~1.0f) */
848  const float axis_eps = 0.5f;
849  float viewinv[4];
850 
851  /* use the view rotation to identify which axis to sync on */
852  float view_axis_all[4][3] = {
853  {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}};
854 
855  float *view_src_x = &view_axis_all[0][0];
856  float *view_src_y = &view_axis_all[1][0];
857 
858  float *view_dst_x = &view_axis_all[2][0];
859  float *view_dst_y = &view_axis_all[3][0];
860  int i;
861 
862  /* we could use rv3d->viewinv, but better not depend on view matrix being updated */
863  if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, rv3d_src->view_axis_roll, viewinv) ==
864  false)) {
865  return;
866  }
867  invert_qt_normalized(viewinv);
868  mul_qt_v3(viewinv, view_src_x);
869  mul_qt_v3(viewinv, view_src_y);
870 
871  if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, rv3d_dst->view_axis_roll, viewinv) ==
872  false)) {
873  return;
874  }
875  invert_qt_normalized(viewinv);
876  mul_qt_v3(viewinv, view_dst_x);
877  mul_qt_v3(viewinv, view_dst_y);
878 
879  /* check source and dest have a matching axis */
880  for (i = 0; i < 3; i++) {
881  if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
882  ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps))) {
883  rv3d_dst->ofs[i] = rv3d_src->ofs[i];
884  }
885  }
886 }
887 
888 /* sync center/zoom view of region to others, for view transforms */
890 {
891  RegionView3D *rv3d = region->regiondata;
892  short clip = 0;
893 
894  LISTBASE_FOREACH (ARegion *, region_test, &area->regionbase) {
895  if (region_test != region && region_test->regiontype == RGN_TYPE_WINDOW) {
896  RegionView3D *rv3dtest = region_test->regiondata;
897 
898  if (RV3D_LOCK_FLAGS(rv3dtest) & RV3D_LOCK_ROTATION) {
899  rv3dtest->dist = rv3d->dist;
900  view3d_boxview_sync_axis(rv3dtest, rv3d);
901  clip |= RV3D_LOCK_FLAGS(rv3dtest) & RV3D_BOXCLIP;
902 
903  ED_region_tag_redraw(region_test);
904  }
905  }
906  }
907 
908  if (clip) {
910  }
911 }
912 
913 /* for home, center etc */
915 {
916  RegionView3D *rv3d = region->regiondata;
917  bool clip = false;
918 
919  LISTBASE_FOREACH (ARegion *, region_test, &area->regionbase) {
920  if (region_test != region && region_test->regiontype == RGN_TYPE_WINDOW) {
921  RegionView3D *rv3dtest = region_test->regiondata;
922 
923  if (RV3D_LOCK_FLAGS(rv3dtest)) {
924  rv3dtest->dist = rv3d->dist;
925  copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
926  ED_region_tag_redraw(region_test);
927 
928  clip |= ((RV3D_LOCK_FLAGS(rv3dtest) & RV3D_BOXCLIP) != 0);
929  }
930  }
931  }
932 
933  if (clip) {
935  }
936 }
937 
938 /* 'clip' is used to know if our clip setting has changed */
939 void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
940 {
941  ARegion *region_sync = NULL;
942  RegionView3D *rv3d = region->regiondata;
943  /* this function copies flags from the first of the 3 other quadview
944  * regions to the 2 other, so it assumes this is the region whose
945  * properties are always being edited, weak */
946  short viewlock = rv3d->viewlock;
947 
948  if ((viewlock & RV3D_LOCK_ROTATION) == 0) {
949  do_clip = (viewlock & RV3D_BOXCLIP) != 0;
950  viewlock = 0;
951  }
952  else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
953  do_clip = true;
954  viewlock &= ~RV3D_BOXCLIP;
955  }
956 
957  for (; region; region = region->prev) {
958  if (region->alignment == RGN_ALIGN_QSPLIT) {
959  rv3d = region->regiondata;
960  rv3d->viewlock = viewlock;
961 
962  if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
963  rv3d->rflag &= ~RV3D_BOXCLIP;
964  }
965 
966  /* use region_sync so we sync with one of the aligned views below
967  * else the view jumps on changing view settings like 'clip'
968  * since it copies from the perspective view */
969  region_sync = region;
970  }
971  }
972 
973  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
974  view3d_boxview_sync(area, region_sync ? region_sync : area->regionbase.last);
975  }
976 
977  /* ensure locked regions have an axis, locked user views don't make much sense */
978  if (viewlock & RV3D_LOCK_ROTATION) {
979  int index_qsplit = 0;
980  for (region = area->regionbase.first; region; region = region->next) {
981  if (region->alignment == RGN_ALIGN_QSPLIT) {
982  rv3d = region->regiondata;
983  if (rv3d->viewlock) {
984  if (!RV3D_VIEW_IS_AXIS(rv3d->view) || (rv3d->view_axis_roll != RV3D_VIEW_AXIS_ROLL_0)) {
985  rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
987  rv3d->persp = RV3D_ORTHO;
988  ED_view3d_lock(rv3d);
989  }
990  }
991  index_qsplit++;
992  }
993  }
994  }
995 
997 }
998 
1001 /* -------------------------------------------------------------------- */
1005 static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin)
1006 {
1007  rcti rect;
1008  if (margin == 0) {
1009  /* Get Z Depths, needed for perspective, nice for ortho */
1010  rect.xmin = mval[0];
1011  rect.ymin = mval[1];
1012  rect.xmax = mval[0] + 1;
1013  rect.ymax = mval[1] + 1;
1014  }
1015  else {
1016  BLI_rcti_init_pt_radius(&rect, mval, margin);
1017  }
1018 
1019  ViewDepths depth_temp = {0};
1020  view3d_update_depths_rect(region, &depth_temp, &rect);
1021  float depth_close = view3d_depth_near(&depth_temp);
1022  MEM_SAFE_FREE(depth_temp.depths);
1023  return depth_close;
1024 }
1025 
1035  ARegion *region,
1036  View3D *v3d,
1037  const int mval[2],
1038  float mouse_worldloc[3],
1039  const bool UNUSED(alphaoverride),
1040  const float fallback_depth_pt[3])
1041 {
1042  float depth_close;
1043  int margin_arr[] = {0, 2, 4};
1044  bool depth_ok = false;
1045 
1046  /* Get Z Depths, needed for perspective, nice for ortho */
1048 
1049  /* Attempt with low margin's first */
1050  int i = 0;
1051  do {
1052  depth_close = view_autodist_depth_margin(region, mval, margin_arr[i++] * U.pixelsize);
1053  depth_ok = (depth_close != FLT_MAX);
1054  } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
1055 
1056  if (depth_ok) {
1057  float centx = (float)mval[0] + 0.5f;
1058  float centy = (float)mval[1] + 0.5f;
1059 
1060  if (ED_view3d_unproject(region, centx, centy, depth_close, mouse_worldloc)) {
1061  return true;
1062  }
1063  }
1064 
1065  if (fallback_depth_pt) {
1066  ED_view3d_win_to_3d_int(v3d, region, fallback_depth_pt, mval, mouse_worldloc);
1067  return true;
1068  }
1069  return false;
1070 }
1071 
1072 /* no 4x4 sampling, run #ED_view3d_depth_override first */
1074  const int mval[2],
1075  float mouse_worldloc[3],
1076  int margin,
1077  const float *force_depth)
1078 {
1079  /* Get Z Depths, needed for perspective, nice for ortho */
1080  float depth;
1081  if (force_depth) {
1082  depth = *force_depth;
1083  }
1084  else {
1085  depth = view_autodist_depth_margin(region, mval, margin);
1086  }
1087 
1088  if (depth == FLT_MAX) {
1089  return false;
1090  }
1091 
1092  float centx = (float)mval[0] + 0.5f;
1093  float centy = (float)mval[1] + 0.5f;
1094  return ED_view3d_unproject(region, centx, centy, depth, mouse_worldloc);
1095 }
1096 
1097 bool ED_view3d_autodist_depth(ARegion *region, const int mval[2], int margin, float *depth)
1098 {
1099  *depth = view_autodist_depth_margin(region, mval, margin);
1100 
1101  return (*depth != FLT_MAX);
1102 }
1103 
1104 static bool depth_segment_cb(int x, int y, void *userData)
1105 {
1106  struct {
1107  ARegion *region;
1108  int margin;
1109  float depth;
1110  } *data = userData;
1111  int mval[2];
1112  float depth;
1113 
1114  mval[0] = x;
1115  mval[1] = y;
1116 
1117  depth = view_autodist_depth_margin(data->region, mval, data->margin);
1118 
1119  if (depth != FLT_MAX) {
1120  data->depth = depth;
1121  return false;
1122  }
1123  return true;
1124 }
1125 
1127  ARegion *region, const int mval_sta[2], const int mval_end[2], int margin, float *depth)
1128 {
1129  struct {
1130  ARegion *region;
1131  int margin;
1132  float depth;
1133  } data = {NULL};
1134  int p1[2];
1135  int p2[2];
1136 
1137  data.region = region;
1138  data.margin = margin;
1139  data.depth = FLT_MAX;
1140 
1141  copy_v2_v2_int(p1, mval_sta);
1142  copy_v2_v2_int(p2, mval_end);
1143 
1145 
1146  *depth = data.depth;
1147 
1148  return (*depth != FLT_MAX);
1149 }
1150 
1153 /* -------------------------------------------------------------------- */
1159 float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
1160 {
1161  return radius * (1.0f / tanf(angle / 2.0f));
1162 }
1163 
1164 float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
1165 {
1166  return radius / (DEFAULT_SENSOR_WIDTH / lens);
1167 }
1168 
1195  const ARegion *region,
1196  const struct Depsgraph *depsgraph,
1197  const char persp,
1198  const bool use_aspect,
1199  const float radius)
1200 {
1201  float dist;
1202 
1204  BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
1205 
1206  if (persp == RV3D_ORTHO) {
1207  dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
1208  }
1209  else {
1210  float lens, sensor_size, zoom;
1211 
1212  if (persp == RV3D_CAMOB) {
1215  params.clip_start = v3d->clip_start;
1216  params.clip_end = v3d->clip_end;
1217  Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
1218  BKE_camera_params_from_object(&params, camera_eval);
1219 
1220  lens = params.lens;
1221  sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
1222 
1223  /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
1225  }
1226  else {
1227  lens = v3d->lens;
1228  sensor_size = DEFAULT_SENSOR_WIDTH;
1230  }
1231 
1232  float angle = focallength_to_fov(lens, sensor_size);
1233 
1234  /* zoom influences lens, correct this by scaling the angle as a distance
1235  * (by the zoom-level) */
1236  angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
1237 
1238  dist = ED_view3d_radius_to_dist_persp(angle, radius);
1239  }
1240 
1241  if (use_aspect) {
1242  const RegionView3D *rv3d = region->regiondata;
1243 
1244  float winx, winy;
1245 
1246  if (persp == RV3D_CAMOB) {
1247  /* camera frame x/y in pixels */
1248  winx = region->winx / rv3d->viewcamtexcofac[0];
1249  winy = region->winy / rv3d->viewcamtexcofac[1];
1250  }
1251  else {
1252  winx = region->winx;
1253  winy = region->winy;
1254  }
1255 
1256  if (winx && winy) {
1257  float aspect = winx / winy;
1258  if (aspect < 1.0f) {
1259  aspect = 1.0f / aspect;
1260  }
1261  dist *= aspect;
1262  }
1263  }
1264 
1265  return dist;
1266 }
1267 
1270 /* -------------------------------------------------------------------- */
1286 float ED_view3d_offset_distance(const float mat[4][4],
1287  const float ofs[3],
1288  const float fallback_dist)
1289 {
1290  float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
1291  float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
1292 
1293  mul_m4_v4(mat, pos);
1294  add_v3_v3(pos, ofs);
1295  mul_m4_v4(mat, dir);
1296  normalize_v3(dir);
1297 
1298  float dist = dot_v3v3(pos, dir);
1299 
1300  if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
1301  dist = fallback_dist;
1302  }
1303 
1304  return dist;
1305 }
1306 
1312 void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
1313 {
1314  float viewinv[4];
1315  float tvec[3];
1316 
1317  BLI_assert(dist >= 0.0f);
1318 
1319  copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
1320  /* rv3d->viewinv isn't always valid */
1321 #if 0
1322  mul_mat3_m4_v3(rv3d->viewinv, tvec);
1323 #else
1324  invert_qt_qt_normalized(viewinv, rv3d->viewquat);
1325  mul_qt_v3(viewinv, tvec);
1326 #endif
1327  sub_v3_v3(rv3d->ofs, tvec);
1328 
1329  rv3d->dist = dist;
1330 }
1331 
1340  const float dist_co[3],
1341  const float dist_min)
1342 {
1343  float viewinv[4];
1344  invert_qt_qt_normalized(viewinv, rv3d->viewquat);
1345 
1346  float tvec[3] = {0.0f, 0.0f, -1.0f};
1347  mul_qt_v3(viewinv, tvec);
1348 
1349  float dist_co_local[3];
1350  negate_v3_v3(dist_co_local, rv3d->ofs);
1351  sub_v3_v3v3(dist_co_local, dist_co, dist_co_local);
1352  const float delta = dot_v3v3(tvec, dist_co_local);
1353  const float dist_new = rv3d->dist + delta;
1354  if (dist_new >= dist_min) {
1355  madd_v3_v3fl(rv3d->ofs, tvec, -delta);
1356  rv3d->dist = dist_new;
1357  return true;
1358  }
1359  return false;
1360 }
1361 
1364 /* -------------------------------------------------------------------- */
1371 static float view3d_quat_axis[6][4][4] = {
1372  /* RV3D_VIEW_FRONT */
1373  {
1374  {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f},
1375  {0.5f, -0.5f, -0.5f, 0.5f},
1376  {0, 0, -M_SQRT1_2, M_SQRT1_2},
1377  {-0.5f, 0.5f, -0.5f, 0.5f},
1378  },
1379  /* RV3D_VIEW_BACK */
1380  {
1381  {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2},
1382  {0.5f, 0.5f, -0.5f, -0.5f},
1383  {M_SQRT1_2, M_SQRT1_2, 0, 0},
1384  {0.5f, 0.5f, 0.5f, 0.5f},
1385  },
1386  /* RV3D_VIEW_LEFT */
1387  {
1388  {0.5f, -0.5f, 0.5f, 0.5f},
1389  {0, -M_SQRT1_2, 0.0f, M_SQRT1_2},
1390  {-0.5f, -0.5f, -0.5f, 0.5f},
1391  {-M_SQRT1_2, 0, -M_SQRT1_2, 0},
1392  },
1393 
1394  /* RV3D_VIEW_RIGHT */
1395  {
1396  {0.5f, -0.5f, -0.5f, -0.5f},
1397  {M_SQRT1_2, 0, -M_SQRT1_2, 0},
1398  {0.5f, 0.5f, -0.5f, 0.5f},
1399  {0, M_SQRT1_2, 0, M_SQRT1_2},
1400  },
1401  /* RV3D_VIEW_TOP */
1402  {
1403  {1.0f, 0.0f, 0.0f, 0.0f},
1404  {M_SQRT1_2, 0, 0, M_SQRT1_2},
1405  {0, 0, 0, 1},
1406  {-M_SQRT1_2, 0, 0, M_SQRT1_2},
1407  },
1408  /* RV3D_VIEW_BOTTOM */
1409  {
1410  {0.0f, -1.0f, 0.0f, 0.0f},
1411  {0, -M_SQRT1_2, -M_SQRT1_2, 0},
1412  {0, 0, -1, 0},
1413  {0, M_SQRT1_2, -M_SQRT1_2, 0},
1414  },
1415 
1416 };
1417 
1418 bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float r_quat[4])
1419 {
1420  BLI_assert(view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270);
1421  if (RV3D_VIEW_IS_AXIS(view)) {
1422  copy_qt_qt(r_quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll]);
1423  return true;
1424  }
1425  return false;
1426 }
1427 
1428 bool ED_view3d_quat_to_axis_view(const float quat[4],
1429  const float epsilon,
1430  char *r_view,
1431  char *r_view_axis_roll)
1432 {
1433  *r_view = RV3D_VIEW_USER;
1434  *r_view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
1435 
1436  /* quat values are all unit length */
1437  for (int view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
1438  for (int view_axis_roll = RV3D_VIEW_AXIS_ROLL_0; view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270;
1439  view_axis_roll++) {
1441  quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll])) < epsilon) {
1442  *r_view = view;
1443  *r_view_axis_roll = view_axis_roll;
1444  return true;
1445  }
1446  }
1447  }
1448 
1449  return false;
1450 }
1451 
1453 {
1454  switch (index) {
1455  case 0:
1456  return RV3D_VIEW_FRONT;
1457  case 1:
1458  return RV3D_VIEW_TOP;
1459  case 2:
1460  return RV3D_VIEW_RIGHT;
1461  default:
1462  return RV3D_VIEW_USER;
1463  }
1464 }
1465 
1467 {
1468  switch (view) {
1469  case RV3D_VIEW_FRONT:
1470  return RV3D_VIEW_BACK;
1471  case RV3D_VIEW_BACK:
1472  return RV3D_VIEW_FRONT;
1473  case RV3D_VIEW_LEFT:
1474  return RV3D_VIEW_RIGHT;
1475  case RV3D_VIEW_RIGHT:
1476  return RV3D_VIEW_LEFT;
1477  case RV3D_VIEW_TOP:
1478  return RV3D_VIEW_BOTTOM;
1479  case RV3D_VIEW_BOTTOM:
1480  return RV3D_VIEW_TOP;
1481  }
1482 
1483  return RV3D_VIEW_USER;
1484 }
1485 
1487 {
1488  return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->view_axis_roll, rv3d->viewquat);
1489 }
1490 
1493 /* -------------------------------------------------------------------- */
1505 void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const float *dist)
1506 {
1507  float nmat[3][3];
1508 
1509  /* dist depends on offset */
1510  BLI_assert(dist == NULL || ofs != NULL);
1511 
1512  copy_m3_m4(nmat, mat);
1513  normalize_m3(nmat);
1514 
1515  /* Offset */
1516  if (ofs) {
1517  negate_v3_v3(ofs, mat[3]);
1518  }
1519 
1520  /* Quat */
1521  if (quat) {
1522  mat3_normalized_to_quat(quat, nmat);
1523  invert_qt_normalized(quat);
1524  }
1525 
1526  if (ofs && dist) {
1527  madd_v3_v3fl(ofs, nmat[2], *dist);
1528  }
1529 }
1530 
1539 void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
1540 {
1541  const float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
1542  float dvec[3] = {0.0f, 0.0f, dist};
1543 
1544  quat_to_mat4(mat, iviewquat);
1545  mul_mat3_m4_v3(mat, dvec);
1546  sub_v3_v3v3(mat[3], dvec, ofs);
1547 }
1548 
1557 void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
1558 {
1559  ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
1560 
1561  if (lens) {
1563 
1566  *lens = params.lens;
1567  }
1568 }
1569 
1580  Object *ob,
1581  const float ofs[3],
1582  const float quat[4],
1583  const float dist)
1584 {
1585  float mat[4][4];
1586  ED_view3d_to_m4(mat, ofs, quat, dist);
1587 
1588  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
1589  BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true);
1590 }
1591 
1594  const Scene *scene,
1595  Object *camera_ob)
1596 {
1597  Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
1598  float co[3]; /* the new location to apply */
1599  float scale; /* only for ortho cameras */
1600 
1601  if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, co, &scale)) {
1603  float obmat_new[4][4];
1604 
1605  if ((camera_ob_eval->type == OB_CAMERA) &&
1606  (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
1607  ((Camera *)camera_ob->data)->ortho_scale = scale;
1608  }
1609 
1610  copy_m4_m4(obmat_new, camera_ob_eval->obmat);
1611  copy_v3_v3(obmat_new[3], co);
1612 
1613  /* only touch location */
1614  BKE_object_tfm_protected_backup(camera_ob, &obtfm);
1615  BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
1617 
1618  /* notifiers */
1619  DEG_id_tag_update_ex(bmain, &camera_ob->id, ID_RECALC_TRANSFORM);
1620 
1621  return true;
1622  }
1623 
1624  return false;
1625 }
1626 
1629 /* -------------------------------------------------------------------- */
1633 struct ReadData {
1634  int count;
1636  float r_depth;
1637 };
1638 
1639 static bool depth_read_test_fn(const void *value, void *userdata)
1640 {
1641  struct ReadData *data = userdata;
1642  float depth = *(float *)value;
1643  if (depth < data->r_depth) {
1644  data->r_depth = depth;
1645  }
1646 
1647  if ((++data->count) >= data->count_max) {
1648  /* Outside the margin. */
1649  return true;
1650  }
1651  return false;
1652 }
1653 
1655  const int mval[2],
1656  int margin,
1657  float *r_depth)
1658 {
1659  if (!vd || !vd->depths) {
1660  return false;
1661  }
1662 
1663  int x = mval[0];
1664  int y = mval[1];
1665  if (x < 0 || y < 0 || x >= vd->w || y >= vd->h) {
1666  return false;
1667  }
1668 
1669  float depth = 1.0f;
1670  if (margin) {
1671  int shape[2] = {vd->w, vd->h};
1672  int pixel_count = (min_ii(x + margin + 1, shape[1]) - max_ii(x - margin, 0)) *
1673  (min_ii(y + margin + 1, shape[0]) - max_ii(y - margin, 0));
1674 
1675  struct ReadData data;
1676  data.count = 0;
1677  data.count_max = pixel_count;
1678  data.r_depth = 1.0f;
1679 
1680  /* TODO: No need to go spiral. */
1682  depth = data.r_depth;
1683  }
1684  else {
1685  depth = vd->depths[y * vd->w + x];
1686  }
1687 
1688  BLI_assert(1.0 <= vd->depth_range[1]);
1689  if (depth != 1.0f) {
1690  *r_depth = depth;
1691  return true;
1692  }
1693 
1694  return false;
1695 }
1696 
1698  const int mval[2],
1699  float r_normal[3])
1700 {
1701  /* Note: we could support passing in a radius.
1702  * For now just read 9 pixels. */
1703 
1704  /* pixels surrounding */
1705  bool depths_valid[9] = {false};
1706  float coords[9][3] = {{0}};
1707 
1708  ARegion *region = vc->region;
1709  const ViewDepths *depths = vc->rv3d->depths;
1710 
1711  for (int x = 0, i = 0; x < 2; x++) {
1712  for (int y = 0; y < 2; y++) {
1713  const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
1714 
1715  float depth_fl = 1.0f;
1716  ED_view3d_depth_read_cached(depths, mval_ofs, 0, &depth_fl);
1717  const double depth = (double)depth_fl;
1718  if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
1719  if (ED_view3d_depth_unproject(region, mval_ofs, depth, coords[i])) {
1720  depths_valid[i] = true;
1721  }
1722  }
1723  i++;
1724  }
1725  }
1726 
1727  const int edges[2][6][2] = {
1728  /* x edges */
1729  {{0, 1}, {1, 2}, {3, 4}, {4, 5}, {6, 7}, {7, 8}},
1730  /* y edges */
1731  {{0, 3}, {3, 6}, {1, 4}, {4, 7}, {2, 5}, {5, 8}},
1732  };
1733 
1734  float cross[2][3] = {{0.0f}};
1735 
1736  for (int i = 0; i < 6; i++) {
1737  for (int axis = 0; axis < 2; axis++) {
1738  if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
1739  float delta[3];
1740  sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
1741  add_v3_v3(cross[axis], delta);
1742  }
1743  }
1744  }
1745 
1746  cross_v3_v3v3(r_normal, cross[0], cross[1]);
1747 
1748  if (normalize_v3(r_normal) != 0.0f) {
1749  return true;
1750  }
1751  return false;
1752 }
1753 
1755  const int mval[2],
1756  const double depth,
1757  float r_location_world[3])
1758 {
1759  float centx = (float)mval[0] + 0.5f;
1760  float centy = (float)mval[1] + 0.5f;
1761  return ED_view3d_unproject(region, centx, centy, depth, r_location_world);
1762 }
1763 
1765 {
1766  if (rv3d->depths) {
1767  rv3d->depths->damaged = true;
1768  }
1769 }
1770 
typedef float(TangentPoint)[2]
Camera data-block and utility functions.
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
Definition: camera.c:242
#define CAMERA_PARAM_ZOOM_INIT_PERSP
Definition: BKE_camera.h:89
void BKE_camera_params_init(CameraParams *params)
Definition: camera.c:271
void BKE_camera_params_from_view3d(CameraParams *params, struct Depsgraph *depsgraph, const struct View3D *v3d, const struct RegionView3D *rv3d)
bool BKE_camera_view_frame_fit_to_scene(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *camera_ob, float r_co[3], float *r_scale)
void BKE_camera_params_from_object(CameraParams *params, const struct Object *cam_ob)
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float aspx, float aspy)
Definition: camera.c:370
#define CAMERA_PARAM_ZOOM_INIT_CAMOB
Definition: BKE_camera.h:88
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:985
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:973
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
General operations, lookup, etc. for blender objects.
void BKE_object_apply_mat4_ex(struct Object *ob, const float mat[4][4], struct Object *parent, const float parentinv[4][4], const bool use_compat)
Definition: object.c:3708
void BKE_object_tfm_protected_backup(const struct Object *ob, ObjectTfmProtectedChannels *obtfm)
void BKE_object_apply_mat4(struct Object *ob, const float mat[4][4], const bool use_compat, const bool use_parent)
Definition: object.c:3754
void BKE_object_tfm_protected_restore(struct Object *ob, const ObjectTfmProtectedChannels *obtfm, const short protectflag)
Definition: object.c:3158
struct ARegion * BKE_area_find_region_active_win(struct ScrArea *area)
Definition: screen.c:918
struct ScrArea struct ScrArea * BKE_screen_find_big_area(struct bScreen *screen, const int spacetype, const short min)
Definition: screen.c:983
Generic array manipulation API.
#define BLI_array_iter_spiral_square(arr, arr_shape, center, test_fn, user_data)
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_bitmap_draw_2d_line_v2v2i(const int p1[2], const int p2[2], bool(*callback)(int, int, void *), void *user_data)
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define M_SQRT1_2
Definition: BLI_math_base.h:50
bool isect_planes_v3_fn(const float planes[][4], const int planes_len, const float eps_coplanar, const float eps_isect, void(*callback_fn)(const float co[3], int i, int j, int k, void *user_data), void *user_data)
Definition: math_geom.c:2312
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:51
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void mul_m4_v4(const float M[4][4], float r[4])
Definition: math_matrix.c:866
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1919
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void normalize_m4_m4(float R[4][4], const float M[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1972
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2590
void invert_qt_normalized(float q[4])
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:97
void invert_qt_qt_normalized(float q1[4], const float q2[4])
float focallength_to_fov(float focal_length, float sensor)
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:52
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
float angle_signed_qtqt(const float q1[4], const float q2[4])
void quat_to_mat4(float mat[4][4], const float q[4])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:1020
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
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 copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE void negate_v4_v4(float r[4], const float a[3])
void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size)
Definition: rct.c:508
#define INIT_MINMAX(min, max)
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag)
void DEG_id_tag_update(struct ID *id, int flag)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ CAM_ORTHO
#define DEFAULT_SENSOR_WIDTH
@ OB_SOLID
@ OB_RENDER
@ OB_MODE_TEXTURE_PAINT
Object is a sort of wrapper for general info.
@ OB_LOCK_ROT4D
@ OB_LOCK_SCALEZ
@ OB_LOCK_SCALEX
@ OB_LOCK_SCALEY
@ OB_LOCK_SCALE
@ OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK
@ BOUNDBOX_DISABLED
@ OB_CAMERA
#define CFRA
@ RGN_ALIGN_QSPLIT
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ USER_AUTOPERSP
@ V3D_SHADING_BACKGROUND_VIEWPORT
@ V3D_SHADING_BACKGROUND_WORLD
@ V3D_SHADING_TEXTURE_COLOR
#define RV3D_VIEW_IS_AXIS(view)
#define V3D_LOCK_CAMERA
#define RV3D_LOCK_FLAGS(rv3d)
#define RV3D_CAMOB
#define RV3D_ZOFFSET_DISABLED
#define RV3D_VIEW_BACK
#define RV3D_CLIPPING
#define RV3D_VIEW_BOTTOM
@ RV3D_LOCK_ANY_TRANSFORM
@ RV3D_LOCK_ROTATION
@ RV3D_BOXVIEW
@ RV3D_BOXCLIP
#define RV3D_VIEW_LEFT
#define RV3D_VIEW_RIGHT
#define RV3D_PERSP
#define RV3D_VIEW_TOP
@ RV3D_VIEW_AXIS_ROLL_270
@ RV3D_VIEW_AXIS_ROLL_0
#define RV3D_VIEW_USER
#define RV3D_VIEW_FRONT
#define RV3D_ORTHO
@ MODIFYKEY_MODE_INSERT
#define ANIM_KS_LOCATION_ID
#define ANIM_KS_ROTATION_ID
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
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])
#define VIEW3D_DIST_FALLBACK
Definition: ED_view3d.h:676
@ V3D_DEPTH_NO_GPENCIL
Definition: ED_view3d.h:148
void ED_view3d_depth_override(struct Depsgraph *depsgraph, struct ARegion *region, struct View3D *v3d, struct Object *obact, eV3DDepthOverrideMode mode, bool update_cache)
Definition: view3d_draw.c:2331
bool ED_view3d_unproject(const struct ARegion *region, float regionx, float regiony, float regionz, float world[3])
static AppView * view
_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 y1
_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
#define GPU_matrix_set(x)
Definition: GPU_matrix.h:224
#define GPU_matrix_projection_set(x)
Definition: GPU_matrix.h:225
void GPU_polygon_offset(float viewdist, float dist)
Definition: gpu_matrix.cc:758
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:39
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1191
@ TH_BACK
Definition: UI_resources.h:55
#define ND_TRANSFORM
Definition: WM_types.h:357
#define NC_OBJECT
Definition: WM_types.h:280
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
Scene scene
const Depsgraph * depsgraph
void * user_data
uint pos
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define tanf(x)
#define atanf(x)
#define fabsf(x)
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
Definition: keyframing.c:2779
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
Definition: keyingsets.c:1028
KeyingSet * ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
Definition: keyingsets.c:725
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
Definition: keyingsets.c:898
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
static double epsilon
const char * RE_engine_id_BLENDER_WORKBENCH
Definition: scene.c:1743
#define min(a, b)
Definition: sort.c:51
void * regiondata
struct ARegion * prev
struct ARegion * next
short alignment
short regiontype
float vec[8][3]
Definition: DNA_ID.h:273
Definition: BKE_main.h:116
short transflag
float parentinv[4][4]
float obmat[4][4]
short protectflag
struct Object * parent
void * data
float r_depth
float viewcamtexcofac[4]
float viewquat[4]
float persmat[4][4]
float lviewquat[4]
float clip[6][4]
float viewmat[4][4]
float persmatob[4][4]
struct ViewDepths * depths
float viewinv[4][4]
struct BoundBox * clipbb
float winmat[4][4]
char engine[32]
View3DShading shading
struct SceneDisplay display
struct RenderData r
struct World * world
float background_color[3]
float clip_end
struct Object * camera
char ob_center_bone[64]
short ob_center_cursor
struct Object * ob_center
View3DShading shading
float clip_start
struct ARegion * region
Definition: ED_view3d.h:80
struct RegionView3D * rv3d
Definition: ED_view3d.h:83
bool damaged
Definition: ED_view3d.h:94
unsigned short w
Definition: ED_view3d.h:89
float * depths
Definition: ED_view3d.h:91
double depth_range[2]
Definition: ED_view3d.h:92
unsigned short h
Definition: ED_view3d.h:89
float horr
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
float max
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119
void view3d_update_depths_rect(ARegion *region, ViewDepths *d, rcti *rect)
Definition: view3d_draw.c:2212
float view3d_depth_near(ViewDepths *d)
Definition: view3d_draw.c:2300
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
Definition: view3d_utils.c:459
float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
void ED_view3d_camera_lock_init_ex(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
Definition: view3d_utils.c:585
Camera * ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
Definition: view3d_utils.c:109
bool ED_view3d_depth_read_cached(const ViewDepths *vd, const int mval[2], int margin, float *r_depth)
bool ED_view3d_autodist_depth_seg(ARegion *region, const int mval_sta[2], const int mval_end[2], int margin, float *depth)
static bool depth_read_test_fn(const void *value, void *userdata)
char ED_view3d_axis_view_opposite(char view)
bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
Definition: view3d_utils.c:611
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *region, const Object *ob, const rcti *rect)
Definition: view3d_utils.c:290
bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *region)
Definition: view3d_utils.c:537
bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
Definition: view3d_utils.c:479
void ED_view3d_depth_tag_update(RegionView3D *rv3d)
static bool view3d_boundbox_clip_m4(const BoundBox *bb, const float persmatob[4][4])
Definition: view3d_utils.c:400
bool ED_view3d_camera_to_view_selected(struct Main *bmain, Depsgraph *depsgraph, const Scene *scene, Object *camera_ob)
bool ED_view3d_lock(RegionView3D *rv3d)
char ED_view3d_lock_view_from_index(int index)
void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float r_color[3])
Definition: view3d_utils.c:73
void ED_view3d_lastview_store(RegionView3D *rv3d)
Definition: view3d_utils.c:487
bool ED_view3d_camera_lock_autokey(View3D *v3d, RegionView3D *rv3d, struct bContext *C, const bool do_rotate, const bool do_translate)
Definition: view3d_utils.c:710
bool ED_view3d_autodist_depth(ARegion *region, const int mval[2], int margin, float *depth)
bool ED_view3d_distance_set_from_location(RegionView3D *rv3d, const float dist_co[3], const float dist_min)
bool ED_view3d_depth_read_cached_normal(const ViewContext *vc, const int mval[2], float r_normal[3])
bool ED_view3d_clip_range_get(Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, float *r_clipsta, float *r_clipend, const bool use_ortho_factor)
Definition: view3d_utils.c:128
bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float r_quat[4])
bool ED_view3d_camera_autokey(const Scene *scene, ID *id_key, struct bContext *C, const bool do_rotate, const bool do_translate)
Definition: view3d_utils.c:669
float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
void ED_view3d_to_object(const Depsgraph *depsgraph, Object *ob, const float ofs[3], const float quat[4], const float dist)
void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const float *dist)
static void points_in_planes_minmax_fn(const float co[3], int UNUSED(i), int UNUSED(j), int UNUSED(k), void *user_data_p)
Definition: view3d_utils.c:335
void ED_view3d_dist_range_get(const View3D *v3d, float r_dist_range[2])
Definition: view3d_utils.c:119
static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
Definition: view3d_utils.c:845
void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
Definition: view3d_utils.c:276
bool ED_view3d_depth_unproject(const ARegion *region, const int mval[2], const double depth, float r_location_world[3])
float ED_view3d_offset_distance(const float mat[4][4], const float ofs[3], const float fallback_dist)
static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin)
bool ED_view3d_clipping_clamp_minmax(const RegionView3D *rv3d, float min[3], float max[3])
Definition: view3d_utils.c:354
bool ED_view3d_context_activate(bContext *C)
Definition: view3d_utils.c:244
void ED_view3d_lock_clear(View3D *v3d)
Definition: view3d_utils.c:497
void view3d_operator_needs_opengl(const bContext *C)
Definition: view3d_utils.c:198
void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *region)
Definition: view3d_utils.c:206
void view3d_boxview_copy(ScrArea *area, ARegion *region)
Definition: view3d_utils.c:914
void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
Definition: view3d_utils.c:224
void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
float ED_view3d_radius_to_dist(const View3D *v3d, const ARegion *region, const struct Depsgraph *depsgraph, const char persp, const bool use_aspect, const float radius)
bool ED_view3d_autodist_simple(ARegion *region, const int mval[2], float mouse_worldloc[3], int margin, const float *force_depth)
void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d, const char persp)
Definition: view3d_utils.c:513
bool ED_view3d_viewplane_get(Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, int winx, int winy, rctf *r_viewplane, float *r_clip_start, float *r_clip_end, float *r_pixsize)
Definition: view3d_utils.c:156
bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
Definition: view3d_utils.c:441
void view3d_boxview_sync(ScrArea *area, ARegion *region)
Definition: view3d_utils.c:889
static bool depth_segment_cb(int x, int y, void *userData)
bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
Definition: view3d_utils.c:575
static void view3d_boxview_clip(ScrArea *area)
Definition: view3d_utils.c:745
void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
Definition: view3d_utils.c:601
bool ED_view3d_autodist(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const int mval[2], float mouse_worldloc[3], const bool UNUSED(alphaoverride), const float fallback_depth_pt[3])
void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
bool ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon, char *r_view, char *r_view_axis_roll)
void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
Definition: view3d_utils.c:939
static float view3d_quat_axis[6][4][4]
bool ED_view3d_has_workbench_in_texture_color(const Scene *scene, const Object *ob, const View3D *v3d)
Definition: view3d_utils.c:89
void WM_main_add_notifier(unsigned int type, void *reference)
void wmViewport(const rcti *winrct)
Definition: wm_subwindow.c:37