svn merge ^/trunk/blender -r43751:43819, need to look into changes made to editmesh_l...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 1 Feb 2012 09:31:13 +0000 (09:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 1 Feb 2012 09:31:13 +0000 (09:31 +0000)
1  2 
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/editors/include/ED_view3d.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/object/object_modifier.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/transform_conversions.c
source/blender/modifiers/intern/MOD_boolean.c
source/blender/modifiers/intern/MOD_curve.c

index 82c9b0c46919f1123d56427d203102c918522d7b,fabc35361b9ad720906bb16535dcf48918e58398..11700d7f0728f2831409c3758992ede3ce72e11e
@@@ -65,7 -65,6 +65,7 @@@
  #include "BKE_particle.h"
  #include "BKE_scene.h"
  #include "BKE_utildefines.h"
 +#include "BKE_tessmesh.h"
  #include "BKE_depsgraph.h"
  #include "BKE_anim.h"
  #include "BKE_report.h"
@@@ -586,11 -585,14 +586,14 @@@ int interval_test(int min, int max, in
  }
  
  
- /* calculate the deformation implied by the curve path at a given parametric position, and returns whether this operation succeeded 
-  *    - *vec needs FOUR items!
-  *    - ctime is normalized range <0-1>
+ /* calculate the deformation implied by the curve path at a given parametric position,
+  * and returns whether this operation succeeded.
+  *
+  * note: ctime is normalized range <0-1>
+  *
+  * returns OK: 1/0
   */
- int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight) /* returns OK */
+ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight)
  {
        Curve *cu;
        Nurb *nu;
@@@ -896,7 -898,7 +899,7 @@@ static void vertex_duplilist(ListBase *
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject * go = NULL;
 -      EditMesh *em;
 +      BMEditMesh *em;
        float vec[3], no[3], pmat[4][4];
        int totvert, a, oblay;
        unsigned int lay;
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
 -      em = BKE_mesh_get_editmesh(me);
 +      em = me->edit_btmesh;
        
        if(em) {
 -              dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
 -              BKE_mesh_end_editmesh(me, em);
 +              dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
        } else
                dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
        
                                        /* mballs have a different dupli handling */
                                        if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;     /* doesnt render */
  
 -                                      if(me->edit_mesh) {
 +                                      if(me->edit_btmesh) {
                                                dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd);
                                        }
                                        else {
@@@ -1012,45 -1015,44 +1015,45 @@@ static void face_duplilist(ListBase *lb
        DupliObject *dob;
        DerivedMesh *dm;
        Mesh *me= par->data;
 -      MTFace *mtface;
 -      MFace *mface;
 +      MLoopUV *mloopuv;
 +      MPoly *mpoly, *mp;
 +      MLoop *mloop;
        MVert *mvert;
        float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w;
        int lay, oblay, totface, a;
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject *go = NULL;
 -      EditMesh *em;
 +      BMEditMesh *em;
        float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
        copy_m4_m4(pmat, par->obmat);
 -      
 -      em = BKE_mesh_get_editmesh(me);
 +      em = me->edit_btmesh;
 +
        if(em) {
 -              dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
 -              BKE_mesh_end_editmesh(me, em);
 +              dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
        }
        else {
                dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
        }
  
 -      totface= dm->getNumFaces(dm);
 -      mface= dm->getFaceArray(dm);
 +      totface= dm->getNumPolys(dm);
 +      mpoly= dm->getPolyArray(dm);
 +      mloop= dm->getLoopArray(dm);
        mvert= dm->getVertArray(dm);
  
        if(G.rendering) {
  
                orco= (float(*)[3])get_mesh_orco_verts(par);
                transform_mesh_orco_verts(me, orco, me->totvert, 0);
 -              mtface= me->mtface;
 +              mloopuv= me->mloopuv;
        }
        else {
                orco= NULL;
 -              mtface= NULL;
 +              mloopuv= NULL;
        }
        
        /* having to loop on scene OR group objects is NOT FUN */
                                        /* mballs have a different dupli handling */
                                        if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;     /* doesnt render */
  
 -                                      for(a=0; a<totface; a++) {
 -                                              int mv1 = mface[a].v1;
 -                                              int mv2 = mface[a].v2;
 -                                              int mv3 = mface[a].v3;
 -                                              int mv4 = mface[a].v4;
 -                                              float *v1= mvert[mv1].co;
 -                                              float *v2= mvert[mv2].co;
 -                                              float *v3= mvert[mv3].co;
 -                                              float *v4= (mv4)? mvert[mv4].co: NULL;
 +                                      for(a=0, mp= mpoly; a<totface; a++, mp++) {
 +                                              int mv1;
 +                                              int mv2;
 +                                              int mv3;
 +                                              /* int mv4; */ /* UNUSED */
 +                                              float *v1;
 +                                              float *v2;
 +                                              float *v3;
 +                                              /* float *v4; */ /* UNUSED */
                                                float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];
 +                                              MLoop *loopstart= mloop + mp->loopstart;
 +
 +                                              if (mp->totloop < 3) {
 +                                                      /* highly unlikely but to be safe */
 +                                                      continue;
 +                                              }
 +                                              else {
 +                                                      v1= mvert[(mv1= loopstart[0].v)].co;
 +                                                      v2= mvert[(mv2= loopstart[1].v)].co;
 +                                                      v3= mvert[(mv3= loopstart[2].v)].co;
 +                                                      /*
 +                                                      if (mp->totloop > 3) {
 +                                                              v4= mvert[(mv4= loopstart[3].v)].co;
 +                                                      }
 +                                                      */
 +                                              }
  
                                                /* translation */
 -                                              if(v4)
 -                                                      cent_quad_v3(cent, v1, v2, v3, v4);
 -                                              else
 -                                                      cent_tri_v3(cent, v1, v2, v3);
 +                                              mesh_calc_poly_center(mp, loopstart, mvert, cent);
 +
                                                mul_m4_v3(pmat, cent);
                                                
                                                sub_v3_v3v3(cent, cent, pmat[3]);
                                                
                                                /* scale */
                                                if(par->transflag & OB_DUPLIFACES_SCALE) {
 -                                                      float size= v4? area_quad_v3(v1, v2, v3, v4): area_tri_v3(v1, v2, v3);
 +                                                      float size= mesh_calc_poly_area(mp, loopstart, mvert, NULL);
                                                        size= sqrtf(size) * par->dupfacesca;
                                                        mul_m3_fl(mat, size);
                                                }
                                                
                                                dob= new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated);
                                                if(G.rendering) {
 -                                                      w= (mv4)? 0.25f: 1.0f/3.0f;
 +                                                      w= 1.0f / (float)mp->totloop;
  
                                                        if(orco) {
 -                                                              madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv1], w);
 -                                                              madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv2], w);
 -                                                              madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv3], w);
 -                                                              if (mv4) {
 -                                                                      madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv4], w);
 +                                                              int j;
 +                                                              for (j = 0; j < mpoly->totloop; j++) {
 +                                                                      madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w);
                                                                }
                                                        }
  
 -                                                      if(mtface) {
 -                                                              madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[0], w);
 -                                                              madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[1], w);
 -                                                              madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[2], w);
 -                                                              if (mv4) {
 -                                                                      madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[3], w);
 +                                                      if(mloopuv) {
 +                                                              int j;
 +                                                              for (j = 0; j < mpoly->totloop; j++) {
 +                                                                      madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w);
                                                                }
                                                        }
                                                }
index 3ef36918f987bfad9cd9e48866a98daff506651c,02b9330d5882ed451727864b97f8ed48db90c45a..9511ce0c4282df99caf2a1df49eac3cc0d29f100
@@@ -945,6 -945,7 +945,6 @@@ void armature_deform_verts(Object *armO
                        else dvert = NULL;
                } else
                        dvert = NULL;
 -
                if(armature_def_nr >= 0 && dvert) {
                        armature_weight= defvert_find_weight(dvert, armature_def_nr);
  
@@@ -1318,6 -1319,23 +1318,23 @@@ void armature_loc_pose_to_bone(bPoseCha
        copy_v3_v3(outloc, nLocMat[3]);
  }
  
+ void armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+ {
+       bPoseChannel work_pchan = *pchan;
+       /* recalculate pose matrix with only parent transformations,
+        * bone loc/sca/rot is ignored, scene and frame are not used. */
+       where_is_pose_bone(NULL, ob, &work_pchan, 0.0f, FALSE);
+       /* find the matrix, need to remove the bone transforms first so this is
+        * calculated as a matrix to set rather then a difference ontop of whats
+        * already there. */
+       unit_m4(outmat);
+       pchan_apply_mat4(&work_pchan, outmat, FALSE);
+       armature_mat_pose_to_bone(&work_pchan, inmat, outmat);
+ }
  /* same as object_mat3_to_rot() */
  void pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat)
  {
index e207334bd4528cab4490b63d5115839b57a8534e,596677435205518851e60bcc5ccad813e224befa..efeacabdba9be320fcef934be0135a4231b5f6a3
  #include "BKE_global.h"
  #include "BKE_library.h"
  #include "BKE_idprop.h"
 +#include "BKE_mesh.h"
  #include "BKE_shrinkwrap.h"
  #include "BKE_mesh.h"
 +#include "BKE_tessmesh.h"
 +#include "BKE_tracking.h"
 +#include "BKE_movieclip.h"
  #include "BKE_tracking.h"
  #include "BKE_movieclip.h"
  
@@@ -303,6 -299,12 +303,12 @@@ void constraint_mat_convertspace (Objec
                                                
                                                copy_m4_m4(tempmat, mat);
                                                mult_m4_m4m4(mat, imat, tempmat);
+                                               /* override with local location */
+                                               if ((pchan->parent) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
+                                                       armature_mat_pose_to_bone_ex(ob, pchan, pchan->pose_mat, tempmat);
+                                                       copy_v3_v3(mat[3], tempmat[3]);
+                                               }
                                        }
                                }
                                /* pose to local with parent */
@@@ -438,7 -440,7 +444,7 @@@ static void contarget_get_mesh_mat (Obj
  {
        DerivedMesh *dm = NULL;
        Mesh *me= ob->data;
 -      EditMesh *em = BKE_mesh_get_editmesh(me);
 +      BMEditMesh *em = me->edit_btmesh;
        float vec[3] = {0.0f, 0.0f, 0.0f};
        float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
        float imat[3][3], tmat[3][3];
        /* get DerivedMesh */
        if (em) {
                /* target is in editmode, so get a special derived mesh */
 -              dm = CDDM_from_editmesh(em, ob->data);
 +              dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE);
                freeDM= 1;
        }
        else {
                        normalize_v3(normal);
                        copy_v3_v3(plane, tmat[1]);
                        
-                       copy_v3_v3(tmat[2], normal);
-                       cross_v3_v3v3(tmat[0], normal, plane);
-                       cross_v3_v3v3(tmat[1], tmat[2], tmat[0]);
-                       
-                       copy_m4_m3(mat, tmat);
+                       cross_v3_v3v3(mat[0], normal, plane);
+                       if(len_v3(mat[0]) < 1e-3) {
+                               copy_v3_v3(plane, tmat[0]);
+                               cross_v3_v3v3(mat[0], normal, plane);
+                       }
+                       copy_v3_v3(mat[2], normal);
+                       cross_v3_v3v3(mat[1], mat[2], mat[0]);
                        normalize_m4(mat);
-                       
                        
                        /* apply the average coordinate as the new location */
                        mul_v3_m4v3(mat[3], ob->obmat, vec);
        /* free temporary DerivedMesh created (in EditMode case) */
        if (dm && freeDM)
                dm->release(dm);
 -      if (em)
 -              BKE_mesh_end_editmesh(me, em);
  }
  
  /* function that sets the given matrix based on given vertex group in lattice */
index 29585d1c5a381f7d9a31f3a800ef0650b34eaec0,7616e25cbe9c6a376d51e0887dbd0ed847dcedac..78de1809f699a9096aee0284af23c20b3129f708
@@@ -38,11 -38,8 +38,11 @@@ struct BezTriple
  struct bglMats;
  struct BoundBox;
  struct BPoint;
 -struct EditEdge;
 -struct EditFace;
 +struct Nurb;
 +struct BezTriple;
 +struct BMVert;
 +struct BMEdge;
 +struct BMFace;
  struct EditVert;
  struct ImBuf;
  struct Main;
@@@ -55,7 -52,8 +55,8 @@@ struct View3D
  struct ViewContext;
  struct wmWindow;
  struct MVert;
+ struct wmOperatorType;
+ struct wmOperator;
  
  /* for derivedmesh drawing callbacks, for view3d_select, .... */
  typedef struct ViewContext {
@@@ -65,7 -63,7 +66,7 @@@
        struct ARegion *ar;
        struct View3D *v3d;
        struct RegionView3D *rv3d;
 -      struct EditMesh *em;
 +      struct BMEditMesh *em;
        int mval[2];
  } ViewContext;
  
@@@ -192,9 -190,9 +193,9 @@@ void ED_view3d_from_object(struct Objec
   */
  void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
  
 -#if 0 /* UNUSED */
 +//#if 0 /* UNUSED */
  void view3d_unproject(struct bglMats *mats, float out[3], const short x, const short y, const float z);
 -#endif
 +//#endif
  
  /* Depth buffer */
  void ED_view3d_depth_update(struct ARegion *ar);
@@@ -212,6 -210,7 +213,7 @@@ void project_short_noclip(struct ARegio
  void project_int(struct ARegion *ar, const float vec[3], int adr[2]);
  void project_int_noclip(struct ARegion *ar, const float vec[3], int adr[2]);
  
+ void apply_project_float(float persmat[4][4], int winx, int winy, const float vec[], float adr[2]);
  void project_float(struct ARegion *ar, const float vec[3], float adr[2]);
  void project_float_noclip(struct ARegion *ar, const float vec[3], float adr[2]);
  
@@@ -220,13 -219,12 +222,13 @@@ int ED_view3d_viewplane_get(struct View
  void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
  void ED_view3d_project_float(const struct ARegion *a, const float vec[3], float adr[2], float mat[4][4]);
  void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift);
 +void ED_view3d_project_float_v3(struct ARegion *a, float *vec, float *adr, float mat[4][4]);
  void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]);
  
  /* drawobject.c iterators */
 -void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct EditVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts);
 -void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts);
 -void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct EditFace *efa, int x, int y, int index), void *userData);
 +void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts);
 +void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts);
 +void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData);
  void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData);
  void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData);
  
