remove unused args in draw*.c and some in view*.c, tag some as UNUSED().
[blender.git] / source / blender / editors / space_view3d / view3d_edit.c
index bbccddd02579277a242e2f2c28d1b559b726fd5f..9f1b55ee2ce511b434a545c58137cb3fcce5f2d1 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id:
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
 #include <math.h>
 #include <float.h>
 
-#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_lamp_types.h"
 #include "DNA_object_types.h"
-#include "DNA_space_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_world_types.h"
 
 #include "MEM_guardedalloc.h"
 
 #include "BLI_math.h"
 #include "BLI_rand.h"
 
-#include "BKE_action.h"
 #include "BKE_context.h"
-#include "BKE_depsgraph.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
 #include "BKE_object.h"
-#include "BKE_global.h"
 #include "BKE_paint.h"
 #include "BKE_report.h"
 #include "BKE_scene.h"
-#include "BKE_screen.h"
-#include "BKE_utildefines.h"
 
-#include "RE_pipeline.h"       // make_stars
 
 #include "BIF_gl.h"
 
 
 #include "ED_particle.h"
 #include "ED_retopo.h"
-#include "ED_space_api.h"
 #include "ED_screen.h"
 #include "ED_transform.h"
-#include "ED_types.h"
+#include "ED_mesh.h"
 
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
 
 #include "PIL_time.h" /* smoothview */
 
@@ -109,9 +93,7 @@ static void view3d_boxview_clip(ScrArea *sa)
 
                                        if(ar->winx>ar->winy) y1= ar->winy*rv3d->dist/ar->winx;
                                        else y1= rv3d->dist;
-
-                                       ofs[0]= rv3d->ofs[0];
-                                       ofs[1]= rv3d->ofs[1];
+                                       copy_v2_v2(ofs, rv3d->ofs);
                                }
                                else if(ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
                                        ofs[2]= rv3d->ofs[2];
@@ -221,7 +203,7 @@ void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
 
                        if(rv3dtest->viewlock) {
                                rv3dtest->dist= rv3d->dist;
-                               VECCOPY(rv3dtest->ofs, rv3d->ofs);
+                               copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
                                ED_region_tag_redraw(artest);
                        }
                }
@@ -325,18 +307,17 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
        vod->ar= CTX_wm_region(C);
        vod->rv3d= rv3d= vod->ar->regiondata;
        vod->dist0= rv3d->dist;
-       QUATCOPY(vod->oldquat, rv3d->viewquat);
+       copy_qt_qt(vod->oldquat, rv3d->viewquat);
        vod->origx= vod->oldx= event->x;
        vod->origy= vod->oldy= event->y;
        vod->origkey= event->type; /* the key that triggered the operator.  */
        vod->use_dyn_ofs= (U.uiflag & USER_ORBIT_SELECTION) ? 1:0;
 
        if (vod->use_dyn_ofs) {
-               VECCOPY(vod->ofs, rv3d->ofs);
+               copy_v3_v3(vod->ofs, rv3d->ofs);
                /* If there's no selection, lastofs is unmodified and last value since static */
                calculateTransformCenter(C, V3D_CENTROID, lastofs);
-               VECCOPY(vod->dyn_ofs, lastofs);
-               mul_v3_fl(vod->dyn_ofs, -1.0f);
+               negate_v3_v3(vod->dyn_ofs, lastofs);
        }
        else if (U.uiflag & USER_ORBIT_ZBUF) {
 
@@ -352,8 +333,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
                                float mat[3][3];
                                float upvec[3];
 
-                               VECCOPY(my_origin, rv3d->ofs);
-                               negate_v3(my_origin);                           /* ofs is flipped */
+                               negate_v3_v3(my_origin, rv3d->ofs);                             /* ofs is flipped */
 
                                /* Set the dist value to be the distance from this 3d point */
                                /* this means youll always be able to zoom into it and panning wont go bad when dist was zero */
@@ -371,11 +351,10 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
                                closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
                                vod->dist0 = rv3d->dist = len_v3v3(my_pivot, dvec);
 
-                               negate_v3(dvec);
-                               VECCOPY(rv3d->ofs, dvec);
+                               negate_v3_v3(rv3d->ofs, dvec);
                        }
                        negate_v3(vod->dyn_ofs);
-                       VECCOPY(vod->ofs, rv3d->ofs);
+                       copy_v3_v3(vod->ofs, rv3d->ofs);
                } else {
                        vod->ofs[0] = vod->ofs[1] = vod->ofs[2] = 0.0f;
                }
@@ -420,49 +399,49 @@ static const float thres = 0.93f; //cos(20 deg);
 #define COS45 0.70710678118654746
 #define SIN45 COS45
 
