merge with trunk at r31523
[blender.git] / source / blender / editors / transform / transform_snap.c
index 6cfffd1ade784febd46b0a788bd594302de4c415..3dbd83bfa52b4913639efcc1c7eca8bbe441734e 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
 
 #include "PIL_time.h"
 
-#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
-#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_object_types.h"
 #include "DNA_meshdata_types.h" // Temporary, for snapping to other unselected meshes
 #include "DNA_space_types.h"
 #include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_windowmanager_types.h"
 
 #include "RNA_access.h"
 
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_editVert.h"
 #include "BLI_blenlib.h"
 
 //#include "editmesh.h"
 //#include "BIF_editsima.h"
 #include "BIF_gl.h"
-#include "BIF_glutil.h"
 //#include "BIF_mywindow.h"
 //#include "BIF_screen.h"
 //#include "BIF_editsima.h"
 //#include "BIF_drawimage.h"
 //#include "BIF_editmesh.h"
 
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_object.h"
 #include "BKE_anim.h" /* for duplis */
 #include "BKE_context.h"
+#include "BKE_tessmesh.h"
+#include "BKE_mesh.h"
 
 #include "ED_armature.h"
 #include "ED_image.h"
 #include "ED_mesh.h"
-#include "ED_transform.h"
 #include "ED_uvedit.h"
 #include "ED_view3d.h"
 
@@ -90,7 +86,7 @@
 
 /********************* PROTOTYPES ***********************/
 
-void setSnappingCallback(TransInfo *t, short snap_target);
+void setSnappingCallback(TransInfo *t);
 
 void ApplySnapTranslation(TransInfo *t, float vec[3]);
 void ApplySnapRotation(TransInfo *t, float *vec);
@@ -123,10 +119,20 @@ int BIF_snappingSupported(Object *obedit)
        return status;
 }
 
+int validSnap(TransInfo *t)
+{
+       return (t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT) ||
+                       (t->tsnap.status & (MULTI_POINTS|TARGET_INIT)) == (MULTI_POINTS|TARGET_INIT);
+}
+
+int activeSnap(TransInfo *t)
+{
+       return (t->modifiers & (MOD_SNAP|MOD_SNAP_INVERT)) == MOD_SNAP || (t->modifiers & (MOD_SNAP|MOD_SNAP_INVERT)) == MOD_SNAP_INVERT;
+}
+
 void drawSnapping(const struct bContext *C, TransInfo *t)
 {
-       if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT) &&
-               (t->modifiers & MOD_SNAP_GEARS))
+       if (validSnap(t) && activeSnap(t))
                {
                
                char col[4] = {1, 0, 1};
@@ -134,6 +140,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
                glColor4ub(col[0], col[1], col[2], 128);
                
                if (t->spacetype == SPACE_VIEW3D) {
+                       TransSnapPoint *p;
                        View3D *v3d = CTX_wm_view3d(C);
                        RegionView3D *rv3d = CTX_wm_region_view3d(C);
                        float tmat[4][4], imat[4][4];
@@ -141,14 +148,18 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
                        
                        glDisable(GL_DEPTH_TEST);
        
-                       size = get_drawsize(t->ar, t->tsnap.snapPoint);
-                       
-                       size *= 0.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
+                       size = 0.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
                        
-                       Mat4CpyMat4(tmat, rv3d->viewmat);
-                       Mat4Invert(imat, tmat);
+                       copy_m4_m4(tmat, rv3d->viewmat);
+                       invert_m4_m4(imat, tmat);
 
-                       drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, size, imat);
+                       for (p = t->tsnap.points.first; p; p = p->next) {
+                               drawcircball(GL_LINE_LOOP, p->co, size * get_drawsize(t->ar, p->co), imat);
+                       }
+
+                       if (t->tsnap.status & POINT_INIT) {
+                               drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, size * get_drawsize(t->ar, t->tsnap.snapPoint), imat);
+                       }
                        
                        /* draw normal if needed */
                        if (usingSnappingNormal(t) && validSnappingNormal(t))
@@ -205,7 +216,8 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
 int  handleSnapping(TransInfo *t, wmEvent *event)
 {
        int status = 0;
-       
+
+#if 0 // XXX need a proper selector for all snap mode
        if (BIF_snappingSupported(t->obedit) && event->type == TABKEY && event->shift)
        {
                /* toggle snap and reinit */
@@ -213,6 +225,7 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
                initSnapping(t, NULL);
                status = 1;
        }
+#endif
        
        return status;
 }
@@ -220,7 +233,7 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
 void applyProject(TransInfo *t)
 {
        /* XXX FLICKER IN OBJECT MODE */
-       if ((t->tsnap.project) && (t->tsnap.status & SNAP_ON) && (t->modifiers & MOD_SNAP_GEARS))
+       if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0)
        {
                TransData *td = t->data;
                float tvec[3];
@@ -229,7 +242,7 @@ void applyProject(TransInfo *t)
        
                if(t->flag & (T_EDIT|T_POSE)) {
                        Object *ob = t->obedit?t->obedit:t->poseobj;
-                       Mat4Invert(imat, ob->obmat);
+                       invert_m4_m4(imat, ob->obmat);
                }
 
                for(i = 0 ; i < t->total; i++, td++) {
@@ -247,7 +260,7 @@ void applyProject(TransInfo *t)
                        if (t->flag & (T_EDIT|T_POSE))
                        {
                                Object *ob = t->obedit?t->obedit:t->poseobj;
-                               Mat4MulVecfl(ob->obmat, iloc);
+                               mul_m4_v3(ob->obmat, iloc);
                        }
                        else if (t->flag & T_OBJECT)
                        {
@@ -256,17 +269,17 @@ void applyProject(TransInfo *t)
                        
                        project_float(t->ar, iloc, mval);
                        
-                       if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode))
+                       if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect))
                        {
 //                             if(t->flag & (T_EDIT|T_POSE)) {
-//                                     Mat4MulVecfl(imat, loc);
+//                                     mul_m4_v3(imat, loc);
 //                             }
 //                             
-                               VecSubf(tvec, loc, iloc);
+                               sub_v3_v3v3(tvec, loc, iloc);
                                
-                               Mat3MulVecfl(td->smtx, tvec);
+                               mul_m3_v3(td->smtx, tvec);
                                
-                               VecAddf(td->loc, td->loc, tvec);
+                               add_v3_v3(td->loc, tvec);
                        }
                        
                        //XXX constraintTransLim(t, td);