@@@ -305,4 -303,9 +307,9 @@@ struct BGpic *ED_view3D_background_imag
  void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic);
  void ED_view3D_background_image_clear(struct View3D *v3d);
  
+ /* view matrix properties utilities */
+ void ED_view3d_operator_properties_viewmat(struct wmOperatorType *ot);
+ void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOperator *op);
+ void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx, int *winy, float persmat[4][4]);
  #endif /* ED_VIEW3D_H */
index 9bc8937a61664c4c51818386c84b2977ae0bfa15,1f6165852d7554a8fbf66c19c83b4fc13c6c9c77..3093a4d40f9fe7e081eef40200746db36ea74670
@@@ -2107,7 -2107,7 +2107,7 @@@ static void list_item_row(bContext *C, 
        name= (namebuf)? namebuf: "";
  
        /* hardcoded types */
 -      if(itemptr->type == &RNA_MeshTextureFaceLayer || itemptr->type == &RNA_MeshColorLayer) {
 +      if(itemptr->type == &RNA_MeshTexturePolyLayer || itemptr->type == &RNA_MeshLoopColorLayer) {
                uiItemL(sub, name, icon);
                uiBlockSetEmboss(block, UI_EMBOSSN);
                uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
                Object *ob= (Object*)activeptr->data;
                Key *key= (Key*)itemptr->id.data;
  
-               split= uiLayoutSplit(sub, 0.75f, 0);
+               split= uiLayoutSplit(sub, 0.66f, 0);
  
                uiItemL(split, name, icon);
  
                row= uiLayoutRow(split, 1);
                if(i == 0 || (key->type != KEY_RELATIVE)) uiItemL(row, "", ICON_NONE);
                else uiItemR(row, itemptr, "value", 0, "", ICON_NONE);
+               uiItemR(row, itemptr, "mute", 0, "", 0);
  
-               if(ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH))
+               if( (key->flag & KEYBLOCK_MUTE) ||
+                   (ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH)) )
+               {
                        uiLayoutSetActive(row, 0);
-               //uiItemR(row, itemptr, "mute", 0, "", ICON_MUTE_IPO_OFF);
+               }
                uiBlockSetEmboss(block, UI_EMBOSS);
        }
        else if(itemptr->type == &RNA_VertexGroup) {
index d6ef894b2c7a0f4c9c213ca89e38ec9292bf7975,ed5899d81a822991a29f59f5ef7818227931d3c4..aef8aa4293198a2ced79e4a707b5e868fd8ed9c6
@@@ -68,7 -68,6 +68,7 @@@
  #include "BKE_ocean.h"
  #include "BKE_particle.h"
  #include "BKE_softbody.h"
 +#include "BKE_tessmesh.h"
  
  #include "RNA_access.h"
  #include "RNA_define.h"
@@@ -215,15 -214,15 +215,15 @@@ static int object_modifier_remove(Objec
                        }
  
                if(ok) {
 -                      if(me->edit_mesh) {
 -                              EditMesh *em= me->edit_mesh;
 +                      if(me->edit_btmesh) {
 +                              BMEditMesh *em= me->edit_btmesh;
                                /* CustomData_external_remove is used here only to mark layer as non-external
                                   for further free-ing, so zero element count looks safer than em->totface */
 -                              CustomData_external_remove(&em->fdata, &me->id, CD_MDISPS, 0);
 -                              EM_free_data_layer(em, &em->fdata, CD_MDISPS);
 +                              CustomData_external_remove(&em->bm->ldata, &me->id, CD_MDISPS, 0);
 +                              BM_free_data_layer(em->bm, &em->bm->ldata, CD_MDISPS);
                        } else {
 -                              CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
 -                              CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
 +                              CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
 +                              CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
                        }
                }
        }
@@@ -447,17 -446,6 +447,17 @@@ static int modifier_apply_shape(ReportL
                return 0;
        }
  
 +      /*
 +        It should be ridiculously easy to extract the original verts that we want
 +        and form the shape data.  We can probably use the CD KEYINDEX layer (or
 +        whatever I ended up calling it, too tired to check now), though this would
 +        by necassity have to make some potentially ugly assumptions about the order
 +        of the mesh data :-/  you can probably assume in 99% of cases that the first
 +        element of a given index is the original, and any subsequent duplicates are
 +        copies/interpolates, but that's an assumption that would need to be tested
 +        and then predominantly stated in comments in a half dozen headers.
 +      */
 +
        if (ob->type==OB_MESH) {
                DerivedMesh *dm;
                Mesh *me= ob->data;
                        return 0;
                }
                
 -              dm = mesh_create_derived_for_modifier(scene, ob, md);
 +              dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
                if (!dm) {
                        BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
                        return 0;
@@@ -527,19 -515,19 +527,19 @@@ static int modifier_apply_obdata(Report
                                return 0;
                        }
                } else {
 -                      dm = mesh_create_derived_for_modifier(scene, ob, md);
 +                      dm = mesh_create_derived_for_modifier(scene, ob, md, 1);
                        if (!dm) {
                                BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
                                return 0;
                        }
  
 -                      DM_to_mesh(dm, me);
 +                      DM_to_mesh(dm, me, ob);
  
                        dm->release(dm);
  
                        if(md->type == eModifierType_Multires) {
 -                              CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
 -                              CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
 +                              CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
 +                              CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
                        }
                }
        }
                int numVerts;
                float (*vertexCos)[3];
  
-               if (mti->type==eModifierTypeType_Constructive) {
+               if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
                        BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
                        return 0;
                }
@@@ -1177,66 -1165,6 +1177,66 @@@ void OBJECT_OT_multires_reshape(wmOpera
        edit_modifier_properties(ot);
  }
  
 +static int multires_test_exec(bContext *C, wmOperator *op)
 +{
 +      Object *ob= ED_object_active_context(C);
 +      Mesh *me = ob->data;
 +      MPoly *mp;
 +      MDisps *mdisps;
 +      int i, x = RNA_int_get(op->ptr, "x"), y = RNA_int_get(op->ptr, "y");
 +      
 +      if (ob->type != OB_MESH || !me)
 +              return OPERATOR_CANCELLED;
 +      
 +      mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
 +      if (!mdisps)
 +              return OPERATOR_CANCELLED;
 +      
 +      mp = me->mpoly;
 +      for (i=0; i<me->totpoly; i++, mp++) {
 +              MLoop *ml;
 +              int j;
 +              
 +              ml = me->mloop + mp->loopstart;
 +              for (j=0; j<mp->totloop; j++, ml++) {
 +                      MLoop *ml_prev = ME_POLY_LOOP_PREV(me->mloop, mp, j);
 +                      MLoop *ml_next = ME_POLY_LOOP_NEXT(me->mloop, mp, j);
 +                      
 +                      if ((me->mvert[ml->v].flag&SELECT) && (me->mvert[ml_prev->v].flag&SELECT) && (me->mvert[ml_next->v].flag&SELECT)) {
 +                              MDisps *md = mdisps + mp->loopstart + j;
 +                              int res = sqrt(md->totdisp);
 +                              
 +                              if (x >= res) x = res-1;
 +                              if (y >= res) y = res-1;
 +                              
 +                              md->disps[y*res + x][2] += 1.0;
 +                      }
 +              }
 +      }
 +              
 +      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
 +
 +      return OPERATOR_FINISHED;
 +}
 +
 +void OBJECT_OT_test_multires(wmOperatorType *ot)
 +{
 +      ot->name= "Multires Object Mode Test";
 +      ot->description= "";
 +      ot->idname= "OBJECT_OT_test_multires";
 +
 +      ot->poll= multires_poll;
 +      ot->exec= multires_test_exec;
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      RNA_def_int(ot->srna, "x", 0, 0, 100, "x", "x", 0, 100);
 +      RNA_def_int(ot->srna, "y", 0, 0, 100, "y", "y", 0, 100);
 +}
 +
 +
 +              
  /****************** multires save external operator *********************/
  
  static int multires_external_save_exec(bContext *C, wmOperator *op)
        if(!me)
                return OPERATOR_CANCELLED;
  
 -      if(CustomData_external_test(&me->fdata, CD_MDISPS))
 +      if(CustomData_external_test(&me->ldata, CD_MDISPS))
                return OPERATOR_CANCELLED;
        
        RNA_string_get(op->ptr, "filepath", path);
        if(relative)
                BLI_path_rel(path, G.main->name);
  
 -      CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path);
 -      CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0);
 +      CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
 +      CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
        
        return OPERATOR_FINISHED;
  }
@@@ -1278,7 -1206,7 +1278,7 @@@ static int multires_external_save_invok
        if (!mmd)
                return OPERATOR_CANCELLED;
        
 -      if(CustomData_external_test(&me->fdata, CD_MDISPS))
 +      if(CustomData_external_test(&me->ldata, CD_MDISPS))
                return OPERATOR_CANCELLED;
  
        if(RNA_struct_property_is_set(op->ptr, "filepath"))
@@@ -1319,11 -1247,11 +1319,11 @@@ static int multires_external_pack_exec(
        Object *ob = ED_object_active_context(C);
        Mesh *me= ob->data;
  
 -      if(!CustomData_external_test(&me->fdata, CD_MDISPS))
 +      if(!CustomData_external_test(&me->ldata, CD_MDISPS))
                return OPERATOR_CANCELLED;
  
        // XXX don't remove..
 -      CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
 +      CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
        
        return OPERATOR_FINISHED;
  }
index 2083b2789ef5b3ef347b43ff7663918f6ab22a94,e12efb72fcc3d0e056edb103b59d2a84c0ae1675..2bca87c564e6f4f45c1bef1580b157e266d3ecda
@@@ -47,7 -47,6 +47,7 @@@
  #include "DNA_world_types.h"
  #include "DNA_armature_types.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
  #include "BLI_editVert.h"
@@@ -80,8 -79,6 +80,8 @@@
  #include "BKE_movieclip.h"
  #include "BKE_tracking.h"
  
 +#include "BKE_tessmesh.h"
 +
  #include "smoke_API.h"
  
  #include "IMB_imbuf.h"
@@@ -122,51 -119,42 +122,51 @@@ typedef enum eWireDrawMode 
  
  /* user data structures for derived mesh callbacks */
  typedef struct foreachScreenVert_userData {
 -      void (*func)(void *userData, EditVert *eve, int x, int y, int index);
 +      void (*func)(void *userData, BMVert *eve, int x, int y, int index);
        void *userData;
        ViewContext vc;
        eV3DClipTest clipVerts;
  } foreachScreenVert_userData;
  
  typedef struct foreachScreenEdge_userData {
 -      void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
 +      void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index);
        void *userData;
        ViewContext vc;
        eV3DClipTest clipVerts;
  } foreachScreenEdge_userData;
  
  typedef struct foreachScreenFace_userData {
 -      void (*func)(void *userData, EditFace *efa, int x, int y, int index);
 +      void (*func)(void *userData, BMFace *efa, int x, int y, int index);
        void *userData;
        ViewContext vc;
  } foreachScreenFace_userData;
  
  typedef struct drawDMVerts_userData {
 +      BMEditMesh *em; /* BMESH BRANCH ONLY */
 +
        int sel;
 -      EditVert *eve_act;
 +      BMVert *eve_act;
  } drawDMVerts_userData;
  
  typedef struct drawDMEdgesSel_userData {
 +      BMEditMesh *em; /* BMESH BRANCH ONLY */
 +
        unsigned char *baseCol, *selCol, *actCol;
 -      EditEdge *eed_act;
 +      BMEdge *eed_act;
  } drawDMEdgesSel_userData;
  
  typedef struct drawDMFacesSel_userData {
        unsigned char *cols[3];
 -      EditFace *efa_act;
 +
 +      DerivedMesh *dm; /* BMESH BRANCH ONLY */
 +      BMEditMesh *em;  /* BMESH BRANCH ONLY */
 +
 +      BMFace *efa_act;
        int *orig_index;
  } drawDMFacesSel_userData;
  
  typedef struct drawDMNormal_userData {
 +      BMEditMesh *em;
        float normalsize;
  } drawDMNormal_userData;
  