-static float snapquats[39][6] = {
-       /*{q0, q1, q3, q4, view, oposite_direction}*/
-{COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT, 0},  //front
-{0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK, 0}, //back
-{1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP, 0},       //top
-{0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM, 0},      //bottom
-{0.5, -0.5, -0.5, -0.5, RV3D_VIEW_LEFT, 0},    //left
-{0.5, -0.5, 0.5, 0.5, RV3D_VIEW_RIGHT, 0},      //right
+static float snapquats[39][5] = {
+       /*{q0, q1, q3, q4, view}*/
+       {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT},  //front
+       {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK}, //back
+       {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP},       //top
+       {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM},      //bottom
+       {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT},    //left
+       {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT},      //right
 
        /* some more 45 deg snaps */
-{0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0, 0},
-{0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0, 0},
-{0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0, 0},
-{0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0, 0},
-{0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0, 0},
-{0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0, 0},
-{0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0, 0},
-{0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0, 0},
-{0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0, 0},
-{0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0, 0},
-{0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0, 0},
-{0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0, 0},
-{0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0, 0},
-{0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0, 0},
-{-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0, 0},
-{-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0, 0},
-{-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0, 0},
-{0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0, 0},
-{-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0, 0},
-{-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0, 0},
-{-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0, 0},
-{-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0, 0},
-{-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0, 0},
-{-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0, 0},
-{-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0, 0},
-{0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0, 0},
-{-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0, 0},
-{-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0, 0},
-{-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0, 0},
-{-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0, 0},
-{-COS45, 0.0, 0.0, SIN45, 0, 0},
-{COS45, 0.0, 0.0, SIN45, 0, 0},
-{0.0, 0.0, 0.0, 1.0, 0, 0}
+       {0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0},
+       {0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0},
+       {0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0},
+       {0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0},
+       {0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0},
+       {0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0},
+       {0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0},
+       {0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0},
+       {0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0},
+       {0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0},
+       {0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0},
+       {0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0},
+       {0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0},
+       {0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0},
+       {-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0},
+       {-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0},
+       {-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0},
+       {0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0},
+       {-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0},
+       {-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0},
+       {-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0},
+       {-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0},
+       {-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0},
+       {-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0},
+       {-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0},
+       {0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0},
+       {-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0},
+       {-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0},
+       {-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0},
+       {-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0},
+       {-COS45, 0.0, 0.0, SIN45, 0},
+       {COS45, 0.0, 0.0, SIN45, 0},
+       {0.0, 0.0, 0.0, 1.0, 0}
 };
 
 enum {
@@ -507,9 +486,11 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
        WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
        WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
 
+       /* disabled mode switching for now, can re-implement better, later on
        WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
        WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
        WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+       */
        
        /* assign map to operators */
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
@@ -547,29 +528,26 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
                        * dragged. */
                phi = si * M_PI / 2.0;
 
-               si= sin(phi);
                q1[0]= cos(phi);
-               q1[1]*= si;
-               q1[2]*= si;
-               q1[3]*= si;
+               mul_v3_fl(q1+1, sin(phi));
                mul_qt_qtqt(rv3d->viewquat, q1, vod->oldquat);
 
                if (vod->use_dyn_ofs) {
                        /* compute the post multiplication quat, to rotate the offset correctly */
-                       QUATCOPY(q1, vod->oldquat);
+                       copy_qt_qt(q1, vod->oldquat);
                        conjugate_qt(q1);
                        mul_qt_qtqt(q1, q1, rv3d->viewquat);
 
                        conjugate_qt(q1); /* conj == inv for unit quat */
-                       VECCOPY(rv3d->ofs, vod->ofs);
-                       sub_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs);
+                       copy_v3_v3(rv3d->ofs, vod->ofs);
+                       sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
                        mul_qt_v3(q1, rv3d->ofs);
-                       add_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs);
+                       add_v3_v3(rv3d->ofs, vod->dyn_ofs);
                }
        }
        else {
                /* New turntable view code by John Aughey */
-               float si, phi, q1[4];
+               float phi, q1[4];
                float m[3][3];
                float m_inv[3][3];
                float xvec[3] = {1,0,0};
@@ -589,18 +567,15 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
 
                /* Perform the up/down rotation */
                phi = sensitivity * -(y - vod->oldy);
-               si = sin(phi);
                q1[0] = cos(phi);
-               q1[1] = si * xvec[0];
-               q1[2] = si * xvec[1];
-               q1[3] = si * xvec[2];
+               mul_v3_v3fl(q1+1, xvec, sin(phi));
                mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
 
                if (vod->use_dyn_ofs) {
                        conjugate_qt(q1); /* conj == inv for unit quat */
-                       sub_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs);
+                       sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
                        mul_qt_v3(q1, rv3d->ofs);
-                       add_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs);
+                       add_v3_v3(rv3d->ofs, vod->dyn_ofs);
                }
 
                /* Perform the orbital rotation */
@@ -612,33 +587,74 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
 
                if (vod->use_dyn_ofs) {
                        conjugate_qt(q1);
-                       sub_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs);
+                       sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
                        mul_qt_v3(q1, rv3d->ofs);