@@ -286,21 +299,20 @@ void applySnapping(TransInfo *t, float *vec)
        
                t->tsnap.applySnap(t, vec);
        }
-       else if ((t->tsnap.status & SNAP_ON) && 
-               (t->modifiers & MOD_SNAP_GEARS))
+       else if ((t->tsnap.mode != SCE_SNAP_MODE_INCREMENT) && activeSnap(t))
        {
                double current = PIL_check_seconds_timer();
                
                // Time base quirky code to go around findnearest slowness
                /* !TODO! add exception for object mode, no need to slow it down then */
-               if (current - t->tsnap.last  >= 0.1)
+               if (current - t->tsnap.last  >= 0.01)
                {
                        t->tsnap.calcSnap(t, vec);
                        t->tsnap.targetSnap(t);
        
                        t->tsnap.last = current;
                }
-               if ((t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT))
+               if (validSnap(t))
                {
                        t->tsnap.applySnap(t, vec);
                }
@@ -310,10 +322,11 @@ void applySnapping(TransInfo *t, float *vec)
 void resetSnapping(TransInfo *t)
 {
        t->tsnap.status = 0;
-       t->tsnap.mode = 0;
        t->tsnap.align = 0;
-       t->tsnap.modePoint = 0;
-       t->tsnap.modeTarget = 0;
+       t->tsnap.project = 0;
+       t->tsnap.mode = 0;
+       t->tsnap.modeSelect = 0;
+       t->tsnap.target = 0;
        t->tsnap.last = 0;
        t->tsnap.applySnap = NULL;
 
@@ -329,9 +342,9 @@ int usingSnappingNormal(TransInfo *t)
 
 int validSnappingNormal(TransInfo *t)
 {
-       if ((t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT))
+       if (validSnap(t))
        {
-               if (Inpf(t->tsnap.snapNormal, t->tsnap.snapNormal) > 0)
+               if (dot_v3v3(t->tsnap.snapNormal, t->tsnap.snapNormal) > 0)
                {
                        return 1;
                }
@@ -340,115 +353,134 @@ int validSnappingNormal(TransInfo *t)
        return 0;
 }
 
-void initSnapping(TransInfo *t, wmOperator *op)
+void initSnappingMode(TransInfo *t)
 {
        ToolSettings *ts = t->settings;
        Object *obedit = t->obedit;
-       int snapping = 0;
-       short snap_mode = t->settings->snap_target;
-       
-       resetSnapping(t);
-       
-       if (op && RNA_struct_find_property(op->ptr, "snap") && RNA_property_is_set(op->ptr, "snap"))
-       {
-               if (RNA_boolean_get(op->ptr, "snap"))
-               {
-                       snapping = 1;
-                       snap_mode = RNA_enum_get(op->ptr, "snap_mode");
-                       
-                       t->tsnap.status |= SNAP_FORCED|POINT_INIT;
-                       RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint);
-                       
-                       /* snap align only defined in specific cases */
-                       if (RNA_struct_find_property(op->ptr, "snap_align"))
-                       {
-                               t->tsnap.align = RNA_boolean_get(op->ptr, "snap_align");
-                               RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal);
-                               Normalize(t->tsnap.snapNormal);
-                       }
+       Scene *scene = t->scene;
 
-                       if (RNA_struct_find_property(op->ptr, "snap_project"))
-                       {
-                               t->tsnap.project = RNA_boolean_get(op->ptr, "snap_project");
-                       }
-               }
-       }
-       else
-       {
-               snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP);
-               t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
-               t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
-       }
-       
        /* force project off when not supported */
        if (ts->snap_mode != SCE_SNAP_MODE_FACE)
        {
                t->tsnap.project = 0;
        }
-       
+
+       t->tsnap.mode = ts->snap_mode;
+
        if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
-                       (t->flag & T_CAMERA) == 0) { // Not with camera selected
-               setSnappingCallback(t, snap_mode);
+                       (t->flag & T_CAMERA) == 0) { // Not with camera selected in camera view
+               setSnappingCallback(t);
 
                /* Edit mode */
                if (t->tsnap.applySnap != NULL && // A snapping function actually exist
-                       (snapping) && // Only if the snap flag is on
                        (obedit != NULL && ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) ) // Temporary limited to edit mode meshes, armature, curves
                {
-                       t->tsnap.status |= SNAP_ON;
-                       t->tsnap.modePoint = SNAP_GEO;
-                       
-                       if (t->flag & T_PROP_EDIT)
+                       if ((t->flag & T_PROP_EDIT) || t->tsnap.project) /* also exclude edit for project, for now */
                        {
-                               t->tsnap.mode = SNAP_NOT_OBEDIT;
+                               t->tsnap.modeSelect = SNAP_NOT_OBEDIT;
                        }
                        else
                        {
-                               t->tsnap.mode = SNAP_ALL;
+                               t->tsnap.modeSelect = SNAP_ALL;
                        }
                }
+               /* Particles edit mode*/
+               else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
+                       (obedit == NULL && BASACT && BASACT->object && BASACT->object->mode & OB_MODE_PARTICLE_EDIT ))
+               {
+                       t->tsnap.modeSelect = SNAP_ALL;
+               }
                /* Object mode */
                else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
-                       (snapping) && // Only if the snap flag is on
                        (obedit == NULL) ) // Object Mode
                {
-                       t->tsnap.status |= SNAP_ON;
-                       t->tsnap.modePoint = SNAP_GEO;
-                       t->tsnap.mode = SNAP_NOT_SELECTED;
+                       t->tsnap.modeSelect = SNAP_NOT_SELECTED;
                }
                else
