Blender  V3.3
view3d_utils.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2008 Blender Foundation. All rights reserved. */
3 
10 #include <float.h>
11 #include <math.h>
12 #include <stdio.h>
13 #include <string.h>
14 
15 #include "DNA_camera_types.h"
16 #include "DNA_curve_types.h"
17 #include "DNA_object_types.h"
18 #include "DNA_scene_types.h"
19 #include "DNA_world_types.h"
20 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_array_utils.h"
24 #include "BLI_bitmap_draw_2d.h"
25 #include "BLI_blenlib.h"
26 #include "BLI_math.h"
27 #include "BLI_utildefines.h"
28 
29 #include "BKE_camera.h"
30 #include "BKE_context.h"
31 #include "BKE_object.h"
32 #include "BKE_scene.h"
33 #include "BKE_screen.h"
34 
35 #include "DEG_depsgraph.h"
36 #include "DEG_depsgraph_query.h"
37 
38 #include "BIF_glutil.h"
39 
40 #include "GPU_matrix.h"
41 
42 #include "WM_api.h"
43 #include "WM_types.h"
44 
45 #include "ED_keyframing.h"
46 #include "ED_screen.h"
47 #include "ED_undo.h"
48 #include "ED_view3d.h"
49 
50 #include "UI_resources.h"
51 
52 #include "view3d_intern.h" /* own include */
53 
54 /* -------------------------------------------------------------------- */
58 void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float r_color[3])
59 {
61  if (scene->world) {
62  copy_v3_v3(r_color, &scene->world->horr);
63  return;
64  }
65  }
67  copy_v3_v3(r_color, v3d->shading.background_color);
68  return;
69  }
70 
71  UI_GetThemeColor3fv(TH_BACK, r_color);
72 }
73 
75  const Object *ob,
76  const View3D *v3d)
77 {
78  if (v3d->shading.type == OB_SOLID) {
80  return true;
81  }
82  if (ob && ob->mode == OB_MODE_TEXTURE_PAINT) {
83  return true;
84  }
85  }
86  else if (v3d->shading.type == OB_RENDER) {
89  }
90  }
91  return false;
92 }
93 
95 {
96  /* establish the camera object,
97  * so we can default to view mapping if anything is wrong with it */
98  if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
99  return v3d->camera->data;
100  }
101  return NULL;
102 }
103 
104 void ED_view3d_dist_range_get(const View3D *v3d, float r_dist_range[2])
105 {
106  r_dist_range[0] = v3d->grid * 0.001f;
107  r_dist_range[1] = v3d->clip_end * 10.0f;
108 }
109 
111  const View3D *v3d,
112  const RegionView3D *rv3d,
113  float *r_clipsta,
114  float *r_clipend,
115  const bool use_ortho_factor)
116 {
118 
121 
122  if (use_ortho_factor && params.is_ortho) {
123  const float fac = 2.0f / (params.clip_end - params.clip_start);
124  params.clip_start *= fac;
125  params.clip_end *= fac;
126  }
127 
128  if (r_clipsta) {
129  *r_clipsta = params.clip_start;
130  }
131  if (r_clipend) {
132  *r_clipend = params.clip_end;
133  }
134 
135  return params.is_ortho;
136 }
137 
139  const View3D *v3d,
140  const RegionView3D *rv3d,
141  int winx,
142  int winy,
143  rctf *r_viewplane,
144  float *r_clip_start,
145  float *r_clip_end,
146  float *r_pixsize)
147 {
149 
152  BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
153 
154  if (r_viewplane) {
155  *r_viewplane = params.viewplane;
156  }
157  if (r_clip_start) {
158  *r_clip_start = params.clip_start;
159  }
160  if (r_clip_end) {
161  *r_clip_end = params.clip_end;
162  }
163  if (r_pixsize) {
164  *r_pixsize = params.viewdx;
165  }
166 
167  return params.is_ortho;
168 }
169 
172 /* -------------------------------------------------------------------- */
177 {
178  wmWindow *win = CTX_wm_window(C);
179  ARegion *region = CTX_wm_region(C);
180 
182 }
183 
185 {
186  /* for debugging purpose, context should always be OK */
187  if ((region == NULL) || (region->regiontype != RGN_TYPE_WINDOW)) {
188  printf("view3d_region_operator_needs_opengl error, wrong region\n");
189  }
190  else {
191  RegionView3D *rv3d = region->regiondata;
192 
193  wmViewport(&region->winrct); /* TODO: bad */
195  GPU_matrix_set(rv3d->viewmat);
196  }
197 }
198 
199 void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
200 {
201  if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
202  return;
203  }
204 
205  float viewdist = rv3d->dist;
206 
207  /* Special exception for orthographic camera (`viewdist` isn't used for perspective cameras). */
208  if (dist != 0.0f) {
209  if (rv3d->persp == RV3D_CAMOB) {
210  if (rv3d->is_persp == false) {
211  viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
212  }
213  }
214  }
215 
216  GPU_polygon_offset(viewdist, dist);
217 }
218 
220 {
221  bScreen *screen = CTX_wm_screen(C);
223 
224  /* area can be NULL when called from python */
225  if (area == NULL || area->spacetype != SPACE_VIEW3D) {
227  }
228 
229  if (area == NULL) {
230  return false;
231  }
232 
234  if (region == NULL) {
235  return false;
236  }
237 
238  /* Bad context switch. */
240  CTX_wm_region_set(C, region);
241 
242  return true;
243 }
244 
247 /* -------------------------------------------------------------------- */
252  const BoundBox *bb,
253  const bool is_flip)
254 {
255  for (int val = 0; val < 4; val++) {
256  normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
257  if (UNLIKELY(is_flip)) {
258  negate_v3(clip[val]);
259  }
260 
261  clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
262  }
263 }
264 
266  BoundBox *bb, float planes[4][4], const ARegion *region, const Object *ob, const rcti *rect)
267 {
268  /* init in case unproject fails */
269  memset(bb->vec, 0, sizeof(bb->vec));
270 
271  /* four clipping planes and bounding volume */
272  /* first do the bounding volume */
273  for (int val = 0; val < 4; val++) {
274  float xs = (ELEM(val, 0, 3)) ? rect->xmin : rect->xmax;
275  float ys = (ELEM(val, 0, 1)) ? rect->ymin : rect->ymax;
276 
277  ED_view3d_unproject_v3(region, xs, ys, 0.0, bb->vec[val]);
278  ED_view3d_unproject_v3(region, xs, ys, 1.0, bb->vec[4 + val]);
279  }
280 
281  /* optionally transform to object space */
282  if (ob) {
283  float imat[4][4];
284  invert_m4_m4(imat, ob->obmat);
285 
286  for (int val = 0; val < 8; val++) {
287  mul_m4_v3(imat, bb->vec[val]);
288  }
289  }
290 
291  /* verify if we have negative scale. doing the transform before cross
292  * product flips the sign of the vector compared to doing cross product
293  * before transform then, so we correct for that. */
294  int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
295 
296  ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
297 }
298 
301 /* -------------------------------------------------------------------- */
306  float min[3];
307  float max[3];
308 };
309 
311  const float co[3], int UNUSED(i), int UNUSED(j), int UNUSED(k), void *user_data_p)
312 {
313  struct PointsInPlanesMinMax_UserData *user_data = user_data_p;
314  minmax_v3v3_v3(user_data->min, user_data->max, co);
315 }
316 
317 bool ED_view3d_clipping_clamp_minmax(const RegionView3D *rv3d, float min[3], float max[3])
318 {
319  /* 6 planes for the cube, 4..6 for the current view clipping planes. */
320  float planes[6 + 6][4];
321 
322  /* Convert the min/max to 6 planes. */
323  for (int i = 0; i < 3; i++) {
324  float *plane_min = planes[(i * 2) + 0];
325  float *plane_max = planes[(i * 2) + 1];
326  zero_v3(plane_min);
327  zero_v3(plane_max);
328  plane_min[i] = -1.0f;
329  plane_min[3] = +min[i];
330  plane_max[i] = +1.0f;
331  plane_max[3] = -max[i];
332  }
333 
334  /* Copy planes from the viewport & flip. */
335  int planes_len = 6;
336  int clip_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6;
337  for (int i = 0; i < clip_len; i++) {
338  negate_v4_v4(planes[planes_len], rv3d->clip[i]);
339  planes_len += 1;
340  }
341 
342  /* Calculate points intersecting all planes (effectively intersecting two bounding boxes). */
344  INIT_MINMAX(user_data.min, user_data.max);
345 
346  const float eps_coplanar = 1e-4f;
347  const float eps_isect = 1e-6f;
348  if (isect_planes_v3_fn(
349  planes, planes_len, eps_coplanar, eps_isect, points_in_planes_minmax_fn, &user_data)) {
350  copy_v3_v3(min, user_data.min);
351  copy_v3_v3(max, user_data.max);
352  return true;
353  }
354  return false;
355 }
356 
359 /* -------------------------------------------------------------------- */
363 static bool view3d_boundbox_clip_m4(const BoundBox *bb, const float persmatob[4][4])
364 {
365  int a, flag = -1, fl;
366 
367  for (a = 0; a < 8; a++) {
368  float vec[4], min, max;
369  copy_v3_v3(vec, bb->vec[a]);
370  vec[3] = 1.0;
371  mul_m4_v4(persmatob, vec);
372  max = vec[3];
373  min = -vec[3];
374 
375  fl = 0;
376  if (vec[0] < min) {
377  fl += 1;
378  }
379  if (vec[0] > max) {
380  fl += 2;
381  }
382  if (vec[1] < min) {
383  fl += 4;
384  }
385  if (vec[1] > max) {
386  fl += 8;
387  }
388  if (vec[2] < min) {
389  fl += 16;
390  }
391  if (vec[2] > max) {
392  fl += 32;
393  }
394 
395  flag &= fl;
396  if (flag == 0) {
397  return true;
398  }
399  }
400 
401  return false;
402 }
403 
404 bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
405 {
406  /* return 1: draw */
407 
408  float persmatob[4][4];
409 
410  if (bb == NULL) {
411  return true;
412  }
413 
414  mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
415 
416  return view3d_boundbox_clip_m4(bb, persmatob);
417 }
418 
420 {
421  if (bb == NULL) {
422  return true;
423  }
424  return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
425 }
426 
429 /* -------------------------------------------------------------------- */
435 bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
436 {
437  return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_center_cursor || v3d->ob_center);
438 }
439 
441 {
442  copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
443  rv3d->lview = rv3d->view;
444  rv3d->lview_axis_roll = rv3d->view_axis_roll;
445  if (rv3d->persp != RV3D_CAMOB) {
446  rv3d->lpersp = rv3d->persp;
447  }
448 }
449 
451 {
452  v3d->ob_center = NULL;
453  v3d->ob_center_bone[0] = '\0';
454  v3d->ob_center_cursor = false;
455 
456  v3d->flag2 &= ~V3D_LOCK_CAMERA;
457 }
458 
460  View3D *v3d,
461  RegionView3D *rv3d,
462  const char persp)
463 {
464  BLI_assert(rv3d->persp == RV3D_CAMOB);
465  BLI_assert(persp != RV3D_CAMOB);
466 
467  if (v3d->camera) {
468  Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
469  rv3d->dist = ED_view3d_offset_distance(ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
470  ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
471  }
472 
473  if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
474  rv3d->persp = persp;
475  }
476 }
478 {
479  RegionView3D *rv3d = region->regiondata;
480  const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
481 
483 
484  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
485  return false;
486  }
487 
488  if (rv3d->persp != RV3D_PERSP) {
489  if (rv3d->persp == RV3D_CAMOB) {
490  /* If autopersp and previous view was an axis one,
491  * switch back to PERSP mode, else reuse previous mode. */
492  char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
494  }
495  else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
496  rv3d->persp = RV3D_PERSP;
497  }
498  return true;
499  }
500 
501  return false;
502 }
503 
506 /* -------------------------------------------------------------------- */
512 bool ED_view3d_camera_view_zoom_scale(RegionView3D *rv3d, const float scale)
513 {
514  const float camzoom_init = rv3d->camzoom;
515  float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
516  /* Clamp both before and after conversion to prevent NAN on negative values. */
517 
518  zoomfac = zoomfac * scale;
520  rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(zoomfac);
522  return (rv3d->camzoom != camzoom_init);
523 }
524 
525 bool ED_view3d_camera_view_pan(ARegion *region, const float event_ofs[2])
526 {
527  RegionView3D *rv3d = region->regiondata;
528  const float camdxy_init[2] = {rv3d->camdx, rv3d->camdy};
529  const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 2.0f;
530  rv3d->camdx += event_ofs[0] / (region->winx * zoomfac);
531  rv3d->camdy += event_ofs[1] / (region->winy * zoomfac);
532  CLAMP(rv3d->camdx, -1.0f, 1.0f);
533  CLAMP(rv3d->camdy, -1.0f, 1.0f);
534  return (camdxy_init[0] != rv3d->camdx) || (camdxy_init[1] != rv3d->camdy);
535 }
536 
539 /* -------------------------------------------------------------------- */
545 bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
546 {
547  return ((v3d->camera) && (!ID_IS_LINKED(v3d->camera)) && (v3d->flag2 & V3D_LOCK_CAMERA) &&
548  (rv3d->persp == RV3D_CAMOB));
549 }
550 
552  View3D *v3d,
553  RegionView3D *rv3d,
554  const bool calc_dist)
555 {
556  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
557  Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
558  if (calc_dist) {
559  /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
561  ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
562  }
563  ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
564  }
565 }
566 
568 {
569  ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, true);
570 }
571 
573 {
574  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
576  Object *root_parent;
577 
579  (root_parent = v3d->camera->parent)) {
580  Object *ob_update;
581  float tmat[4][4];
582  float imat[4][4];
583  float view_mat[4][4];
584  float diff_mat[4][4];
585  float parent_mat[4][4];
586 
587  while (root_parent->parent) {
588  root_parent = root_parent->parent;
589  }
590  Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
591  Object *root_parent_eval = DEG_get_evaluated_object(depsgraph, root_parent);
592 
593  ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
594 
595  normalize_m4_m4(tmat, ob_camera_eval->obmat);
596 
597  invert_m4_m4(imat, tmat);
598  mul_m4_m4m4(diff_mat, view_mat, imat);
599 
600  mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->obmat);
601 
602  BKE_object_tfm_protected_backup(root_parent, &obtfm);
603  BKE_object_apply_mat4(root_parent, parent_mat, true, false);
604  BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
605 
606  ob_update = v3d->camera;
607  while (ob_update) {
610  ob_update = ob_update->parent;
611  }
612  }
613  else {
614  /* always maintain the same scale */
615  const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
617  ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
619  v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
620 
623  }
624 
625  return true;
626  }
627  return false;
628 }
629 
631  ID *id_key,
632  struct bContext *C,
633  const bool do_rotate,
634  const bool do_translate)
635 {
636  if (autokeyframe_cfra_can_key(scene, id_key)) {
637  const float cfra = (float)scene->r.cfra;
638  ListBase dsources = {NULL, NULL};
639 
640  /* add data-source override for the camera object */
641  ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
642 
643  /* insert keyframes
644  * 1) on the first frame
645  * 2) on each subsequent frame
646  * TODO: need to check in future that frame changed before doing this
647  */
648  if (do_rotate) {
650  ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
651  }
652  if (do_translate) {
654  ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
655  }
656 
657  /* free temp data */
658  BLI_freelistN(&dsources);
659 
660  return true;
661  }
662  return false;
663 }
664 
666  RegionView3D *rv3d,
667  struct bContext *C,
668  const bool do_rotate,
669  const bool do_translate)
670 {
671  /* similar to ED_view3d_cameracontrol_update */
672  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
674  ID *id_key;
675  Object *root_parent;
677  (root_parent = v3d->camera->parent)) {
678  while (root_parent->parent) {
679  root_parent = root_parent->parent;
680  }
681  id_key = &root_parent->id;
682  }
683  else {
684  id_key = &v3d->camera->id;
685  }
686 
687  return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
688  }
689  return false;
690 }
691 
693  const RegionView3D *rv3d,
694  struct bContext *C)
695 {
696  if (ED_view3d_camera_lock_check(v3d, rv3d)) {
698  return true;
699  }
700  }
701  return false;
702 }
703 
712  const char *str, View3D *v3d, RegionView3D *rv3d, struct bContext *C, bool undo_group)
713 {
714  if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) {
715  if (undo_group) {
717  }
718  else {
719  ED_undo_push(C, str);
720  }
721  return true;
722  }
723  return false;
724 }
725 
727 {
728  return view3d_camera_lock_undo_ex(str, v3d, rv3d, C, false);
729 }
730 
732  View3D *v3d,
733  RegionView3D *rv3d,
734  bContext *C)
735 {
736  return view3d_camera_lock_undo_ex(str, v3d, rv3d, C, true);
737 }
738 
741 /* -------------------------------------------------------------------- */
748 {
749  BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
750  float clip[6][4];
751  float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
752 
753  /* create bounding box */
754  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
755  if (region->regiontype == RGN_TYPE_WINDOW) {
756  RegionView3D *rv3d = region->regiondata;
757 
758  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) {
759  if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
760  if (region->winx > region->winy) {
761  x1 = rv3d->dist;
762  }
763  else {
764  x1 = region->winx * rv3d->dist / region->winy;
765  }
766 
767  if (region->winx > region->winy) {
768  y1 = region->winy * rv3d->dist / region->winx;
769  }
770  else {
771  y1 = rv3d->dist;
772  }
773  copy_v2_v2(ofs, rv3d->ofs);
774  }
775  else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
776  ofs[2] = rv3d->ofs[2];
777 
778  if (region->winx > region->winy) {
779  z1 = region->winy * rv3d->dist / region->winx;
780  }
781  else {
782  z1 = rv3d->dist;
783  }
784  }
785  }
786  }
787  }
788 
789  for (int val = 0; val < 8; val++) {
790  if (ELEM(val, 0, 3, 4, 7)) {
791  bb->vec[val][0] = -x1 - ofs[0];
792  }
793  else {
794  bb->vec[val][0] = x1 - ofs[0];
795  }
796 
797  if (ELEM(val, 0, 1, 4, 5)) {
798  bb->vec[val][1] = -y1 - ofs[1];
799  }
800  else {
801  bb->vec[val][1] = y1 - ofs[1];
802  }
803 
804  if (val > 3) {
805  bb->vec[val][2] = -z1 - ofs[2];
806  }
807  else {
808  bb->vec[val][2] = z1 - ofs[2];
809  }
810  }
811 
812  /* normals for plane equations */
813  normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
814  normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
815  normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
816  normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
817  normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
818  normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
819 
820  /* then plane equations */
821  for (int val = 0; val < 6; val++) {
822  clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
823  }
824 
825  /* create bounding box */
826  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
827  if (region->regiontype == RGN_TYPE_WINDOW) {
828  RegionView3D *rv3d = region->regiondata;
829 
830  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) {
831  rv3d->rflag |= RV3D_CLIPPING;
832  memcpy(rv3d->clip, clip, sizeof(clip));
833  if (rv3d->clipbb) {
834  MEM_freeN(rv3d->clipbb);
835  }
836  rv3d->clipbb = MEM_dupallocN(bb);
837  }
838  }
839  }
840  MEM_freeN(bb);
841 }
842 
847 static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
848 {
849  /* absolute axis values above this are considered to be set (will be ~1.0f) */
850  const float axis_eps = 0.5f;
851  float viewinv[4];
852 
853  /* use the view rotation to identify which axis to sync on */
854  float view_axis_all[4][3] = {
855  {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}};
856 
857  float *view_src_x = &view_axis_all[0][0];
858  float *view_src_y = &view_axis_all[1][0];
859 
860  float *view_dst_x = &view_axis_all[2][0];
861  float *view_dst_y = &view_axis_all[3][0];
862  int i;
863 
864  /* we could use rv3d->viewinv, but better not depend on view matrix being updated */
865  if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, rv3d_src->view_axis_roll, viewinv) ==
866  false)) {
867  return;
868  }
869  invert_qt_normalized(viewinv);
870  mul_qt_v3(viewinv, view_src_x);
871  mul_qt_v3(viewinv, view_src_y);
872 
873  if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, rv3d_dst->view_axis_roll, viewinv) ==
874  false)) {
875  return;
876  }
877  invert_qt_normalized(viewinv);
878  mul_qt_v3(viewinv, view_dst_x);
879  mul_qt_v3(viewinv, view_dst_y);
880 
881  /* check source and dest have a matching axis */
882  for (i = 0; i < 3; i++) {
883  if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
884  ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps))) {
885  rv3d_dst->ofs[i] = rv3d_src->ofs[i];
886  }
887  }
888 }
889 
891 {
892  RegionView3D *rv3d = region->regiondata;
893  short clip = 0;
894 
895  LISTBASE_FOREACH (ARegion *, region_test, &area->regionbase) {
896  if (region_test != region && region_test->regiontype == RGN_TYPE_WINDOW) {
897  RegionView3D *rv3dtest = region_test->regiondata;
898 
899  if (RV3D_LOCK_FLAGS(rv3dtest) & RV3D_LOCK_ROTATION) {
900  rv3dtest->dist = rv3d->dist;
901  view3d_boxview_sync_axis(rv3dtest, rv3d);
902  clip |= RV3D_LOCK_FLAGS(rv3dtest) & RV3D_BOXCLIP;
903 
904  ED_region_tag_redraw(region_test);
905  }
906  }
907  }
908 
909  if (clip) {
911  }
912 }
913 
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 void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
939 {
940  ARegion *region_sync = NULL;
941  RegionView3D *rv3d = region->regiondata;
942  /* this function copies flags from the first of the 3 other quadview
943  * regions to the 2 other, so it assumes this is the region whose
944  * properties are always being edited, weak */
945  short viewlock = rv3d->viewlock;
946 
947  if ((viewlock & RV3D_LOCK_ROTATION) == 0) {
948  do_clip = (viewlock & RV3D_BOXCLIP) != 0;
949  viewlock = 0;
950  }
951  else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
952  do_clip = true;
953  viewlock &= ~RV3D_BOXCLIP;
954  }
955 
956  for (; region; region = region->prev) {
957  if (region->alignment == RGN_ALIGN_QSPLIT) {
958  rv3d = region->regiondata;
959  rv3d->viewlock = viewlock;
960 
961  if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
962  rv3d->rflag &= ~RV3D_BOXCLIP;
963  }
964 
965  /* use region_sync so we sync with one of the aligned views below
966  * else the view jumps on changing view settings like 'clip'
967  * since it copies from the perspective view */
968  region_sync = region;
969  }
970  }
971 
972  if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
973  view3d_boxview_sync(area, region_sync ? region_sync : area->regionbase.last);
974  }
975 
976  /* ensure locked regions have an axis, locked user views don't make much sense */
977  if (viewlock & RV3D_LOCK_ROTATION) {
978  int index_qsplit = 0;
979  for (region = area->regionbase.first; region; region = region->next) {
980  if (region->alignment == RGN_ALIGN_QSPLIT) {
981  rv3d = region->regiondata;
982  if (rv3d->viewlock) {
983  if (!RV3D_VIEW_IS_AXIS(rv3d->view) || (rv3d->view_axis_roll != RV3D_VIEW_AXIS_ROLL_0)) {
984  rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
986  rv3d->persp = RV3D_ORTHO;
987  ED_view3d_lock(rv3d);
988  }
989  }
990  index_qsplit++;
991  }
992  }
993  }
994 
996 }
997 
1000 /* -------------------------------------------------------------------- */
1004 static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin)
1005 {
1006  rcti rect;
1007  if (margin == 0) {
1008  /* Get Z Depths, needed for perspective, nice for ortho */
1009  rect.xmin = mval[0];
1010  rect.ymin = mval[1];
1011  rect.xmax = mval[0] + 1;
1012  rect.ymax = mval[1] + 1;
1013  }
1014  else {
1015  BLI_rcti_init_pt_radius(&rect, mval, margin);
1016  }
1017 
1018  ViewDepths depth_temp = {0};
1019  view3d_depths_rect_create(region, &rect, &depth_temp);
1020  float depth_close = view3d_depth_near(&depth_temp);
1021  MEM_SAFE_FREE(depth_temp.depths);
1022  return depth_close;
1023 }
1024 
1026  ARegion *region,
1027  View3D *v3d,
1028  const int mval[2],
1029  float mouse_worldloc[3],
1030  const bool UNUSED(alphaoverride),
1031  const float fallback_depth_pt[3])
1032 {
1033  float depth_close;
1034  int margin_arr[] = {0, 2, 4};
1035  bool depth_ok = false;
1036 
1037  /* Get Z Depths, needed for perspective, nice for ortho */
1039 
1040  /* Attempt with low margin's first */
1041  int i = 0;
1042  do {
1043  depth_close = view_autodist_depth_margin(region, mval, margin_arr[i++] * U.pixelsize);
1044  depth_ok = (depth_close != FLT_MAX);
1045  } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
1046 
1047  if (depth_ok) {
1048  float centx = (float)mval[0] + 0.5f;
1049  float centy = (float)mval[1] + 0.5f;
1050 
1051  if (ED_view3d_unproject_v3(region, centx, centy, depth_close, mouse_worldloc)) {
1052  return true;
1053  }
1054  }
1055 
1056  if (fallback_depth_pt) {
1057  ED_view3d_win_to_3d_int(v3d, region, fallback_depth_pt, mval, mouse_worldloc);
1058  return true;
1059  }
1060  return false;
1061 }
1062 
1064  const int mval[2],
1065  float mouse_worldloc[3],
1066  int margin,
1067  const float *force_depth)
1068 {
1069  /* Get Z Depths, needed for perspective, nice for ortho */
1070  float depth;
1071  if (force_depth) {
1072  depth = *force_depth;
1073  }
1074  else {
1075  depth = view_autodist_depth_margin(region, mval, margin);
1076  }
1077 
1078  if (depth == FLT_MAX) {
1079  return false;
1080  }
1081 
1082  float centx = (float)mval[0] + 0.5f;
1083  float centy = (float)mval[1] + 0.5f;
1084  return ED_view3d_unproject_v3(region, centx, centy, depth, mouse_worldloc);
1085 }
1086 
1087 static bool depth_segment_cb(int x, int y, void *userData)
1088 {
1089  struct {
1090  const ViewDepths *vd;
1091  int margin;
1092  float depth;
1093  } *data = userData;
1094  int mval[2];
1095  float depth;
1096 
1097  mval[0] = x;
1098  mval[1] = y;
1099 
1100  if (ED_view3d_depth_read_cached(data->vd, mval, data->margin, &depth)) {
1101  data->depth = depth;
1102  return false;
1103  }
1104  return true;
1105 }
1106 
1108  const ViewDepths *vd, const int mval_sta[2], const int mval_end[2], int margin, float *depth)
1109 {
1110  struct {
1111  const ViewDepths *vd;
1112  int margin;
1113  float depth;
1114  } data = {NULL};
1115  int p1[2];
1116  int p2[2];
1117 
1118  data.vd = vd;
1119  data.margin = margin;
1120  data.depth = 1.0f;
1121 
1122  copy_v2_v2_int(p1, mval_sta);
1123  copy_v2_v2_int(p2, mval_end);
1124 
1126 
1127  *depth = data.depth;
1128 
1129  return (*depth != 1.0f);
1130 }
1131 
1134 /* -------------------------------------------------------------------- */
1140 float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
1141 {
1142  return radius * (1.0f / tanf(angle / 2.0f));
1143 }
1144 
1145 float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
1146 {
1147  return radius / (DEFAULT_SENSOR_WIDTH / lens);
1148 }
1149 
1151  const ARegion *region,
1152  const struct Depsgraph *depsgraph,
1153  const char persp,
1154  const bool use_aspect,
1155  const float radius)
1156 {
1157  float dist;
1158 
1160  BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
1161 
1162  if (persp == RV3D_ORTHO) {
1163  dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
1164  }
1165  else {
1166  float lens, sensor_size, zoom;
1167 
1168  if (persp == RV3D_CAMOB) {
1171  params.clip_start = v3d->clip_start;
1172  params.clip_end = v3d->clip_end;
1173  Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
1174  BKE_camera_params_from_object(&params, camera_eval);
1175 
1176  lens = params.lens;
1177  sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
1178 
1179  /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
1181  }
1182  else {
1183  lens = v3d->lens;
1184  sensor_size = DEFAULT_SENSOR_WIDTH;
1186  }
1187 
1188  float angle = focallength_to_fov(lens, sensor_size);
1189 
1190  /* zoom influences lens, correct this by scaling the angle as a distance
1191  * (by the zoom-level) */
1192  angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
1193 
1194  dist = ED_view3d_radius_to_dist_persp(angle, radius);
1195  }
1196 
1197  if (use_aspect) {
1198  const RegionView3D *rv3d = region->regiondata;
1199 
1200  float winx, winy;
1201 
1202  if (persp == RV3D_CAMOB) {
1203  /* camera frame x/y in pixels */
1204  winx = region->winx / rv3d->viewcamtexcofac[0];
1205  winy = region->winy / rv3d->viewcamtexcofac[1];
1206  }
1207  else {
1208  winx = region->winx;
1209  winy = region->winy;
1210  }
1211 
1212  if (winx && winy) {
1213  float aspect = winx / winy;
1214  if (aspect < 1.0f) {
1215  aspect = 1.0f / aspect;
1216  }
1217  dist *= aspect;
1218  }
1219  }
1220 
1221  return dist;
1222 }
1223 
1226 /* -------------------------------------------------------------------- */
1230 float ED_view3d_offset_distance(const float mat[4][4],
1231  const float ofs[3],
1232  const float fallback_dist)
1233 {
1234  float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
1235  float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
1236 
1237  mul_m4_v4(mat, pos);
1238  add_v3_v3(pos, ofs);
1239  mul_m4_v4(mat, dir);
1240  normalize_v3(dir);
1241 
1242  float dist = dot_v3v3(pos, dir);
1243 
1244  if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
1245  dist = fallback_dist;
1246  }
1247 
1248  return dist;
1249 }
1250 
1251 void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
1252 {
1253  float viewinv[4];
1254  float tvec[3];
1255 
1256  BLI_assert(dist >= 0.0f);
1257 
1258  copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
1259  /* rv3d->viewinv isn't always valid */
1260 #if 0
1261  mul_mat3_m4_v3(rv3d->viewinv, tvec);
1262 #else
1263  invert_qt_qt_normalized(viewinv, rv3d->viewquat);
1264  mul_qt_v3(viewinv, tvec);
1265 #endif
1266  sub_v3_v3(rv3d->ofs, tvec);
1267 
1268  rv3d->dist = dist;
1269 }
1270 
1272  const float dist_co[3],
1273  const float dist_min)
1274 {
1275  float viewinv[4];
1276  invert_qt_qt_normalized(viewinv, rv3d->viewquat);
1277 
1278  float tvec[3] = {0.0f, 0.0f, -1.0f};
1279  mul_qt_v3(viewinv, tvec);
1280 
1281  float dist_co_local[3];
1282  negate_v3_v3(dist_co_local, rv3d->ofs);
1283  sub_v3_v3v3(dist_co_local, dist_co, dist_co_local);
1284  const float delta = dot_v3v3(tvec, dist_co_local);
1285  const float dist_new = rv3d->dist + delta;
1286  if (dist_new >= dist_min) {
1287  madd_v3_v3fl(rv3d->ofs, tvec, -delta);
1288  rv3d->dist = dist_new;
1289  return true;
1290  }
1291  return false;
1292 }
1293 
1296 /* -------------------------------------------------------------------- */
1303 static float view3d_quat_axis[6][4][4] = {
1304  /* RV3D_VIEW_FRONT */
1305  {
1306  {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f},
1307  {0.5f, -0.5f, -0.5f, 0.5f},
1308  {0, 0, -M_SQRT1_2, M_SQRT1_2},
1309  {-0.5f, 0.5f, -0.5f, 0.5f},
1310  },
1311  /* RV3D_VIEW_BACK */
1312  {
1313  {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2},
1314  {0.5f, 0.5f, -0.5f, -0.5f},
1315  {M_SQRT1_2, M_SQRT1_2, 0, 0},
1316  {0.5f, 0.5f, 0.5f, 0.5f},
1317  },
1318  /* RV3D_VIEW_LEFT */
1319  {
1320  {0.5f, -0.5f, 0.5f, 0.5f},
1321  {0, -M_SQRT1_2, 0.0f, M_SQRT1_2},
1322  {-0.5f, -0.5f, -0.5f, 0.5f},
1323  {-M_SQRT1_2, 0, -M_SQRT1_2, 0},
1324  },
1325 
1326  /* RV3D_VIEW_RIGHT */
1327  {
1328  {0.5f, -0.5f, -0.5f, -0.5f},
1329  {M_SQRT1_2, 0, -M_SQRT1_2, 0},
1330  {0.5f, 0.5f, -0.5f, 0.5f},
1331  {0, M_SQRT1_2, 0, M_SQRT1_2},
1332  },
1333  /* RV3D_VIEW_TOP */
1334  {
1335  {1.0f, 0.0f, 0.0f, 0.0f},
1336  {M_SQRT1_2, 0, 0, M_SQRT1_2},
1337  {0, 0, 0, 1},
1338  {-M_SQRT1_2, 0, 0, M_SQRT1_2},
1339  },
1340  /* RV3D_VIEW_BOTTOM */
1341  {
1342  {0.0f, -1.0f, 0.0f, 0.0f},
1343  {0, -M_SQRT1_2, -M_SQRT1_2, 0},
1344  {0, 0, -1, 0},
1345  {0, M_SQRT1_2, -M_SQRT1_2, 0},
1346  },
1347 
1348 };
1349 
1350 bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float r_quat[4])
1351 {
1352  BLI_assert(view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270);
1353  if (RV3D_VIEW_IS_AXIS(view)) {
1354  copy_qt_qt(r_quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll]);
1355  return true;
1356  }
1357  return false;
1358 }
1359 
1360 bool ED_view3d_quat_to_axis_view(const float quat[4],
1361  const float epsilon,
1362  char *r_view,
1363  char *r_view_axis_roll)
1364 {
1365  *r_view = RV3D_VIEW_USER;
1366  *r_view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
1367 
1368  /* Quaternion values are all unit length. */
1369 
1370  if (epsilon < M_PI_4) {
1371  /* Under 45 degrees, just pick the closest value. */
1372  for (int view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
1373  for (int view_axis_roll = RV3D_VIEW_AXIS_ROLL_0; view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270;
1374  view_axis_roll++) {
1376  quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll])) < epsilon) {
1377  *r_view = view;
1378  *r_view_axis_roll = view_axis_roll;
1379  return true;
1380  }
1381  }
1382  }
1383  }
1384  else {
1385  /* Epsilon over 45 degrees, check all & find use the closest. */
1386  float delta_best = FLT_MAX;
1387  for (int view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
1388  for (int view_axis_roll = RV3D_VIEW_AXIS_ROLL_0; view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270;
1389  view_axis_roll++) {
1390  const float delta_test = fabsf(
1391  angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll]));
1392  if (delta_best > delta_test) {
1393  delta_best = delta_test;
1394  *r_view = view;
1395  *r_view_axis_roll = view_axis_roll;
1396  }
1397  }
1398  }
1399  if (*r_view != RV3D_VIEW_USER) {
1400  return true;
1401  }
1402  }
1403 
1404  return false;
1405 }
1406 
1408  const float epsilon,
1409  char *r_view,
1410  char *r_view_axis_roll)
1411 {
1412  const bool is_axis_view = ED_view3d_quat_to_axis_view(quat, epsilon, r_view, r_view_axis_roll);
1413  if (is_axis_view) {
1414  /* Reset `quat` to it's view axis, so axis-aligned views are always *exactly* aligned. */
1415  BLI_assert(*r_view != RV3D_VIEW_USER);
1416  ED_view3d_quat_from_axis_view(*r_view, *r_view_axis_roll, quat);
1417  }
1418  return is_axis_view;
1419 }
1420 
1422 {
1423  switch (index) {
1424  case 0:
1425  return RV3D_VIEW_FRONT;
1426  case 1:
1427  return RV3D_VIEW_TOP;
1428  case 2:
1429  return RV3D_VIEW_RIGHT;
1430  default:
1431  return RV3D_VIEW_USER;
1432  }
1433 }
1434 
1436 {
1437  switch (view) {
1438  case RV3D_VIEW_FRONT:
1439  return RV3D_VIEW_BACK;
1440  case RV3D_VIEW_BACK:
1441  return RV3D_VIEW_FRONT;
1442  case RV3D_VIEW_LEFT:
1443  return RV3D_VIEW_RIGHT;
1444  case RV3D_VIEW_RIGHT:
1445  return RV3D_VIEW_LEFT;
1446  case RV3D_VIEW_TOP:
1447  return RV3D_VIEW_BOTTOM;
1448  case RV3D_VIEW_BOTTOM:
1449  return RV3D_VIEW_TOP;
1450  }
1451 
1452  return RV3D_VIEW_USER;
1453 }
1454 
1456 {
1457  return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->view_axis_roll, rv3d->viewquat);
1458 }
1459 
1462 /* -------------------------------------------------------------------- */
1466 void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const float *dist)
1467 {
1468  float nmat[3][3];
1469 
1470  /* dist depends on offset */
1471  BLI_assert(dist == NULL || ofs != NULL);
1472 
1473  copy_m3_m4(nmat, mat);
1474  normalize_m3(nmat);
1475 
1476  /* Offset */
1477  if (ofs) {
1478  negate_v3_v3(ofs, mat[3]);
1479  }
1480 
1481  /* Quat */
1482  if (quat) {
1483  mat3_normalized_to_quat(quat, nmat);
1484  invert_qt_normalized(quat);
1485  }
1486 
1487  if (ofs && dist) {
1488  madd_v3_v3fl(ofs, nmat[2], *dist);
1489  }
1490 }
1491 
1492 void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
1493 {
1494  const float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
1495  float dvec[3] = {0.0f, 0.0f, dist};
1496 
1497  quat_to_mat4(mat, iviewquat);
1498  mul_mat3_m4_v3(mat, dvec);
1499  sub_v3_v3v3(mat[3], dvec, ofs);
1500 }
1501 
1502 void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
1503 {
1504  ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
1505 
1506  if (lens) {
1508 
1511  *lens = params.lens;
1512  }
1513 }
1514 
1516  Object *ob,
1517  const float ofs[3],
1518  const float quat[4],
1519  const float dist)
1520 {
1521  float mat[4][4];
1522  ED_view3d_to_m4(mat, ofs, quat, dist);
1523 
1524  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
1525  BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true);
1526 }
1527 
1528 static bool view3d_camera_to_view_selected_impl(struct Main *bmain,
1530  const Scene *scene,
1531  Object *camera_ob,
1532  float *r_clip_start,
1533  float *r_clip_end)
1534 {
1535  Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
1536  float co[3]; /* the new location to apply */
1537  float scale; /* only for ortho cameras */
1538 
1540  depsgraph, scene, camera_ob_eval, co, &scale, r_clip_start, r_clip_end)) {
1542  float obmat_new[4][4];
1543  bool is_ortho_camera = false;
1544 
1545  if ((camera_ob_eval->type == OB_CAMERA) &&
1546  (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
1547  ((Camera *)camera_ob->data)->ortho_scale = scale;
1548  is_ortho_camera = true;
1549  }
1550 
1551  copy_m4_m4(obmat_new, camera_ob_eval->obmat);
1552  copy_v3_v3(obmat_new[3], co);
1553 
1554  /* only touch location */
1555  BKE_object_tfm_protected_backup(camera_ob, &obtfm);
1556  BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
1558 
1559  /* notifiers */
1560  DEG_id_tag_update_ex(bmain, &camera_ob->id, ID_RECALC_TRANSFORM);
1561  if (is_ortho_camera) {
1562  DEG_id_tag_update_ex(bmain, camera_ob->data, ID_RECALC_PARAMETERS);
1563  }
1564 
1565  return true;
1566  }
1567 
1568  return false;
1569 }
1570 
1573  const Scene *scene,
1574  Object *camera_ob)
1575 {
1576  return view3d_camera_to_view_selected_impl(bmain, depsgraph, scene, camera_ob, NULL, NULL);
1577 }
1578 
1581  const Scene *scene,
1582  Object *camera_ob)
1583 {
1584  float clip_start;
1585  float clip_end;
1587  bmain, depsgraph, scene, camera_ob, &clip_start, &clip_end)) {
1588 
1589  ((Camera *)camera_ob->data)->clip_start = clip_start;
1590  ((Camera *)camera_ob->data)->clip_end = clip_end;
1591 
1592  /* TODO: Support update via #ID_RECALC_PARAMETERS. */
1593  Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
1594  ((Camera *)camera_ob_eval->data)->clip_start = clip_start;
1595  ((Camera *)camera_ob_eval->data)->clip_end = clip_end;
1596 
1597  return true;
1598  }
1599 
1600  return false;
1601 }
1602 
1605 /* -------------------------------------------------------------------- */
1609 struct ReadData {
1610  int count;
1612  float r_depth;
1613 };
1614 
1615 static bool depth_read_test_fn(const void *value, void *userdata)
1616 {
1617  struct ReadData *data = userdata;
1618  float depth = *(float *)value;
1619  if (depth < data->r_depth) {
1620  data->r_depth = depth;
1621  }
1622 
1623  if ((++data->count) >= data->count_max) {
1624  /* Outside the margin. */
1625  return true;
1626  }
1627  return false;
1628 }
1629 
1631  const int mval[2],
1632  int margin,
1633  float *r_depth)
1634 {
1635  BLI_assert(1.0 <= vd->depth_range[1]);
1636  *r_depth = 1.0f;
1637 
1638  if (!vd || !vd->depths) {
1639  return false;
1640  }
1641 
1642  int x = mval[0];
1643  int y = mval[1];
1644  if (x < 0 || y < 0 || x >= vd->w || y >= vd->h) {
1645  return false;
1646  }
1647 
1648  float depth = 1.0f;
1649  if (margin) {
1650  int shape[2] = {vd->w, vd->h};
1651  int pixel_count = (min_ii(x + margin + 1, shape[1]) - max_ii(x - margin, 0)) *
1652  (min_ii(y + margin + 1, shape[0]) - max_ii(y - margin, 0));
1653 
1654  struct ReadData data;
1655  data.count = 0;
1656  data.count_max = pixel_count;
1657  data.r_depth = 1.0f;
1658 
1659  /* TODO: No need to go spiral. */
1661  depth = data.r_depth;
1662  }
1663  else {
1664  depth = vd->depths[y * vd->w + x];
1665  }
1666 
1667  if (depth != 1.0f) {
1668  *r_depth = depth;
1669  return true;
1670  }
1671 
1672  return false;
1673 }
1674 
1676  const ViewDepths *depths,
1677  const int mval[2],
1678  float r_normal[3])
1679 {
1680  /* NOTE: we could support passing in a radius.
1681  * For now just read 9 pixels. */
1682 
1683  /* pixels surrounding */
1684  bool depths_valid[9] = {false};
1685  float coords[9][3] = {{0}};
1686 
1687  for (int x = 0, i = 0; x < 2; x++) {
1688  for (int y = 0; y < 2; y++) {
1689  const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
1690 
1691  float depth_fl = 1.0f;
1692  ED_view3d_depth_read_cached(depths, mval_ofs, 0, &depth_fl);
1693  const double depth = (double)depth_fl;
1694  if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
1695  if (ED_view3d_depth_unproject_v3(region, mval_ofs, depth, coords[i])) {
1696  depths_valid[i] = true;
1697  }
1698  }
1699  i++;
1700  }
1701  }
1702 
1703  const int edges[2][6][2] = {
1704  /* x edges */
1705  {{0, 1}, {1, 2}, {3, 4}, {4, 5}, {6, 7}, {7, 8}},
1706  /* y edges */
1707  {{0, 3}, {3, 6}, {1, 4}, {4, 7}, {2, 5}, {5, 8}},
1708  };
1709 
1710  float cross[2][3] = {{0.0f}};
1711 
1712  for (int i = 0; i < 6; i++) {
1713  for (int axis = 0; axis < 2; axis++) {
1714  if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
1715  float delta[3];
1716  sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
1717  add_v3_v3(cross[axis], delta);
1718  }
1719  }
1720  }
1721 
1722  cross_v3_v3v3(r_normal, cross[0], cross[1]);
1723 
1724  if (normalize_v3(r_normal) != 0.0f) {
1725  return true;
1726  }
1727  return false;
1728 }
1729 
1731  const int mval[2],
1732  const double depth,
1733  float r_location_world[3])
1734 {
1735  float centx = (float)mval[0] + 0.5f;
1736  float centy = (float)mval[1] + 0.5f;
1737  return ED_view3d_unproject_v3(region, centx, centy, depth, r_location_world);
1738 }
1739 
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:236
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, float *r_clip_start, float *r_clip_end)
#define CAMERA_PARAM_ZOOM_INIT_PERSP
Definition: BKE_camera.h:77
void BKE_camera_params_init(CameraParams *params)
Definition: camera.c:265
void BKE_camera_params_from_view3d(CameraParams *params, const struct Depsgraph *depsgraph, const struct View3D *v3d, const struct RegionView3D *rv3d)
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:364
#define CAMERA_PARAM_ZOOM_INIT_CAMOB
Definition: BKE_camera.h:76
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:1009
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:733
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:997
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
General operations, lookup, etc. for blender objects.
void BKE_object_tfm_protected_restore(struct Object *ob, const ObjectTfmProtectedChannels *obtfm, short protectflag)
Definition: object.cc:3007
void BKE_object_apply_mat4_ex(struct Object *ob, const float mat[4][4], struct Object *parent, const float parentinv[4][4], bool use_compat)
Definition: object.cc:3532
void BKE_object_apply_mat4(struct Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
Definition: object.cc:3575
void BKE_object_tfm_protected_backup(const struct Object *ob, ObjectTfmProtectedChannels *obtfm)
float BKE_screen_view3d_zoom_from_fac(float zoomfac)
Definition: screen.c:1032
struct ARegion * BKE_area_find_region_active_win(struct ScrArea *area)
Definition: screen.c:883
float BKE_screen_view3d_zoom_to_fac(float camzoom)
Definition: screen.c:1027
struct ARegion struct ARegion struct ScrArea struct ScrArea * BKE_screen_find_big_area(struct bScreen *screen, int spacetype, short min)
Definition: screen.c:937
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:46
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:336
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
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:32
#define M_PI_4
Definition: BLI_math_base.h:26
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:33
bool isect_planes_v3_fn(const float planes[][4], int planes_len, float eps_coplanar, 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:2168
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void mul_m4_v4(const float M[4][4], float r[4])
Definition: math_matrix.c:862
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1912
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void normalize_m4_m4(float R[4][4], const float M[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1965
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2509
void invert_qt_normalized(float q[4])
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:59
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:33
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:867
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_v4_v4(float r[4], const float a[4])
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])
void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size)
Definition: rct.c:469
#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:35
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_PARAMETERS
Definition: DNA_ID.h:854
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ CAM_ORTHO
#define DEFAULT_SENSOR_WIDTH
@ OB_SOLID
@ OB_RENDER
@ OB_MODE_TEXTURE_PAINT
Object is a sort of wrapper for general info.
@ OB_CAMERA
@ OB_LOCK_ROT4D
@ OB_LOCK_SCALEZ
@ OB_LOCK_SCALEX
@ OB_LOCK_SCALEY
@ OB_LOCK_SCALE
@ OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK
@ RGN_TYPE_WINDOW
@ RGN_ALIGN_QSPLIT
@ SPACE_VIEW3D
@ USER_AUTOPERSP
@ V3D_SHADING_BACKGROUND_VIEWPORT
@ V3D_SHADING_BACKGROUND_WORLD
@ V3D_SHADING_TEXTURE_COLOR
#define RV3D_VIEW_IS_AXIS(view)
#define RV3D_CAMZOOM_MAX
#define V3D_LOCK_CAMERA
#define RV3D_CAMZOOM_MIN_FACTOR
#define RV3D_LOCK_FLAGS(rv3d)
#define RV3D_CAMZOOM_MAX_FACTOR
@ RV3D_VIEW_AXIS_ROLL_270
@ RV3D_VIEW_AXIS_ROLL_0
#define RV3D_CAMOB
#define RV3D_ZOFFSET_DISABLED
#define RV3D_VIEW_BACK
@ RV3D_LOCK_ANY_TRANSFORM
@ RV3D_LOCK_ROTATION
@ RV3D_BOXVIEW
@ RV3D_BOXCLIP
#define RV3D_CLIPPING
#define RV3D_VIEW_BOTTOM
#define RV3D_VIEW_LEFT
#define RV3D_VIEW_RIGHT
#define RV3D_PERSP
#define RV3D_VIEW_TOP
#define RV3D_CAMZOOM_MIN
#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:729
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
bool ED_undo_is_memfile_compatible(const struct bContext *C)
void ED_undo_grouped_push(struct bContext *C, const char *str)
Definition: ed_undo.c:382
void ED_undo_push(struct bContext *C, const char *str)
Definition: ed_undo.c:100
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_unproject_v3(const struct ARegion *region, float regionx, float regiony, float regionz, float world[3])
#define VIEW3D_DIST_FALLBACK
Definition: ED_view3d.h:1230
@ V3D_DEPTH_NO_GPENCIL
Definition: ED_view3d.h:182
void ED_view3d_depth_override(struct Depsgraph *depsgraph, struct ARegion *region, struct View3D *v3d, struct Object *obact, eV3DDepthOverrideMode mode, struct ViewDepths **r_depths)
Definition: view3d_draw.c:2294
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:225
#define GPU_matrix_projection_set(x)
Definition: GPU_matrix.h:226
void GPU_polygon_offset(float viewdist, float dist)
Definition: gpu_matrix.cc:721
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define C
Definition: RandGen.cpp:25
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1165
@ TH_BACK
Definition: UI_resources.h:39
#define ND_TRANSFORM
Definition: WM_types.h:405
#define NC_OBJECT
Definition: WM_types.h:329
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 tanf(x)
Definition: cuda/compat.h:104
Scene scene
const Depsgraph * depsgraph
void * user_data
#define str(s)
uint pos
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
Definition: keyframing.c:2850
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
Definition: keyingsets.c:1038
KeyingSet * ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
Definition: keyingsets.c:696
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
Definition: keyingsets.c:924
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define atanf(x)
Definition: metal/compat.h:223
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned a[3]
Definition: RandGen.cpp:78
static void area(int d1, int d2, int e1, int e2, float weights[2])
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
static double epsilon
const char * RE_engine_id_BLENDER_WORKBENCH
Definition: scene.cc:1696
#define min(a, b)
Definition: sort.c:35
void * regiondata
struct ARegion * prev
struct ARegion * next
short alignment
short regiontype
float vec[8][3]
Definition: DNA_ID.h:368
Definition: BKE_main.h:121
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]
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
unsigned short w
Definition: ED_view3d.h:78
float * depths
Definition: ED_view3d.h:80
double depth_range[2]
Definition: ED_view3d.h:81
unsigned short h
Definition: ED_view3d.h:78
float horr
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63
float max
void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
Definition: view3d_draw.c:2206
float view3d_depth_near(ViewDepths *d)
Definition: view3d_draw.c:2271
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
Definition: view3d_utils.c:419
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:551
Camera * ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
Definition: view3d_utils.c:94
bool ED_view3d_depth_read_cached(const ViewDepths *vd, const int mval[2], int margin, float *r_depth)
bool ED_view3d_depth_unproject_v3(const ARegion *region, const int mval[2], const double depth, float r_location_world[3])
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:572
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *region, const Object *ob, const rcti *rect)
Definition: view3d_utils.c:265
static bool view3d_camera_lock_undo_ex(const char *str, View3D *v3d, RegionView3D *rv3d, struct bContext *C, bool undo_group)
Definition: view3d_utils.c:711
bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *region)
Definition: view3d_utils.c:477
bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
Definition: view3d_utils.c:435
static bool view3d_boundbox_clip_m4(const BoundBox *bb, const float persmatob[4][4])
Definition: view3d_utils.c:363
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:58
bool ED_view3d_depth_read_cached_seg(const ViewDepths *vd, const int mval_sta[2], const int mval_end[2], int margin, float *depth)
void ED_view3d_lastview_store(RegionView3D *rv3d)
Definition: view3d_utils.c:440
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:665
bool ED_view3d_distance_set_from_location(RegionView3D *rv3d, const float dist_co[3], const float dist_min)
bool ED_view3d_camera_lock_undo_grouped_push(const char *str, View3D *v3d, RegionView3D *rv3d, bContext *C)
Definition: view3d_utils.c:731
bool ED_view3d_camera_view_zoom_scale(RegionView3D *rv3d, const float scale)
Definition: view3d_utils.c:512
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:630
static bool view3d_camera_to_view_selected_impl(struct Main *bmain, Depsgraph *depsgraph, const Scene *scene, Object *camera_ob, float *r_clip_start, float *r_clip_end)
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:310
void ED_view3d_dist_range_get(const View3D *v3d, float r_dist_range[2])
Definition: view3d_utils.c:104
static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
Definition: view3d_utils.c:847
void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
Definition: view3d_utils.c:251
bool ED_view3d_clip_range_get(const Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, float *r_clipsta, float *r_clipend, const bool use_ortho_factor)
Definition: view3d_utils.c:110
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_depth_read_cached_normal(const ARegion *region, const ViewDepths *depths, const int mval[2], float r_normal[3])
bool ED_view3d_clipping_clamp_minmax(const RegionView3D *rv3d, float min[3], float max[3])
Definition: view3d_utils.c:317
bool ED_view3d_context_activate(bContext *C)
Definition: view3d_utils.c:219
void ED_view3d_lock_clear(View3D *v3d)
Definition: view3d_utils.c:450
void view3d_operator_needs_opengl(const bContext *C)
Definition: view3d_utils.c:176
void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *region)
Definition: view3d_utils.c:184
bool ED_view3d_camera_view_pan(ARegion *region, const float event_ofs[2])
Definition: view3d_utils.c:525
bool ED_view3d_camera_lock_undo_push(const char *str, View3D *v3d, RegionView3D *rv3d, bContext *C)
Definition: view3d_utils.c:726
void view3d_boxview_copy(ScrArea *area, ARegion *region)
Definition: view3d_utils.c:914
bool ED_view3d_camera_lock_undo_test(const View3D *v3d, const RegionView3D *rv3d, struct bContext *C)
Definition: view3d_utils.c:692
void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
Definition: view3d_utils.c:199
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:459
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:138
bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
Definition: view3d_utils.c:404
void view3d_boxview_sync(ScrArea *area, ARegion *region)
Definition: view3d_utils.c:890
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:545
static void view3d_boxview_clip(ScrArea *area)
Definition: view3d_utils.c:747
void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
bool ED_view3d_camera_to_view_selected_with_set_clipping(struct Main *bmain, Depsgraph *depsgraph, const Scene *scene, Object *camera_ob)
void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
Definition: view3d_utils.c:567
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:938
static float view3d_quat_axis[6][4][4]
bool ED_view3d_quat_to_axis_view_and_reset_quat(float quat[4], const float epsilon, char *r_view, char *r_view_axis_roll)
bool ED_view3d_has_workbench_in_texture_color(const Scene *scene, const Object *ob, const View3D *v3d)
Definition: view3d_utils.c:74
void WM_main_add_notifier(unsigned int type, void *reference)
void wmViewport(const rcti *winrct)
Definition: wm_subwindow.c:21