-                       add_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs);
+                       add_v3_v3(rv3d->ofs, vod->dyn_ofs);
                }
        }
 
        /* check for view snap */
        if (vod->axis_snap){
                int i;
-               float viewmat[3][3];
-
+               float viewquat_inv[4];
+               float zaxis[3]={0,0,1};
+               invert_qt_qt(viewquat_inv, rv3d->viewquat);
 
-               quat_to_mat3( viewmat,rv3d->viewquat);
+               mul_qt_v3(viewquat_inv, zaxis);
 
                for (i = 0 ; i < 39; i++){
-                       float snapmat[3][3];
-                       float view = (int)snapquats[i][4];
-
-                       quat_to_mat3( snapmat,snapquats[i]);
 
-                       if ((dot_v3v3(snapmat[0], viewmat[0]) > thres) &&
-                               (dot_v3v3(snapmat[1], viewmat[1]) > thres) &&
-                               (dot_v3v3(snapmat[2], viewmat[2]) > thres)){
+                       float view = (int)snapquats[i][4];
+                       float viewquat_inv_test[4];
+                       float zaxis_test[3]={0,0,1};
 
-                               QUATCOPY(rv3d->viewquat, snapquats[i]);
+                       invert_qt_qt(viewquat_inv_test, snapquats[i]);
+                       mul_qt_v3(viewquat_inv_test, zaxis_test);
+                       
+                       if(angle_v3v3(zaxis_test, zaxis) < DEG2RAD(45/3)) {
+                               /* find the best roll */
+                               float quat_roll[4], quat_final[4], quat_best[4];
+                               float viewquat_align[4]; /* viewquat aligned to zaxis_test */
+                               float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */
+                               float best_angle = FLT_MAX;
+                               int j;
+
+                               /* viewquat_align is the original viewquat aligned to the snapped axis
+                                * for testing roll */
+                               rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
+                               normalize_qt(viewquat_align);
+                               mul_qt_qtqt(viewquat_align, rv3d->viewquat, viewquat_align);
+                               normalize_qt(viewquat_align);
+                               invert_qt_qt(viewquat_align_inv, viewquat_align);
+
+                               /* find best roll */
+                               for(j= 0; j<8; j++) {
+                                       float angle;
+                                       float xaxis1[3]={1,0,0};
+                                       float xaxis2[3]={1,0,0};
+                                       float quat_final_inv[4];
+
+                                       axis_angle_to_quat(quat_roll, zaxis_test, j * DEG2RAD(45.0));
+                                       normalize_qt(quat_roll);
+
+                                       mul_qt_qtqt(quat_final, snapquats[i], quat_roll);
+                                       normalize_qt(quat_final);
+                                       
+                                       /* compare 2 vector angles to find the least roll */
+                                       invert_qt_qt(quat_final_inv, quat_final);
+                                       mul_qt_v3(viewquat_align_inv, xaxis1);
+                                       mul_qt_v3(quat_final_inv, xaxis2);
+                                       angle= angle_v3v3(xaxis1, xaxis2);
+
+                                       if(angle <= best_angle) {
+                                               best_angle= angle;
+                                               copy_qt_qt(quat_best, quat_final);
+                                               if(j) view= 0; /* view grid assumes certain up axis */
+                                       }
+                               }
 
-                               rv3d->view = view;
+                               copy_qt_qt(rv3d->viewquat, quat_best);
+                               rv3d->view= view; /* if we snap to a rolled camera the grid is invalid */
 
                                break;
                        }
@@ -716,8 +732,15 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
                if (U.uiflag & USER_AUTOPERSP)
                        vod->rv3d->persp= RV3D_PERSP;
-               else if(vod->rv3d->persp==RV3D_CAMOB)
+               else if(vod->rv3d->persp==RV3D_CAMOB) {
+
+                       /* changed since 2.4x, use the camera view */
+                       View3D *v3d = CTX_wm_view3d(C);
+                       if(v3d->camera)
+                               view3d_settings_from_ob(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
+
                        vod->rv3d->persp= RV3D_PERSP;
+               }
                ED_region_tag_redraw(vod->ar);
        }
        
@@ -746,9 +769,21 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
 }
 
-static int ED_operator_view3d_rotate(bContext *C)
+static int view3d_camera_active_poll(bContext *C)
+{
+       if(ED_operator_view3d_active(C)) {
+               RegionView3D *rv3d= CTX_wm_region_view3d(C);
+               if(rv3d && rv3d->persp==RV3D_CAMOB) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int view3d_rotate_poll(bContext *C)
 {
-       if (!ED_operator_view3d_active(C)) {
+       if (!ED_operator_region_view3d_active(C)) {
                return 0;
        } else {
                RegionView3D *rv3d= CTX_wm_region_view3d(C);
@@ -772,7 +807,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
        /* api callbacks */
        ot->invoke= viewrotate_invoke;
        ot->modal= viewrotate_modal;
-       ot->poll= ED_operator_view3d_rotate;
+       ot->poll= view3d_rotate_poll;
 
        /* flags */
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -788,6 +823,9 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
 {
        static EnumPropertyItem modal_items[] = {
        {VIEW_MODAL_CONFIRM,    "CONFIRM", 0, "Confirm", ""},
+               
+       {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
+       {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
 
        {0, NULL, 0, NULL, NULL}};
 
@@ -802,9 +840,11 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
        WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
        WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
 
+       /* disabled mode switching for now, can re-implement better, later on
        WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
        WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
        WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+       */
        
        /* assign map to operators */
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
@@ -814,10 +854,11 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
 static void viewmove_apply(ViewOpsData *vod, int x, int y)
 {
        if(vod->rv3d->persp==RV3D_CAMOB) {
-               float max= (float)MAX2(vod->ar->winx, vod->ar->winy);
+               float zoomfac= (M_SQRT2 + vod->rv3d->camzoom/50.0);
+               zoomfac= (zoomfac*zoomfac)*0.5;
 
-               vod->rv3d->camdx += (vod->oldx - x)/(max);
-               vod->rv3d->camdy += (vod->oldy - y)/(max);
+               vod->rv3d->camdx += (vod->oldx - x)/(vod->ar->winx * zoomfac);
+               vod->rv3d->camdy += (vod->oldy - y)/(vod->ar->winy * zoomfac);
                CLAMP(vod->rv3d->camdx, -1.0f, 1.0f);
                CLAMP(vod->rv3d->camdy, -1.0f, 1.0f);
 // XXX         preview3d_event= 0;
@@ -826,7 +867,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
                float dvec[3];
 
                window_to_3d_delta(vod->ar, dvec, x-vod->oldx, y-vod->oldy);
-               add_v3_v3v3(vod->rv3d->ofs, vod->rv3d->ofs, dvec);
+               add_v3_v3(vod->rv3d->ofs, dvec);
 
                if(vod->rv3d->viewlock & RV3D_BOXVIEW)
                        view3d_boxview_sync(vod->sa, vod->ar);
@@ -928,6 +969,9 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
 {
        static EnumPropertyItem modal_items[] = {
        {VIEW_MODAL_CONFIRM,    "CONFIRM", 0, "Confirm", ""},
+               
+       {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
+       {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
 
        {0, NULL, 0, NULL, NULL}};
 
@@ -942,9 +986,11 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
        WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
        WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
 
+       /* disabled mode switching for now, can re-implement better, later on
        WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
        WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
        WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+        */
        
        /* assign map to operators */
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
@@ -968,31 +1014,24 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
                vb[0] = ar->winx;
                vb[1] = ar->winy;
 
-               tpos[0] = -rv3d->ofs[0];
-               tpos[1] = -rv3d->ofs[1];
-               tpos[2] = -rv3d->ofs[2];
+               negate_v3_v3(tpos, rv3d->ofs);
 
                /* Project cursor position into 3D space */
                initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
                window_to_3d_delta(ar, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
 
                /* Calculate view target position for dolly */
-               tvec[0] = -(tpos[0] + dvec[0]);
-               tvec[1] = -(tpos[1] + dvec[1]);
-               tvec[2] = -(tpos[2] + dvec[2]);
+               add_v3_v3v3(tvec, tpos, dvec);
+               negate_v3(tvec);
 
                /* Offset to target position and dolly */
                new_dist = rv3d->dist * dfac;
 
-               VECCOPY(rv3d->ofs, tvec);
+               copy_v3_v3(rv3d->ofs, tvec);
                rv3d->dist = new_dist;
 
                /* Calculate final offset */
-               dvec[0] = tvec[0] + dvec[0] * dfac;
-               dvec[1] = tvec[1] + dvec[1] * dfac;
-               dvec[2] = tvec[2] + dvec[2] * dfac;
-
-               VECCOPY(rv3d->ofs, dvec);
+               madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
        } else {
                rv3d->dist *= dfac;
        }
@@ -1054,7 +1093,7 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, short viewzoom)
                vod->rv3d->dist = vod->dist0;
                copy_m3_m4(mat, vod->rv3d->viewinv);
                mul_m3_v3(mat, upvec);
-               add_v3_v3v3(vod->rv3d->ofs, vod->rv3d->ofs, upvec);
+               add_v3_v3(vod->rv3d->ofs, upvec);
        } else {
                /* these limits were in old code too */
                if(vod->rv3d->dist<0.001*vod->grid) vod->rv3d->dist= 0.001*vod->grid;
@@ -1127,7 +1166,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
                /* this min and max is also in viewmove() */
                if(rv3d->persp==RV3D_CAMOB) {
                        rv3d->camzoom-= 10;
-                       if(rv3d->camzoom<-30) rv3d->camzoom= -30;
+                       if(rv3d->camzoom < RV3D_CAMZOOM_MIN) rv3d->camzoom= RV3D_CAMZOOM_MIN;
                }
                else if(rv3d->dist<10.0*v3d->far) {
                        view_zoom_mouseloc(CTX_wm_region(C), 1.2f, mx, my);
@@ -1136,7 +1175,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
        else {
                if(rv3d->persp==RV3D_CAMOB) {
                        rv3d->camzoom+= 10;
-                       if(rv3d->camzoom>300) rv3d->camzoom= 300;
+                       if(rv3d->camzoom > RV3D_CAMZOOM_MAX) rv3d->camzoom= RV3D_CAMZOOM_MAX;
                }
                else if(rv3d->dist> 0.001*v3d->grid) {
                        view_zoom_mouseloc(CTX_wm_region(C), .83333f, mx, my);
@@ -1189,8 +1228,8 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
                        else {
                                
                                /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
-                               vod->origy = vod->oldy = event->x;
-                               viewzoom_apply(vod, event->x, event->prevx, USER_ZOOM_DOLLY);
+                               vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
+                               viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY);
                        }
                        request_depth_update(CTX_wm_region_view3d(C));
                        
@@ -1225,7 +1264,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
        ot->invoke= viewzoom_invoke;
        ot->exec= viewzoom_exec;
        ot->modal= viewzoom_modal;
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1235,7 +1274,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
        RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX);
 }
 
-static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */
+static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */
 {
        ARegion *ar= CTX_wm_region(C);
        View3D *v3d = CTX_wm_view3d(C);
@@ -1250,12 +1289,11 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
        int ok= 1, onedone=0;
 
        if(center) {
-               min[0]= min[1]= min[2]= 0.0f;
-               max[0]= max[1]= max[2]= 0.0f;
-
                /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */
                curs= give_cursor(scene, v3d);
-               curs[0]= curs[1]= curs[2]= 0.0;
+               zero_v3(min);
+               zero_v3(max);
+               zero_v3(curs);
        }
        else {
                INIT_MINMAX(min, max);
@@ -1267,11 +1305,19 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
                        minmax_object(base->object, min, max);
                }
        }
-       if(!onedone) return OPERATOR_FINISHED; /* TODO - should this be cancel? */
+       if(!onedone) {
+               ED_region_tag_redraw(ar);
+               /* TODO - should this be cancel?
+                * I think no, because we always move the cursor, with or without
+                * object, but in this case there is no change in the scene,
+                * only the cursor so I choice a ED_region_tag like
+                * smooth_view do for the center_cursor.
+                * See bug #22640
+                */
+               return OPERATOR_FINISHED;
+       }
 
-       afm[0]= (max[0]-min[0]);
-       afm[1]= (max[1]-min[1]);
-       afm[2]= (max[2]-min[2]);
+       sub_v3_v3v3(afm, max, min);
        size= 0.7f*MAX3(afm[0], afm[1], afm[2]);
        if(size==0.0) ok= 0;
 
@@ -1293,11 +1339,11 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
 
                if (rv3d->persp==RV3D_CAMOB) {
                        rv3d->persp= RV3D_PERSP;
-                       smooth_view(C, NULL, v3d->camera, new_ofs, NULL, &new_dist, NULL);
+                       smooth_view(C, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL);
+               }
+               else {
+                       smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL);
                }
-        else {
-            smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL);
-        }
        }
 // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
 
@@ -1309,6 +1355,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
        return OPERATOR_FINISHED;
 }
 
+
 void VIEW3D_OT_view_all(wmOperatorType *ot)
 {
        /* identifiers */
@@ -1317,7 +1364,7 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
        ot->idname= "VIEW3D_OT_view_all";
 
        /* api callbacks */
-       ot->exec= viewhome_exec;
+       ot->exec= view3d_all_exec;
        ot->poll= ED_operator_view3d_active;
 
        /* flags */
@@ -1326,6 +1373,7 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "center", 0, "Center", "");
 }
 
+
 static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview without local!, was centerview() in 2.4x */
 {
        ARegion *ar= CTX_wm_region(C);
@@ -1371,12 +1419,11 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
                        for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                                if(pchan->bone->flag & BONE_SELECTED) {
                                        if(pchan->bone->layer & arm->layer) {
+                                               bPoseChannel *pchan_tx= pchan->custom_tx ? pchan->custom_tx : pchan;
                                                ok= 1;
-                                               VECCOPY(vec, pchan->pose_head);
-                                               mul_m4_v3(ob->obmat, vec);
+                                               mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
                                                DO_MINMAX(vec, min, max);
-                                               VECCOPY(vec, pchan->pose_tail);
-                                               mul_m4_v3(ob->obmat, vec);
+                                               mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
                                                DO_MINMAX(vec, min, max);
                                        }
                                }
@@ -1384,7 +1431,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
                }
        }
        else if (paint_facesel_test(ob)) {
-               ok= minmax_tface(scene, ob, min, max);
+               ok= minmax_tface(ob, min, max);
        }
        else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
                ok= PE_minmax(scene, min, max);
@@ -1406,9 +1453,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
 
        if(ok==0) return OPERATOR_FINISHED;
 
-       afm[0]= (max[0]-min[0]);
-       afm[1]= (max[1]-min[1]);
-       afm[2]= (max[2]-min[2]);
+       sub_v3_v3v3(afm, max, min);
        size= MAX3(afm[0], afm[1], afm[2]);
 
        if(rv3d->persp==RV3D_ORTHO) {
@@ -1426,9 +1471,8 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
                }
        }
 
-       new_ofs[0]= -(min[0]+max[0])/2.0f;
-       new_ofs[1]= -(min[1]+max[1])/2.0f;
-       new_ofs[2]= -(min[2]+max[2])/2.0f;
+       add_v3_v3v3(new_ofs, min, max);
+       mul_v3_fl(new_ofs, -0.5f);
 
        new_dist = size;
 
@@ -1464,7 +1508,7 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= viewselected_exec;
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= 0;
@@ -1477,21 +1521,10 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
        Scene *scene= CTX_data_scene(C);
        
        if (rv3d) {
-               if (rv3d->persp==RV3D_CAMOB) {
-                       /* center the camera offset */
-                       rv3d->camdx= rv3d->camdy= 0.0;
-               }
-               else {
-                       /* non camera center */
-                       float *curs= give_cursor(scene, v3d);
-                       float new_ofs[3];
-                       
-                       new_ofs[0]= -curs[0];
-                       new_ofs[1]= -curs[1];
-                       new_ofs[2]= -curs[2];
-                       
-                       smooth_view(C, NULL, NULL, new_ofs, NULL, NULL, NULL);
-               }
+               /* non camera center */
+               float new_ofs[3];
+               negate_v3_v3(new_ofs, give_cursor(scene, v3d));
+               smooth_view(C, NULL, NULL, new_ofs, NULL, NULL, NULL);
                
                if (rv3d->viewlock & RV3D_BOXVIEW)
                        view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C));
@@ -1515,12 +1548,39 @@ void VIEW3D_OT_view_center_cursor(wmOperatorType *ot)
        ot->flag= 0;
 }
 
+static int view3d_center_camera_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */
+{
+       RegionView3D *rv3d= CTX_wm_region_view3d(C);
+
+       rv3d->camdx= rv3d->camdy= 0.0f;
+
+       WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+
+       return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_view_center_camera(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "View Camera Center";
+       ot->description = "Center the camera view";
+       ot->idname= "VIEW3D_OT_view_center_camera";
+
+       /* api callbacks */
+       ot->exec= view3d_center_camera_exec;
+       ot->poll= view3d_camera_active_poll;
+
+       /* flags */
+       ot->flag= 0;
+}
+
 /* ********************* Set render border operator ****************** */
 
 static int render_border_exec(bContext *C, wmOperator *op)
 {
        View3D *v3d = CTX_wm_view3d(C);
        ARegion *ar= CTX_wm_region(C);
+       RegionView3D *rv3d= ED_view3d_context_rv3d(C);
        Scene *scene= CTX_data_scene(C);
 
        rcti rect;
@@ -1533,7 +1593,7 @@ static int render_border_exec(bContext *C, wmOperator *op)
        rect.ymax= RNA_int_get(op->ptr, "ymax");
 
        /* calculate range */
-       calc_viewborder(scene, ar, v3d, &vb);
+       view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb);
 
        scene->r.border.xmin= ((float)rect.xmin-vb.xmin)/(vb.xmax-vb.xmin);
        scene->r.border.ymin= ((float)rect.ymin-vb.ymin)/(vb.ymax-vb.ymin);
@@ -1564,15 +1624,6 @@ static int render_border_exec(bContext *C, wmOperator *op)
 
 }
 
-static int view3d_render_border_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-       RegionView3D *rv3d= CTX_wm_region_view3d(C);
-
-       /* if not in camera view do not exec the operator*/
-       if (rv3d->persp == RV3D_CAMOB) return WM_border_select_invoke(C, op, event);
-       else return OPERATOR_PASS_THROUGH;
-}
-
 void VIEW3D_OT_render_border(wmOperatorType *ot)
 {
        /* identifiers */
@@ -1581,11 +1632,11 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
        ot->idname= "VIEW3D_OT_render_border";
 
        /* api callbacks */
-       ot->invoke= view3d_render_border_invoke;
+       ot->invoke= WM_border_select_invoke;
        ot->exec= render_border_exec;
        ot->modal= WM_border_select_modal;
 
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= view3d_camera_active_poll;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1707,15 +1758,13 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
                        new_ofs[2] = -p[2];
                } else {
                        /* We cant use the depth, fallback to the old way that dosnt set the center depth */
-                       new_ofs[0] = rv3d->ofs[0];
-                       new_ofs[1] = rv3d->ofs[1];
-                       new_ofs[2] = rv3d->ofs[2];
+                       copy_v3_v3(new_ofs, rv3d->ofs);
 
                        initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]);
 
                        window_to_3d_delta(ar, dvec, (rect.xmin+rect.xmax-vb[0])/2, (rect.ymin+rect.ymax-vb[1])/2);
                        /* center the view to the center of the rectangle */
-                       sub_v3_v3v3(new_ofs, new_ofs, dvec);
+                       sub_v3_v3(new_ofs, dvec);
                }
 
                /* work out the ratios, so that everything selected fits when we zoom */
@@ -1748,7 +1797,6 @@ static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, wmEvent *event
 
 void VIEW3D_OT_zoom_border(wmOperatorType *ot)
 {
-
        /* identifiers */
        ot->name= "Border Zoom";
        ot->description = "Zoom in the view to the nearest object contained in the border";
@@ -1759,7 +1807,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot)
        ot->exec= view3d_zoom_border_exec;
        ot->modal= WM_border_select_modal;
 
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= 0;
@@ -1840,14 +1888,14 @@ static void axis_set_view(bContext *C, float q1, float q2, float q3, float q4, s
 
        if (rv3d->persp==RV3D_CAMOB && v3d->camera) {
 
-               if (U.uiflag & USER_AUTOPERSP) rv3d->persp= RV3D_ORTHO;
+               if (U.uiflag & USER_AUTOPERSP) rv3d->persp= view ? RV3D_ORTHO : RV3D_PERSP;
                else if(rv3d->persp==RV3D_CAMOB) rv3d->persp= perspo;
 
                smooth_view(C, v3d->camera, NULL, rv3d->ofs, new_quat, NULL, NULL);
        }
        else {
 
-               if (U.uiflag & USER_AUTOPERSP) rv3d->persp= RV3D_ORTHO;
+               if (U.uiflag & USER_AUTOPERSP) rv3d->persp= view ? RV3D_ORTHO : RV3D_PERSP;
                else if(rv3d->persp==RV3D_CAMOB) rv3d->persp= perspo;
 
                smooth_view(C, NULL, NULL, NULL, new_quat, NULL, NULL);
@@ -1905,11 +1953,12 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
                                /* lastview -  */
 
                                if(rv3d->persp != RV3D_CAMOB) {
+                                       Object *ob= OBACT;
 
                                        if (!rv3d->smooth_timer) {
                                                /* store settings of current view before allowing overwriting with camera view
                                                 * only if we're not currently in a view transition */
-                                               QUATCOPY(rv3d->lviewquat, rv3d->viewquat);
+                                               copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
                                                rv3d->lview= rv3d->view;
                                                rv3d->lpersp= rv3d->persp;
                                        }
@@ -1922,19 +1971,35 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
                                                handle_view3d_lock();
                                        }
        #endif
-
-                                       if(BASACT) {
-                                               /* check both G.vd as G.scene cameras */
-                                               if((v3d->camera==NULL || scene->camera==NULL) && OBACT->type==OB_CAMERA) {
-                                                       v3d->camera= OBACT;
-                                                       /*handle_view3d_lock();*/
+                                       
+                                       /* first get the default camera for the view lock type */
+                                       if(v3d->scenelock) {
+                                               /* sets the camera view if available */
+                                               v3d->camera= scene->camera;                                             
+                                       }
+                                       else {
+                                               /* use scene camera if one is not set (even though we're unlocked) */
+                                               if(v3d->camera==NULL) {
+                                                       v3d->camera= scene->camera;
                                                }
                                        }
 
-                                       if(v3d->camera==NULL) {
-                                               v3d->camera= scene_find_camera(scene);
-                                               /*handle_view3d_lock();*/
-                                       }
+                                       /* if the camera isnt found, check a number of options */
+                                       if(v3d->camera==NULL && ob && ob->type==OB_CAMERA)
+                                               v3d->camera= ob;
+                                       
+                                       if(v3d->camera==NULL)
+                                               v3d->camera= scene_find_camera(scene);          
+
+                                       /* couldnt find any useful camera, bail out */
+                                       if(v3d->camera==NULL)
+                                               return OPERATOR_CANCELLED;
+                                       
+                                       /* important these dont get out of sync for locked scenes */
+                                       if(v3d->scenelock)
+                                               scene->camera= v3d->camera;
+
+                                       /* finally do snazzy view zooming */
                                        rv3d->persp= RV3D_CAMOB;
                                        smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens);
 
@@ -1964,7 +2029,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= viewnumpad_exec;
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= 0;
@@ -1983,7 +2048,7 @@ static EnumPropertyItem prop_view_orbit_items[] = {
 static int vieworbit_exec(bContext *C, wmOperator *op)
 {
        RegionView3D *rv3d= CTX_wm_region_view3d(C);
-       float phi, si, q1[4], new_quat[4];
+       float phi, q1[4], new_quat[4];
        int orbitdir;
 
        orbitdir = RNA_enum_get(op->ptr, "type");
@@ -1992,6 +2057,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
 
                if(rv3d->persp != RV3D_CAMOB) {
                        if(orbitdir == V3D_VIEW_STEPLEFT || orbitdir == V3D_VIEW_STEPRIGHT) {
+                               float si;
                                /* z-axis */
                                phi= (float)(M_PI/360.0)*U.pad_rot_angle;
                                if(orbitdir == V3D_VIEW_STEPRIGHT) phi= -phi;
@@ -2004,16 +2070,13 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
                        }
                        else if(orbitdir == V3D_VIEW_STEPDOWN || orbitdir == V3D_VIEW_STEPUP) {
                                /* horizontal axis */
-                               VECCOPY(q1+1, rv3d->viewinv[0]);
+                               copy_v3_v3(q1+1, rv3d->viewinv[0]);
 
                                normalize_v3(q1+1);
                                phi= (float)(M_PI/360.0)*U.pad_rot_angle;
                                if(orbitdir == V3D_VIEW_STEPDOWN) phi= -phi;
-                               si= (float)sin(phi);
                                q1[0]= (float)cos(phi);
-                               q1[1]*= si;
-                               q1[2]*= si;
-                               q1[3]*= si;
+                               mul_v3_fl(q1+1, sin(phi));
                                mul_qt_qtqt(new_quat, rv3d->viewquat, q1);
                                rv3d->view= 0;
                        }
@@ -2034,7 +2097,7 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= vieworbit_exec;
-       ot->poll= ED_operator_view3d_rotate;
+       ot->poll= view3d_rotate_poll;
 
        /* flags */
        ot->flag= 0;
@@ -2058,14 +2121,11 @@ static int viewpan_exec(bContext *C, wmOperator *op)
        pandir = RNA_enum_get(op->ptr, "type");
 
        initgrabz(rv3d, 0.0, 0.0, 0.0);
-
        if(pandir == V3D_VIEW_PANRIGHT) window_to_3d_delta(ar, vec, -32, 0);
        else if(pandir == V3D_VIEW_PANLEFT) window_to_3d_delta(ar, vec, 32, 0);
        else if(pandir == V3D_VIEW_PANUP) window_to_3d_delta(ar, vec, 0, -25);
        else if(pandir == V3D_VIEW_PANDOWN) window_to_3d_delta(ar, vec, 0, 25);
-       rv3d->ofs[0]+= vec[0];
-       rv3d->ofs[1]+= vec[1];
-       rv3d->ofs[2]+= vec[2];
+       add_v3_v3(rv3d->ofs, vec);
 
        if(rv3d->viewlock & RV3D_BOXVIEW)
                view3d_boxview_sync(CTX_wm_area(C), ar);
@@ -2084,7 +2144,7 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= viewpan_exec;
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= 0;
@@ -2116,7 +2176,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= viewpersportho_exec;
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= 0;
@@ -2124,27 +2184,64 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
 
 /* ******************** add background image operator **************** */
 
-static int add_background_image_exec(bContext *C, wmOperator *op)
+static BGpic *add_background_image(bContext *C)
 {
        View3D *v3d= CTX_wm_view3d(C);
-
+       
        BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image");
        bgpic->size= 5.0;
        bgpic->blend= 0.5;
        bgpic->iuser.fie_ima= 2;
        bgpic->iuser.ok= 1;
        bgpic->view= 0; /* 0 for all */
-
+       
        BLI_addtail(&v3d->bgpicbase, bgpic);
+       
+       return bgpic;
+}
 
-       //ED_region_tag_redraw(v3d);
+static int add_background_image_exec(bContext *C, wmOperator *op)
+{
+       add_background_image(C);
 
        return OPERATOR_FINISHED;
 }
 
 static int add_background_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       return add_background_image_exec(C, op);
+       Scene *scene= CTX_data_scene(C);
+       View3D *v3d= CTX_wm_view3d(C);
+       Image *ima= NULL;
+       BGpic *bgpic;
+       char name[32];
+       
+       /* check input variables */
+       if(RNA_property_is_set(op->ptr, "filepath")) {
+               char path[FILE_MAX];
+               
+               RNA_string_get(op->ptr, "filepath", path);
+               ima= BKE_add_image_file(path, scene ? scene->r.cfra : 1);
+       }
+       else if(RNA_property_is_set(op->ptr, "name")) {
+               RNA_string_get(op->ptr, "name", name);
+               ima= (Image *)find_id("IM", name);
+       }
+       
+       bgpic = add_background_image(C);
+       
+       if (ima) {
+               bgpic->ima = ima;
+               
+               if(ima->id.us==0) id_us_plus(&ima->id);
+               else id_lib_extern(&ima->id);
+               
+               if (!(v3d->flag & V3D_DISPBGPICS))
+                       v3d->flag |= V3D_DISPBGPICS;
+       }
+       
+       WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, v3d);
+       
+       return OPERATOR_FINISHED;
 }
 
 void VIEW3D_OT_add_background_image(wmOperatorType *ot)
@@ -2161,8 +2258,13 @@ void VIEW3D_OT_add_background_image(wmOperatorType *ot)
 
        /* flags */
        ot->flag   = 0;
+       
+       /* properties */
+       RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign.");
+       RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
 }
 
+
 /* ***** remove image operator ******* */
 static int remove_background_image_exec(bContext *C, wmOperator *op)
 {
@@ -2198,6 +2300,7 @@ void VIEW3D_OT_remove_background_image(wmOperatorType *ot)
 
        RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove ", 0, INT_MAX);
 }
+
 /* ********************* set clipping operator ****************** */
 
 static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb)
@@ -2292,7 +2395,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
        ot->exec= view3d_clipping_exec;
        ot->modal= WM_border_select_modal;
 
-       ot->poll= ED_operator_view3d_active;
+       ot->poll= ED_operator_region_view3d_active;
 
        /* flags */
        ot->flag= 0;
@@ -2316,17 +2419,26 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
        float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3];
        short mx, my, mval[2];
 //     short ctrl= 0; // XXX
-
+       int flip;
        fp= give_cursor(scene, v3d);
 
 //     if(obedit && ctrl) lr_click= 1;
-       VECCOPY(oldcurs, fp);
+       copy_v3_v3(oldcurs, fp);
 
        mx= event->x - ar->winrct.xmin;
        my= event->y - ar->winrct.ymin;
+
        project_short_noclip(ar, fp, mval);
+       flip= initgrabz(rv3d, fp[0], fp[1], fp[2]);
+       
+       /* reset the depth based on the view offset */
+       if(flip) {
+               negate_v3_v3(fp, rv3d->ofs);
 
-       initgrabz(rv3d, fp[0], fp[1], fp[2]);
+               /* re initialize */
+               project_short_noclip(ar, fp, mval);
+               flip= initgrabz(rv3d, fp[0], fp[1], fp[2]);
+       }
 
        if(mval[0]!=IS_CLIPPED) {
                short depth_used = 0;
@@ -2340,7 +2452,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
                if(depth_used==0) {
                        window_to_3d_delta(ar, dvec, mval[0]-mx, mval[1]-my);
-                       sub_v3_v3v3(fp, fp, dvec);
+                       sub_v3_v3(fp, dvec);
                }
        }
        else {
@@ -2419,8 +2531,8 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot)
 
        ot->poll= ED_operator_view3d_active;
 
-       /* rna later */
-       RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
+       /* properties to pass to transform */
+       Transform_Properties(ot, P_CONSTRAINT);
 }
 
 static int enable_manipulator_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -2676,21 +2788,21 @@ float m_dist;
 void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode)
 {
        RegionView3D *rv3d= ar->regiondata;
-    int i;
-    float phi;
-    float dval[7];
+       int i;
+       float phi;
+       float dval[7];
        // static fval[6] for low pass filter; device input vector is dval[6]
        static float fval[6];
-    float tvec[3],rvec[3];
-    float q1[4];
+       float tvec[3],rvec[3];
+       float q1[4];
        float mat[3][3];
        float upvec[3];
 
 
-    /*----------------------------------------------------
+       /*----------------------------------------------------
         * sometimes this routine is called from headerbuttons
-     * viewmove needs to refresh the screen
-     */
+        * viewmove needs to refresh the screen
+        */
 // XXX areawinset(ar->win);
 
 
@@ -2748,7 +2860,7 @@ void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode)
                upvec[2] = rv3d->dist;
                copy_m3_m4(mat, rv3d->viewinv);
                mul_m3_v3(mat, upvec);
-               sub_v3_v3v3(rv3d->ofs, rv3d->ofs, upvec);
+               sub_v3_v3(rv3d->ofs, upvec);
                rv3d->dist = 0.0;
        }
 