-               {       
+               {
                        /* Grid if snap is not possible */
-                       t->tsnap.modePoint = SNAP_GRID;
+                       t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
                }
        }
        else
        {
                /* Always grid outside of 3D view */
-               t->tsnap.modePoint = SNAP_GRID;
+               t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
        }
 }
 
-void setSnappingCallback(TransInfo *t, short snap_target)
+void initSnapping(TransInfo *t, wmOperator *op)
+{
+       ToolSettings *ts = t->settings;
+       short snap_target = t->settings->snap_target;
+       
+       resetSnapping(t);
+       
+       /* if snap property exists */
+       if (op && RNA_struct_find_property(op->ptr, "snap") && RNA_property_is_set(op->ptr, "snap"))
+       {
+               if (RNA_boolean_get(op->ptr, "snap"))
+               {
+                       t->modifiers |= MOD_SNAP;
+
+                       if (RNA_property_is_set(op->ptr, "snap_target"))
+                       {
+                               snap_target = RNA_enum_get(op->ptr, "snap_target");
+                       }
+                       
+                       if (RNA_property_is_set(op->ptr, "snap_point"))
+                       {
+                               RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint);
+                               t->tsnap.status |= SNAP_FORCED|POINT_INIT;
+                       }
+                       
+                       /* snap align only defined in specific cases */
+                       if (RNA_struct_find_property(op->ptr, "snap_align"))
+                       {
+                               t->tsnap.align = RNA_boolean_get(op->ptr, "snap_align");
+                               RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal);
+                               normalize_v3(t->tsnap.snapNormal);
+                       }
+
+                       if (RNA_struct_find_property(op->ptr, "use_snap_project"))
+                       {
+                               t->tsnap.project = RNA_boolean_get(op->ptr, "use_snap_project");
+                       }
+               }
+       }
+       /* use scene defaults only when transform is modal */
+       else if (t->flag & T_MODAL)
+       {
+               if (ts->snap_flag & SCE_SNAP) {
+                       t->modifiers |= MOD_SNAP;
+               }
+
+               t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+               t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+               t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+       }
+       
+       t->tsnap.target = snap_target;
+
+       initSnappingMode(t);
+}
+
+void setSnappingCallback(TransInfo *t)
 {
        t->tsnap.calcSnap = CalcSnapGeometry;
 
-       switch(snap_target)
+       switch(t->tsnap.target)
        {
                case SCE_SNAP_TARGET_CLOSEST:
-                       t->tsnap.modeTarget = SNAP_CLOSEST;
                        t->tsnap.targetSnap = TargetSnapClosest;
                        break;
                case SCE_SNAP_TARGET_CENTER:
-                       t->tsnap.modeTarget = SNAP_CENTER;
                        t->tsnap.targetSnap = TargetSnapCenter;
                        break;
                case SCE_SNAP_TARGET_MEDIAN:
-                       t->tsnap.modeTarget = SNAP_MEDIAN;
                        t->tsnap.targetSnap = TargetSnapMedian;
                        break;
                case SCE_SNAP_TARGET_ACTIVE:
-                       t->tsnap.modeTarget = SNAP_ACTIVE;
                        t->tsnap.targetSnap = TargetSnapActive;
                        break;
 
@@ -465,8 +497,8 @@ void setSnappingCallback(TransInfo *t, short snap_target)
                t->tsnap.distance = RotationBetween;
                
                // Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead
-               if (snap_target == SCE_SNAP_TARGET_CENTER) {
-                       t->tsnap.modeTarget = SNAP_MEDIAN;
+               if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) {
+                       t->tsnap.target = SCE_SNAP_TARGET_MEDIAN;
                        t->tsnap.targetSnap = TargetSnapMedian;
                }
                break;
@@ -475,8 +507,8 @@ void setSnappingCallback(TransInfo *t, short snap_target)
                t->tsnap.distance = ResizeBetween;
                
                // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead
-               if (snap_target == SCE_SNAP_TARGET_CENTER) {
-                       t->tsnap.modeTarget = SNAP_MEDIAN;
+               if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) {
+                       t->tsnap.target = SCE_SNAP_TARGET_MEDIAN;
                        t->tsnap.targetSnap = TargetSnapMedian;
                }
                break;
@@ -486,30 +518,82 @@ void setSnappingCallback(TransInfo *t, short snap_target)
        }
 }
 
