View3D: Quad-view opposite axis switching
authorCampbell Barton <ideasman42@gmail.com>
Thu, 12 Mar 2015 17:45:40 +0000 (04:45 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 12 Mar 2015 17:48:23 +0000 (04:48 +1100)
Pressing Numpad9 now orbits to the opposite side in any viewport,
with the advantage that it can switch locked-quadview axis to their opposite side.

release/scripts/startup/bl_ui/space_view3d.py
source/blender/editors/include/ED_view3d.h
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/space_view3d/view3d_view.c

index 10e7d89cf68786b10eb5e0eada1ce67b59ca37e3..c65cebfde10a7af344425e5c574f36b51de6cd5a 100644 (file)
@@ -446,6 +446,9 @@ class VIEW3D_MT_view_navigation(Menu):
         layout = self.layout
 
         layout.operator_enum("view3d.view_orbit", "type")
+        props = layout.operator("view3d.view_orbit", "Orbit Opposite")
+        props.type = 'ORBITRIGHT'
+        props.angle = pi
 
         layout.separator()
 
index 30f8fb4f9228e9a11e1281eeb1031974403048a7..5fc5738c88ff6a0558745fca2b4a1ce64dbbb5b1 100644 (file)
@@ -326,6 +326,7 @@ void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct AR
 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);
 char ED_view3d_lock_view_from_index(int index);
+char ED_view3d_axis_view_opposite(char view);
 bool ED_view3d_lock(struct RegionView3D *rv3d);
 
 uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
index 4043a86eb4460f558fba59015be6fc208b46dcf8..51915e05a9e77cbb2b88ea1c95037d194979d571 100644 (file)
@@ -3874,23 +3874,37 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
        ARegion *ar;
        RegionView3D *rv3d;
        int orbitdir;
+       char view_opposite;
+       PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
+       float angle = RNA_property_is_set(op->ptr, prop_angle) ?
+                     RNA_property_float_get(op->ptr, prop_angle) : DEG2RADF((float)U.pad_rot_angle);
 
        /* no NULL check is needed, poll checks */
-       ED_view3d_context_user_region(C, &v3d, &ar);
+       v3d = CTX_wm_view3d(C);
+       ar = CTX_wm_region(C);
        rv3d = ar->regiondata;
 
+       /* support for switching to the opposite view (even when in locked views) */
+       view_opposite = (fabsf(angle) == (float)M_PI) ? ED_view3d_axis_view_opposite(rv3d->view) : RV3D_VIEW_USER;
        orbitdir = RNA_enum_get(op->ptr, "type");
 
-       if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+       if ((rv3d->viewlock & RV3D_LOCKED) && (view_opposite == RV3D_VIEW_USER)) {
+               /* no NULL check is needed, poll checks */
+               ED_view3d_context_user_region(C, &v3d, &ar);
+               rv3d = ar->regiondata;
+       }
+
+       if ((rv3d->viewlock & RV3D_LOCKED) == 0 || (view_opposite != RV3D_VIEW_USER)) {
                if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
                        int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-                       float angle = DEG2RADF((float)U.pad_rot_angle);
                        float quat_mul[4];
                        float quat_new[4];
                        float ofs_new[3];
                        float *ofs_new_pt = NULL;
 
-                       view3d_ensure_persp(v3d, ar);
+                       if (view_opposite == RV3D_VIEW_USER) {
+                               view3d_ensure_persp(v3d, ar);
+                       }
 
                        if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
                                const float zvec[3] = {0.0f, 0.0f, 1.0f};
@@ -3913,7 +3927,15 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
                        }
 
                        mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
-                       rv3d->view = RV3D_VIEW_USER;
+
+                       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);
+                       }
+                       else {
+                               rv3d->view = RV3D_VIEW_USER;
+                       }
 
                        if (U.uiflag & USER_ORBIT_SELECTION) {
                                float dyn_ofs[3];
@@ -3944,6 +3966,8 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
 
 void VIEW3D_OT_view_orbit(wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+
        /* identifiers */
        ot->name = "View Orbit";
        ot->description = "Orbit the view";
@@ -3957,7 +3981,11 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
        ot->flag = 0;
        
        /* properties */
+       prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
+       RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
        ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
+
 }
 
 
index 0457f5f2d526ca9bbd84ce8d6f9bc85db98cca92..8c668b2b8e0c5ccc1b357a983abd136b876e2896 100644 (file)
@@ -299,6 +299,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANUP);
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD6, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
+       kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD9, KM_PRESS, 0, 0);
+       RNA_enum_set(kmi->ptr, "type", V3D_VIEW_STEPRIGHT);
+       RNA_float_set(kmi->ptr, "angle", (float)M_PI);
 
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT);
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT);
index 76d9762ab0997a1ae8cf91b71c075ff9257ada49..4888c6846d2f1f5103140dc818774b053c9e1fbd 100644 (file)
@@ -896,6 +896,21 @@ char ED_view3d_lock_view_from_index(int index)
 
 }
 
+char ED_view3d_axis_view_opposite(char view)
+{
+       switch (view) {
+               case RV3D_VIEW_FRONT:   return RV3D_VIEW_BACK;
+               case RV3D_VIEW_BACK:    return RV3D_VIEW_FRONT;
+               case RV3D_VIEW_LEFT:    return RV3D_VIEW_RIGHT;
+               case RV3D_VIEW_RIGHT:   return RV3D_VIEW_LEFT;
+               case RV3D_VIEW_TOP:     return RV3D_VIEW_BOTTOM;
+               case RV3D_VIEW_BOTTOM:  return RV3D_VIEW_TOP;
+       }
+
+       return RV3D_VIEW_USER;
+}
+
+
 bool ED_view3d_lock(RegionView3D *rv3d)
 {
        return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);