@@ -2790,12 +2902,12 @@ void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode)
 
        // translate the view
 
-       sub_v3_v3v3(rv3d->ofs, rv3d->ofs, tvec);
+       sub_v3_v3(rv3d->ofs, tvec);
 
 
        /*----------------------------------------------------
-     * refresh the screen XXX
-      */
+        * refresh the screen XXX
+         */
 
        // update render preview window
 
@@ -2816,7 +2928,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
        float xvec[3] = {1,0,0};
        float yvec[3] = {0,-1,0};
        float zvec[3] = {0,0,1};
-       float phi, si;
+       float phi;
        float q1[4];
        float obofs[3];
        float reverse;
@@ -2825,10 +2937,10 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
        float mat[3][3];
        float upvec[3];
 
-    /* Sensitivity will control how fast the view rotates.  The value was
-     * obtained experimentally by tweaking until the author didn't get dizzy watching.
-     * Perhaps this should be a configurable user parameter.
-     */
+       /* Sensitivity will control how fast the view rotates.  The value was
+        * obtained experimentally by tweaking until the author didn't get dizzy watching.
+        * Perhaps this should be a configurable user parameter.
+        */
        float psens = 0.005f * (float) U.ndof_pan;   /* pan sensitivity */
        float rsens = 0.005f * (float) U.ndof_rotate;  /* rotate sensitivity */
        float zsens = 0.3f;   /* zoom sensitivity */