+void addSnapPoint(TransInfo *t)
+{
+       if (t->tsnap.status & POINT_INIT) {
+               TransSnapPoint *p = MEM_callocN(sizeof(TransSnapPoint), "SnapPoint");
+
+               VECCOPY(p->co, t->tsnap.snapPoint);
+
+               BLI_addtail(&t->tsnap.points, p);
+
+               t->tsnap.status |= MULTI_POINTS;
+       }
+}
+
+void removeSnapPoint(TransInfo *t)
+{
+       if (t->tsnap.status & MULTI_POINTS) {
+               BLI_freelinkN(&t->tsnap.points, t->tsnap.points.last);
+
+               if (t->tsnap.points.first == NULL)
+                       t->tsnap.status &= ~MULTI_POINTS;
+       }
+}
+
+void getSnapPoint(TransInfo *t, float vec[3])
+{
+       if (t->tsnap.points.first) {
+               TransSnapPoint *p;
+               int total = 0;
+
+               vec[0] = vec[1] = vec[2] = 0;
+
+               for (p = t->tsnap.points.first; p; p = p->next, total++) {
+                       add_v3_v3(vec, p->co);
+               }
+
+               if (t->tsnap.status & POINT_INIT) {
+                       add_v3_v3(vec, t->tsnap.snapPoint);
+                       total++;
+               }
+
+               mul_v3_fl(vec, 1.0f / total);
+       } else {
+               VECCOPY(vec, t->tsnap.snapPoint)
+       }
+}
+
 /********************** APPLY **************************/
 
 void ApplySnapTranslation(TransInfo *t, float vec[3])
 {
-       VecSubf(vec, t->tsnap.snapPoint, t->tsnap.snapTarget);
+       float point[3];
+       getSnapPoint(t, point);
+       sub_v3_v3v3(vec, point, t->tsnap.snapTarget);
 }
 
 void ApplySnapRotation(TransInfo *t, float *vec)
 {
-       if (t->tsnap.modeTarget == SNAP_CLOSEST) {
+       if (t->tsnap.target == SCE_SNAP_TARGET_CLOSEST) {
                *vec = t->tsnap.dist;
        }
        else {
-               *vec = RotationBetween(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
+               float point[3];
+               getSnapPoint(t, point);
+               *vec = RotationBetween(t, t->tsnap.snapTarget, point);
        }
 }
 
 void ApplySnapResize(TransInfo *t, float vec[3])
 {
-       if (t->tsnap.modeTarget == SNAP_CLOSEST) {
+       if (t->tsnap.target == SCE_SNAP_TARGET_CLOSEST) {
                vec[0] = vec[1] = vec[2] = t->tsnap.dist;
        }
        else {
-               vec[0] = vec[1] = vec[2] = ResizeBetween(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
+               float point[3];
+               getSnapPoint(t, point);
+               vec[0] = vec[1] = vec[2] = ResizeBetween(t, t->tsnap.snapTarget, point);
        }
 }
 
@@ -517,7 +601,7 @@ void ApplySnapResize(TransInfo *t, float vec[3])
 
 float TranslationBetween(TransInfo *t, float p1[3], float p2[3])
 {
-       return VecLenf(p1, p2);
+       return len_v3v3(p1, p2);
 }
 
 float RotationBetween(TransInfo *t, float p1[3], float p2[3])
@@ -527,11 +611,11 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3])
        VECCOPY(center, t->center);     
        if(t->flag & (T_EDIT|T_POSE)) {
                Object *ob= t->obedit?t->obedit:t->poseobj;
-               Mat4MulVecfl(ob->obmat, center);
+               mul_m4_v3(ob->obmat, center);
        }
 
-       VecSubf(start, p1, center);
-       VecSubf(end, p2, center);       
+       sub_v3_v3v3(start, p1, center);
+       sub_v3_v3v3(end, p2, center);   
                
        // Angle around a constraint axis (error prone, will need debug)
        if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
@@ -539,29 +623,29 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3])
                
                t->con.applyRot(t, NULL, axis, NULL);
 
-               Projf(tmp, end, axis);
-               VecSubf(end, end, tmp);
+               project_v3_v3v3(tmp, end, axis);
+               sub_v3_v3v3(end, end, tmp);
                
-               Projf(tmp, start, axis);
-               VecSubf(start, start, tmp);
+               project_v3_v3v3(tmp, start, axis);
+               sub_v3_v3v3(start, start, tmp);
                
-               Normalize(end);
-               Normalize(start);
+               normalize_v3(end);
+               normalize_v3(start);
                
-               Crossf(tmp, start, end);
+               cross_v3_v3v3(tmp, start, end);
                
-               if (Inpf(tmp, axis) < 0.0)
-                       angle = -acos(Inpf(start, end));
+               if (dot_v3v3(tmp, axis) < 0.0)
+                       angle = -acos(dot_v3v3(start, end));
                else    
-                       angle = acos(Inpf(start, end));
+                       angle = acos(dot_v3v3(start, end));
        }
        else {
                float mtx[3][3];
                
-               Mat3CpyMat4(mtx, t->viewmat);
+               copy_m3_m4(mtx, t->viewmat);
 
-               Mat3MulVecfl(mtx, end);
-               Mat3MulVecfl(mtx, start);
+               mul_m3_v3(mtx, end);
+               mul_m3_v3(mtx, start);
                
                angle = atan2(start[1],start[0]) - atan2(end[1],end[0]);
        }
@@ -583,18 +667,18 @@ float ResizeBetween(TransInfo *t, float p1[3], float p2[3])
        VECCOPY(center, t->center);     
        if(t->flag & (T_EDIT|T_POSE)) {
                Object *ob= t->obedit?t->obedit:t->poseobj;
-               Mat4MulVecfl(ob->obmat, center);
+               mul_m4_v3(ob->obmat, center);
        }
 
-       VecSubf(d1, p1, center);
-       VecSubf(d2, p2, center);
+       sub_v3_v3v3(d1, p1, center);
+       sub_v3_v3v3(d2, p2, center);
        
        if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
-               Mat3MulVecfl(t->con.pmtx, d1);
-               Mat3MulVecfl(t->con.pmtx, d2);
+               mul_m3_v3(t->con.pmtx, d1);
+               mul_m3_v3(t->con.pmtx, d2);
        }
        
-       return VecLength(d2) / VecLength(d1);
+       return len_v3(d2) / len_v3(d1);
 }
 
 /********************** CALC **************************/
@@ -617,13 +701,13 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                mval[0] = t->mval[0];
                mval[1] = t->mval[1];
                
-               if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME)
+               if (t->tsnap.mode == SCE_SNAP_MODE_VOLUME)
                {
                        ListBase depth_peels;
                        DepthPeel *p1, *p2;
                        float *last_p = NULL;
                        float dist = FLT_MAX;
-                       float p[3];
+                       float p[3] = {0.0f, 0.0f, 0.0f};
                        
                        depth_peels.first = depth_peels.last = NULL;
                        
@@ -675,8 +759,8 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                                        {
                                                p2->flag = 1;
                                                
-                                               VecAddf(vec, p1->p, p2->p);
-                                               VecMulf(vec, 0.5f);
+                                               add_v3_v3v3(vec, p1->p, p2->p);
+                                               mul_v3_fl(vec, 0.5f);
                                        }
                                        else
                                        {
@@ -690,7 +774,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                                                break;
                                        }
                                        
-                                       new_dist = VecLenf(last_p, vec);
+                                       new_dist = len_v3v3(last_p, vec);
                                        
                                        if (new_dist < dist)
                                        {
@@ -710,17 +794,17 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                }
                else
                {
-                       found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode);
-               }
-               
+                       found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect);
+                       }
+                               
                if (found == 1)
                {
                        float tangent[3];
                        
-                       VecSubf(tangent, loc, t->tsnap.snapPoint);
+                       sub_v3_v3v3(tangent, loc, t->tsnap.snapPoint);
                        tangent[2] = 0; 
                        
-                       if (Inpf(tangent, tangent) > 0)
+                       if (dot_v3v3(tangent, tangent) > 0)
                        {
                                VECCOPY(t->tsnap.snapTangent, tangent);
                        }
@@ -749,8 +833,6 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                        t->tsnap.snapPoint[0] *= aspx;
                        t->tsnap.snapPoint[1] *= aspy;
 
-                       Mat4MulVecfl(t->obedit->obmat, t->tsnap.snapPoint);
-                       
                        t->tsnap.status |=  POINT_INIT;
                }
                else