@@@ -240,10 -228,8 +240,10 @@@ static void view3d_project_short_clip(A
        }
  }
  
 +/* BMESH NOTE: this function is unused in bmesh only */
 +
  /* only use while object drawing */
 -static void view3d_project_short_noclip(ARegion *ar, const float vec[3], short adr[2])
 +static void UNUSED_FUNCTION(view3d_project_short_noclip)(ARegion *ar, const float vec[3], short adr[2])
  {
        RegionView3D *rv3d= ar->regiondata;
        float fx, fy, vec4[4];
@@@ -2004,17 -1990,15 +2004,17 @@@ static void drawlattice(Scene *scene, V
  static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
        foreachScreenVert_userData *data = userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      BMVert *eve = EDBM_get_vert_for_index(data->vc.em, index);
  
 -      if (eve->h==0) {
 +      if (!BM_TestHFlag(eve, BM_HIDDEN)) {
                short s[2]= {IS_CLIPPED, 0};
  
                if (data->clipVerts != V3D_CLIP_TEST_OFF) {
                        view3d_project_short_clip(data->vc.ar, co, s, 1);
                } else {
 -                      view3d_project_short_noclip(data->vc.ar, co, s);
 +                      float co2[2];
 +                      mul_v3_m4v3(co2, data->vc.obedit->obmat, co);
 +                      project_short_noclip(data->vc.ar, co2, s);
                }
  
                if (s[0]!=IS_CLIPPED)
  
  void mesh_foreachScreenVert(
          ViewContext *vc,
 -        void (*func)(void *userData, EditVert *eve, int x, int y, int index),
 +        void (*func)(void *userData, BMVert *eve, int x, int y, int index),
          void *userData, eV3DClipTest clipVerts)
  {
        foreachScreenVert_userData data;
 -      DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 +      DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
        
        data.vc= *vc;
        data.func = func;
        if(clipVerts != V3D_CLIP_TEST_OFF)
                ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
  
 -      EM_init_index_arrays(vc->em, 1, 0, 0);
 +      EDBM_init_index_arrays(vc->em, 1, 0, 0);
        dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
@@@ -2082,23 -2066,17 +2082,23 @@@ static int is_co_in_region(ARegion *ar
  static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
  {
        foreachScreenEdge_userData *data = userData;
 -      EditEdge *eed = EM_get_edge_for_index(index);
 -      short s[2][2];
 +      BMEdge *eed = EDBM_get_edge_for_index(data->vc.em, index);
 +
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
 +              short s[2][2];
  
 -      if (eed->h==0) {
                if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) {
                        view3d_project_short_clip(data->vc.ar, v0co, s[0], 1);
                        view3d_project_short_clip(data->vc.ar, v1co, s[1], 1);
                }
                else {
 -                      view3d_project_short_noclip(data->vc.ar, v0co, s[0]);
 -                      view3d_project_short_noclip(data->vc.ar, v1co, s[1]);
 +                      float v1_co[3], v2_co[3];
 +
 +                      mul_v3_m4v3(v1_co, data->vc.obedit->obmat, v0co);
 +                      mul_v3_m4v3(v2_co, data->vc.obedit->obmat, v1co);
 +
 +                      project_short_noclip(data->vc.ar, v1_co, s[0]);
 +                      project_short_noclip(data->vc.ar, v2_co, s[1]);
  
                        if (data->clipVerts == V3D_CLIP_TEST_REGION) {
                                if ( !is_co_in_region(data->vc.ar, s[0]) &&
  
  void mesh_foreachScreenEdge(
          ViewContext *vc,
 -        void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index),
 +        void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index),
          void *userData, eV3DClipTest clipVerts)
  {
        foreachScreenEdge_userData data;
 -      DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 +      DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
  
        data.vc= *vc;
        data.func = func;
        if(clipVerts != V3D_CLIP_TEST_OFF)
                ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
  
 -      EM_init_index_arrays(vc->em, 0, 1, 0);
 +      EDBM_init_index_arrays(vc->em, 0, 1, 0);
        dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
  static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no))
  {
        foreachScreenFace_userData *data = userData;
 -      EditFace *efa = EM_get_face_for_index(index);
 -      short s[2];
 +      BMFace *efa = EDBM_get_face_for_index(data->vc.em, index);
 +
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
 +              float cent2[3];
 +              short s[2];
  
 -      if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
 -              view3d_project_short_clip(data->vc.ar, cent, s, 1);
 +              mul_v3_m4v3(cent2, data->vc.obedit->obmat, cent);
 +              project_short(data->vc.ar, cent2, s);
  
                if (s[0] != IS_CLIPPED) {
                        data->func(data->userData, efa, s[0], s[1], index);
  
  void mesh_foreachScreenFace(
          ViewContext *vc,
 -        void (*func)(void *userData, EditFace *efa, int x, int y, int index),
 +        void (*func)(void *userData, BMFace *efa, int x, int y, int index),
          void *userData)
  {
        foreachScreenFace_userData data;
 -      DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 +      DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
  
        data.vc= *vc;
        data.func = func;
        //if(clipVerts)
        ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
  
 -      EM_init_index_arrays(vc->em, 0, 0, 1);
 +      EDBM_init_index_arrays(vc->em, 0, 0, 1);
        dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
@@@ -2242,20 -2217,19 +2242,20 @@@ void nurbs_foreachScreenVert
  static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
  {
        drawDMNormal_userData *data = userData;
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(data->em, index);
  
 -      if (efa->h==0 && efa->fgonf!=EM_FGON) {
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                glVertex3fv(cent);
                glVertex3f(cent[0] + no[0] * data->normalsize,
                           cent[1] + no[1] * data->normalsize,
                           cent[2] + no[2] * data->normalsize);
        }
  }
 -static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
 +static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
  {
        drawDMNormal_userData data;
  
 +      data.em = em;
        data.normalsize = scene->toolsettings->normalsize;
  
        glBegin(GL_LINES);
  
  static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *UNUSED(no))
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 -      int sel = *((int*) userData);
 -
 -      if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
 +      BMFace *efa = EDBM_get_face_for_index(((void **)userData)[0], index);
 +      int sel = *(((int **)userData)[1]);
 +      
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT)==sel) {
                bglVertex3fv(cent);
        }
  }
 -static void draw_dm_face_centers(DerivedMesh *dm, int sel)
 +static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, int sel)
  {
 +      void *ptrs[2] = {em, &sel};
 +
        bglBegin(GL_POINTS);
 -      dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &sel);
 +      dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs);
        bglEnd();
  }
  
  static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
  {
        drawDMNormal_userData *data = userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      BMVert *eve = EDBM_get_vert_for_index(data->em, index);
  
 -      if (eve->h==0) {
 +      if (!BM_TestHFlag(eve, BM_HIDDEN)) {
                glVertex3fv(co);
  
                if (no_f) {
                }
        }
  }
 -static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm) 
 +static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
  {
        drawDMNormal_userData data;
  
 +      data.em = em;
        data.normalsize = scene->toolsettings->normalsize;
  
        glBegin(GL_LINES);
        glEnd();
  }
  
 -      /* Draw verts with color set based on selection */
 +/* Draw verts with color set based on selection */
  static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
        drawDMVerts_userData * data = userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      BMVert *eve = EDBM_get_vert_for_index(data->em, index);
  
 -      if (eve->h==0 && (eve->f&SELECT)==data->sel) {
 +      if (!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT)==data->sel) {
                /* draw active larger - need to stop/start point drawing for this :/ */
                if (eve==data->eve_act) {
                        float size = UI_GetThemeValuef(TH_VERTEX_SIZE);
        }
  }
  
 -static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
 +static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act)
  {
        drawDMVerts_userData data;
        data.sel = sel;
        data.eve_act = eve_act;
 +      data.em = em;
  
        bglBegin(GL_POINTS);
        dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
        /* Draw edges with color set based on selection */
  static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed;
        //unsigned char **cols = userData, *col;
        drawDMEdgesSel_userData * data = userData;
        unsigned char *col;
  
 -      if (eed->h==0) {
 +      eed = EDBM_get_edge_for_index(data->em, index);
 +
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
                if (eed==data->eed_act) {
                        glColor4ubv(data->actCol);
                } else {
 -                      if (eed->f&SELECT) {
 +                      if (BM_TestHFlag(eed, BM_SELECT)) {
                                col = data->selCol;
                        } else {
                                col = data->baseCol;
                return 0;
        }
  }
 -static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act) 
 +static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
 +                            unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) 
  {
        drawDMEdgesSel_userData data;
        
        data.baseCol = baseCol;
        data.selCol = selCol;
        data.actCol = actCol;
 +      data.em = em;
        data.eed_act = eed_act;
        dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data);
  }
  
        /* Draw edges */
 -static int draw_dm_edges__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges__setDrawOptions(void *userData, int index)
  {
 -      return EM_get_edge_for_index(index)->h==0;
 +      return !BM_TestHFlag(EDBM_get_edge_for_index(userData, index), BM_HIDDEN);
  }
 -static void draw_dm_edges(DerivedMesh *dm) 
 +static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) 
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em);
  }
  
        /* Draw edges with color interpolated based on selection */
 -static int draw_dm_edges_sel_interp__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
  {
 -      return EM_get_edge_for_index(index)->h==0;
 +      return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[0], index), BM_HIDDEN);
  }
  static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[0], index);
        unsigned char **cols = userData;
 -      unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
 -      unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
 +      unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?2:1];
 +      unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?2:1];
  
        glColor4ub(     col0[0] + (col1[0]-col0[0])*t,
                                col0[1] + (col1[1]-col0[1])*t,
                                col0[3] + (col1[3]-col0[3])*t);
  }
  
 -static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
 +static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
  {
 -      unsigned char *cols[2];
 -      cols[0]= baseCol;
 -      cols[1]= selCol;
 +      void *cols[3] = {em, baseCol, selCol};
 +
        dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
  }
  
        /* Draw only seam edges */
 -static int draw_dm_edges_seams__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_seams__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
  
 -      return (eed->h==0 && eed->seam);
 +      return !BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SEAM);
  }
 -static void draw_dm_edges_seams(DerivedMesh *dm)
 +
 +static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em);
  }
  
        /* Draw only sharp edges */
 -static int draw_dm_edges_sharp__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
  
 -      return (eed->h==0 && eed->sharp);
 +      return !BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SHARP);
  }
 -static void draw_dm_edges_sharp(DerivedMesh *dm)
 +static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em);
  }
  
  
  static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
  {
        drawDMFacesSel_userData * data = userData;
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(data->em, index);
        unsigned char *col;
        
 -      if (efa->h==0) {
 +      if (!efa)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                if (efa == data->efa_act) {
                        glColor4ubv(data->cols[2]);
                        return 2; /* stipple */
                } else {
 -                      col = data->cols[(efa->f&SELECT)?1:0];
 +                      col = data->cols[BM_TestHFlag(efa, BM_SELECT)?1:0];
                        if (col[3]==0) return 0;
                        glColor4ubv(col);
                        return 1;
  
  static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
  {
 +
        drawDMFacesSel_userData *data = userData;
 -      EditFace *efa;
 -      EditFace *next_efa;
 +      BMFace *efa;
 +      BMFace *next_efa;
 +
        unsigned char *col, *next_col;
  
        if(!data->orig_index)
                return 0;
  
 -      efa= EM_get_face_for_index(data->orig_index[index]);
 -      next_efa= EM_get_face_for_index(data->orig_index[next_index]);
 +      efa= EDBM_get_face_for_index(data->em, data->orig_index[index]);
 +      next_efa= EDBM_get_face_for_index(data->em, data->orig_index[next_index]);
  
        if(efa == next_efa)
                return 1;
        if(efa == data->efa_act || next_efa == data->efa_act)
                return 0;
  
 -      col = data->cols[(efa->f&SELECT)?1:0];
 -      next_col = data->cols[(next_efa->f&SELECT)?1:0];
 +      col = data->cols[BM_TestHFlag(efa, BM_SELECT)?1:0];
 +      next_col = data->cols[BM_TestHFlag(next_efa, BM_SELECT)?1:0];
  
        if(col[3]==0 || next_col[3]==0)
                return 0;
  }
  
  /* also draws the active face */
 -static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
 +                            unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
  {
        drawDMFacesSel_userData data;
 +      data.dm= dm;
        data.cols[0] = baseCol;
 +      data.em = em;
        data.cols[1] = selCol;
        data.cols[2] = actCol;
        data.efa_act = efa_act;
 -      data.orig_index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
 +      data.orig_index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
  
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
  }
  
 -static int draw_dm_creases__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_creases__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 -
 -      if (eed->h==0 && eed->crease != 0.0f) {
 -              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_CREASE, eed->crease);
 +      BMEditMesh *em = userData;
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 +      float *crease = eed ? bm_get_cd_float(&em->bm->edata, eed->head.data, CD_CREASE) : NULL;
 +      
 +      if (!crease)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(eed, BM_HIDDEN) && *crease!=0.0f) {
 +              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_CREASE, *crease);
                return 1;
        } else {
                return 0;
        }
  }
 -static void draw_dm_creases(DerivedMesh *dm)
 +static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
  {
        glLineWidth(3.0);
 -      dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, em);
        glLineWidth(1.0);
  }
  
 -static int draw_dm_bweights__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_bweights__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEditMesh *em = userData;
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 +      float *bweight = bm_get_cd_float(&em->bm->edata, eed->head.data, CD_BWEIGHT);
  
 -      if (eed->h==0 && eed->bweight != 0.0f) {
 -              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->bweight);
 +      if (!bweight)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(eed, BM_HIDDEN) && *bweight!=0.0f) {
 +              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, *bweight);
                return 1;
        } else {
                return 0;
        }
  }
 -static void draw_dm_bweights__mapFunc(void *UNUSED(userData), int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 +static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      EditVert *eve = EM_get_vert_for_index(index);
 -
 -      if (eve->h==0 && eve->bweight != 0.0f) {
 -              UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, eve->bweight);
 +      BMEditMesh *em = userData;
 +      BMVert *eve = EDBM_get_vert_for_index(userData, index);
 +      float *bweight = bm_get_cd_float(&em->bm->vdata, eve->head.data, CD_BWEIGHT);
 +      
 +      if (!bweight)
 +              return;
 +      
 +      if (!BM_TestHFlag(eve, BM_HIDDEN) && *bweight!=0.0f) {
 +              UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, *bweight);
                bglVertex3fv(co);
        }
  }
 -static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 +static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
  {
        ToolSettings *ts= scene->toolsettings;
  
        if (ts->selectmode & SCE_SELECT_VERTEX) {
                glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
                bglBegin(GL_POINTS);
 -              dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
 +              dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, em);
                bglEnd();
        }
        else {
                glLineWidth(3.0);
 -              dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, NULL);
 +              dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em);
                glLineWidth(1.0);
        }
  }
  
  /* EditMesh drawing routines*/
  
 -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
 -                                DerivedMesh *cageDM, EditVert *eve_act)
 +static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, 
 +                                BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act)
  {
        ToolSettings *ts= scene->toolsettings;
        int sel;
                        if(ts->selectmode & SCE_SELECT_VERTEX) {
                                glPointSize(size);
                                glColor4ubv(col);
 -                              draw_dm_verts(cageDM, sel, eve_act);
 +                              draw_dm_verts(em, cageDM, sel, eve_act);
                        }
                        
                        if(check_ob_drawface_dot(scene, v3d, obedit->dt)) {
                                glPointSize(fsize);
                                glColor4ubv(fcol);
 -                              draw_dm_face_centers(cageDM, sel);
 +                              draw_dm_face_centers(em, cageDM, sel);
                        }
                        
                        if (pass==0) {
        glPointSize(1.0);
  }
  
 -static void draw_em_fancy_edges(Scene *scene, View3D *v3d,
 +static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
                                  Mesh *me, DerivedMesh *cageDM, short sel_only,
 -                                EditEdge *eed_act)
 +                                BMEdge *eed_act)
  {
        ToolSettings *ts= scene->toolsettings;
        int pass;
                }
  
                if(ts->selectmode == SCE_SELECT_FACE) {
 -                      draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
 +                      draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
                }       
                else if( (me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE) ) {        
                        if(cageDM->drawMappedEdgesInterp && (ts->selectmode & SCE_SELECT_VERTEX)) {
                                glShadeModel(GL_SMOOTH);
 -                              draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
 +                              draw_dm_edges_sel_interp(em, cageDM, wireCol, selCol);
                                glShadeModel(GL_FLAT);
                        } else {
 -                              draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
 +                              draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
                        }
                }
                else {
                        if (!sel_only) {
                                glColor4ubv(wireCol);
 -                              draw_dm_edges(cageDM);
 +                              draw_dm_edges(em, cageDM);
                        }
                }
  
        }
  }     
  
 -static void draw_em_measure_stats(View3D *v3d, Object *ob, EditMesh *em, UnitSettings *unit)
 +static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit)
  {
        Mesh *me= ob->data;
 -      EditEdge *eed;
 -      EditFace *efa;
 -      float v1[3], v2[3], v3[3], v4[3], vmid[3];
 -      float fvec[3];
 +      float v1[3], v2[3], v3[3], vmid[3], fvec[3];
        char numstr[32]; /* Stores the measurement display text here */
        const char *conv_float; /* Use a float conversion matching the grid size */
        unsigned char col[4]= {0, 0, 0, 255}; /* color of the text to draw */
        const int do_global= v3d->flag & V3D_GLOBAL_STATS;
        const int do_moving= G.moving;
  
 +      BMIter iter;
 +      int i;
 +
        /* make the precision of the pronted value proportionate to the gridsize */
  
        if (grid < 0.01f)               conv_float= "%.6g";
        else                                    conv_float= "%.2g";
        
        if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
 +              BMEdge *eed;
 +
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
  
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      /* draw non fgon edges, or selected edges, or edges next to selected verts while draging */
 -                      if((eed->h != EM_FGON) && ((eed->f & SELECT) || (do_moving && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT)) ))) {
 +              eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 +              for(; eed; eed=BMIter_Step(&iter)) {
 +                      /* draw selected edges, or edges next to selected verts while draging */
 +                      if(BM_TestHFlag(eed, BM_SELECT) ||
 +                              (do_moving && (BM_TestHFlag(eed->v1, BM_SELECT) || BM_TestHFlag(eed->v2, BM_SELECT) ))) {
 +
                                copy_v3_v3(v1, eed->v1->co);
                                copy_v3_v3(v2, eed->v2->co);
  
        }
  
        if(me->drawflag & ME_DRAWEXTRA_FACEAREA) {
 -// XXX                extern int faceselectedOR(EditFace *efa, int flag); // editmesh.h shouldn't be in this file... ok for now?
 +              /* would be nice to use BM_Compute_Face_Area, but that is for 2d faces
 +              so instead add up tessalation triangle areas */
 +              BMFace *f;
 +              int n;
 +
 +#define DRAW_EM_MEASURE_STATS_FACEAREA()                                             \
 +              if (BM_TestHFlag(f, BM_SELECT)) {                                            \
 +                      mul_v3_fl(vmid, 1.0/n);                                                  \
 +                      if(unit->system)                                                         \
 +                              bUnit_AsString(numstr, sizeof(numstr), area*unit->scale_length,      \
 +                                      3, unit->system, B_UNIT_LENGTH, do_split, FALSE);                \
 +                      else                                                                     \
 +                              BLI_snprintf(numstr, sizeof(numstr), conv_float, area);              \
 +                      view3d_cached_text_draw_add(vmid, numstr, 0, V3D_CACHE_TEXT_ASCII, col); \
 +              }
 +
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
                
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      if((efa->f & SELECT)) { // XXX || (do_moving && faceselectedOR(efa, SELECT)) ) {
 -                              copy_v3_v3(v1, efa->v1->co);
 -                              copy_v3_v3(v2, efa->v2->co);
 -                              copy_v3_v3(v3, efa->v3->co);
 -                              if (efa->v4) {
 -                                      copy_v3_v3(v4, efa->v4->co);
 -                              }
 -                              if(do_global) {
 -                                      mul_mat3_m4_v3(ob->obmat, v1);
 -                                      mul_mat3_m4_v3(ob->obmat, v2);
 -                                      mul_mat3_m4_v3(ob->obmat, v3);
 -                                      if (efa->v4) mul_mat3_m4_v3(ob->obmat, v4);
 -                              }
 -                              
 -                              if (efa->v4)
 -                                      area=  area_quad_v3(v1, v2, v3, v4);
 -                              else
 -                                      area = area_tri_v3(v1, v2, v3);
 -
 -                              if(unit->system) {
 -                                      // XXX should be B_UNIT_AREA
 -                                      bUnit_AsString(numstr, sizeof(numstr), area * unit->scale_length, 3,
 -                                                     unit->system, B_UNIT_LENGTH, do_split, FALSE);
 -                              }
 -                              else {
 -                                      sprintf(numstr, conv_float, area);
 -                              }
 -
 -                              view3d_cached_text_draw_add(efa->cent, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
 +              f = NULL;
 +              area = 0.0;
 +              zero_v3(vmid);
 +              n = 0;
 +              for(i = 0; i < em->tottri; i++) {
 +                      BMLoop **l = em->looptris[i];
 +                      if(f && l[0]->f != f) {
 +                              DRAW_EM_MEASURE_STATS_FACEAREA();
 +                              zero_v3(vmid);
 +                              area = 0.0;
 +                              n = 0;
 +                      }
 +
 +                      f = l[0]->f;
 +                      copy_v3_v3(v1, l[0]->v->co);
 +                      copy_v3_v3(v2, l[1]->v->co);
 +                      copy_v3_v3(v3, l[2]->v->co);
 +                      if(do_global) {
 +                              mul_mat3_m4_v3(ob->obmat, v1);
 +                              mul_mat3_m4_v3(ob->obmat, v2);
 +                              mul_mat3_m4_v3(ob->obmat, v3);
                        }
 +                      area += area_tri_v3(v1, v2, v3);
 +                      add_v3_v3(vmid, v1);
 +                      add_v3_v3(vmid, v2);
 +                      add_v3_v3(vmid, v3);
 +                      n += 3;
                }
 +
 +              if(f){
 +                      DRAW_EM_MEASURE_STATS_FACEAREA();
 +              }
 +#undef DRAW_EM_MEASURE_STATS_FACEAREA
        }
  
        if(me->drawflag & ME_DRAWEXTRA_FACEANG) {
 -              EditEdge *e1, *e2, *e3, *e4;
 +              BMFace *efa;
 +
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      copy_v3_v3(v1, efa->v1->co);
 -                      copy_v3_v3(v2, efa->v2->co);
 -                      copy_v3_v3(v3, efa->v3->co);
 -                      if(efa->v4) {
 -                              copy_v3_v3(v4, efa->v4->co); 
 -                      }
 -                      else {
 -                              copy_v3_v3(v4, v3);
 -                      }
 -                      if(do_global) {
 -                              mul_mat3_m4_v3(ob->obmat, v1);
 -                              mul_mat3_m4_v3(ob->obmat, v2);
 -                              mul_mat3_m4_v3(ob->obmat, v3);
 -                              mul_mat3_m4_v3(ob->obmat, v4); /* intentionally executed even for tri's */
 -                      }
 -                      
 -                      e1= efa->e1;
 -                      e2= efa->e2;
 -                      e3= efa->e3;
 -                      if(efa->e4) e4= efa->e4; else e4= e3;
 -                      
 -                      /* Calculate the angles */
 -                              
 -                      if( (e4->f & e1->f & SELECT) || (do_moving && (efa->v1->f & SELECT)) ) {
 -                              /* Vec 1 */
 -                              sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v4, v1, v2)));
 -                              interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f);
 -                              view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
 -                      }
 -                      if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) {
 -                              /* Vec 2 */
 -                              sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
 -                              interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f);
 -                              view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
 -                      }
 -                      if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) {
 -                              /* Vec 3 */
 -                              if(efa->v4) 
 -                                      sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v4)));
 -                              else
 -                                      sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v1)));
 -                              interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f);
 -                              view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
 -                      }
 -                              /* Vec 4 */
 -                      if(efa->v4) {
 -                              if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) {
 -                                      sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v3, v4, v1)));
 -                                      interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f);
 +
 +
 +              for(efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
 +                  efa; efa=BMIter_Step(&iter)) {
 +                      BMIter liter;
 +                      BMLoop *loop;
 +
 +                      BM_Compute_Face_CenterBounds(em->bm, efa, vmid);
 +
 +                      for(loop = BMIter_New(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
 +                          loop; loop = BMIter_Step(&liter)) {
 +
 +                              float v1[3], v2[3], v3[3];
 +
 +                              copy_v3_v3(v1, loop->prev->v->co);
 +                              copy_v3_v3(v2, loop->v->co);
 +                              copy_v3_v3(v3, loop->next->v->co);
 +
 +                              if(do_global){
 +                                      mul_mat3_m4_v3(ob->obmat, v1);
 +                                      mul_mat3_m4_v3(ob->obmat, v2);
 +                                      mul_mat3_m4_v3(ob->obmat, v3);
 +                              }
 +
 +                              if ( (BM_TestHFlag(efa, BM_SELECT)) ||
 +                                   (do_moving && BM_TestHFlag(loop->v, BM_SELECT)))
 +                              {
 +                                      BLI_snprintf(numstr, sizeof(numstr), "%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
 +                                      interp_v3_v3v3(fvec, vmid, v2, 0.8f);
                                        view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                                }
                        }
        }
  }
  
 -static void draw_em_indices(EditMesh *em)
 +static void draw_em_indices(BMEditMesh *em)
  {
 -      EditEdge *e;
 -      EditFace *f;
 -      EditVert *v;
 +      BMEdge *e;
 +      BMFace *f;
 +      BMVert *v;
        int i;
        char numstr[32];
        float pos[3];
        unsigned char col[4];
  
 -      /* For now, reuse appropriate theme colors from stats text colors */
 +      BMIter iter;
 +      BMesh *bm= em->bm;
  
 +      /* For now, reuse appropriate theme colors from stats text colors */
 +      i= 0;
        if (em->selectmode & SCE_SELECT_VERTEX) {
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 -              for (v = em->verts.first, i = 0; v; v = v->next, i++) {
 -                      if (v->f & SELECT) {
 +              BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(v, BM_SELECT)) {
                                sprintf(numstr, "%d", i);
                                view3d_cached_text_draw_add(v->co, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
 +                      i++;
                }
        }
  
        if (em->selectmode & SCE_SELECT_EDGE) {
 +              i= 0;
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
 -              for (e = em->edges.first, i = 0; e; e = e->next, i++) {
 -                      if (e->f & SELECT) {
 +              BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(e, BM_SELECT)) {
                                sprintf(numstr, "%d", i);
                                mid_v3_v3v3(pos, e->v1->co, e->v2->co);
                                view3d_cached_text_draw_add(pos, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
 +                      i++;
                }
        }
  
        if (em->selectmode & SCE_SELECT_FACE) {
 +              i= 0;
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
 -              for (f = em->faces.first, i = 0; f; f = f->next, i++) {
 -                      if (f->f & SELECT) {
 +              BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(f, BM_SELECT)) {
 +                              BM_Compute_Face_CenterMean(bm, f, pos);
                                sprintf(numstr, "%d", i);
 -                              view3d_cached_text_draw_add(f->cent, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
 +                              view3d_cached_text_draw_add(pos, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
 +                      i++;
                }
        }
  }
  
 -static int draw_em_fancy__setFaceOpts(void *UNUSED(userData), int index, int *UNUSED(drawSmooth_r))
 +static int draw_em_fancy__setFaceOpts(void *userData, int index, int *UNUSED(drawSmooth_r))
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(userData, index);
  
 -      if (efa->h==0) {
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
                GPU_enable_material(efa->mat_nr+1, NULL);
                return 1;
        }
                return 0;
  }
  
 -static int draw_em_fancy__setGLSLFaceOpts(void *UNUSED(userData), int index)
 +static int draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(userData, index);
  
 -      return (efa->h==0);
 +      return !BM_TestHFlag(efa, BM_HIDDEN);
  }
  
  static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
 -                          Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
 +                          Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
 +
  {
        Mesh *me = ob->data;
 -      EditFace *efa_act = EM_get_actFace(em, 0); /* annoying but active faces is stored differently */
 -      EditEdge *eed_act = NULL;
 -      EditVert *eve_act = NULL;
 +      BMFace *efa_act = BM_get_actFace(em->bm, 0); /* annoying but active faces is stored differently */
 +      BMEdge *eed_act = NULL;
 +      BMVert *eve_act = NULL;
        
 -      if (em->selected.last) {
 -              EditSelection *ese = em->selected.last;
 +      if (em->bm->selected.last) {
 +              BMEditSelection *ese= em->bm->selected.last;
                /* face is handeled above */
 -              /*if (ese->type == EDITFACE ) {
 -                      efa_act = (EditFace *)ese->data;
 -              } else */ if ( ese->type == EDITEDGE ) {
 -                      eed_act = (EditEdge *)ese->data;
 -              } else if ( ese->type == EDITVERT ) {
 -                      eve_act = (EditVert *)ese->data;
 +              /*if (ese->type == BM_FACE ) {
 +                      efa_act = (BMFace *)ese->data;
 +              } else */ if ( ese->htype == BM_EDGE ) {
 +                      eed_act = (BMEdge *)ese->data;
 +              } else if ( ese->htype == BM_VERT ) {
 +                      eve_act = (BMVert *)ese->data;
                }
        }
        
 -      EM_init_index_arrays(em, 1, 1, 1);
 +      EDBM_init_index_arrays(em, 1, 1, 1);
  
        if(dt>OB_WIRE) {
                if(CHECK_OB_DRAWTEXTURE(v3d, dt)) {
  
                        glEnable(GL_LIGHTING);
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 -                      finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_enable_material, NULL, NULL, 0);
 +                      finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_enable_material, NULL, me->edit_btmesh, 0);
  
                        glFrontFace(GL_CCW);
                        glDisable(GL_LIGHTING);
                if CHECK_OB_DRAWTEXTURE(v3d, dt)
                        col1[3] = 0;
                
 -              draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
 +              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
  
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
                glEnable(GL_BLEND);
                glDepthMask(0);         // disable write in zbuffer, needed for nice transp
                
 -              draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
 +              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
  
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
                /* we are drawing textures and 'ME_DRAWEDGES' is disabled, dont draw any edges */
                
                /* only draw selected edges otherwise there is no way of telling if a face is selected */
 -              draw_em_fancy_edges(scene, v3d, me, cageDM, 1, eed_act);
 +              draw_em_fancy_edges(em, scene, v3d, me, cageDM, 1, eed_act);
                
        } else {
                if(me->drawflag & ME_DRAWSEAMS) {
                        UI_ThemeColor(TH_EDGE_SEAM);
                        glLineWidth(2);
        
 -                      draw_dm_edges_seams(cageDM);
 +                      draw_dm_edges_seams(em, cageDM);
        
                        glColor3ub(0,0,0);
                        glLineWidth(1);
                        UI_ThemeColor(TH_EDGE_SHARP);
                        glLineWidth(2);
        
 -                      draw_dm_edges_sharp(cageDM);
 +                      draw_dm_edges_sharp(em, cageDM);
        
                        glColor3ub(0,0,0);
                        glLineWidth(1);
                }
        
 -              if(me->drawflag & ME_DRAWCREASES) {
 -                      draw_dm_creases(cageDM);
 +              if(me->drawflag & ME_DRAWCREASES && CustomData_has_layer(&em->bm->edata, CD_CREASE)) {
 +                      draw_dm_creases(em, cageDM);
                }
                if(me->drawflag & ME_DRAWBWEIGHTS) {
 -                      draw_dm_bweights(scene, cageDM);
 +                      draw_dm_bweights(em, scene, cageDM);
                }
  
 -              draw_em_fancy_edges(scene, v3d, me, cageDM, 0, eed_act);
 +              draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act);
        }
        if(em) {
 -              draw_em_fancy_verts(scene, v3d, ob, cageDM, eve_act);
 +              draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act);
  
                if(me->drawflag & ME_DRAWNORMALS) {
                        UI_ThemeColor(TH_NORMAL);
 -                      draw_dm_face_normals(scene, cageDM);
 +                      draw_dm_face_normals(em, scene, cageDM);
                }
                if(me->drawflag & ME_DRAW_VNORMALS) {
                        UI_ThemeColor(TH_VNORMAL);
 -                      draw_dm_vert_normals(scene, cageDM);
 +                      draw_dm_vert_normals(em, scene, cageDM);
                }
  
                if ( (me->drawflag & (ME_DRAWEXTRA_EDGELEN|ME_DRAWEXTRA_FACEAREA|ME_DRAWEXTRA_FACEANG)) &&
                GPU_disable_material();
        }
  
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(em);
  }
  
  /* Mesh drawing routines */
@@@ -3168,7 -3100,7 +3168,7 @@@ static void draw_mesh_fancy(Scene *scen
  
        /* Check to draw dynamic paint colors (or weights from WeightVG modifiers).
         * Note: Last "preview-active" modifier in stack will win! */
 -      if(DM_get_face_data_layer(dm, CD_WEIGHT_MCOL) && modifiers_isPreview(ob))
 +      if(DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL) && modifiers_isPreview(ob))
                draw_flags |= DRAW_MODIFIERS_PREVIEW;
  
        /* Unwanted combination */
        
        /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/
        totedge = dm->getNumEdges(dm);
 -      totface = dm->getNumFaces(dm);
 +      totface = dm->getNumTessFaces(dm);
        
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
@@@ -3458,7 -3390,7 +3458,7 @@@ static int draw_mesh_object(Scene *scen
        Object *ob= base->object;
        Object *obedit= scene->obedit;
        Mesh *me= ob->data;
 -      EditMesh *em= me->edit_mesh;
 +      BMEditMesh *em= me->edit_btmesh;
        int do_alpha_after= 0, drawlinked= 0, retval= 0, glsl, check_alpha, i;
  
        /* If we are drawing shadows and any of the materials don't cast a shadow,
                DerivedMesh *finalDM, *cageDM;
                
                if (obedit!=ob)
 -                      finalDM = cageDM = editmesh_get_derived_base(ob, em);
 +                      finalDM = cageDM = editbmesh_get_derived_base(ob, em);
                else
 -                      cageDM = editmesh_get_derived_cage_and_final(scene, ob, em, &finalDM,
 +                      cageDM = editbmesh_get_derived_cage_and_final(scene, ob, em, &finalDM,
                                                                                        scene->customdata_mask);
  
                if(dt>OB_WIRE) {
@@@ -3771,7 -3703,7 +3771,7 @@@ static int drawCurveDerivedMesh(Scene *
                return 1;
        }
  
 -      if(dt>OB_WIRE && dm->getNumFaces(dm)) {
 +      if(dt>OB_WIRE && dm->getNumTessFaces(dm)) {
                int glsl = draw_glsl_material(scene, ob, v3d, dt);
                GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
  
@@@ -4110,7 -4042,7 +4110,7 @@@ static void draw_new_particle_system(Sc
        ParticleDrawData *pdd = psys->pdd;
        Material *ma;
        float vel[3], imat[4][4];
-       float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
+       float timestep, pixsize_scale, pa_size, r_tilt, r_length;
        float pa_time, pa_birthtime, pa_dietime, pa_health, intensity;
        float cfra;
        float ma_col[3]= {0.0f, 0.0f, 0.0f};
                case PART_DRAW_CROSS:
                case PART_DRAW_AXIS:
                        /* lets calculate the scale: */
-                       pixsize= ED_view3d_pixel_size(rv3d, ob->obmat[3]);
                        
-                       if(part->draw_size==0.0)
-                               pixsize *= 2.0f;
+                       if (part->draw_size == 0.0)
+                               pixsize_scale = 2.0f;
                        else
-                               pixsize*=part->draw_size;
+                               pixsize_scale = part->draw_size;
  
                        if(draw_as==PART_DRAW_AXIS)
                                create_cdata = 1;
  
                                ct+=dt;
                                for(i=0; i < trail_count; i++, ct += dt) {
+                                       float pixsize;
                                        if(part->draw & PART_ABS_PATH_TIME) {
                                                if(ct < pa_birthtime || ct > pa_dietime)
                                                        continue;
                                                bb.time = ct;
                                        }
  
+                                       pixsize = ED_view3d_pixel_size(rv3d, state.co) * pixsize_scale;
                                        draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
  
                                        totpoint++;
                        {
                                state.time=cfra;
                                if(psys_get_particle_state(&sim,a,&state,0)){
+                                       float pixsize;
                                        if(psys->parent)
                                                mul_m4_v3(psys->parent->obmat, state.co);
  
                                                bb.time = pa_time;
                                        }
  
+                                       pixsize = ED_view3d_pixel_size(rv3d, state.co) * pixsize_scale;
                                        draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
  
                                        totpoint++;
@@@ -6108,7 -6047,7 +6115,7 @@@ static void drawObjectSelect(Scene *sce
                int hasfaces= 0;
  
                if (dm) {
 -                      hasfaces= dm->getNumFaces(dm);
 +                      hasfaces= dm->getNumTessFaces(dm);
                } else {
                        hasfaces= displist_has_faces(&ob->disp);
                }
@@@ -7039,51 -6978,44 +7046,51 @@@ static void bbs_obmode_mesh_verts(Objec
  
  static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      int offset = (intptr_t) userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      void **ptrs = userData;
 +      int offset = (intptr_t) ptrs[0];
 +      BMVert *eve = EDBM_get_vert_for_index(ptrs[1], index);
  
 -      if (eve->h==0) {
 +      if (!BM_TestHFlag(eve, BM_HIDDEN)) {
                WM_set_framebuffer_index_color(offset+index);
                bglVertex3fv(co);
        }
  }
 -static void bbs_mesh_verts(DerivedMesh *dm, int offset)
 +static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
  {
 +      void *ptrs[2] = {(void*)(intptr_t) offset, em};
 +
        glPointSize( UI_GetThemeValuef(TH_VERTEX_SIZE) );
        bglBegin(GL_POINTS);
 -      dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, (void*)(intptr_t) offset);
 +      dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs);
        bglEnd();
        glPointSize(1.0);
  }             
  
  static int bbs_mesh_wire__setDrawOptions(void *userData, int index)
  {
 -      int offset = (intptr_t) userData;
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      void **ptrs = userData;
 +      int offset = (intptr_t) ptrs[0];
 +      BMEdge *eed = EDBM_get_edge_for_index(ptrs[1], index);
  
 -      if (eed->h==0) {
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
                WM_set_framebuffer_index_color(offset+index);
                return 1;
        } else {
                return 0;
        }
  }
 -static void bbs_mesh_wire(DerivedMesh *dm, int offset)
 +static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
  {
 -      dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*)(intptr_t) offset);
 +      void *ptrs[2] = {(void*)(intptr_t) offset, em};
 +      dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs);
  }             
  
  static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
  {
 -      if (EM_get_face_for_index(index)->h==0) {
 -              if (userData) {
 +      BMFace *efa = EDBM_get_face_for_index(((void**)userData)[0], index);
 +      
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
 +              if (((void**)userData)[1]) {
                        WM_set_framebuffer_index_color(index+1);
                }
                return 1;
        }
  }
  
 -static void bbs_mesh_solid__drawCenter(void *UNUSED(userData), int index, float *cent, float *UNUSED(no))
 +static void bbs_mesh_solid__drawCenter(void *userData, int index, float *cent, float *UNUSED(no))
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(((void**)userData)[0], index);
  
 -      if (efa->h==0 && efa->fgonf!=EM_FGON) {
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                WM_set_framebuffer_index_color(index+1);
  
                bglVertex3fv(cent);
  }
  
  /* two options, facecolors or black */
 -static void bbs_mesh_solid_EM(Scene *scene, View3D *v3d,
 +static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
                                Object *ob, DerivedMesh *dm, int facecol)
  {
 +      void *ptrs[2] = {em, NULL}; //second one being null means to draw black
        cpack(0);
  
        if (facecol) {
 -              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU_enable_material, NULL, (void*)(intptr_t) 1, 0);
 +              ptrs[1] = (void*)(intptr_t) 1;
 +              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU_enable_material, NULL, ptrs, 0);
  
                if(check_ob_drawface_dot(scene, v3d, ob->dt)) {
                        glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
                
                        bglBegin(GL_POINTS);
 -                      dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, NULL);
 +                      dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs);
                        bglEnd();
                }
  
        } else {
 -              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU_enable_material, NULL, (void*) 0, 0);
 +              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU_enable_material, NULL, ptrs, 0);
        }
  }
  
@@@ -7184,36 -7114,36 +7191,36 @@@ void draw_object_backbufsel(Scene *scen
        case OB_MESH:
                if(ob->mode & OB_MODE_EDIT) {
                        Mesh *me= ob->data;
 -                      EditMesh *em= me->edit_mesh;
 +                      BMEditMesh *em= me->edit_btmesh;
  
 -                      DerivedMesh *dm = editmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
 +                      DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
  
 -                      EM_init_index_arrays(em, 1, 1, 1);
 +                      EDBM_init_index_arrays(em, 1, 1, 1);
  
 -                      bbs_mesh_solid_EM(scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
 +                      bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
                        if(ts->selectmode & SCE_SELECT_FACE)
 -                              em_solidoffs = 1+em->totface;
 +                              bm_solidoffs = 1+em->bm->totface;
                        else
 -                              em_solidoffs= 1;
 +                              bm_solidoffs= 1;
                        
                        bglPolygonOffset(rv3d->dist, 1.0);
                        
                        // we draw edges always, for loop (select) tools
 -                      bbs_mesh_wire(dm, em_solidoffs);
 -                      em_wireoffs= em_solidoffs + em->totedge;
 +                      bbs_mesh_wire(em, dm, bm_solidoffs);
 +                      bm_wireoffs= bm_solidoffs + em->bm->totedge;
                        
                        // we draw verts if vert select mode or if in transform (for snap).
                        if(ts->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
 -                              bbs_mesh_verts(dm, em_wireoffs);
 -                              em_vertoffs= em_wireoffs + em->totvert;
 +                              bbs_mesh_verts(em, dm, bm_wireoffs);
 +                              bm_vertoffs= bm_wireoffs + em->bm->totvert;
                        }
 -                      else em_vertoffs= em_wireoffs;
 +                      else bm_vertoffs= bm_wireoffs;
                        
                        bglPolygonOffset(rv3d->dist, 0.0);
  
                        dm->release(dm);
  
 -                      EM_free_index_arrays();
 +                      EDBM_free_index_arrays(em);
                }
                else {
                        Mesh *me= ob->data;
  
                                
                                bbs_obmode_mesh_verts(ob, dm, 1);
 -                              em_vertoffs = me->totvert+1;
 +                              bm_vertoffs = me->totvert+1;
                                dm->release(dm);
                        }
                        else {
@@@ -7257,7 -7187,7 +7264,7 @@@ static void draw_object_mesh_instance(S
        int glsl;
        
        if(ob->mode & OB_MODE_EDIT)
 -              edm= editmesh_get_derived_base(ob, me->edit_mesh);
 +              edm= editbmesh_get_derived_base(ob, me->edit_btmesh);
        else 
                dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
  
index 67165560def66b8fef4b6c897a1da257d790acc6,1a2e893241183ed4ecce9a0fd0059fa106e52866..c05f9de691b93bb53e29150d4c57557d140ae3e7
@@@ -68,6 -68,9 +68,9 @@@
  #include "BL_System.h"
  #endif
  
+ #include "RNA_access.h"
+ #include "RNA_define.h"
  #include "view3d_intern.h"    // own include
  
  /* use this call when executing an operator,
@@@ -753,6 -756,7 +756,6 @@@ void ED_view3d_ob_project_mat_get(Regio
        mult_m4_m4m4(pmat, rv3d->winmat, vmat);
  }
  
 -#if 0
  /* Uses window coordinates (x,y) and depth component z to find a point in
     modelspace */
  void view3d_unproject(bglMats *mats, float out[3], const short x, const short y, const float z)
        out[1] = uy;
        out[2] = uz;
  }
 -#endif
  
  /* use view3d_get_object_project_mat to get projecting mat */
  void ED_view3d_project_float(const ARegion *ar, const float vec[3], float adr[2], float mat[4][4])
@@@ -945,23 -950,29 +948,29 @@@ void project_short_noclip(ARegion *ar, 
        }
  }
  
- void project_float(ARegion *ar, const float vec[3], float adr[2])
+ void apply_project_float(float persmat[4][4], int winx, int winy, const float vec[3], float adr[2])
  {
-       RegionView3D *rv3d= ar->regiondata;
        float vec4[4];
-       
        copy_v3_v3(vec4, vec);
        vec4[3]= 1.0;
        adr[0]= IS_CLIPPED;
-       
-       mul_m4_v4(rv3d->persmat, vec4);
-       
+       mul_m4_v4(persmat, vec4);
        if(vec4[3] > (float)BL_NEAR_CLIP) {
-               adr[0] = (float)(ar->winx/2.0f)+(ar->winx/2.0f)*vec4[0]/vec4[3];
-               adr[1] = (float)(ar->winy/2.0f)+(ar->winy/2.0f)*vec4[1]/vec4[3];
+               adr[0] = (float)(winx/2.0f)+(winx/2.0f)*vec4[0]/vec4[3];
+               adr[1] = (float)(winy/2.0f)+(winy/2.0f)*vec4[1]/vec4[3];
        }
  }
  
+ void project_float(ARegion *ar, const float vec[3], float adr[2])
+ {
+       RegionView3D *rv3d= ar->regiondata;
+       apply_project_float(rv3d->persmat, ar->winx, ar->winy, vec, adr);
+ }
  void project_float_noclip(ARegion *ar, const float vec[3], float adr[2])
  {
        RegionView3D *rv3d= ar->regiondata;
@@@ -1852,3 -1863,42 +1861,42 @@@ float ED_view3d_pixel_size(struct Regio
                                rv3d->persmat[2][3]*co[2])
                        ) * rv3d->pixsize;
  }
+ /* view matrix properties utilities */
+ void ED_view3d_operator_properties_viewmat(wmOperatorType *ot)
+ {
+       PropertyRNA *prop;
+       prop = RNA_def_int(ot->srna, "region_width", 0, 0, INT_MAX, "Region Width", "", 0, INT_MAX);
+       RNA_def_property_flag(prop, PROP_HIDDEN);
+       prop = RNA_def_int(ot->srna, "region_height", 0, 0, INT_MAX, "Region height", "", 0, INT_MAX);
+       RNA_def_property_flag(prop, PROP_HIDDEN);
+       prop = RNA_def_float_matrix(ot->srna, "perspective_matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Perspective Matrix", 0.0f, 0.0f);
+       RNA_def_property_flag(prop, PROP_HIDDEN);
+ }
+ void ED_view3d_operator_properties_viewmat_set(bContext *C, wmOperator *op)
+ {
+       ARegion *ar= CTX_wm_region(C);
+       RegionView3D *rv3d= ED_view3d_context_rv3d(C);
+       if(!RNA_struct_property_is_set(op->ptr, "region_width"))
+               RNA_int_set(op->ptr, "region_width", ar->winx);
+       if(!RNA_struct_property_is_set(op->ptr, "region_height"))
+               RNA_int_set(op->ptr, "region_height", ar->winy);
+       if(!RNA_struct_property_is_set(op->ptr, "perspective_matrix"))
+               RNA_float_set_array(op->ptr, "perspective_matrix", (float *)rv3d->persmat);
+ }
+ void ED_view3d_operator_properties_viewmat_get(wmOperator *op, int *winx, int *winy, float persmat[4][4])
+ {
+       *winx = RNA_int_get(op->ptr, "region_width");
+       *winy = RNA_int_get(op->ptr, "region_height");
+       RNA_float_get_array(op->ptr, "perspective_matrix", (float *)persmat);
+ }
index eea9c13c1ac52d2524bd166f06756de93fa490a2,ced6bb8da636699933321fa9f020444c3cad79cd..1a075b37cca12444bcfe81694d4f3079035fb05e
@@@ -73,7 -73,6 +73,7 @@@
  #include "BKE_sequencer.h"
  #include "BKE_pointcache.h"
  #include "BKE_bmesh.h"
 +#include "BKE_tessmesh.h"
  #include "BKE_scene.h"
  #include "BKE_report.h"
  #include "BKE_tracking.h"
  #include "BLI_math.h"
  #include "BLI_blenlib.h"
  #include "BLI_editVert.h"
 +#include "BLI_array.h"
  #include "BLI_utildefines.h"
 +#include "BLI_smallhash.h"
  
  #include "RNA_access.h"
  
  extern ListBase editelems;
  
  #include "transform.h"
 +#include "bmesh.h"
  
  #include "BLO_sys_types.h" // for intptr_t support
  
@@@ -302,17 -298,16 +302,17 @@@ static void createTransTexspace(TransIn
  
  static void createTransEdge(TransInfo *t)
  {
 -      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 +      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
        TransData *td = NULL;
 -      EditEdge *eed;
 +      BMEdge *eed;
 +      BMIter iter;
        float mtx[3][3], smtx[3][3];
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
  
 -      for(eed= em->edges.first; eed; eed= eed->next) {
 -              if(eed->h==0) {
 -                      if (eed->f & SELECT) countsel++;
 +      BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
 +              if (!BM_TestHFlag(eed, BM_HIDDEN)) {
 +                      if (BM_TestHFlag(eed, BM_SELECT)) countsel++;
                        if (propmode) count++;
                }
        }
        copy_m3_m4(mtx, t->obedit->obmat);
        invert_m3_m3(smtx, mtx);
  
 -      for(eed= em->edges.first; eed; eed= eed->next) {
 -              if(eed->h==0 && (eed->f & SELECT || propmode)) {
 +      BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
 +              if(!BM_TestHFlag(eed, BM_HIDDEN) && (BM_TestHFlag(eed, BM_SELECT) || propmode)) { 
 +                      float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT);
 +                      float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE);
 +                      
                        /* need to set center for center calculations */
                        add_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
                        mul_v3_fl(td->center, 0.5f);
  
                        td->loc= NULL;
 -                      if (eed->f & SELECT)
 +                      if (BM_TestHFlag(eed, BM_SELECT))
                                td->flag= TD_SELECTED;
                        else
                                td->flag= 0;
  
                        td->ext = NULL;
                        if (t->mode == TFM_BWEIGHT) {
 -                              td->val = &(eed->bweight);
 -                              td->ival = eed->bweight;
 +                              td->val = bweight;
 +                              td->ival = bweight ? *bweight : 1.0f;
                        }
                        else {
 -                              td->val = &(eed->crease);
 -                              td->ival = eed->crease;
 +                              td->val = crease;
 +                              td->ival = crease ? *crease : 0.0f;
                        }
  
                        td++;
@@@ -1862,123 -1854,126 +1862,123 @@@ void flushTransParticles(TransInfo *t
  /* proportional distance based on connectivity  */
  #define THRESHOLDFACTOR (1.0f-0.0001f)
  
 -static int connectivity_edge(float mtx[][3], EditVert *v1, EditVert *v2)
 +/*I did this wrong, it should be a breadth-first search
 +  but instead it's a depth-first search, fudged
 +  to report shortest distances.  I have no idea how fast
 +  or slow this is.*/
 +static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists)
  {
 -      float edge_vec[3];
 -      float edge_len;
 -      int done = 0;
 -
 -      /* note: hidden verts are not being checked for, this assumes
 -       * flushing of hidden faces & edges is working right */
 -      
 -      if (v1->f2 + v2->f2 == 4)
 -              return 0;
 +      BMVert **queue = NULL;
 +      float *dqueue = NULL;
 +      int *tots = MEM_callocN(sizeof(int)*em->bm->totvert, "tots editmesh_set_connectivity_distance");
 +      BLI_array_declare(queue);
 +      BLI_array_declare(dqueue);
 +      SmallHash svisit, *visit=&svisit;
 +      BMVert *v;
 +      BMIter viter;
 +      int i, start;
        
 -      sub_v3_v3v3(edge_vec, v1->co, v2->co);
 -      mul_m3_v3(mtx, edge_vec);
 -
 -      edge_len = len_v3(edge_vec);
 -
 -      if (v1->f2) {
 -              if (v2->f2) {
 -                      if (v2->tmp.fp + edge_len < THRESHOLDFACTOR * v1->tmp.fp) {
 -                              v1->tmp.fp = v2->tmp.fp + edge_len;
 -                              done = 1;
 -                      } else if (v1->tmp.fp + edge_len < THRESHOLDFACTOR * v2->tmp.fp) {
 -                              v2->tmp.fp = v1->tmp.fp + edge_len;
 -                              done = 1;
 -                      }
 -              }
 -              else {
 -                      v2->f2 = 1;
 -                      v2->tmp.fp = v1->tmp.fp + edge_len;
 -                      done = 1;
 -              }
 -      }
 -      else if (v2->f2) {
 -              v1->f2 = 1;
 -              v1->tmp.fp = v2->tmp.fp + edge_len;
 -              done = 1;
 -      }
 +      fill_vn_fl(dists, em->bm->totvert, FLT_MAX);
  
 -      return done;
 -}
 +      BM_ElemIndex_Ensure(em->bm, BM_VERT);
  
 -static void editmesh_set_connectivity_distance(EditMesh *em, float mtx[][3])
 -{
 -      EditVert *eve;
 -      EditEdge *eed;
 -      EditFace *efa;
 -      int done= 1;
 -
 -      /* f2 flag is used for 'selection' */
 -      /* tmp.l is offset on scratch array   */
 -      for(eve= em->verts.first; eve; eve= eve->next) {
 -              if(eve->h==0) {
 -                      eve->tmp.fp = 0;
 -
 -                      if(eve->f & SELECT) {
 -                              eve->f2= 2;
 -                      }
 -                      else {
 -                              eve->f2 = 0;
 -                      }
 -              }
 -      }
 +      BLI_smallhash_init(visit);
  
 +      BM_ITER(v, &viter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +              if (BM_TestHFlag(v, BM_SELECT)==0 || BM_TestHFlag(v, BM_HIDDEN))
 +                      continue;
 +                      
 +              
 +              BLI_smallhash_insert(visit, (uintptr_t)v, NULL);
 +              BLI_array_append(queue, v);
 +              BLI_array_append(dqueue, 0.0f);
 +              dists[BM_GetIndex(v)] = 0.0f;
 +      }
 +      
 +      start = 0;
 +      while (start < BLI_array_count(queue)) {
 +              BMIter eiter;
 +              BMEdge *e;
 +              BMVert *v3, *v2;
 +              float d, vec[3];
 +              
 +              v2 = queue[start];
 +              d = dqueue[start];
 +              
 +              BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v2) {
 +                      float d2;
 +                      v3 = BM_OtherEdgeVert(e, v2);
 +                      
 +                      if (BM_TestHFlag(v3, BM_SELECT) || BM_TestHFlag(v3, BM_HIDDEN))
 +                              continue;
 +                      
 +                      sub_v3_v3v3(vec, v2->co, v3->co);
 +                      mul_m3_v3(mtx, vec);
 +                      
 +                      d2 = d + len_v3(vec);
 +                      
 +                      if (dists[BM_GetIndex(v3)] != FLT_MAX)
 +                              dists[BM_GetIndex(v3)] = MIN2(d2, dists[BM_GetIndex(v3)]);
 +                      else
 +                              dists[BM_GetIndex(v3)] = d2;
 +                      
 +                      tots[BM_GetIndex(v3)] = 1;
  
 -      /* Floodfill routine */
 -      /*
 -      At worst this is n*n of complexity where n is number of edges
 -      Best case would be n if the list is ordered perfectly.
 -      Estimate is n log n in average (so not too bad)
 -      */
 -      while(done) {
 -              done= 0;
 -
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      if(eed->h==0) {
 -                              done |= connectivity_edge(mtx, eed->v1, eed->v2);
 -                      }
 +                      if (BLI_smallhash_haskey(visit, (uintptr_t)v3))
 +                              continue;
 +                      
 +                      BLI_smallhash_insert(visit, (uintptr_t)v3, NULL);
 +                      
 +                      BLI_array_append(queue, v3);
 +                      BLI_array_append(dqueue, d2);
                }
 +              
 +              start++;
 +      }
  
 -              /* do internal edges for quads */
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      if (efa->v4 && efa->h==0) {
 -                              done |= connectivity_edge(mtx, efa->v1, efa->v3);
 -                              done |= connectivity_edge(mtx, efa->v2, efa->v4);
 -                      }
 -              }
 +      BLI_smallhash_release(visit);
 +      
 +      for (i=0; i<em->bm->totvert; i++) {
 +              if (tots[i])
 +                      dists[i] /= (float)tots[i];
        }
 +      
 +      BLI_array_free(queue);
 +      BLI_array_free(dqueue);
 +      MEM_freeN(tots);
  }
  
  /* loop-in-a-loop I know, but we need it! (ton) */
 -static void get_face_center(float *cent, EditMesh *em, EditVert *eve)
 + static void get_face_center(float cent_r[3], BMesh *bm, BMVert *eve)
 +
  {
 -      EditFace *efa;
 +      BMFace *efa;
 +      BMIter iter;
  
 -      for(efa= em->faces.first; efa; efa= efa->next)
 -              if(efa->f & SELECT)
 -                      if(efa->v1==eve || efa->v2==eve || efa->v3==eve || efa->v4==eve)
 -                              break;
 -      if(efa) {
 -              copy_v3_v3(cent, efa->cent);
 +      BM_ITER(efa, &iter, bm, BM_FACES_OF_VERT, eve) {
 +              if (BM_Selected(bm, efa)) {
 +                      BM_Compute_Face_CenterMean(bm, efa, cent_r);
 +                      break;
 +              }
        }
  }
  
 -static void get_edge_center(float *cent, EditMesh *em, EditVert *eve)
 +static void get_edge_center(float cent_r[3], BMesh *bm, BMVert *eve)
  {
 -      EditEdge *eed;
 +      BMEdge *eed;
 +      BMIter iter;
  
 -      for(eed= em->edges.first; eed; eed= eed->next)
 -              if(eed->f & SELECT)
 -                      if(eed->v1==eve || eed->v2==eve)
 -                              break;
 -      if(eed) {
 -              mid_v3_v3v3(cent, eed->v1->co, eed->v2->co);
 +      BM_ITER(eed, &iter, bm, BM_EDGES_OF_VERT, eve) {
 +              if (BM_Selected(bm, eed)) {
 +                      mid_v3_v3v3(cent_r, eed->v1->co, eed->v2->co);
 +                      break;
 +              }
        }
  }
  
  /* way to overwrite what data is edited with transform
   * static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key) */
 -static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert *eve)
 +static void VertsToTransData(TransInfo *t, TransData *td, BMEditMesh *em, BMVert *eve, float *bweight)
  {
        td->flag = 0;
        //if(key)
        td->loc = eve->co;
  
        copy_v3_v3(td->center, td->loc);
 +
        if(t->around==V3D_LOCAL) {
                if(em->selectmode & SCE_SELECT_FACE)
 -                      get_face_center(td->center, em, eve);
 +                      get_face_center(td->center, em->bm, eve);
                else if(em->selectmode & SCE_SELECT_EDGE)
 -                      get_edge_center(td->center, em, eve);
 +                      get_edge_center(td->center, em->bm, eve);
        }
        copy_v3_v3(td->iloc, td->loc);
  
        td->val = NULL;
        td->extra = NULL;
        if (t->mode == TFM_BWEIGHT) {
 -              td->val = &(eve->bweight);
 -              td->ival = eve->bweight;
 +              td->val = bweight;
 +              td->ival = bweight ? *(bweight) : 1.0f;
        }
  }
  
@@@ -2018,23 -2012,18 +2018,23 @@@ static void createTransEditVerts(bConte
  {
        ToolSettings *ts = CTX_data_tool_settings(C);
        TransData *tob = NULL;
 -      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 -      EditVert *eve;
 -      EditVert *eve_act = NULL;
 +      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
 +      BMesh *bm = em->bm;
 +      BMVert *eve;
 +      BMIter iter;
 +      BMVert *eve_act = NULL;
        float *mappedcos = NULL, *quats= NULL;
        float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
 +      float *dists=NULL;
        int count=0, countsel=0, a, totleft;
        int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
        int mirror = 0;
 +      char *selstate = NULL;
        short selectmode = ts->selectmode;
  
        if (t->flag & T_MIRROR)
        {
 +              EDBM_CacheMirrorVerts(em, TRUE);
                mirror = 1;
        }
  
                selectmode = SCE_SELECT_EDGE;
        }
  
 +      /* BMESH_TODO, writing into the index values is BAD!, means we cant
 +       * use the values for vertex mirror - campbell */
 +
        // transform now requires awareness for select mode, so we tag the f1 flags in verts
        if(selectmode & SCE_SELECT_VERTEX) {
 -              for(eve= em->verts.first; eve; eve= eve->next) {
 -                      if(eve->h==0 && (eve->f & SELECT))
 -                              eve->f1= SELECT;
 -                      else
 -                              eve->f1= 0;
 +              BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
 +                      if (BM_Selected(bm, eve)) {
 +                              BM_SetHFlag(eve, BM_TMP_TAG);
 +                      }
 +                      else {
 +                              BM_ClearHFlag(eve, BM_TMP_TAG);
 +                      }
                }
        }
        else if(selectmode & SCE_SELECT_EDGE) {
 -              EditEdge *eed;
 -              for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      if(eed->h==0 && (eed->f & SELECT))
 -                              eed->v1->f1= eed->v2->f1= SELECT;
 +              BMEdge *eed;
 +
 +              eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +              for( ; eve; eve=BMIter_Step(&iter)) BM_ClearHFlag(eve, BM_TMP_TAG);
 +
 +              eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
 +              for( ; eed; eed=BMIter_Step(&iter)) {
 +                      if (BM_Selected(bm, eed)) {
 +                              BM_SetHFlag(eed->v1, BM_TMP_TAG);
 +                              BM_SetHFlag(eed->v2, BM_TMP_TAG);
 +                      }
                }
        }
        else {
 -              EditFace *efa;
 -              for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      if(efa->h==0 && (efa->f & SELECT)) {
 -                              efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
 -                              if(efa->v4) efa->v4->f1= SELECT;
 +              BMFace *efa;
 +              eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +              for( ; eve; eve=BMIter_Step(&iter)) BM_ClearHFlag(eve, BM_TMP_TAG);
 +
 +              efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
 +              for( ; efa; efa=BMIter_Step(&iter)) {
 +                      if (BM_Selected(bm, efa)) {
 +                              BMIter liter;
 +                              BMLoop *l;
 +
 +                              l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, efa);
 +                              for (; l; l=BMIter_Step(&liter)) {
 +                                      BM_SetHFlag(l->v, BM_TMP_TAG);
 +                              }
                        }
                }
        }
  
 -      /* now we can count */
 -      for(eve= em->verts.first; eve; eve= eve->next) {
 -              if(eve->h==0) {
 -                      if(eve->f1) countsel++;
 -                      if(propmode) count++;
 +      /* now we can count. we store selection state in selstate, since
 +       * get_crazy_mapped_editverts messes up the index state of the
 +       * verts*/
 +      selstate = MEM_callocN(sizeof(*selstate) * bm->totvert, __func__);
 +      eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +      for(a=0; eve; eve=BMIter_Step(&iter), a++) {
 +              if (BM_TestHFlag(eve, BM_TMP_TAG)) {
 +                      selstate[a] = 1;
 +                      countsel++;
                }
 +              if(propmode) count++;
        }
  
 -       /* note: in prop mode we need at least 1 selected */
 -      if (countsel==0) return;
 +      /* note: in prop mode we need at least 1 selected */
 +      if (countsel == 0) {
 +              goto cleanup;
 +      }
  
        /* check active */
 -      if (em->selected.last) {
 -              EditSelection *ese = em->selected.last;
 -              if ( ese->type == EDITVERT ) {
 -                      eve_act = (EditVert *)ese->data;
 +      if (em->bm->selected.last) {
 +              BMEditSelection *ese = em->bm->selected.last;
 +              if (ese->htype == BM_VERT) {
 +                      eve_act = (BMVert *)ese->data;
                }
        }
  
  
 -      if(propmode) t->total = count;
 +      if(propmode) {
 +              t->total = count;
 +
 +              /* allocating scratch arrays */
 +              if (propmode & T_PROP_CONNECTED)
 +                      dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
 +      }
        else t->total = countsel;
  
        tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
        invert_m3_m3(smtx, mtx);
  
        if(propmode & T_PROP_CONNECTED) {
 -              editmesh_set_connectivity_distance(em, mtx);
 +              editmesh_set_connectivity_distance(em, mtx, dists);
        }
  
        /* detect CrazySpace [tm] */
                if(modifiers_isCorrectableDeformed(t->obedit)) {
                        /* check if we can use deform matrices for modifier from the
                           start up to stack, they are more accurate than quats */
 -                      totleft= editmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
 +                      totleft= editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
  
                        /* if we still have more modifiers, also do crazyspace
                           correction with quats, relative to the coordinates after
                        if(totleft > 0) {
                                mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit);
                                quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
 -                              crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats);
 +                              crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats); /* BMESH_TODO, abuses vertex index, should use an int array */
                                if(mappedcos)
                                        MEM_freeN(mappedcos);
                        }
  
        /* find out which half we do */
        if(mirror) {
 -              for (eve=em->verts.first; eve; eve=eve->next) {
 -                      if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
 +              eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +              for(a=0; eve; eve=BMIter_Step(&iter), a++) {
 +                      if(!BM_TestHFlag(eve, BM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) {
                                if(eve->co[0]<0.0f)
                                {
                                        t->mirror = -1;
                }
        }
  
 -      for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
 -              if(eve->h==0) {
 -                      if(propmode || eve->f1) {
 -                              VertsToTransData(t, tob, em, eve);
 +      eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +      for(a=0; eve; eve=BMIter_Step(&iter), a++) {
 +              if(!BM_TestHFlag(eve, BM_HIDDEN)) {
 +                      if(propmode || selstate[a]) {
 +                              float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
 +                              
 +                              VertsToTransData(t, tob, em, eve, bweight);
  
                                /* selected */
 -                              if(eve->f1) tob->flag |= TD_SELECTED;
 +                              if(selstate[a]) tob->flag |= TD_SELECTED;
  
                                /* active */
                                if(eve == eve_act) tob->flag |= TD_ACTIVE;
  
                                if(propmode) {
 -                                      if (eve->f2) {
 -                                              tob->dist= eve->tmp.fp;
 -                                      }
 -                                      else {
 +                                      if (propmode & T_PROP_CONNECTED) {
 +                                              tob->dist = dists[a];
 +                                      } else {
                                                tob->flag |= TD_NOTCONNECTED;
                                                tob->dist = MAXFLOAT;
                                        }
                                }
  
                                /* CrazySpace */
 -                              if(defmats || (quats && eve->tmp.p)) {
 -                                      float mat[3][3], imat[3][3], qmat[3][3];
 +                              if(defmats || (quats && BM_GetIndex(eve) != -1)) {
 +                                      float mat[3][3], qmat[3][3], imat[3][3];
  
                                        /* use both or either quat and defmat correction */
 -                                      if(quats && eve->tmp.f) {
 -                                              quat_to_mat3( qmat,eve->tmp.p);
 +                                      if(quats && BM_GetIndex(eve) != -1) {
 +                                              quat_to_mat3(qmat, quats + 4*BM_GetIndex(eve));
  
                                                if(defmats)
                                                        mul_serie_m3(mat, mtx, qmat, defmats[a],
  
                                /* Mirror? */
                                if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
 -                                      EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, eve, tob->iloc, a);   /* initializes octree on first call */
 -                                      if(vmir != eve) {
 +                                      BMVert *vmir= EDBM_GetMirrorVert(em, eve); //t->obedit, em, eve, tob->iloc, a);
 +                                      if(vmir && vmir != eve) {
                                                tob->extra = vmir;
                                        }
                                }
                        }
                }
        }
 -      
 +
 +cleanup:
        /* crazy space free */
        if(quats)
                MEM_freeN(quats);
        if(defmats)
                MEM_freeN(defmats);
 +      if (dists)
 +              MEM_freeN(dists);
 +      
 +      MEM_freeN(selstate);
 +
 +      if (t->flag & T_MIRROR) {
 +              EDBM_EndMirrorCache(em);
 +              mirror = 1;
 +      }
  }
  
  /* *** NODE EDITOR *** */
@@@ -2434,33 -2378,30 +2434,33 @@@ static void createTransUVs(bContext *C
        Scene *scene = t->scene;
        TransData *td = NULL;
        TransData2D *td2d = NULL;
 -      MTFace *tf;
 +      MTexPoly *tf;
 +      MLoopUV *luv;
 +      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
 +      BMFace *efa;
 +      BMLoop *l;
 +      BMIter iter, liter;
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
  
 -      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 -      EditFace *efa;
 -
        if(!ED_space_image_show_uvedit(sima, t->obedit)) return;
  
        /* count */
 -      for (efa= em->faces.first; efa; efa= efa->next) {
 -              tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 +      BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
 +              tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
  
 -              if(uvedit_face_visible(scene, ima, efa, tf)) {
 -                      efa->tmp.p = tf;
 +              if(!uvedit_face_visible(scene, ima, efa, tf)) {
 +                      BM_ClearHFlag(efa, BM_TMP_TAG);
 +                      continue;
 +              }
 +              
 +              BM_SetHFlag(efa, BM_TMP_TAG);
 +              BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
 +                      if (uvedit_uv_selected(em, scene, l)) 
 +                              countsel++;
  
 -                      if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++;
 -                      if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++;
 -                      if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++;
 -                      if (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) countsel++;
                        if(propmode)
 -                              count += (efa->v4)? 4: 3;
 -              } else {
 -                      efa->tmp.p = NULL;
 +                              count++;
                }
        }
  
        td= t->data;
        td2d= t->data2d;
  
 -      for (efa= em->faces.first; efa; efa= efa->next) {
 -              if ((tf=(MTFace *)efa->tmp.p)) {
 -                      if (propmode) {
 -                              UVsToTransData(sima, td++, td2d++, tf->uv[0], uvedit_uv_selected(scene, efa, tf, 0));
 -                              UVsToTransData(sima, td++, td2d++, tf->uv[1], uvedit_uv_selected(scene, efa, tf, 1));
 -                              UVsToTransData(sima, td++, td2d++, tf->uv[2], uvedit_uv_selected(scene, efa, tf, 2));
 -                              if(efa->v4)
 -                                      UVsToTransData(sima, td++, td2d++, tf->uv[3], uvedit_uv_selected(scene, efa, tf, 3));
 -                      } else {
 -                              if(uvedit_uv_selected(scene, efa, tf, 0))                               UVsToTransData(sima, td++, td2d++, tf->uv[0], 1);
 -                              if(uvedit_uv_selected(scene, efa, tf, 1))                               UVsToTransData(sima, td++, td2d++, tf->uv[1], 1);
 -                              if(uvedit_uv_selected(scene, efa, tf, 2))                               UVsToTransData(sima, td++, td2d++, tf->uv[2], 1);
 -                              if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))    UVsToTransData(sima, td++, td2d++, tf->uv[3], 1);
 -                      }
 +      BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
 +              if (!BM_TestHFlag(efa, BM_TMP_TAG))
 +                      continue;
 +
 +              tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 +              BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
 +                      if (!propmode && !uvedit_uv_selected(em, scene, l))
 +                              continue;
 +                      
 +                      luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 +                      UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_selected(em, scene, l));
                }
        }
  
@@@ -4864,7 -4808,7 +4864,7 @@@ void special_aftertrans_update(bContex
        if (t->spacetype==SPACE_VIEW3D) {
                if (t->obedit) {
                        if (cancelled==0) {
 -                              EM_automerge(t->scene, t->obedit, 1);
 +                              EDBM_automerge(t->scene, t->obedit, 1);
                        }
                }
        }
        else if (t->obedit) {
                if (t->obedit->type == OB_MESH)
                {
 -                      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 +                      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
                        /* table needs to be created for each edit command, since vertices can move etc */
                        mesh_octree_table(t->obedit, em, NULL, 'e');
                }
@@@ -5696,10 -5640,13 +5696,13 @@@ static void createTransTrackingData(bCo
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
  
-       if(!clip || !BKE_movieclip_has_frame(clip, &sc->user)) {
-               t->total = 0;
+       t->total = 0;
+       if(!clip || !BKE_movieclip_has_frame(clip, &sc->user))
+               return;
+       if(!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION))
                return;
-       }
  
        if(ar->regiontype == RGN_TYPE_PREVIEW) {
                /* transformation was called from graph editor */
index 6014413bd00687295bc0c6d2616b407361345498,2493b5e0f747962daa6557c6ac794dd6b4f6ad89..72e5475449803bb3dcb2fa9dba0bf9183c9c7bd7
@@@ -47,6 -47,8 +47,8 @@@
  #include "MOD_boolean_util.h"
  #include "MOD_util.h"
  
+ #include "PIL_time.h"
  static void copyData(ModifierData *md, ModifierData *target)
  {
        BooleanModifierData *bmd = (BooleanModifierData*) md;
@@@ -93,14 -95,14 +95,14 @@@ static DerivedMesh *get_quick_derivedMe
  {
        DerivedMesh *result = NULL;
  
 -      if(derivedData->getNumFaces(derivedData) == 0 || dm->getNumFaces(dm) == 0) {
 +      if(derivedData->getNumPolys(derivedData) == 0 || dm->getNumPolys(dm) == 0) {
                switch(operation) {
                        case eBooleanModifierOp_Intersect:
 -                              result = CDDM_new(0, 0, 0);
 +                              result = CDDM_new(0, 0, 0, 0, 0);
                                break;
  
                        case eBooleanModifierOp_Union:
 -                              if(derivedData->getNumFaces(derivedData)) result = derivedData;
 +                              if(derivedData->getNumPolys(derivedData)) result = derivedData;
                                else result = CDDM_copy(dm);
  
                                break;
@@@ -136,12 -138,12 +138,16 @@@ static DerivedMesh *applyModifier(Modif
                result = get_quick_derivedMesh(derivedData, dm, bmd->operation);
  
                if(result == NULL) {
 +
 +                      DM_ensure_tessface(dm);          /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
 +                      DM_ensure_tessface(derivedData); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
 +
+                       // TIMEIT_START(NewBooleanDerivedMesh)
                        result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
                                        1 + bmd->operation);
+                       // TIMEIT_END(NewBooleanDerivedMesh)
                }
  
                /* if new mesh returned, return it; otherwise there was
index dcde921f84481975b1d8f88d2a0bf5fd596ca3e3,5ce05e5e062632f1cfb854560c450b222f965230..0ff37c6fa76e8d6f88bb12ba6951a9de1922db6b
@@@ -119,17 -119,19 +119,19 @@@ static void deformVerts(ModifierData *m
  {
        CurveModifierData *cmd = (CurveModifierData*) md;
  
+       /* silly that defaxis and curve_deform_verts are off by 1
+        * but leave for now to save having to call do_versions */
        curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts,
-                          cmd->name, cmd->defaxis);
+                          cmd->name, cmd->defaxis-1);
  }
  
  static void deformVertsEM(
 -                                      ModifierData *md, Object *ob, struct EditMesh *editData,
 +                                      ModifierData *md, Object *ob, struct BMEditMesh *editData,
         DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
  {
        DerivedMesh *dm = derivedData;
  
 -      if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
 +      if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, FALSE, FALSE);
  
        deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);