@@ -2851,19 +2963,19 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
                upvec[2] = rv3d->dist;
                copy_m3_m4(mat, rv3d->viewinv);
                mul_m3_v3(mat, upvec);
-               add_v3_v3v3(rv3d->ofs, rv3d->ofs, upvec);
+               add_v3_v3(rv3d->ofs, upvec);
        }
 
-    /*----------------------------------------------------
+       /*----------------------------------------------------
         * sometimes this routine is called from headerbuttons
-     * viewmove needs to refresh the screen
-     */
+        * viewmove needs to refresh the screen
+        */
 // XXX areawinset(curarea->win);
 
-    /*----------------------------------------------------
-     * record how much time has passed. clamp at 10 Hz
-     * pretend the previous frame occured at the clamped time
-     */
+       /*----------------------------------------------------
+        * record how much time has passed. clamp at 10 Hz
+        * pretend the previous frame occurred at the clamped time
+        */
 //    now = PIL_check_seconds_timer();
  //   frametime = (now - prevTime);
  //   if (frametime > 0.1f){        /* if more than 1/10s */
@@ -2872,13 +2984,13 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
 //    prevTime = now;
  //   sbadjust *= 60 * frametime;             /* normalize ndof device adjustments to 100Hz for framerate independence */
 
-    /* fetch the current state of the ndof device & enforce dominant mode if selected */
+       /* fetch the current state of the ndof device & enforce dominant mode if selected */
 // XXX    getndof(fval);
        if (v3d->ndoffilter)
                filterNDOFvalues(fval);
 
 