@@ -770,7 +852,7 @@ void TargetSnapCenter(TransInfo *t)
                VECCOPY(t->tsnap.snapTarget, t->center);        
                if(t->flag & (T_EDIT|T_POSE)) {
                        Object *ob= t->obedit?t->obedit:t->poseobj;
-                       Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+                       mul_m4_v3(ob->obmat, t->tsnap.snapTarget);
                }
                
                t->tsnap.status |= TARGET_INIT;         
@@ -801,7 +883,7 @@ void TargetSnapActive(TransInfo *t)
                                
                        if(t->flag & (T_EDIT|T_POSE)) {
                                Object *ob= t->obedit?t->obedit:t->poseobj;
-                               Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+                               mul_m4_v3(ob->obmat, t->tsnap.snapTarget);
                        }
                        
                        t->tsnap.status |= TARGET_INIT;
@@ -809,7 +891,7 @@ void TargetSnapActive(TransInfo *t)
                /* No active, default to median */
                else
                {
-                       t->tsnap.modeTarget = SNAP_MEDIAN;
+                       t->tsnap.target = SCE_SNAP_TARGET_MEDIAN;
                        t->tsnap.targetSnap = TargetSnapMedian;
                        TargetSnapMedian(t);
                }               
@@ -830,14 +912,14 @@ void TargetSnapMedian(TransInfo *t)
                
                for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
                {
-                       VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->center);
+                       add_v3_v3(t->tsnap.snapTarget, td->center);
                }
                
-               VecMulf(t->tsnap.snapTarget, 1.0 / i);
+               mul_v3_fl(t->tsnap.snapTarget, 1.0 / i);
                
                if(t->flag & (T_EDIT|T_POSE)) {
                        Object *ob= t->obedit?t->obedit:t->poseobj;
-                       Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+                       mul_m4_v3(ob->obmat, t->tsnap.snapTarget);
                }
                
                t->tsnap.status |= TARGET_INIT;         
@@ -869,7 +951,7 @@ void TargetSnapClosest(TransInfo *t)
                                                float dist;
                                                
                                                VECCOPY(loc, bb->vec[j]);
-                                               Mat4MulVecfl(td->ext->obmat, loc);
+                                               mul_m4_v3(td->ext->obmat, loc);
                                                
                                                dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
                                                
@@ -912,7 +994,7 @@ void TargetSnapClosest(TransInfo *t)
                                
                                if(t->flag & (T_EDIT|T_POSE)) {
                                        Object *ob= t->obedit?t->obedit:t->poseobj;
-                                       Mat4MulVecfl(ob->obmat, loc);
+                                       mul_m4_v3(ob->obmat, loc);
                                }
                                
                                dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
@@ -937,7 +1019,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
        int result;
        int retval = 0;
        
-       result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, v1co, v2co, v3co, &lambda, NULL, 0.001);
+       result = isect_ray_tri_threshold_v3(ray_start_local, ray_normal_local, v1co, v2co, v3co, &lambda, NULL, 0.001);
        
        if (result) {
                float location[3], normal[3];
@@ -947,19 +1029,19 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
                int new_dist;
                
                VECCOPY(intersect, ray_normal_local);
-               VecMulf(intersect, lambda);
-               VecAddf(intersect, intersect, ray_start_local);
+               mul_v3_fl(intersect, lambda);
+               add_v3_v3(intersect, ray_start_local);
                
                VECCOPY(location, intersect);
                
                if (v4co)
-                       CalcNormFloat4(v1co, v2co, v3co, v4co, normal);
+                       normal_quad_v3( normal,v1co, v2co, v3co, v4co);
                else
-                       CalcNormFloat(v1co, v2co, v3co, normal);
+                       normal_tri_v3( normal,v1co, v2co, v3co);
 
-               Mat4MulVecfl(obmat, location);
+               mul_m4_v3(obmat, location);
                
-               new_depth = VecLenf(location, ray_start);                                       
+               new_depth = len_v3v3(location, ray_start);                                      
                
                project_int(ar, location, screen_loc);
                new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
@@ -972,8 +1054,8 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
                        VECCOPY(loc, location);
                        VECCOPY(no, normal);
                        
-                       Mat3MulVecfl(timat, no);
-                       Normalize(no);
+                       mul_m3_v3(timat, no);
+                       normalize_v3(no);
 
                        *dist = new_dist;
                } 
@@ -989,10 +1071,10 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
        int retval = 0;
        
        VECCOPY(ray_end, ray_normal_local);
-       VecMulf(ray_end, 2000);
-       VecAddf(ray_end, ray_start_local, ray_end);
+       mul_v3_fl(ray_end, 2000);
+       add_v3_v3v3(ray_end, ray_start_local, ray_end);
        
