[Bf-blender-cvs] [8e981efe38a] master: 3D View: support axis views with axis-aligned roll

Campbell Barton noreply at git.blender.org
Sun Feb 9 15:54:23 CET 2020


Commit: 8e981efe38ae6d0760f08c49564010104eee78c6
Author: Campbell Barton
Date:   Sun Feb 9 11:50:25 2020 +1100
Branches: master
https://developer.blender.org/rB8e981efe38ae6d0760f08c49564010104eee78c6

3D View: support axis views with axis-aligned roll

Previously any of the named views could not have any roll,
this commit supports roll as long as it's axis-aligned (90,180,270 deg).

This is useful for snapping to views,
an improvement on cebd025e02f11.

===================================================================

M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/editors/space_view3d/view3d_edit.c
M	source/blender/editors/space_view3d/view3d_utils.c
M	source/blender/makesdna/DNA_view3d_types.h

===================================================================

diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index cfeffae1052..a1bc3b028b6 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -622,9 +622,11 @@ void ED_view3d_update_viewmat(struct Depsgraph *depsgraph,
                               float winmat[4][4],
                               const struct rcti *rect,
                               bool offscreen);
-bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
-char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
-bool ED_view3d_quat_is_axis_aligned(const float viewquat[4]);
+bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float quat[4]);
+bool ED_view3d_quat_to_axis_view(const float viewquat[4],
+                                 const float epsilon,
+                                 char *r_view,
+                                 char *r_view_axis_rotation);
 
 char ED_view3d_lock_view_from_index(int index);
 char ED_view3d_axis_view_opposite(char view);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 14ea3aca623..62fa2cd8fa7 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3812,6 +3812,7 @@ static void region_quadview_init_rv3d(
 
   rv3d->viewlock = viewlock;
   rv3d->view = view;
+  rv3d->view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
   rv3d->persp = persp;
 
   ED_view3d_lock(rv3d);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d092de4fcce..7bfb0460c41 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -27,6 +27,7 @@
 #include "BLI_math.h"
 #include "BLI_rect.h"
 #include "BLI_string.h"
+#include "BLI_string_utils.h"
 #include "BLI_threads.h"
 #include "BLI_jitter_2d.h"
 
@@ -1255,21 +1256,44 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d, int xoffset, int *yoffs
 {
   RegionView3D *rv3d = ar->regiondata;
   const char *name = view3d_get_name(v3d, rv3d);
+  const char *name_array[3] = {name, NULL, NULL};
+  int name_array_len = 1;
   const int font_id = BLF_default();
 
+  /* 6 is the maximum size of the axis roll text. */
   /* increase size for unicode languages (Chinese in utf-8...) */
 #ifdef WITH_INTERNATIONAL
-  char tmpstr[96];
+  char tmpstr[96 + 6];
 #else
-  char tmpstr[32];
+  char tmpstr[32 + 6];
 #endif
 
   BLF_enable(font_id, BLF_SHADOW);
   BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
   BLF_shadow_offset(font_id, 1, -1);
 
+  if (RV3D_VIEW_IS_AXIS(rv3d->view) && (rv3d->view_axis_roll != RV3D_VIEW_AXIS_ROLL_0)) {
+    const char *axis_roll;
+    switch (rv3d->view_axis_roll) {
+      case RV3D_VIEW_AXIS_ROLL_90:
+        axis_roll = " 90\xC2\xB0";
+        break;
+      case RV3D_VIEW_AXIS_ROLL_180:
+        axis_roll = " 180\xC2\xB0";
+        break;
+      default:
+        axis_roll = " -90\xC2\xB0";
+        break;
+    }
+    name_array[name_array_len++] = axis_roll;
+  }
+
   if (v3d->localvd) {
-    BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
+    name_array[name_array_len++] = IFACE_(" (Local)");
+  }
+
+  if (name_array_len > 1) {
+    BLI_string_join_array(tmpstr, sizeof(tmpstr), name_array, name_array_len);
     name = tmpstr;
   }
 
@@ -1277,11 +1301,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d, int xoffset, int *yoffs
 
   *yoffset -= U.widget_unit;
 
-#ifdef WITH_INTERNATIONAL
   BLF_draw_default(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
-#else
-  BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
-#endif
 
   BLF_disable(font_id, BLF_SHADOW);
 }
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 83fb87264e3..a045988cb55 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -700,9 +700,9 @@ static void viewrotate_apply_snap(ViewOpsData *vod)
 
     if (found) {
       /* lock 'quat_best' to an axis view if we can */
-      rv3d->view = ED_view3d_quat_to_axis_view(quat_best, 0.01f);
+      ED_view3d_quat_to_axis_view(quat_best, 0.01f, &rv3d->view, &rv3d->view_axis_roll);
       if (rv3d->view != RV3D_VIEW_USER) {
-        ED_view3d_quat_from_axis_view(rv3d->view, quat_best);
+        ED_view3d_quat_from_axis_view(rv3d->view, rv3d->view_axis_roll, quat_best);
       }
     }
     else {
@@ -3804,7 +3804,8 @@ static void axis_set_view(bContext *C,
                           View3D *v3d,
                           ARegion *ar,
                           const float quat_[4],
-                          short view,
+                          char view,
+                          char view_axis_roll,
                           int perspo,
                           const float *align_to_quat,
                           const int smooth_viewtx)
@@ -3818,10 +3819,12 @@ static void axis_set_view(bContext *C,
   if (align_to_quat) {
     mul_qt_qtqt(quat, quat, align_to_quat);
     rv3d->view = view = RV3D_VIEW_USER;
+    rv3d->view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
   }
 
   if (align_to_quat == NULL) {
     rv3d->view = view;
+    rv3d->view_axis_roll = view_axis_roll;
   }
 
   if (rv3d->viewlock & RV3D_LOCKED) {
@@ -3901,6 +3904,7 @@ static int view_axis_exec(bContext *C, wmOperator *op)
   RegionView3D *rv3d;
   static int perspo = RV3D_PERSP;
   int viewnum;
+  int view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
   const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
 
   /* no NULL check is needed, poll checks */
@@ -3928,58 +3932,73 @@ static int view_axis_exec(bContext *C, wmOperator *op)
   }
 
   if (RNA_boolean_get(op->ptr, "relative")) {
-    float z_rel[3];
+    float quat_rotate[4];
+    float quat_test[4];
 
-    if (viewnum == RV3D_VIEW_RIGHT) {
-      negate_v3_v3(z_rel, rv3d->viewinv[0]);
+    if (viewnum == RV3D_VIEW_LEFT) {
+      axis_angle_to_quat(quat_rotate, rv3d->viewinv[1], -M_PI / 2.0f);
     }
-    else if (viewnum == RV3D_VIEW_LEFT) {
-      copy_v3_v3(z_rel, rv3d->viewinv[0]);
+    else if (viewnum == RV3D_VIEW_RIGHT) {
+      axis_angle_to_quat(quat_rotate, rv3d->viewinv[1], M_PI / 2.0f);
     }
     else if (viewnum == RV3D_VIEW_TOP) {
-      negate_v3_v3(z_rel, rv3d->viewinv[1]);
+      axis_angle_to_quat(quat_rotate, rv3d->viewinv[0], -M_PI / 2.0f);
     }
     else if (viewnum == RV3D_VIEW_BOTTOM) {
-      copy_v3_v3(z_rel, rv3d->viewinv[1]);
+      axis_angle_to_quat(quat_rotate, rv3d->viewinv[0], M_PI / 2.0f);
     }
     else if (viewnum == RV3D_VIEW_FRONT) {
-      negate_v3_v3(z_rel, rv3d->viewinv[2]);
+      unit_qt(quat_rotate);
     }
     else if (viewnum == RV3D_VIEW_BACK) {
-      copy_v3_v3(z_rel, rv3d->viewinv[2]);
+      axis_angle_to_quat(quat_rotate, rv3d->viewinv[0], M_PI);
     }
     else {
       BLI_assert(0);
     }
 
-    float angle_max = FLT_MAX;
-    int view_closest = -1;
+    mul_qt_qtqt(quat_test, rv3d->viewquat, quat_rotate);
+
+    float angle_best = FLT_MAX;
+    int view_best = -1;
+    int view_axis_roll_best = -1;
     for (int i = RV3D_VIEW_FRONT; i <= RV3D_VIEW_BOTTOM; i++) {
-      float quat[4];
-      float mat[3][3];
-      ED_view3d_quat_from_axis_view(i, quat);
-      quat[0] *= -1.0f;
-      quat_to_mat3(mat, quat);
-      if (align_quat) {
-        mul_qt_qtqt(quat, quat, align_quat);
-      }
-      const float angle_test = angle_normalized_v3v3(z_rel, mat[2]);
-      if (angle_max > angle_test) {
-        angle_max = angle_test;
-        view_closest = i;
+      for (int j = RV3D_VIEW_AXIS_ROLL_0; j <= RV3D_VIEW_AXIS_ROLL_270; j++) {
+        float quat_axis[4];
+        ED_view3d_quat_from_axis_view(i, j, quat_axis);
+        if (align_quat) {
+          mul_qt_qtqt(quat_axis, quat_axis, align_quat);
+        }
+        const float angle_test = fabsf(angle_signed_qtqt(quat_axis, quat_test));
+        if (angle_best > angle_test) {
+          angle_best = angle_test;
+          view_best = i;
+          view_axis_roll_best = j;
+        }
       }
     }
-    if (view_closest == -1) {
-      view_closest = RV3D_VIEW_FRONT;
+    if (view_best == -1) {
+      view_best = RV3D_VIEW_FRONT;
+      view_axis_roll_best = RV3D_VIEW_AXIS_ROLL_0;
     }
-    viewnum = view_closest;
+
+    /* Disallow non-upright views in turn-table modes,
+     * it's too difficult to navigate out of them. */
+    if ((U.flag & USER_TRACKBALL) == 0) {
+      if (!ELEM(view_best, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
+        view_axis_roll_best = RV3D_VIEW_AXIS_ROLL_0;
+      }
+    }
+
+    viewnum = view_best;
+    view_axis_roll = view_axis_roll_best;
   }
 
   /* Use this to test if we started out with a camera */
   const int nextperspo = (rv3d->persp == RV3D_CAMOB) ? rv3d->lpersp : perspo;
   float quat[4];
-  ED_view3d_quat_from_axis_view(viewnum, quat);
-  axis_set_view(C, v3d, ar, quat, viewnum, nextperspo, align_quat, smooth_viewtx);
+  ED_view3d_quat_from_axis_view(viewnum, view_axis_roll, quat);
+  axis_set_view(C, v3d, ar, quat, viewnum, view_axis_roll, nextperspo, align_quat, smooth_viewtx);
 
   perspo = rv3d->persp;
 
@@ -4105,7 +4124,15 @@ static int view_camera_exec(bContext *C, wmOperator *op)
     else {
       /* return to settings of last view */
       /* does view3d_smooth_view too */
-      axis_set_view(C, v3d, ar, rv3d->lviewquat, rv3d->lview, rv3d->lpersp, NULL, smooth_viewtx);
+      axis_set_view(C,
+                    v3d,
+                    ar,
+                    rv3d->lviewquat,
+                    rv3d->lview,
+                    rv3d->lview_axis_roll,
+                    rv3d->lpersp,
+                    NULL,
+                    smooth_viewtx);
     }
   }
 
@@ -4217,7 +4244,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
       if (view_opposite != RV3D_VIEW_USER) {
         rv3d->view = view_opposite;
         /* avoid float in-precision, just get a new orientation */
-        ED_view3d_quat_from_axis_view(view_opposite, quat_new);
+        ED_view3d_quat_from_axis_view(view_opposite, rv3d->view_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list