-    // put scaling back here, was previously in ghostwinlay
+       // put scaling back here, was previously in ghostwinlay
        fval[0] = fval[0] * (1.0f/600.0f);
        fval[1] = fval[1] * (1.0f/600.0f);
        fval[2] = fval[2] * (1.0f/1100.0f);
@@ -2887,7 +2999,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
        fval[5] = fval[5] * 0.00005f;
        fval[6] = fval[6] / 1000000.0f;
 
-    // scale more if not in perspective mode
+       // scale more if not in perspective mode
        if (rv3d->persp == RV3D_ORTHO) {
                fval[0] = fval[0] * 0.05f;
                fval[1] = fval[1] * 0.05f;
@@ -2898,115 +3010,112 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
                zsens *= 8;
        }
 
-    /* set object offset */
+       /* set object offset */
        if (ob) {
                obofs[0] = -ob->obmat[3][0];
                obofs[1] = -ob->obmat[3][1];
                obofs[2] = -ob->obmat[3][2];
        }
        else {
-               VECCOPY(obofs, rv3d->ofs);
+               copy_v3_v3(obofs, rv3d->ofs);
        }
 
-    /* calc an adjustment based on distance from camera
-       disabled per patch 14402 */
-     d = 1.0f;
+       /* calc an adjustment based on distance from camera
+          disabled per patch 14402 */
+        d = 1.0f;
 
 /*    if (ob) {
-        sub_v3_v3v3(diff, obofs, rv3d->ofs);
-        d = len_v3(diff);
-    }
+               sub_v3_v3v3(diff, obofs, rv3d->ofs);
+               d = len_v3(diff);
+       }
 */
 