-       result = LineIntersectLine(v1co, v2co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */
+       result = isect_line_line_v3(v1co, v2co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */
        
        if (result)
        {
@@ -1000,12 +1082,12 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
                float mul;
        
                /* check for behind ray_start */
-               VecSubf(dvec, intersect, ray_start_local);
+               sub_v3_v3v3(dvec, intersect, ray_start_local);
                
-               VecSubf(edge_loc, v1co, v2co);
-               VecSubf(vec, intersect, v2co);
+               sub_v3_v3v3(edge_loc, v1co, v2co);
+               sub_v3_v3v3(vec, intersect, v2co);
                
-               mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
+               mul = dot_v3v3(vec, edge_loc) / dot_v3v3(edge_loc, edge_loc);
                
                if (mul > 1) {
                        mul = 1;
@@ -1016,7 +1098,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
                        VECCOPY(intersect, v2co);
                }
 
-               if (Inpf(ray_normal_local, dvec) > 0)
+               if (dot_v3v3(ray_normal_local, dvec) > 0)
                {
                        float location[3];
                        float new_depth;
@@ -1025,9 +1107,9 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
                        
                        VECCOPY(location, intersect);
                        
-                       Mat4MulVecfl(obmat, location);
+                       mul_m4_v3(obmat, location);
                        
-                       new_depth = VecLenf(location, ray_start);                                       
+                       new_depth = len_v3v3(location, ray_start);                                      
                        
                        project_int(ar, location, screen_loc);
                        new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
@@ -1043,18 +1125,18 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
                                *depth = new_depth;
                                retval = 1;
                                
-                               VecSubf(edge_loc, v1co, v2co);
-                               VecSubf(vec, intersect, v2co);
+                               sub_v3_v3v3(edge_loc, v1co, v2co);
+                               sub_v3_v3v3(vec, intersect, v2co);
                                
-                               mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
+                               mul = dot_v3v3(vec, edge_loc) / dot_v3v3(edge_loc, edge_loc);
                                
                                if (no)
                                {
-                                       NormalShortToFloat(n1, v1no);                                           
-                                       NormalShortToFloat(n2, v2no);
-                                       VecLerpf(no, n2, n1, mul);
-                                       Mat3MulVecfl(timat, no);
-                                       Normalize(no);
+                                       normal_short_to_float_v3(n1, v1no);                                             
+                                       normal_short_to_float_v3(n2, v2no);
+                                       interp_v3_v3v3(no, n2, n1, mul);
+                                       mul_m3_v3(timat, no);
+                                       normalize_v3(no);
                                }                       
 
                                VECCOPY(loc, location);
@@ -1072,9 +1154,9 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray
        int retval = 0;
        float dvec[3];
        
-       VecSubf(dvec, vco, ray_start_local);
+       sub_v3_v3v3(dvec, vco, ray_start_local);
        
-       if (Inpf(ray_normal_local, dvec) > 0)
+       if (dot_v3v3(ray_normal_local, dvec) > 0)
        {
                float location[3];
                float new_depth;
@@ -1083,9 +1165,9 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray
                
                VECCOPY(location, vco);
                
-               Mat4MulVecfl(obmat, location);
+               mul_m4_v3(obmat, location);
                
-               new_depth = VecLenf(location, ray_start);                                       
+               new_depth = len_v3v3(location, ray_start);                                      
                
                project_int(ar, location, screen_loc);
                new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
@@ -1099,9 +1181,9 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray
                        
                        if (no)
                        {
-                               NormalShortToFloat(no, vno);
-                               Mat3MulVecfl(timat, no);
-                               Normalize(no);
+                               normal_short_to_float_v3(no, vno);
+                               mul_m3_v3(timat, no);
+                               normalize_v3(no);
                        }
 
                        *dist = new_dist;
@@ -1117,13 +1199,13 @@ int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float
        float ray_start_local[3], ray_normal_local[3];
        int retval = 0;
 
-       Mat4Invert(imat, obmat);
+       invert_m4_m4(imat, obmat);
 
        VECCOPY(ray_start_local, ray_start);
        VECCOPY(ray_normal_local, ray_normal);
        
-       Mat4MulVecfl(imat, ray_start_local);
-       Mat4Mul3Vecfl(imat, ray_normal_local);
+       mul_m4_v3(imat, ray_start_local);
+       mul_mat3_m4_v3(imat, ray_normal_local);
 
        if(arm->edbo)
        {
@@ -1176,11 +1258,11 @@ int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float
        return retval;
 }
 
-int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth)
+int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
 {
        int retval = 0;
        int totvert = dm->getNumVerts(dm);
-       int totface = dm->getNumFaces(dm);
+       int totface = dm->getNumTessFaces(dm);
        
        if (totvert > 0) {
                float imat[4][4];
@@ -1188,16 +1270,16 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                float ray_start_local[3], ray_normal_local[3];
                int test = 1;
 
-               Mat4Invert(imat, obmat);
+               invert_m4_m4(imat, obmat);
 
-               Mat3CpyMat4(timat, imat);
-               Mat3Transp(timat);
+               copy_m3_m4(timat, imat);
+               transpose_m3(timat);
                
                VECCOPY(ray_start_local, ray_start);
                VECCOPY(ray_normal_local, ray_normal);
                
-               Mat4MulVecfl(imat, ray_start_local);
-               Mat4Mul3Vecfl(imat, ray_normal_local);
+               mul_m4_v3(imat, ray_start_local);
+               mul_mat3_m4_v3(imat, ray_normal_local);
                
                
                /* If number of vert is more than an arbitrary limit, 
@@ -1214,20 +1296,49 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                        {
                                case SCE_SNAP_MODE_FACE:
                                { 
+#if 1                          // Added for durian
+                                       BVHTreeRayHit hit;
+                                       BVHTreeFromMesh treeData;
+
+                                       bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6);
+
+                                       hit.index = -1;
+                                       hit.dist = *depth;
+
+                                       if(treeData.tree && BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1)
+                                       {
+                                               if(hit.dist<=*depth) {
+                                                       *depth= hit.dist;
+                                                       copy_v3_v3(loc, hit.co);
+                                                       copy_v3_v3(no, hit.no);
+
+                                                       /* back to worldspace */
+                                                       mul_m4_v3(obmat, loc);
+                                                       copy_v3_v3(no, hit.no);
+
+                                                       mul_m3_v3(timat, no);
+                                                       normalize_v3(no);
+
+                                                       retval |= 1;
+                                               }
+                                       }
+                                       break;
+
+#else
                                        MVert *verts = dm->getVertArray(dm);
-                                       MFace *faces = dm->getFaceArray(dm);
+                                       MFace *faces = dm->getTessFaceArray(dm);
                                        int *index_array = NULL;
                                        int index = 0;
                                        int i;
                                        
                                        if (em != NULL)
                                        {
-                                               index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX);
-                                               EM_init_index_arrays(em, 0, 0, 1);
+                                               index_array = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+                                               EDBM_init_index_arrays(em, 0, 0, 1);
                                        }
                                        
                                        for( i = 0; i < totface; i++) {
-                                               EditFace *efa = NULL;
+                                               BMFace *efa = NULL;
                                                MFace *f = faces + i;
                                                
                                                test = 1; /* reset for every face */
@@ -1249,11 +1360,22 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                                                        }
                                                        else
                                                        {
-                                                               efa = EM_get_face_for_index(index);
+                                                               efa = EDBM_get_face_for_index(em, index);
                                                                
-                                                               if (efa && (efa->h || (efa->v1->f & SELECT) || (efa->v2->f & SELECT) || (efa->v3->f & SELECT) || (efa->v4 && efa->v4->f & SELECT)))
+                                                               if (efa && BM_TestHFlag(efa, BM_HIDDEN))
                                                                {
                                                                        test = 0;
+                                                               } else if (efa) {
+                                                                       BMIter iter;
+                                                                       BMLoop *l;
+                                                                       
+                                                                       l = BMIter_New(&iter, em->bm, BM_LOOPS_OF_FACE, efa);
+                                                                       for ( ; l; l=BMIter_Step(&iter)) {
+                                                                               if (BM_TestHFlag(l->v, BM_SELECT)) {
+                                                                                       test = 0;
+                                                                                       break;
+                                                                               }
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -1281,8 +1403,9 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                                        
                                        if (em != NULL)
                                        {
-                                               EM_free_index_arrays();
+                                               EDBM_free_index_arrays(em);
                                        }
+#endif
                                        break;
                                }
                                case SCE_SNAP_MODE_VERTEX:
@@ -1295,11 +1418,11 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                                        if (em != NULL)
                                        {
                                                index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
-                                               EM_init_index_arrays(em, 1, 0, 0);
+                                               EDBM_init_index_arrays(em, 1, 0, 0);
                                        }
                                        
                                        for( i = 0; i < totvert; i++) {
-                                               EditVert *eve = NULL;
+                                               BMVert *eve = NULL;
                                                MVert *v = verts + i;
                                                
                                                test = 1; /* reset for every vert */
@@ -1321,9 +1444,9 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                                                        }
                                                        else
                                                        {
-                                                               eve = EM_get_vert_for_index(index);
+                                                               eve = EDBM_get_vert_for_index(em, index);
                                                                
-                                                               if (eve && (eve->h || (eve->f & SELECT)))
+                                                               if (eve && (BM_TestHFlag(eve, BM_HIDDEN) || BM_TestHFlag(eve, BM_SELECT)))
                                                                {
                                                                        test = 0;
                                                                }
@@ -1339,7 +1462,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
 
                                        if (em != NULL)
                                        {
-                                               EM_free_index_arrays();
+                                               EDBM_free_index_arrays(em);
                                        }
                                        break;
                                }
@@ -1355,11 +1478,11 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                                        if (em != NULL)
                                        {
                                                index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
-                                               EM_init_index_arrays(em, 0, 1, 0);
+                                               EDBM_init_index_arrays(em, 0, 1, 0);
                                        }
                                        
                                        for( i = 0; i < totedge; i++) {
-                                               EditEdge *eed = NULL;
+                                               BMEdge *eed = NULL;
                                                MEdge *e = edges + i;
                                                
                                                test = 1; /* reset for every vert */
@@ -1381,9 +1504,11 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
                                                        }
                                                        else
                                                        {
-                                                               eed = EM_get_edge_for_index(index);
+                                                               eed = EDBM_get_edge_for_index(em, index);
                                                                
-                                                               if (eed && (eed->h || (eed->v1->f & SELECT) || (eed->v2->f & SELECT)))
+                                                               if (eed && (BM_TestHFlag(eed, BM_HIDDEN) ||
+                                                                       BM_TestHFlag(eed->v1, BM_SELECT) || 
+                                                                       BM_TestHFlag(eed->v2, BM_SELECT)))
                                                                {
                                                                        test = 0;
                                                                }
@@ -1399,7 +1524,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
 
                                        if (em != NULL)
                                        {
-                                               EM_free_index_arrays();
+                                               EDBM_free_index_arrays(em);
                                        }
                                        break;
                                }
@@ -1416,13 +1541,13 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma
        int retval = 0;
        
        if (ob->type == OB_MESH) {
-               EditMesh *em;
+               BMEditMesh *em;
                DerivedMesh *dm;
                
                if (editobject)
                {
-                       em = ((Mesh *)ob->data)->edit_mesh;
-                       dm = editmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
+                       em = ((Mesh *)ob->data)->edit_btmesh;
+                       dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
                }
                else
                {
@@ -1453,9 +1578,21 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mv
        if (mode == SNAP_ALL && obedit)
        {
                Object *ob = obedit;
-               
+
                retval |= snapObject(scene, ar, ob, 1, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
        }
+
+       /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA
+        * which makes the loop skip it, even the derived mesh will never change
+        *
+        * To solve that problem, we do it first as an exception. 
+        * */
+       base= BASACT;
+       if(base && base->object && base->object->mode & OB_MODE_PARTICLE_EDIT)
+       {
+               Object *ob = base->object;
+               retval |= snapObject(scene, ar, ob, 0, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
+       }
        
        base= FIRSTBASE;
        for ( base = FIRSTBASE; base != NULL; base = base->next ) {
@@ -1558,7 +1695,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
 {
        int retval = 0;
        int totvert = dm->getNumVerts(dm);
-       int totface = dm->getNumFaces(dm);
+       int totface = dm->getNumTessFaces(dm);
        
        if (totvert > 0) {
                float imat[4][4];
@@ -1566,16 +1703,16 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
                float ray_start_local[3], ray_normal_local[3];
                int test = 1;
 
-               Mat4Invert(imat, obmat);
+               invert_m4_m4(imat, obmat);
 
-               Mat3CpyMat4(timat, imat);
-               Mat3Transp(timat);
+               copy_m3_m4(timat, imat);
+               transpose_m3(timat);
                
                VECCOPY(ray_start_local, ray_start);
                VECCOPY(ray_normal_local, ray_normal);
                
-               Mat4MulVecfl(imat, ray_start_local);
-               Mat4Mul3Vecfl(imat, ray_normal_local);
+               mul_m4_v3(imat, ray_start_local);
+               mul_mat3_m4_v3(imat, ray_normal_local);
                
                
                /* If number of vert is more than an arbitrary limit, 
@@ -1588,7 +1725,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
                
                if (test == 1) {
                        MVert *verts = dm->getVertArray(dm);
-                       MFace *faces = dm->getFaceArray(dm);
+                       MFace *faces = dm->getTessFaceArray(dm);
                        int i;
                        
                        for( i = 0; i < totface; i++) {
@@ -1597,7 +1734,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
                                int result;
                                
                                
-                               result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL, 0.001);
+                               result = isect_ray_tri_threshold_v3(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL, 0.001);
                                
                                if (result) {
                                        float location[3], normal[3];
@@ -1605,29 +1742,29 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
                                        float new_depth;
                                        
                                        VECCOPY(intersect, ray_normal_local);
-                                       VecMulf(intersect, lambda);
-                                       VecAddf(intersect, intersect, ray_start_local);
+                                       mul_v3_fl(intersect, lambda);
+                                       add_v3_v3(intersect, ray_start_local);
                                        
                                        VECCOPY(location, intersect);
                                        
                                        if (f->v4)
-                                               CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+                                               normal_quad_v3( normal,verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co);
                                        else
-                                               CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+                                               normal_tri_v3( normal,verts[f->v1].co, verts[f->v2].co, verts[f->v3].co);
 
-                                       Mat4MulVecfl(obmat, location);
+                                       mul_m4_v3(obmat, location);
                                        
-                                       new_depth = VecLenf(location, ray_start);                                       
+                                       new_depth = len_v3v3(location, ray_start);                                      
                                        
-                                       Mat3MulVecfl(timat, normal);
-                                       Normalize(normal);
+                                       mul_m3_v3(timat, normal);
+                                       normalize_v3(normal);
 
                                        addDepthPeel(depth_peels, new_depth, location, normal, ob);
                                }
                
                                if (f->v4 && result == 0)
                                {
-                                       result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL, 0.001);
+                                       result = isect_ray_tri_threshold_v3(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL, 0.001);
                                        
                                        if (result) {
                                                float location[3], normal[3];
@@ -1635,22 +1772,22 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
                                                float new_depth;
                                                
                                                VECCOPY(intersect, ray_normal_local);
-                                               VecMulf(intersect, lambda);
-                                               VecAddf(intersect, intersect, ray_start_local);
+                                               mul_v3_fl(intersect, lambda);
+                                               add_v3_v3(intersect, ray_start_local);
                                                
                                                VECCOPY(location, intersect);
                                                
                                                if (f->v4)
-                                                       CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+                                                       normal_quad_v3( normal,verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co);
                                                else
-                                                       CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+                                                       normal_tri_v3( normal,verts[f->v1].co, verts[f->v2].co, verts[f->v3].co);
 
-                                               Mat4MulVecfl(obmat, location);
+                                               mul_m4_v3(obmat, location);
                                                
-                                               new_depth = VecLenf(location, ray_start);                                       
+                                               new_depth = len_v3v3(location, ray_start);                                      
                                                
-                                               Mat3MulVecfl(timat, normal);
-                                               Normalize(normal);
+                                               mul_m3_v3(timat, normal);
+                                               normalize_v3(normal);
        
                                                addDepthPeel(depth_peels, new_depth, location, normal, ob);
                                        } 
@@ -1684,6 +1821,7 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase
                                        Object *ob = dupli_ob->ob;
                                        
                                        if (ob->type == OB_MESH) {
+#if 0 //BMESH_TODO
                                                EditMesh *em;
                                                DerivedMesh *dm = NULL;
                                                int val;
@@ -1705,6 +1843,7 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase
                                                retval = retval || val;
                                                
                                                dm->release(dm);
+#endif
                                        }
                                }
                                
@@ -1712,7 +1851,7 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase
                        }
                        
                        if (ob->type == OB_MESH) {
-                               EditMesh *em;
+                               BMEditMesh *em;
                                DerivedMesh *dm = NULL;
                                int val;
 
@@ -1724,8 +1863,8 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase
                                }
                                else
                                {
-                                       em = ((Mesh *)ob->data)->edit_mesh;
-                                       dm = editmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH);
+                                       em = ((Mesh *)ob->data)->edit_btmesh;
+                                       dm = editbmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH);
                                        
                                        val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
                                }
@@ -1773,26 +1912,13 @@ void snapGridAction(TransInfo *t, float *val, GearsType action) {
 
 
 void snapGrid(TransInfo *t, float *val) {
-       int invert;
        GearsType action;
 
        // Only do something if using Snap to Grid
-       if (t->tsnap.modePoint != SNAP_GRID)
+       if (t->tsnap.mode != SCE_SNAP_MODE_INCREMENT)
                return;
 
-       if(t->mode==TFM_ROTATION || t->mode==TFM_WARP || t->mode==TFM_TILT || t->mode==TFM_TRACKBALL || t->mode==TFM_BONE_ROLL)
-               invert = U.flag & USER_AUTOROTGRID;
-       else if(t->mode==TFM_RESIZE || t->mode==TFM_SHEAR || t->mode==TFM_BONESIZE || t->mode==TFM_SHRINKFATTEN || t->mode==TFM_CURVE_SHRINKFATTEN)
-               invert = U.flag & USER_AUTOSIZEGRID;
-       else
-               invert = U.flag & USER_AUTOGRABGRID;
-
-       if(invert) {
-               action = (t->modifiers & MOD_SNAP_GEARS) ? NO_GEARS: BIG_GEARS;
-       }
-       else {
-               action = (t->modifiers & MOD_SNAP_GEARS) ? BIG_GEARS : NO_GEARS;
-       }
+       action = activeSnap(t) ? BIG_GEARS : NO_GEARS;
 
        if (action == BIG_GEARS && (t->modifiers & MOD_PRECISION)) {
                action = SMALL_GEARS;