-    reverse = (rv3d->persmat[2][1] < 0.0f) ? -1.0f : 1.0f;
-
-    /*----------------------------------------------------
-     * ndof device pan
-     */
-    psens *= 1.0f + d;
-    curareaX = sbadjust * psens * fval[0];
-    curareaY = sbadjust * psens * fval[1];
-    dvec[0] = curareaX * rv3d->persinv[0][0] + curareaY * rv3d->persinv[1][0];
-    dvec[1] = curareaX * rv3d->persinv[0][1] + curareaY * rv3d->persinv[1][1];
-    dvec[2] = curareaX * rv3d->persinv[0][2] + curareaY * rv3d->persinv[1][2];
-    add_v3_v3v3(rv3d->ofs, rv3d->ofs, dvec);
-
-    /*----------------------------------------------------
-     * ndof device dolly
-     */
-    len = zsens * sbadjust * fval[2];
-
-    if (rv3d->persp==RV3D_CAMOB) {
-        if(rv3d->persp==RV3D_CAMOB) { /* This is stupid, please fix - TODO */
-            rv3d->camzoom+= 10.0f * -len;
-        }
-        if (rv3d->camzoom < minZoom) rv3d->camzoom = minZoom;
-        else if (rv3d->camzoom > maxZoom) rv3d->camzoom = maxZoom;
-    }
-    else if ((rv3d->dist> 0.001*v3d->grid) && (rv3d->dist<10.0*v3d->far)) {
-        rv3d->dist*=(1.0 + len);
-    }
-
-
-    /*----------------------------------------------------
-     * ndof device turntable
-     * derived from the turntable code in viewmove
-     */
-
-    /* Get the 3x3 matrix and its inverse from the quaternion */
-    quat_to_mat3( m,rv3d->viewquat);
-    invert_m3_m3(m_inv,m);
-
-    /* Determine the direction of the x vector (for rotating up and down) */
-    /* This can likely be compuated directly from the quaternion. */
-    mul_m3_v3(m_inv,xvec);
-    mul_m3_v3(m_inv,yvec);
-    mul_m3_v3(m_inv,zvec);
-
-    /* Perform the up/down rotation */
-    phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
-    si = sin(phi);
-    q1[0] = cos(phi);
-    q1[1] = si * xvec[0];
-    q1[2] = si * xvec[1];
-    q1[3] = si * xvec[2];
-    mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
-
-    if (use_sel) {
-        conjugate_qt(q1); /* conj == inv for unit quat */
-        sub_v3_v3v3(rv3d->ofs, rv3d->ofs, obofs);
-        mul_qt_v3(q1, rv3d->ofs);
-        add_v3_v3v3(rv3d->ofs, rv3d->ofs, obofs);
-    }
-
-    /* Perform the orbital rotation */
-    /* Perform the orbital rotation
-       If the seen Up axis is parallel to the zoom axis, rotation should be
-       achieved with a pure Roll motion (no Spin) on the device. When you start
-       to tilt, moving from Top to Side view, Spinning will increasingly become
-       more relevant while the Roll component will decrease. When a full
-       Side view is reached, rotations around the world's Up axis are achieved
-       with a pure Spin-only motion.  In other words the control of the spinning
-       around the world's Up axis should move from the device's Spin axis to the
-       device's Roll axis depending on the orientation of the world's Up axis
-       relative to the screen. */
-    //phi = sbadjust * rsens * reverse * fval[4];  /* spin the knob, y axis */
-    phi = sbadjust * rsens * (yvec[2] * fval[4] + zvec[2] * fval[5]);
-    q1[0] = cos(phi);
-    q1[1] = q1[2] = 0.0;
-    q1[3] = sin(phi);
-    mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
-
-    if (use_sel) {
-        conjugate_qt(q1);
-        sub_v3_v3v3(rv3d->ofs, rv3d->ofs, obofs);
-        mul_qt_v3(q1, rv3d->ofs);
-        add_v3_v3v3(rv3d->ofs, rv3d->ofs, obofs);
-    }
-
-    /*----------------------------------------------------
-     * refresh the screen
-     */
+       reverse = (rv3d->persmat[2][1] < 0.0f) ? -1.0f : 1.0f;
+
+       /*----------------------------------------------------
+        * ndof device pan
+        */
+       psens *= 1.0f + d;
+       curareaX = sbadjust * psens * fval[0];
+       curareaY = sbadjust * psens * fval[1];
+       dvec[0] = curareaX * rv3d->persinv[0][0] + curareaY * rv3d->persinv[1][0];
+       dvec[1] = curareaX * rv3d->persinv[0][1] + curareaY * rv3d->persinv[1][1];
+       dvec[2] = curareaX * rv3d->persinv[0][2] + curareaY * rv3d->persinv[1][2];
+       add_v3_v3(rv3d->ofs, dvec);
+
+       /*----------------------------------------------------
+        * ndof device dolly
+        */
+       len = zsens * sbadjust * fval[2];
+
+       if (rv3d->persp==RV3D_CAMOB) {
+               if(rv3d->persp==RV3D_CAMOB) { /* This is stupid, please fix - TODO */
+                       rv3d->camzoom+= 10.0f * -len;
+               }
+               if (rv3d->camzoom < minZoom) rv3d->camzoom = minZoom;
+               else if (rv3d->camzoom > maxZoom) rv3d->camzoom = maxZoom;
+       }
+       else if ((rv3d->dist> 0.001*v3d->grid) && (rv3d->dist<10.0*v3d->far)) {
+               rv3d->dist*=(1.0 + len);
+       }
+
+
+       /*----------------------------------------------------
+        * ndof device turntable
+        * derived from the turntable code in viewmove
+        */
+
+       /* Get the 3x3 matrix and its inverse from the quaternion */
+       quat_to_mat3( m,rv3d->viewquat);
+       invert_m3_m3(m_inv,m);
+
+       /* Determine the direction of the x vector (for rotating up and down) */
+       /* This can likely be compuated directly from the quaternion. */
+       mul_m3_v3(m_inv,xvec);
+       mul_m3_v3(m_inv,yvec);
+       mul_m3_v3(m_inv,zvec);
+
+       /* Perform the up/down rotation */
+       phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
+       q1[0] = cos(phi);
+       mul_v3_v3fl(q1+1, xvec, sin(phi));
+       mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
+
+       if (use_sel) {
+               conjugate_qt(q1); /* conj == inv for unit quat */
+               sub_v3_v3(rv3d->ofs, obofs);
+               mul_qt_v3(q1, rv3d->ofs);
+               add_v3_v3(rv3d->ofs, obofs);
+       }
+
+       /* Perform the orbital rotation */
+       /* Perform the orbital rotation
+          If the seen Up axis is parallel to the zoom axis, rotation should be
+          achieved with a pure Roll motion (no Spin) on the device. When you start
+          to tilt, moving from Top to Side view, Spinning will increasingly become
+          more relevant while the Roll component will decrease. When a full
+          Side view is reached, rotations around the world's Up axis are achieved
+          with a pure Spin-only motion.  In other words the control of the spinning
+          around the world's Up axis should move from the device's Spin axis to the
+          device's Roll axis depending on the orientation of the world's Up axis
+          relative to the screen. */
+       //phi = sbadjust * rsens * reverse * fval[4];  /* spin the knob, y axis */
+       phi = sbadjust * rsens * (yvec[2] * fval[4] + zvec[2] * fval[5]);
+       q1[0] = cos(phi);
+       q1[1] = q1[2] = 0.0;
+       q1[3] = sin(phi);
+       mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
+
+       if (use_sel) {
+               conjugate_qt(q1);
+               sub_v3_v3(rv3d->ofs, obofs);
+               mul_qt_v3(q1, rv3d->ofs);
+               add_v3_v3(rv3d->ofs, obofs);
+       }
+
+       /*----------------------------------------------------
+        * refresh the screen
+        */
 // XXX    scrarea_do_windraw(curarea);
 }